diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index 7ba87d37edd..e4b2864fac6 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -36,6 +36,13 @@ jobs: mkdir build && cd build && cp ../misc/clang-static-analyzer-run.sh . ./clang-static-analyzer-run.sh + - name: Summary + if: success() || failure() + run: | + sudo apt-get install html2text + html2text build/scan-reports-all/*/index.html + + linux_cov: # See https://app.codecov.io/gh/BRL-CAD/brlcad for analysis results name: LCOV Coverage testing diff --git a/AUTHORS b/AUTHORS index 83839a314c5..c7b2b2a32b5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1011,6 +1011,25 @@ Bergeron, Wesley Paul 2022 February Texas A&M University +Chen, Zhuo (Danny) +2023 February +Texas A&M University + +Hoskinson, Allyson +2023 February +Texas A&M University + +Plant, Andrew +2023 February +Texas A&M University + +Sturtevant, Mark +2023 February +Texas A&M University + +Tao, Michael +2023 February +Texas A&M University SPECIAL THANKS @@ -1326,6 +1345,10 @@ Liu, Jeffrey 2019 December Open Source (GCI) +Wade, Pauline +2021 August +Texas A&M University + nicknames r-ricci 2022 January Open Source diff --git a/CHANGES b/CHANGES index 14146721099..f082848dc77 100644 --- a/CHANGES +++ b/CHANGES @@ -129,13 +129,13 @@ generally listed for reference. Items marked with a "'" (single quote) are undocumented and may be removed at any time. -7.32 +7.38 ---- -burst - Point Burst Damage Assessment Model (PDAM) input preparation - tool. Obsolete, no longer in use by upstream tools, - scheduling for removal +MGED commands + E (a.k.a "big E") - replaced by "draw -m5" +7.32 +---- include/bu/app.h bu_brlcad_root: replaced by bu_dir bu_brlcad_dir: replaced by bu_dir @@ -208,11 +208,6 @@ MGED commands savekey, shaded_mode, sync Removed as part of distillation effort [deprecated 7.28] -libtermio, libcursor - Public API scope reduction - any client code that needs - to interact with the terminal at these levels should handle - what is needed locally. - 7.26 ---- image tools @@ -399,6 +394,18 @@ include/raytrace.h ********************************************************************** (reverse chronological order) +7.38.0 +------ +burst + Point Burst Damage Assessment Model (PDAM) input preparation + tool. Obsolete, no longer in use by upstream tools, + removed [deprecated 7.32] + +libtermio, libcursor + Public API scope reduction - any client code that needs + to interact with the terminal at these levels should handle + what is needed locally. [deprecated 7.28] + 7.34.0 ------ nirt @@ -1677,3 +1684,16 @@ s/bu_whereis\(/bu_whence\(/g s/bu_which\(/bu_whence\(/g s/rt_gettree_muves\(/rt_gettrees_and_attrs\(/g +7.36 +---- +s/V3DIR_FROM_AZEL\(/bn_vec_ae\(/g +s/AZEL_FROM_V3DIR\([[:space:]]*([^,]*),[[:space:]]*([^,]*),/bn_ae_vec\(&\1, &\2/g + +7.38 +---- +s/bg_polygon_triangulate/bg_poly_triangulate/g +s/bg_nested_polygon_triangulate/bg_nested_poly_triangulate/g +s/OP_NMG_TESS/OP_TESS/g +s/tree_nmgregion/tree_tessellation/g +s/nmg_booltree_leaf_tess/rt_booltree_leaf_tess/g + diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a8d3d1bf71..85b8f217c43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,11 +101,6 @@ if (POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif (POLICY CMP0074) -# Test name character check - need to look into this one... -if (POLICY CMP0110) - cmake_policy(SET CMP0110 OLD) -endif (POLICY CMP0110) - # cmake_dependent_option() supports full Condition Syntax if (POLICY CMP0127) cmake_policy(SET CMP0127 NEW) @@ -152,6 +147,47 @@ endif(BRLCAD_PRINT_MSGS) # do this early in the process. include(BRLCAD_Environment_Setup) +# Populate these early, even though their main use is in +# misc/CMake/BRLCAD_ExternalDeps.cmake - find_program and find_package calls +# may also make use of them, particularly BRLCAD_EXT_NOINSTALL_DIR +set(ENV_HOME "$ENV{HOME}") +if (NOT ENV_HOME) + set(ENV_HOME "$ENV{USERPROFILE}") +endif (NOT ENV_HOME) + +# Check common location(s) in home directory +set(EXT_CANDIDATES bext_output brlcad_ext) +foreach(EC ${EXT_CANDIDATES}) + if (NOT DEFINED BRLCAD_EXT_DIR AND EXISTS "${ENV_HOME}/${EC}") + set(BRLCAD_EXT_DIR "${ENV_HOME}/${EC}") + endif (NOT DEFINED BRLCAD_EXT_DIR AND EXISTS "${ENV_HOME}/${EC}") +endforeach(EC ${EXT_CANDIDATES}) + +if (NOT DEFINED BRLCAD_EXT_INSTALL_DIR AND DEFINED BRLCAD_EXT_DIR AND EXISTS "${BRLCAD_EXT_DIR}/install") + set(BRLCAD_EXT_INSTALL_DIR "${BRLCAD_EXT_DIR}/install") +endif (NOT DEFINED BRLCAD_EXT_INSTALL_DIR AND DEFINED BRLCAD_EXT_DIR AND EXISTS "${BRLCAD_EXT_DIR}/install") +# Need to handle the case where BRLCAD_EXT_DIR is a symlink - if it +# is, we need to expand the symlink in order for the tar tricks we use +# later for file copying to work... +if (DEFINED BRLCAD_EXT_INSTALL_DIR AND IS_SYMLINK ${BRLCAD_EXT_INSTALL_DIR}) + file(REAL_PATH "${BRLCAD_EXT_INSTALL_DIR}" EXT_PATH) + set(BRLCAD_EXT_INSTALL_DIR "${EXT_PATH}") +endif (DEFINED BRLCAD_EXT_INSTALL_DIR AND IS_SYMLINK ${BRLCAD_EXT_INSTALL_DIR}) + +# For noinstall we don't need to worry about symlinks since we'll be using +# the contents in place. +if (NOT DEFINED BRLCAD_EXT_NOINSTALL_DIR AND DEFINED BRLCAD_EXT_DIR AND EXISTS "${BRLCAD_EXT_DIR}/noinstall") + set(BRLCAD_EXT_NOINSTALL_DIR "${BRLCAD_EXT_DIR}/noinstall") +endif (NOT DEFINED BRLCAD_EXT_NOINSTALL_DIR AND DEFINED BRLCAD_EXT_DIR AND EXISTS "${BRLCAD_EXT_DIR}/noinstall") + +# If we're doing the non-src-other build, we've got to have brlcad_externals +# for at least a few custom components no matter how many system packages got +# installed. +if (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other") + if (NOT DEFINED BRLCAD_EXT_NOINSTALL_DIR OR NOT DEFINED BRLCAD_EXT_INSTALL_DIR) + message(FATAL_ERROR "BRL-CAD requires a source for external components - please set BRLCAD_EXT_DIR to a directory location containing the install and noinstall folders (the outputs produced by building https://github.com/BRL-CAD/brlcad_externals). By default this location is ${ENV_HOME}/brlcad_ext but it can be overridden. In lieu of setting BRLCAD_EXT_DIR, it is also possible to directly set BRLCAD_EXT_INSTALL_DIR and BRLCAD_EXT_NOINSTALL_DIR to custom indivdiaul folders holding the necessary dependencies.") + endif (NOT DEFINED BRLCAD_EXT_NOINSTALL_DIR OR NOT DEFINED BRLCAD_EXT_INSTALL_DIR) +endif (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other") #--------------------------------------------------------------------- # Define various utilities. @@ -266,36 +302,64 @@ endif (IS_DIRECTORY /usr/local) include(BRLCAD_Install_Prefix) #--------------------------------------------------------------------- -# The following logic is what allows binaries to run successfully in -# the build directory AND install directory. Thanks to plplot for -# identifying the necessity of setting CMAKE_INSTALL_NAME_DIR on OSX. -# Documentation of these options is available at -# http://www.cmake.org/Wiki/CMake_RPATH_handling -if (NOT COMMAND std_build_rpath) - include(RPath_Setup) -endif (NOT COMMAND std_build_rpath) +# RPath is used on platforms such as Linux to allow programs to be +# relocatable. It is also used to help programs run from their +# positions in the build directory. +# +# Managing this is somewhat involved - there are lots of situations +# where the logic will work because of a full path present in the +# rpath settings and mask a problem with the relative lookup. # We want the full RPATH set in the build tree so we can run programs without # needing to set LD_LIBRARY_PATH set(CMAKE_SKIP_BUILD_RPATH FALSE) -# We DON'T want the final install directory RPATH set in the build directory -# - it should only be set to the installation value when actually installed. +# We DON'T want the final install directory RPATH set in the build directory - +# it should only be set to the installation value when actually installed. set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # Add the automatically determined parts of the RPATH which point to # directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -# Set RPATH value to use when installing. This should be set to always -# prefer the version in the installed path when possible, but fall back on a -# location relative to the loading file's path if the installed version is -# not present. How to do so is platform specific. -relative_rpath(RELPATH) -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}${RELPATH}") - -std_build_rpath() +# The following logic is what allows binaries to run successfully in the build +# directory AND install directory. Thanks to plplot for identifying the +# necessity of setting CMAKE_INSTALL_NAME_DIR on OSX. Documentation of these +# options is available at http://www.cmake.org/Wiki/CMake_RPATH_handling +# +# TODO - it looks like this doesn't work reliably with relocation - for the new +# ext setup, let's see if we can solve the per-target usage of the +# INSTALL_RPATH property for a more precise solution. +if (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) + if (NOT COMMAND std_build_rpath) + include(RPath_Setup) + endif (NOT COMMAND std_build_rpath) + + # Set RPATH value to use when installing. This should be set to always + # prefer the version in the installed path when possible, but fall back on a + # location relative to the loading file's path if the installed version is + # not present. How to do so is platform specific. + relative_rpath(RELPATH) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}${RELPATH}") + + std_build_rpath() +else (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) + + # This will need to be overridden for some targets that have a different + # relative position to LIB_DIR using the INSTALL_RPATH target property. + # However, we can cover the most common case for RPATH setting using the + # global default. + if (NOT APPLE) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}:$ORIGIN/../${LIB_DIR}") + else (NOT APPLE) + # For OSX, use the INSTALL_NAME_DIR target property + set(CMAKE_INSTALL_RPATH "@executable_path/../${LIB_DIR}") + set(CMAKE_INSTALL_NAME_DIR "@executable_path/../${LIB_DIR}") + endif (NOT APPLE) + +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) +#--------------------------------------------------------------------- # For certain platforms (in particular Visual C++) we want to keep some pre-defined # flags that are commonly used in the build logic. if(NOT DEFINED CMAKE_C_FLAGS_DEFAULT) @@ -350,7 +414,7 @@ string(STRIP "${C_STANDARD_FLAGS}" C_STANDARD_FLAGS) # C++ unset(CXX_STANDARD_FLAGS) set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CXX_STANDARD_FLAGS "${CMAKE_CXX_FLAGS_DEFAULT} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION} ${API_FLAGS}") string(STRIP "${CXX_STANDARD_FLAGS}" CXX_STANDARD_FLAGS) @@ -1450,6 +1514,7 @@ BRLCAD_HEADER_SYS_WAIT() BRLCAD_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) BRLCAD_INCLUDE_FILE(arpa/inet.h HAVE_ARPA_INET_H) +BRLCAD_INCLUDE_FILE(conio.h HAVE_CONIO_H) BRLCAD_INCLUDE_FILE(direct.h HAVE_DIRECT_H) BRLCAD_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H) BRLCAD_INCLUDE_FILE(dslib.h HAVE_DSLIB_H) @@ -2060,8 +2125,35 @@ mark_as_advanced(MISC_ADDED_DIRS) # options.) add_subdirectory(misc/tools) -# The first order of business in src/other is the ext projects -add_subdirectory(src/other/ext) +if (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) + # The first order of business in src/other is the ext projects + add_subdirectory(src/other/ext) +else (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) + # Now that the user options are set and we have misc/tools... if we're going to + # be bundling 3rd party dependencies, we need to get them staged - some of the + # build steps will require that dependencies work during the build process, and + # the most reliably way to do that is to get them in place in the build + # directory. Because the feature flags may impact what we're looking to use, + # we wait until they are set to do the find_package calls. + # + # The way BRL-CAD handles bundled dependencies is simple - if a dependency + # is found in the specified BRLCAD_EXT_DIR directory by find_package, that + # version is used in preference to a system version. If no bundled version + # is found the standard system search logic will kick in. (System versions + # will NOT be bundled with BRL-CAD.) + # + # Note that while feature flags can change which elements of BRL-CAD are built, + # they WON'T change what's bundled with BRL-CAD for install - that's based + # strictly on the contents of the user's specified external dependencies + # directory. If (for example) STEP support is disabled, this logic will not + # skip bundling the STEPCODE external dependencies - the user should set up an + # external dependencies repository without that component if they don't want to + # bundle it. + # + # This logic will also set up the necessary steps to install the bundling + # targets as part of BRL-CAD's install process + include(BRLCAD_ExternalDeps) +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) # Now that we've done the system tests with BRL-CAD's compile flags, # add src/other to pick up any tests it needs. We must add src/other @@ -2069,7 +2161,9 @@ add_subdirectory(src/other/ext) # targets. Remember that src/other wipes the top level flags generated # by BRL-CAD for its own subdirectories - it is added after the BRL-CAD # tests so the CACHE reflects BRL-CAD's test results. -add_subdirectory(src/other) +if (EXISTS ${CMAKE_SOURCE_DIR}/src/other) + add_subdirectory(src/other) +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/other) # Now put back the BRL-CAD flags RESTORE_CACHED_BUILD_FLAGS(_BRLCAD) @@ -2416,6 +2510,9 @@ function(DIFF_FILE filename) endif(NOT "${OLD_STR}" STREQUAL "${NEW_STR}") endfunction(DIFF_FILE filename) +# TODO - once we remove src/other/ext, eliminate this guard and +# update INSTALL and configure to reflect the new approach. +if (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) # Finalize and check INSTALL file file(READ "${BRLCAD_SOURCE_DIR}/INSTALL" SRC_INSTALL_STR) string(REGEX REPLACE "${CONFIG_OPT_STRING}.*" "" INSTALL_PREFIX "${SRC_INSTALL_STR}") @@ -2440,7 +2537,7 @@ DIFF_FILE(configure) if(CONFIG_FATAL_ERROR) message(FATAL_ERROR "Configure haulted because INSTALL and/or configure script are out of date.") endif(CONFIG_FATAL_ERROR) - +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/other/ext) # Because the build-time-delta needs a configure-file but comes at the # end of the CMake configure, the preparation of the final distclean @@ -2500,11 +2597,17 @@ add_custom_target(print-warning-message ${CMAKE_COMMAND} -E echo "" ) set_target_properties(print-warning-message PROPERTIES FOLDER "Compilation Utilities") -# NOTE: set to NEW and remove slashes after 3.19 is required -if(POLICY CMP0110) - cmake_policy(SET CMP0110 OLD) -endif(POLICY CMP0110) -add_test(NAME "NOTE:\\ some\\ 'test'\\ tests\\ are\\ expected\\ to\\ fail,\\ 'regress'\\ must\\ pass" COMMAND ${CMAKE_COMMAND} --build . --target print-warning-message) +# NOTE: after we require a minimum of 3.19, set CMP0110 NEW and +# remove the version check +if (${CMAKE_VERSION} VERSION_LESS "3.19") + if(POLICY CMP0110) + cmake_policy(SET CMP0110 OLD) + endif(POLICY CMP0110) + add_test(NAME "NOTE:\\ some\\ 'test'\\ tests\\ are\\ expected\\ to\\ fail,\\ 'regress'\\ must\\ pass" COMMAND ${CMAKE_COMMAND} --build . --target print-warning-message) +else (${CMAKE_VERSION} VERSION_LESS "3.19") + cmake_policy(SET CMP0110 NEW) + add_test(NAME "NOTE: some 'test' tests are expected to fail, 'regress' must pass" COMMAND ${CMAKE_COMMAND} --build . --target print-warning-message) +endif (${CMAKE_VERSION} VERSION_LESS "3.19") # Local Variables: # tab-width: 8 diff --git a/ChangeLog b/ChangeLog index 3f903d7b0e6..a092153ba4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,1539 +1,4331 @@ -commit 834994a075da397c581499ce41662d2f9d878ef2 +commit 677fe0b3fb8f5fe2ba2a1ff6ba83388bf6e5cea8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 10:24:43 2023 -0500 + + Version number updates + +commit 01ae447bdfc678a21eebc974980304f0274d4277 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 10:23:44 2023 -0500 + + Stray parenthesis + +commit 453f1eae98f0095e124f9faf65f623fdbc1202a9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 10:22:42 2023 -0500 + + typo + +commit 5dad26403a8de09c5cb9609bce66741e0f7f32b5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 10:21:36 2023 -0500 + + Adjust wording for facetize writeup + +commit cdcba538cfc23d9728e7cc9229feda5d92083bfe +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 10:13:53 2023 -0500 + + Note initial efforts for edge curve repair + +commit 9a27ede816e946ed281e1f4370c31e331c124427 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Nov 6 00:47:15 2023 -0500 + + Initialize + +commit aaf9cee93da46211dcaebf6d3f3a0795ab0c5ab4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Nov 4 19:40:53 2023 -0400 + + Teach libicv to generate a diff image + + Not 100% sure we're properly matching pixdiff yet, but it's the right + general idea... Teach libicv to programmatically generate diff images, + so we can automatically write them out when drawing tests fail. + + Usually, the first thing the dev wants to do is inspect the differences + between the control image and the generated image, so we go ahead and + provide that data as a PNG image under various failure conditions. + +commit 4bdf5bc6707bd8477212cb9f50f662815b197020 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Nov 4 18:42:21 2023 -0400 + + Add an option to keep the generated images. As we have to adjust the outputs, it'll be easier if we can just keep a set of correct generated images rather than having to do everything manually. + +commit dc502a303c7dd94725117d7ad2544ee3671ac61d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Nov 4 17:40:28 2023 -0400 + + Try to protect more of the nmg_mdl_to_bot calls + + Getting an infinite loop failure in the libged lod draw test when trying + to facetize tor.r, but the failure doesn't repeat if I do the facetize + in MGED. Still not sure why the failure is taking place, but first + order of business is to try and make the facetize process more robust to + the failures. + +commit 9f6e0dd8a55ad2e74b0ed9527c7c67649af5b27b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Nov 4 08:57:07 2023 -0400 + + Right, already have unistd from bio.h here + +commit 7e29f82a2b42dac1e09b87ce9ecac94f922e1b48 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 22:25:00 2023 -0400 + + Add the headers for the various platform specific thread info calls + +commit e358f9b1eeeb2b9288b2e0fa8e61c79f066b10a8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 21:09:08 2023 -0400 + + The musl libc implementation doesn't define fcloseall, so just checking for GCC isn't enough + +commit ea94d525dae631d8ef506621105725d3942fc985 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 20:05:56 2023 -0400 + + Add a few notes about setting up Alpine Linux for BRL-CAD building. Very minimal as yet - haven't figured out the graphical/OpenGL aspects. + +commit 00b5bb1baa7bf610a43f34ea1072010b8626a94b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 19:24:04 2023 -0400 + + Initialize min and max points for bounding box + +commit 1c6713dd7c6cb2a3214c72f273e021e019861088 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 16:40:58 2023 -0400 + + Try to always print the summary + + Per https://stackoverflow.com/a/58859404/2037687 there should be + a way to print the summary both in success and failure, which is what we + want here - we always want to see the analysis results, ESPECIALLY if it + failed... + +commit 88c468668f3a189106e2a0bc60b55b2d8b37b114 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 16:36:22 2023 -0400 + + Bail if we don't have a valid rmax + +commit 8193e2b83f6cd88a2def3027bc3ac5eab1c194bf +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 15:22:47 2023 -0400 + + Backport a libpng fix from bext + + Newer Ubuntu systems have a freetype that links in libpng as a shared + library, and using a default name for BRL-CAD's copy results in freetype + trying to use our file. However, because we prefix our function names, + freetype can't find the symbols it needs. (In a sense the symbol + prefixing is doing its job, as we want freetype to be using the system + .so it expects and was compiled for.) To avoid this, we do the same + thing we do for zlib and adjust the library output name. + +commit f08a6614182a6620b275e7b303ac2ca037f7f8a0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 14:26:01 2023 -0400 + + Try to dump the clang static report summary as txt + + It may not be easy or possible for a dev to duplicate the clang analyzer + run locally, so try and at least dump the summary so we have a chance of + seeing what newly appeared from one run to the next. + +commit 91f193009fb55adefa3f29d3f3fa31b4fd81c544 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 13:05:12 2023 -0400 + + do/while will still try to read from next on the first pass, so we need an initial check. + +commit 1585a1d8f46ab034d760a14f50d1c8dea0715238 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 12:23:24 2023 -0400 + + Try reworking the g-iges mult-file naming code to be a little clearer. + +commit 98b497581c47fe6429c7df8417875f3761b2e943 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:50:06 2023 -0400 + + Couple more link time warning suppressions for GCC + +commit 953a5e94331b33a049e87a5b9a9d549c858e41e7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:09:40 2023 -0400 + + Suppress libbu failing on GCC's stringop-overflow error during release build + + Newer GCC is warning about our bitv container: + + src/libbu/bitv.c: In function ‘bu_bitv_and’: + src/libbu/bitv.c:172:16: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] + 172 | *out++ &= *in++; + | ^ + include/bu/bitv.h:111:12: note: at offset [16, 2305843009213693944] into destination object ‘bits’ of size 2 + 111 | bitv_t bits[2]; /**< variable size array */ + + Per Sean we're making deliberate use of an isoteric but legitimate C + behavior here, so when we're doing the optimized linking for libbu don't + make this a fatal error. + +commit fd6ad381b8c8aba4e59223f98eeb70be6d10c7d4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:36:54 2023 -0400 + + Guard against NULL dereferences + +commit df9808b0ddaae9e39f0f0250f39f3e3d56581a13 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:34:09 2023 -0400 + + initial assignment to program was never used + +commit 6cc433a961939082ce19fff772ad2a6a2d01b2e8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:32:38 2023 -0400 + + "-" assignment to file_name is never used + +commit 3897696d30d32a4c4e16c69ab9674f0db667d713 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:30:49 2023 -0400 + + Assignment of "-" to afile was never used + +commit a2979e681c11e3da77074b415f4d50ce142b4b3d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 11:28:06 2023 -0400 + + op_str being assigned " u " was a dead initialization. + +commit 98345360375cbd57dd963b2016ef94312c07d63a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 10:37:26 2023 -0400 + + Fix rtwizard command line execution + + Since ged_init isn't setting up ged_gvp automatically, we need to make + sure it gets notified when Tclcad sets up a new view for the first time. + Was crashing command line rtwizard by not setting up ged_gvp properly, + resulting in null dereferences. + +commit c7229d39120c893535c4e7ca66f8c1d5df0f055d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 10:35:24 2023 -0400 + + Remove debug printing + +commit b558bf6e97eda267a29172234a93fad3133aa0d0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 08:15:49 2023 -0400 + + Update numbers for just higher level conversions + + Re-run with the following filter: + export OBJECTS="\( -above -type region -or -type region \) -and \( -not -above -type half \) -and \( -above -nnodes \>2 \) -and \( -depth \<3 \) + + Translated, that selection looks for regions or assemblies with + trees not containing half spaces (which are problematic for + facetization), have at least one comb with two nodes in their + tree (to avoid trivial trees and test the boolean logic) and are at + depth one or two overall in the .g file (and thus likely candidates for + complex user facetization operations.) + + While running these tests, discovered that (if I'm understanding this + logic correctly) the boolean tree walk for facetization is intended to + be (or at least, as implemented ends up being) tolerant of lower level + failures. This can result in "successes" that are skipping individual + lower level components that don't work - this may be intended since it + does at least give the user partial results, but could also be a + surprise if pieces end up facetized oddly or are missing. + + Perhaps we should consider an explicit option to facetize to be fault + tolerant and/or fail fast and hard if lower level pieces fail. + +commit 469e2d4cdc53e4bb9316dce67dbf7213dca4fc23 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Nov 3 00:14:22 2023 -0400 + + If we fail to do the manifold bool, return the correct error code. + + Was "skipping" failed evaluations when processing, which resulted in + (for example) havoc's top level "succeeding" by simply ignoring the + missing window region that fails to evaluate using manifold. Adjust + the returns accordingly. + +commit d263153948785d24d5c27df744196b845fc2c16b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Nov 2 23:59:04 2023 -0400 + + Remove erroneous numbers - discovered an error in the new logic. Need to reassess + +commit 3f97119cf01a1730437a328b4bda2c48f38b05dc +Author: f4alt +Date: Thu Nov 2 15:48:57 2023 -0400 + + codecvt is deprecated c++17 + + doing it this way limits the reliability to only ASCII chars. not near + as robust a conversion, but given the nature of the string is object + names, we should be able to get away with using this naive approach. + +commit d22c4cd0083b55e99e265e44f700463913c97cf4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Nov 2 14:53:31 2023 -0400 + + Right - if we turn off Tcl, we don't have mged, rtwizard, etc. targets + +commit 526a7dce5897a11c23c94ca0f018b530ed074d9b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Nov 2 14:41:34 2023 -0400 + + Add brep repair subcommand to generate new edge curves + + Probably shouldn't be announced to users just yet, but checkpoing progress so + far. We hit a case (possibly caused by a flaw in one of our older importers) + where we have valid 2D trim curve data but bad 3D edge curves. This command + uses one of the 2D trim curves and tries to generate new 3D edge curves. Not + sure yet if it works, or if so how well. + +commit 641f2e2909a088d1b9608e86caf8776869fb4a12 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Nov 2 12:48:51 2023 -0400 + + List test .g files for cleanup + +commit 6ebbb36a09573348abd61e6ef0bcae7681a186c4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Nov 2 07:04:11 2023 -0400 + + Note changes in facetize speed and success rates + + Refining what to report here a bit - this test is bot only output of + share/db/*.g with the filter: + + export OBJECTS="\( -above -type region -or -type region \) -and \( -not -above -type half \)" + + However, the most interesting cases for this particular change are the + complex ones where bool plays a major roll. So these numbers may be + re-run with an additional filter such as -and \( -above -nnodes \>2 \) + to hone in on those more difficult cases. + +commit 0b038cd0b2289451ba1091196d6379e140506e69 +Author: f4alt +Date: Wed Nov 1 17:12:11 2023 -0400 + + note new brep dump subcommand + + f3a84b705ec1bdc31887c4f3163098005a309b76 + +commit ee74711645d7765972fc89b9622f8f106d18efd1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 17:07:01 2023 -0400 + + Add a TODO note for brep edge repair investigation + +commit 75412696de55fc0cad889adca064926a510a7c73 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 16:58:24 2023 -0400 + + Start working on 7.38.0 writeup + +commit dbbd6b59dc1d573ef8b8f8a0ccc9984bf259565e +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 16:11:29 2023 -0400 + + Turn off brep boolean debug plotting, at least for now - generating too many files. + +commit eb5924c8f62eb19ec79b047ea0bc40ea0630cb39 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 15:18:56 2023 -0400 + + Add a hook to allow experimenting with opencv + +commit 902ec98ba2c5a4925de623b2366e329b3d45fa76 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 14:56:38 2023 -0400 + + Stash a note about looking into glb failure case writing support + +commit 1634ec6a3445e4e4dd0ebf12ff39e080770178cc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 14:01:59 2023 -0400 + + Make a note for future debugging explaining what needs to happen to activate mged_pr_output + +commit 1a68756b497559adc92b6234d4358e8cd4902a59 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 13:57:12 2023 -0400 + + Restore default gui_output callback + + After discussion and user feedback, leave existing behavior until we can + get asynchronous command execution going. + +commit 01f14dc6f4612e7626f45b80768374eab628626d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 13:07:06 2023 -0400 + + Need alternative for MGED bu_log callback if on Windows + + Since ged_exec calls are blocking for GUI updates, we try to leave the + bu_log callback that forcibly inserts text from other threads on if the + platform isn't Windows. + + Deliberately using an #ifndef _WIN32 here, as we want to keep the + immediate feedback if we can get away with it for long running + subcommands like gqa and rt. On non-Windows platforms it usually seems + to work. + + The right answer here long term is to get ged_exec running in its own + thread, so we can keep the GUI refresh going "normally" and have the + text update calls come from there. (That's the mged_pr_output call in + refresh() - right now it's fairly useless as refresh() is blocked, but + once we have ged_exec calls asynchronous it should start doing the job.) + +commit 0441478fa490ae3d0f994b5b25e58031e5375047 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 12:36:46 2023 -0400 + + Another flushing of the bu_log buffer + +commit 45cc7a551a3eea701bef30480daacb5da4b545cd +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Nov 1 12:32:34 2023 -0400 + + Before appending the results of a GED command, make sure we flush any accumulated bu_log output. + +commit cb5bfb07c6557d11bc9501ac1bdaf507a1d8f572 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 31 14:01:47 2023 -0400 + + Add in the trimesh solid check to validate Manifold output + + In principle Manifold shouldn't be producing outputs that would be a + problem for this test, if I'm understanding what it does correctly, but + since it's a new library and we have the check for the CM/SPSR methods + already, go ahead and add it to the mix. + +commit 2cf3573b6dec2124bb0dbab9629250d047e0d77c +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 19:17:23 2023 -0400 + + Manifold needs logging management too, since it also relys on NMG for individual primitive tessellation. + +commit e839f08ebd45366d44a7cafd4e06552357158aad +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 16:17:23 2023 -0400 + + Guard against some NMG null dereferences + + Getting a tessellation failure - these are undoubtedly symptoms of + something else, but at least avoid the obvious NULL dereferences. + +commit 53a998b789f2a39a91d5141464f43604cfa9b8b0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 15:06:29 2023 -0400 + + Remove "using namespace std" from VRML reader + + BRL-CAD avoids the using namespace std trick as a rule, and this is a + good example where it paid off - when we bumped the std required to + C++17 for Manifold, it triggered what appears to be this issue: + https://developercommunity.visualstudio.com/t/error-c2872-byte-ambiguous-symbol/93889 + + Fix should be to just update the code to be explicit about std:: usage. + +commit f3a84b705ec1bdc31887c4f3163098005a309b76 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 14:51:35 2023 -0400 + + Add a 'dump' subcommand to brep to write out brep objects to 3dm files. + +commit fb3de71aee9d4f74081affbb87ad9bd391773486 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 12:45:01 2023 -0400 + + Updates to gist for building with g++ on Linux + +commit c36e99b6d292baf0f9edc70c10892f39087951fb +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 30 12:13:37 2023 -0400 + + Update build logic to also handle a bext supplied Manifold library + +commit 8342f1813f332410c157dec070bf7e20bf799eec +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 29 13:08:27 2023 -0400 + + Update facetize man page for Manifold option + + Since the Manifold library (https://github.com/elalish/manifold) seems + to be producing interesting results, enable it as a default method for + facetize. If it fails we next try the old-school NMG boolean (the + combination of these two methods results in a fully successful havoc + facetize -r) and then proceed to CM and (if enabled) SPSR. + +commit b83aaa007736174f1abf438a462ca50d42027def +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 29 10:12:27 2023 -0400 + + Export Status + +commit aaeb6c65444a28b86c95b636cb54d9e591497dbe +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 29 10:11:15 2023 -0400 + + Export some more methods + +commit d987acd9d098afca3c62bb86615c16eff8cc2e38 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 29 10:03:49 2023 -0400 + + Correct define for manifold lib build + +commit a43714bd93f7878b9fc1c91f393d2ed243200f90 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 29 09:56:25 2023 -0400 + + Copy/paste error + +commit b8657bfd559a3a962abbf06254251a0aaf4dc29d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Oct 28 21:00:30 2023 -0400 + + Will need import/export logic for Windows - start figuring out what that looks like. + +commit 11cc1fb10fab487cef8c50707ff76d3c3235b2be +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Oct 28 08:06:53 2023 -0400 + + Correct snprintf size + +commit bae2ff66563104eddd65eb8a81356ffd0a211e3d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Oct 28 08:03:20 2023 -0400 + + Chec write return code + +commit 69224adc0ae9208077d6cf85631b55f97276ecf4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Oct 28 00:01:11 2023 -0400 + + Scrub a few more hidden files + +commit 093a7c783e9f46ff13bdf5ea3f535f1579b6e5e8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 23:52:06 2023 -0400 + + Gah. Remove manifold build directory from earlier testing. + +commit e86d34dcd4b80e2ffad428f4a403a73c452767a7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 23:40:21 2023 -0400 + + Remove tmp file from dist list + +commit 9f90c730323a329832607c2657139a656349e1ac +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 22:36:05 2023 -0400 + + Interestingly, the MANIFOLD failure case in havoc works with NMG. Set up NMG as a fallback for MANIFOLD. + +commit aedab66f5deb339dd0c0bbc8ff35858d6b147758 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 21:59:48 2023 -0400 + + Need to do some memory cleanup after completing the boolean evaluation + +commit fd3b6d3b1dd7eebf8a9f86d52527225128ce8746 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 21:52:38 2023 -0400 + + Use the names of the evaluation states for stl names + +commit 87d096a1ff4870b2de4113db82df07cef1055af5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 21:42:08 2023 -0400 + + Make a stab at writing out stl outputs to help debug failures + +commit 1e7478b2560bb2c3d5a5d74185dc5c574ca414f0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 20:51:46 2023 -0400 + + Enable a bundled manifold, given C++17 support + + Boolean results seen on some of the example CSG targets are impressive, + so go ahead and get a bundled Manifold set up so we can do additional + testing more easily on various models and platforms. + + Will need to think about how to handle non-manifold inputs if this + becomes a default option (facetize -r --MANIFOLD on the faa Generic Twin + ends up ditching most of the BoTs, as they're not manifold). May want + to fall back to NMG if one of the inputs isn't a manifold, but I'm not + sure how much better NMG is for those cases - needs some + thought/testing. + +commit 115540b6c241f05e38c1a2f49cf86da6e555f701 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 18:40:02 2023 -0400 + + As with poly2tri, use try/catch to wrap the manifold boolean evaluation to avoid crashing if something goes wrong. + +commit f52dd9cbe65b9e548337c000f2a93a74750cac7e +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 18:31:02 2023 -0400 + + Need to create the mesh in the trivial case as well. + +commit 5e76aabf8d6fcaf1f64e71ea27dde59ea5a5f134 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 15:54:21 2023 -0400 + + Rework MANIFOLD testing + + OK, that's more like it. Getting more failures on M35 now, and havoc is + all-up crashing. Next we'll need to figure out how to dump out the + failures for convenient inspection and (maybe) upstream submission. + +commit 780fc798b45686ae692dbd96946c333f81ad4df8 +Merge: f3bd856177 0bb4587b1a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 15:43:06 2023 -0400 + + Merge branch 'main' into manifold + +commit 0bb4587b1a2f61f3b5c46027fe8d2dd5c184349c +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 15:42:22 2023 -0400 + + Whoops, without NMG_BOOL values we're not using op + +commit bb6b26de755e70fdd82b1d5ce2ec46381ef5c97e +Author: f4alt +Date: Fri Oct 27 15:30:14 2023 -0400 + + catch up on some forgotten NEWS documentation + + b6a5354d01adcca463aefac1ca85a9e8129d5710 + 9c53c66d0467ca6db33b14610b44149f95ff50ad + 18504e07b0c4871f086c10cfc19f997327dc00e7 + 37a0234499c40d8d641167fdeae8d8aa3ac70229 + 95d8800fd7d6dbeef2befaad38955c7cd9908e4c + ae110d5067372f732242e4fbd1c8db395bc9f243 + 9094488b8fc96221a0d8dc221a9d3dd701432fdd + cfaac7f61c52e996061bdfce9b654d65cf807c3e + de61c3a0f6432557d0a860a246df3fa0ffee0958 + +commit f3bd8561778a503dd1be137a73f0389848f40654 +Merge: c04e140976 6e3a685e03 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 14:35:59 2023 -0400 + + Merge branch 'main' into manifold + +commit 6e3a685e032e5c87233ddfd32bb0e68fbee8cc91 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 14:32:21 2023 -0400 + + nmg_booltree_evaluate -> rt_booltree_evaluate + + Make a version of nmg_booltree_evaluate that abstract out the actual nmg + boolean evaluation into a callback function, in order to allow the + substitution of other evaluation methods in lieu of nmg_bool. + + Hopefully, this will make for easier apples-to-apples comparisons with + more complex CSG tree hierarchies when evaluating alternative boolean + methods. + +commit 00f5403bf41f0e7d14bd9046f71b7dbcc53a3dd1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 12:12:16 2023 -0400 + + Rename, add generic slot to tree_nmgregion + +commit 1b95a8542f52b5ea0446b4ae8fa7173fb14c50a2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 27 12:02:05 2023 -0400 + + Rename OP_NMG_TESS to OP_TESS + + This operation shouldn't be specific to NMG - there is a lot of logic + for the tessellation process that should be generic to the librt tree + structure and walking it. + + Background: when testing alternative tessellation methods, I keep + writing quick, poor-man's tree walkers to fire off the experimental + boolean evaluation logic. Inevitably, if I get far enough, I find I'm + not walking the tree the way the NMG facetization routines do. + + Rather than keep doing that, I want to look at whether the non-NMG + aspects of the facetization tree walk can be made generic, so we can + swap in whatever evaluation method we want and have the CSG trees be + handled the same way. + +commit b6a5354d01adcca463aefac1ca85a9e8129d5710 +Author: f4alt +Date: Fri Oct 27 12:30:54 2023 -0400 + + improve 'x' default behavior + + 'x' / 'solid_report' should use the default level 0 with no arguments - + not print usage and return + +commit 0934badc227be4e2b0fc12e5c17e60c995d87fc4 +Author: f4alt +Date: Thu Oct 26 20:01:00 2023 -0400 + + cant have colon next to param name + +commit 276bcce5d0552e83f07c17d9aab0fb61263d574d +Author: f4alt +Date: Thu Oct 26 19:40:14 2023 -0400 + + fix type warnings + +commit c04e1409769ae37dc5590fb474e1f344a0fb44fe +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 26 16:57:52 2023 -0400 + + Correct tree walking for manifold mesh processing + +commit 2545968fbc0553a52599bfcb09963ed24c651e4d +Author: f4alt +Date: Thu Oct 26 15:45:50 2023 -0400 + + write some unit tests for bu_temp_file_name + + memory is being set wrong in 'parallel' somewhere- so leaving that test + commented out until it gets fixed + +commit 4f375163fc7229a0a751fa5d5db4deadd77456d7 +Author: f4alt +Date: Thu Oct 26 15:39:42 2023 -0400 + + lets use bu_dir correctly.. thanks Cliff + +commit 8d0ef9666f0de95db966e1787a3b5c39f2b2d389 +Author: f4alt +Date: Thu Oct 26 14:16:48 2023 -0400 + + fix print types - these are longs now + +commit 219f0127d5590908b6664bf2bcffa7ef3ab18c92 +Author: f4alt +Date: Thu Oct 26 14:12:24 2023 -0400 + + use maxlen to not overrun buffer + +commit 9bda7496ba7fa6920d6dee041dec1c3c6e2b0c2c +Author: f4alt +Date: Thu Oct 26 14:11:34 2023 -0400 + + oops, this shouldn't be static + +commit 7bbfdf2f66020266e70006c7df4614bf17f20469 +Author: f4alt +Date: Thu Oct 26 14:10:13 2023 -0400 + + fix headers and definitions + +commit 08755b7af0a5b42e75af3c086f0938dde5b6f243 +Author: f4alt +Date: Thu Oct 26 13:01:40 2023 -0400 + + update color.xml + + document -e purpose and usage. + remove 'str' option as it never matured into the command. + +commit 706dec345dfa16ec0d0f1069115bebd377106745 +Author: f4alt +Date: Thu Oct 26 12:38:08 2023 -0400 + + document edcolor / color -e fixes + + a3e4ab4a36, 40a3b53200 + +commit a3e4ab4a365c734287ad3c556550cecb740a5fbf +Author: f4alt +Date: Thu Oct 26 12:30:33 2023 -0400 + + help windows find wordpad + + this define is used as a fallback to the editor opener. bu_file_exists + (which uses stat()) will NOT find a path wrapped in quotes. Similarly, + windows is picky and needs the .exe + +commit 40a3b53200b0dd11d837e6847c5926d9689743a9 +Author: f4alt +Date: Thu Oct 26 09:59:18 2023 -0400 + + fix edcolors external opener on windows + + Windows does a pretty good job of cleaning up temp files as soon as + they're closed. So, this method of opening, writing the current state, + closing, and then opening again to read is not reliable. Instead, + generate a name with bu_temp_file_name and open with w+ so the file is + guaranteed to stick around until it is removed with bu_file_delete + +commit 3f5eff111bb48cf92ca75aaad710169d69ba42bc +Author: f4alt +Date: Wed Oct 25 16:24:34 2023 -0400 + + create bu helper bu_temp_file_name() + + creates a string unique to a process / thread pair. Useful for creating + a temporary file name that is reproducable in the calling application + with minimal collision possibility. + +commit 8cedcbbee3bd9970768d4f8072481c6692bde872 +Author: f4alt +Date: Wed Oct 25 14:36:40 2023 -0400 + + helper function to get current thread ID + +commit 1e161ac461febd3ee71bc336473b9612a70ec991 +Author: f4alt +Date: Wed Oct 25 14:35:13 2023 -0400 + + match type with region ID + +commit 7df0ef3c86284f6f917d5e300a4795fa82d5ed5a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 26 09:54:39 2023 -0400 + + Enable approximate diffing for the LoD drawing cases + +commit 40bcd657d38dcc62589a194408383723cddec9e4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 26 09:40:21 2023 -0400 + + Update ctrl images for ell and circ polygons + +commit 9183faf692b19e8a0e062d23bc3cf762491d16c1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 26 07:22:21 2023 -0400 + + Latest upstream no longer uses libgraphlite + +commit ab2daf2ef2b9852d0119289d8d5bc5e626f78885 +Merge: 646bb9df60 da1c9119a3 +Author: Christopher Sean Morrison +Date: Wed Oct 25 22:15:01 2023 -0400 + + Merge branch 'main' of https://github.com/BRL-CAD/brlcad + +commit 646bb9df602c79a0befdf2a033e612a04e6d0572 +Author: Christopher Sean Morrison +Date: Wed Oct 25 22:14:19 2023 -0400 + + actually check the -fsanitize=fuzzer flag. + + just checking for the fuzzer flag via check_cxx_compiler_flag() is apparently inadequate on windows because visual studio 2019 just issues a warning. switching to check_cxx_source_compiles() appears to result in a proper failure. + +commit c78e3146501cb3c3c827a6ea2a4860a0036c2e2e +Merge: 605280706a da1c9119a3 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 18:51:49 2023 -0400 + + Merge branch 'main' into manifold + +commit da1c9119a37663e3d6089506a6ee10cb8e92c662 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 16:49:08 2023 -0400 + + Eliminate the jump at the beginning of a polygon move + +commit ba027bf4db54bbf49f864a9c2f627bce03e18d65 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 16:29:37 2023 -0400 + + Adjust polygon move logic + +commit 5a32a90496c3bd04d6553ef1827eab8fe48bd3fe +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 15:44:56 2023 -0400 + + Adjust nsegs calculation for circle and ellipse polygons + +commit 9eacad9c4d824b7d14330deb16896b4c4e0ba8fa +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 12:19:51 2023 -0400 + + Note a needed correction for segment length calculations. + +commit dc1ca44d61e155ce741092a39ec32f521d6f3331 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 25 12:09:54 2023 -0400 + + Don't override prev_point Z value + +commit 21dab4df0036268716bb408fe82b90dbe8842856 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 16:48:54 2023 -0400 + + Closer, but vertex ordering is still different. May need a more intelligent sketch diffing routine for this... + +commit c158fdc1b129c2cf5d73c4148128943f9b4cf08e +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 16:00:16 2023 -0400 + + ws + +commit 2ef034d3580e1c20955d8302328c39325b7f7867 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 15:57:49 2023 -0400 + + Rename file + +commit 4256cce1265a1880d9f358d2cb939971fbc70db1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 13:10:51 2023 -0400 + + Adjust view polygon logic to use planes, 3d pt + + It was proving confusing to have view polygons store a complete view + copy - when to operate on or use the app view vs the polygon view, when + and whether to sync view states, etc. Instead, have the polygons store + a plane. Also, have apps supply 3D points in lieu of having the lower + level polygon logic try to handle the snapping logic. + + This needs more shaking out, but we're as far as passing the regression + tests so it's a good time to checkpoint. + +commit 3cff59528f65ac389d4ac26f0d48d5cc386da8ca +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 14:21:48 2023 -0400 + + Add a function to construct a plane_t from a bview + +commit 57198a4c27b211541bfce178ff57ae8c02c24ba4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 15:49:01 2023 -0400 + + Report sketch info if difference is found + +commit c2e396d28fe50903880c45eeefec875d746ae52f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 15:34:59 2023 -0400 + + Remove unnecessary headers + + For convenience, this is the current before-and-after state of the + sketch. Note that from a drawing perspective they are the same, so the + difference appears to be in definition style, rather than the final + geometric shape. + + old.s: 2D sketch (SKETCH) + V = (0 0 0), A = (1 0 0), B = (0 1 0) + 6 vertices + Vertices: + 0-(-250 -250) 1-(400 -500) 2-(400 250) + 3-(0 450) 4-(-250 250) 5-(-400 150) + + Curve: + Line segment (-250 -250) <-> (400 -500) + Line segment (400 -500) <-> (400 250) + Line segment (400 250) <-> (0 450) + Line segment (0 450) <-> (-250 250) + Line segment (-250 250) <-> (-400 150) + Line segment (-400 150) <-> (-250 -250) + + new.s: 2D sketch (SKETCH) + V = (1 0 -0), A = (-0 1 0), B = (-1 -0 0) + 6 vertices + Vertices: + 0-(150 401) 1-(-250 251) 2-(-500 -399) + 3-(250 -399) 4-(450 1) 5-(250 251) + + Curve: + Line segment (150 401) <-> (-250 251) + Line segment (-250 251) <-> (-500 -399) + Line segment (-500 -399) <-> (250 -399) + Line segment (250 -399) <-> (450 1) + Line segment (450 1) <-> (250 251) + Line segment (250 251) <-> (150 401) + +commit a2a37c60fa08db91ed285455c9a69dde43442084 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 24 15:32:40 2023 -0400 + + Set up a round-trip test for sketch<->bv_polygon + + Not enabled by default yet, as the sketches differ, but set up to test + the sketch import/export abilities for bv_polygon view objects. + +commit 283f13def8c16ade13b49aff2e38998c60deb673 +Author: Christopher Sean Morrison +Date: Tue Oct 24 10:54:12 2023 -0400 + + fix indirection + +commit e80edf3ccd38ffc7cc00393ae8378e7e55d692e6 +Author: Christopher Sean Morrison +Date: Tue Oct 24 10:53:53 2023 -0400 + + ancient function, use math.h + +commit df57ab0840c40eb35c624f9c855fb2e279c5818c +Author: Christopher Sean Morrison +Date: Tue Oct 24 10:46:01 2023 -0400 + + fix preprocessor typo and bad arrays of func pointers decl. + +commit a02431bd2dcc721095d3b6bb20f02d12ff8e726c +Author: Christopher Sean Morrison +Date: Mon Oct 23 16:15:29 2023 -0400 + + various fb tools should be compiling on windows now, but still need to confirm they work via conio + +commit 9aee50f8c18d8461d1683e061bf1fad20fa252ff +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 20:06:40 2023 -0400 + + Fix function name + +commit 717eaf57ef5c9bb7dfdab3196f00efc4e8ca6aab +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 12:47:32 2023 -0400 + + Make plot3.h independent of libbv + + We use a libbu color data type and vmath.h, so the header is not truly + stand-alone, but this way we can use plotting in libbg without having to + have libbg depend on libbv. + + It may make sense to have plot3.h be its own top level file like vmath.h + +commit 1da99c85bb9fdb1b592c3662762cd0ae68e8d3c0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 12:03:03 2023 -0400 + + Move libbv-specific functionality from bg to bv + + Working with this logic, it's becoming clearer that libbg should be the + lower level library. Shift the LoD and view-specific aspects of the + polygon logic to libbv. + + Still need to move the plot3 logic - right now the libbg plotting + routines are just turned off while focusing on other changes, but that + won't fly long term. + +commit df9ab0843166937b6bb4d61b8e41624d4505c637 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 12:10:05 2023 -0400 + + remrt is on or off based on platform logic, so we can't get too cute about validing the filtered man page list yet. + +commit 3766afd2ac6f00ba52067eb8599042cddbf21702 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 23 10:29:45 2023 -0400 + + remrt isn't built on Windows - filter man page from target check until that changes + +commit ad01767dc6317b4b973a51883dba36f29f9333a7 +Author: Christopher Sean Morrison +Date: Mon Oct 23 03:47:05 2023 -0400 + + add the new FindOpenCV.cmake + +commit 70c187048b54c2d0497b1b35ba9a145747af6b15 +Author: Christopher Sean Morrison +Date: Mon Oct 23 03:46:05 2023 -0400 + + expand LIBRARIES + +commit dd90c648d1e2b97b79e648c24c7e999fe3d1d304 +Author: Christopher Sean Morrison +Date: Mon Oct 23 03:45:12 2023 -0400 + + add opencv find logic. + + This is needed on windows where the version of cmake didn't have a find config. Used the one in libgeodecomp from https://github.com/STEllAR-GROUP/libgeodecomp/blob/master/CMakeModules/FindOpenCV.cmake + +commit 2af1f8f840561f84c0e47ac1ab9a2d7ea85cb60b +Author: Christopher Sean Morrison +Date: Mon Oct 23 03:29:51 2023 -0400 + + need templatized type for std::pair + +commit 4fcca83696bef039bf28eb846b488e53f0338b45 +Author: Christopher Sean Morrison +Date: Mon Oct 23 03:28:59 2023 -0400 + + simplify the dll copy code to copy all runtime dlls. note c++17 issue. + +commit bb84c7ed406510e78d45367b54708112716c5652 +Author: Christopher Sean Morrison +Date: Sun Oct 22 23:26:17 2023 -0400 + + enable fbpoint and fbzoom on windows, see how the libtermio accommodations fare. + + fbpoint is directly reading bytes with read() so it possibly works without any termio interference altogether. + +commit 1f830d6e651b0289813916fa64af914864c97965 +Author: Christopher Sean Morrison +Date: Sun Oct 22 23:24:28 2023 -0400 + + potential port to windows. + + if we have conio.h, just call getch() instead of getchar() may be adequate. testing compilation by way of CI runners. libtermio.h should be providing conio.h + +commit 85b6631cb59d2c8ec300e78e5b52bda24f7fd2f8 +Author: Christopher Sean Morrison +Date: Sun Oct 22 23:19:03 2023 -0400 + + add support for conio.h which is raw by default. + + avoids needing to conditionalize caller code. + +commit 8a5f3a06f6bbbb2ea82af20b3ce4a67a92bab8d5 +Author: Christopher Sean Morrison +Date: Sun Oct 22 22:49:52 2023 -0400 + + put a bigger warning label on the printings + +commit 4fa30fb693f396fc4793275a794ae60438cb3629 +Author: Christopher Sean Morrison +Date: Sun Oct 22 22:45:03 2023 -0400 + + no doc, ref, or other instance of external global.. wip? + +commit bfd147ddb89082e5d5bc208b80d10110513268da +Author: Christopher Sean Morrison +Date: Sun Oct 22 22:30:47 2023 -0400 + + don't fail hard on the new build target checks until all have been reported. + +commit 86cb2cc407ccf743f7dbdbc10d6cc030f5c0ab53 +Author: Christopher Sean Morrison +Date: Sun Oct 22 21:54:40 2023 -0400 + + add few files missing from dist + +commit a01a41a7758a59f3a1feab45813c4d095bb8ab63 +Author: Christopher Sean Morrison +Date: Sun Oct 22 21:52:57 2023 -0400 + + remove errant .DS_Store + +commit cc6d13526668cacad8ca436cb8d4085b9ea04221 +Author: Christopher Sean Morrison +Date: Sun Oct 22 12:56:51 2023 -0400 + + port fblabel to windows. + + appears to only use termio to set raw mode for getchar(), which is akin to calling getch() via conio on windows. relying on ci to build-test on windows, but should be close to what is needed. + +commit a5e68ff61d59d5e97b8f782970f3cc2cbfbf33bd +Author: Christopher Sean Morrison +Date: Sun Oct 22 00:31:11 2023 -0400 + + document picohash as public domain + +commit 8a237a32c7b1b9d1d836e8918041b9608f5d5599 +Author: Christopher Sean Morrison +Date: Sun Oct 22 00:30:40 2023 -0400 + + document picohash.txt license + +commit 9e2bff373c42c909d4ec374a500c4ca286df08f9 +Author: Christopher Sean Morrison +Date: Sun Oct 22 00:22:28 2023 -0400 + + fix license header, senseless + +commit 5bdc22b1a1be8aa0d72f966cf346359392519e9a +Author: Christopher Sean Morrison +Date: Sat Oct 21 18:12:35 2023 -0400 + + include cleanup + +commit 45e638577439d6c7293d7dd4e535704d35d26226 +Author: Christopher Sean Morrison +Date: Sat Oct 21 18:10:27 2023 -0400 + + common.h must come before any system headers + +commit 69af9f95dd15fa6b42eaeeb0ac51459bdbf90961 +Author: Christopher Sean Morrison +Date: Sat Oct 21 18:09:30 2023 -0400 + + 10 fewer + +commit 18fc55f44ebaa6051773ce225913e72c06778cbd +Author: Christopher Sean Morrison +Date: Sat Oct 21 18:05:41 2023 -0400 + + use bu_fgets() instead of fgets() directly + +commit 429ab354d9b06687c81dff02dc2867ad649e8d99 +Author: Christopher Sean Morrison +Date: Sat Oct 21 15:16:15 2023 -0400 + + sort in order + +commit 427880a36673b84bc61a5aeedd985a8d56d51437 +Author: Christopher Sean Morrison +Date: Sat Oct 21 15:15:11 2023 -0400 + + credit professor pauline wade of tamu. + + she has provided extensive support on various projects including supervision, mentoring, and direction given to tamu capstone participants across multiple semesters. her influences have had direct effect on the capstone participants and their code development efforts. + +commit ac75c895e3dbae63e98b354b05db63ddc9f4daa0 +Author: Christopher Sean Morrison +Date: Sat Oct 21 15:12:10 2023 -0400 + + note new 'gist' tool worked on under the TAMU-NSIN capstone program. + + formerly named 'rgen' during development, for report generator, the tool generates a 1-page summary of geometry files including rendered images and summary computtations in an intentionally minimal report. the tool was developed primarily under a capstone mentorship program with TAMU (sponsored by NSIN) with Allyson, Andrew, Mark, Danny, and Michael working various aspects of the project under (my) mentorship during the 2023 Spring semester. + +commit b009f0037c48f926764b22d11183f3f37c365f49 +Author: Christopher Sean Morrison +Date: Sat Oct 21 15:00:30 2023 -0400 + + traverse into gist regardless. + + this is so all files are incorporated into the dist. also re-enabled copying the opencv dlls. + +commit 2f2b8aa9b0313c9a26c3eb21c2bab10bcf247c54 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 23:47:52 2023 -0400 + + Validate man1 and man3 man pages to see if they have an associated build target. + +commit d2ffebbbc97bd94c835a0ad19864294369416103 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 23:47:14 2023 -0400 + + libfb is merged into libdm + +commit 44e008716418424e6fb13bcf7d59cf71593c2417 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 23:37:28 2023 -0400 + + db isn't a command line utility + +commit 0cc8c085933d9eb34efc3487fb959eda403316b7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 23:31:42 2023 -0400 + + Remove old fbed man page + +commit d90eb40905dcbfb3f59079a0635a4074349266e5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 21:34:37 2023 -0400 + + libplot3's functionality is in libbv + +commit 11f9d18bed9d6118bc77e49f531503f83dff404f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 21:27:04 2023 -0400 + + Remove more obsolete man pages + + Checking if the man1 and man3 man pages have associated targets is + actually looking like it might be a handy thing to do - it's flushing + out a few more obsolete pages. + +commit edbe762ab5b16b1d122296ad76f12fb1476d4930 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 21:14:04 2023 -0400 + + Remove old canonize man page + +commit b925f6e2b02381b6e18fff8a4cca99f5530120ec +Merge: 622e39814f 1f3e04c18f +Author: Christopher Sean Morrison +Date: Fri Oct 20 16:24:25 2023 -0400 + + Merge pull request #79 from zhuodannychen/merge-5102023 + + 2023 Spring TAMU 1-pager + + This imports the bulk of effort from Danny, Allyson, Andrew, Mark, and Michael to develop a 1-page summary of geometry files using existing tools, OpenCV for composition, and custom layout logic. The tool was originally named 'rgen' but is now renamed to 'gist' and is enabled based on the availability of OpenCV. + +commit 1f3e04c18fe72a929cfba761298cd80666753cd1 +Merge: 3d69248d1b 622e39814f +Author: Christopher Sean Morrison +Date: Fri Oct 20 16:21:53 2023 -0400 + + Merge branch 'main' into merge-5102023 + +commit 3d69248d1b4071505bc3b47e36568da1dd17b18f +Author: Christopher Sean Morrison +Date: Thu Oct 19 16:00:38 2023 -0400 + + enable gist for compilation (now that it compiles) by uncommenting + +commit 601339793e54a476e74213d275793a461707090e +Author: Christopher Sean Morrison +Date: Thu Oct 19 15:59:54 2023 -0400 + + disable dll copying as is windows-specific. + + needs to be conditioned better cross-platform. see art for similar example. + +commit 4c0fdfedd919d3610ac4b1ef4e2a553fb373d532 +Author: Christopher Sean Morrison +Date: Thu Oct 19 15:37:48 2023 -0400 + + get it compiling on mac. + + lots of strictness issues, unused vars, type mismatching, and a couple bugs (string that gets deallocated getting referenced). + +commit 622e39814f0073977436e6ba6309897f19f704b9 +Author: Christopher Sean Morrison +Date: Thu Oct 19 14:16:56 2023 -0400 + + note recent request for drawing on images. + +commit 41becf75e7cd82d68556d533eef48bf901928d91 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 18:54:57 2023 -0400 + + Same deal with MGED - libtermio.h doesn't work on Windows + +commit 849bae36ee6794ab52878c140544c9f3bc831985 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 18:51:31 2023 -0400 + + Don't include libtermio.h on Windows + +commit 54289a4bafe29c2ed3cc7279f25013d051c1a7c2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 18:51:05 2023 -0400 + + Don't appear to need db4.h include in this file + +commit b99198de29ca30c835b3c3c5fd60718aa9990677 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 15:13:59 2023 -0400 + + Reduce libtermio to a single header + + Taking a page from the stb_truetype playbook to further simplify dealing + with libtermio. This change allows us to keep all the logic we still + need in a single header, which is included only by the programs that + still need it. + +commit d684d8536e6f8728406ac967085ea28d2d27af32 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 11:18:36 2023 -0400 + + Move some more library dep lists + +commit ca886e06f7998d903f34f37f7d500b68153f647c +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 10:35:23 2023 -0400 + + Start moving BRL-CAD target dep lists to src/CMakeLists.txt + + I'd really like to do better than the level 1,2,3 logic for enabling and + disabling parts of BRL-CAD for building, but the dependencies of various pieces + on each other complicate matters. Should be able to learn from the bext work + and come up with something better, but will definitely need high level + information (i.e. before we start doing add_subdirectory calls) on the various + dependencies. + + In order to avoid any problems with the high level dependency info and the + per-target listings getting out of sync, go with a DRY approach and define the + high level lists in such a way they can be used directly by the target + definitions as well. + + Only did the basic libraries as an initial test, and this only defines the + lists - there isn't yet any new enable/disable logic. This will be written + with an eye towards the new bext dependency approach, so third party build + enable/disable logic won't be a part of this - all such decisions are made in + the bext configure process. However, if so desired, the eventual + add_subdirectory decisions for BRL-CAD components can also be based on + find_package results. + + One important caveot - if no specific components are specified for building, we + need to add everything. This will still be the default configuration, and the + standard build and distcheck logic needs to see everything. The component + builds are intended for specific user use cases that neither need nor desire a + full BRL-CAD install. It is intended to replace the BRLCAD_LEVEL* arrangement. + +commit ef9d2db843d8d83160777e884e0c75aa09abb982 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 18 10:34:07 2023 -0400 + + I think we want snapping in polygon move as well? + +commit 8087f0c596938e2ab547d057f4b1c21be8241538 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 17 19:26:18 2023 -0400 + + Checkpoint early stages of libbu cache API + + Since both the new drawing code and libbg's LoD logic are using the LMDB + key/value cache, it makes sense to see if we can consolidate the LMDB + logic common to both. In principle the key/value store functionality + should be fully generic, so it seems like a logical fit for libbu. + + I suspect my initial implementation of the LMDB calls wasn't optimal, + but some experimentation will be necessary since docs are a bit sparse + for these sorts of cases. Also will want a function to return all keys + in the cache (initially for debugging, but it may have other uses too) - + I think this will need a slightly more advanced LMDB API call. Look at + https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/mdb_dump.c + for some hints. + + The idea will be to first set up unit tests of the cache and hammer it + with more easily validated inputs and outputs - both current uses of + this mechanism (particularly the LoD) tend to show success/failure + visually, unless the lookups outright fail. (That's one reason I didn't + get adventuresome with the LMDB calls initially.) However, if we can + get data out of the cache faster with parallel reads, it would be very + nice to support that use case. Not certain if that's possible or not, + but worth checking. + +commit 223028ed902d51072606cbc082e34a987c5275b1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 17 18:38:18 2023 -0400 + + Set up BU_DIR_CACHE env var to override the bu_dir cache location + + Looking at possibility of unit testing cache behavior, and if we do that + we definitely DON'T want to target the real BU_DIR_CACHE location. + Beyond polluting the user cache with non-working files, that would be a + major potential issue for multiple BRL-CAD builds simultaneously doing + unit testing with the same cache tests. Allowing for an env variable + gives us a way to target a local build directory in those cases instead. + +commit 62152bce8e59be3a93a2f2a8e5d94923c4b8c9f2 +Author: f4alt +Date: Tue Oct 17 10:29:07 2023 -0400 + + fix print type + +commit 91c74ec8233c03dfd337d9da45d3d444edd33024 +Author: f4alt +Date: Tue Oct 17 09:27:16 2023 -0400 + + add option to dbconcat for overwriting + +commit a64e6d3b2d155b1a77a8b3c493bd979441b4565d +Author: Christopher Sean Morrison +Date: Tue Oct 17 04:19:16 2023 -0400 + + note X11 and glx with the SYSTEM label so they are found correctly without things like -Wdocumentation + +commit d3c029c56cfac6890eb783bf15bb2147d4e7b786 +Author: Christopher Sean Morrison +Date: Tue Oct 17 04:14:58 2023 -0400 + + style cleanup and comment word wrap cleanup + +commit 5d17e75b7d9da325ba4bbb922be660f61f6cab0e +Author: Christopher Sean Morrison +Date: Tue Oct 17 01:47:19 2023 -0400 + + delete mac turd + +commit 90841a0c61c224a757fdb635f1ca6a6edd16cd8b +Author: Christopher Sean Morrison +Date: Tue Oct 17 01:46:58 2023 -0400 + + rename rgen references to gist + +commit 5567f907a17d357fde496fb4852fecb074ea7dce +Author: Christopher Sean Morrison +Date: Tue Oct 17 01:46:25 2023 -0400 + + wrap to 70 + +commit 5cc18ec644e5469cd81f7dd96d08c79ed5dde8fc +Author: Christopher Sean Morrison +Date: Mon Oct 16 22:07:03 2023 -0700 + + indent and ws cleanup. fixed some mixed end-of-line carriage returns too. + +commit eca6169d52af05d7d657882ae3c3f07c82421790 +Author: Christopher Sean Morrison +Date: Mon Oct 16 21:49:10 2023 -0700 + + add license headers and style footers + +commit b80ddaff35e5d3f52dcce8450b8bae9ee4dfb2f4 +Author: Christopher Sean Morrison +Date: Mon Oct 16 19:12:47 2023 -0700 + + begin renaming the 'rgen' tool to 'gist'. + + this should give better discoverability and notability to the tool as it's intended to graphically and textually convey the 'gist' of a given geometry file. backronym is something along the lines of Geometric Information Summary Tool. + +commit 5ba97451362b200c126d6126947eb7873d4895d0 +Author: f4alt +Date: Fri Oct 13 09:57:26 2023 -0400 + + update news for 0fd3570fc2, ea6a7b6025, 4f56c63d76 + +commit 4f56c63d76066023664d11c00cf218327fb3fd53 +Author: f4alt +Date: Thu Oct 12 15:38:35 2023 -0400 + + lc -m should ignore non-set region_id's + +commit ea6a7b6025ebaa4836949ec44f0db9162adbaa84 +Author: f4alt +Date: Thu Oct 12 12:57:17 2023 -0400 + + handle aircodes specially for lc -d + + aircodes are often set without a region_id. Previous implementation would + trigger when region_id is unset (ie '--') and print non-duplicate + aircodes. Matching aircodes (with or without matching region_id) should + still be listed. + +commit 0fd3570fc2b14e822ec3dae9be9d585e7c3f9589 +Author: f4alt +Date: Wed Oct 11 14:28:57 2023 -0400 + + fix 'make bot' vertex ordering for outward normals + +commit 818b67d7322b2028616726489391bf5cf6c2fcfc +Author: f4alt +Date: Tue Oct 10 16:37:31 2023 -0400 + + update facetize help text for modern usage + +commit 413999b48e321d0af250bb240c9d79dacca6840a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 12 12:34:17 2023 -0400 + + Need floating point value to add the grid origin offset + +commit a2dbdd94d7fd34f1082e914809a3afece29f0de2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 11 17:24:27 2023 -0400 + + Work on reflecting updated grid settings + +commit a18eebf5f1faf555fc34a326aab9b010272b2efc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Oct 8 10:51:08 2023 -0400 + + Initialize + +commit efc728aeb926b91d0675c21430525c2a88a334ea +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 6 19:34:03 2023 -0400 + + Like glx, wgl needs Tcl/Tk + +commit bad79f397275f54a6678258bbd318a9f02893288 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 6 19:23:56 2023 -0400 + + Add snapping setting logic for QPolyMod as well. + +commit d74f92dff7b75894fbb197a4faba3af3a9f47358 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 6 12:30:10 2023 -0400 + + First cut at logic for triangulating bg_polygons (untested) + +commit 00c2b64b9ed5ba828b381bb7918c68ea51a4f0f8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 6 11:47:41 2023 -0400 + + Rename bg triangulate functions - want to use the full bg_polygon name for the function that will work with the actual bg_polygon struct. + +commit 09616257c3f9654fdf5eda8ff7828247b13c0ce8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Oct 6 11:16:44 2023 -0400 + + Adjust behavior of polygon point editing + + Clear point selection after mouse button release. Also needed to add + support for properly clearing the selection at the polygon level - + previously the selection lingered even after point editing was complete. + +commit 37795e4b70ada8be6632f42cd0b1dd61d814ec19 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 22:43:33 2023 -0400 + + Add a way to turn of installation of the docs + +commit 6039c4f2d9a0e109ee8f5941fe74000ae83bcef9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 22:25:32 2023 -0400 + + Don't install tclscripts if we're not doing a Tcl enabled build + +commit 15555855a8094908d81a5cc946eba09309a24931 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 16:57:57 2023 -0400 + + Stub in a function for finding a good default fill delta. + +commit dd01d5586e516dc1937fcabc0101f915b1d07669 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 16:17:57 2023 -0400 + + Correct signatures of openmesh stub functions. + +commit a85828aa3a1c5361da65ace97cf85e871ae175e9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 16:00:45 2023 -0400 + + Make a few adjustments to Tcl CMake logic + + When we use bext without Tcl and disable Tcl, it exposes a few places in our + CMake logic where we were adding unnecessary Tcl include vars even if they were + set to NOTFOUND or otherwise assuming Tcl was available. + +commit 2bc38b371375e0336369df71b5a16a339ed4ed35 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 12:32:42 2023 -0400 + + Correct grid snapping logic + +commit e71f29bf91dcf903d76833a60885302577c78c05 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 11:25:51 2023 -0400 + + Fix MGED bv_grid initialization + +commit 1df59ebcf3f6c32834871c9928c9a8ca58732a39 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Oct 5 11:23:19 2023 -0400 + + Add a slot to indicate adaptive grid drawing + +commit 9c53c66d0467ca6db33b14610b44149f95ff50ad +Author: f4alt +Date: Wed Oct 4 16:58:48 2023 -0400 + + rework fa07929 + + a 'l' command with a path should evaluate the matrices, if present. + + note that a name with a slash, although bad, is not explicitly resticted + so try to handle the simplest form here (ie 'l slash/name'). + +commit 42736f67f2fc7616907a5599b31a0786891f76d1 +Author: f4alt +Date: Mon Oct 2 14:39:51 2023 -0400 + + update translate man page + + translate moves along an input vector, not to an absolute coordinate. + +commit f59365ea51d942e84ff070e2b1bed1aba3eba88f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 4 14:29:44 2023 -0400 + + Add separate settings for line and grid snapping (latter isn't working) + +commit 782ec99383bb4f928b0a5f733c9a624e58a5ebfc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 4 14:13:41 2023 -0400 + + Whoops, don't duplicate closedb command name + +commit 25f5b1f708b10a15046ad3ec30c2641520fa05e6 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Oct 4 12:32:58 2023 -0400 + + Have GED define both opendb/open and closedb/close + + We need opendb and closedb to avoid collision with Tcl commands, but open and close should + also be options for environments that don't need to worry about collision with those names. + As long as GED supports both opendb/closedb and open/close, even if the latter are masked + by environment the former are still visible. Conversely, if the enviornment doesn't mask + them open and close will do what is expected in the GED context. + +commit cb7fb17c155b03dd926966ddbfee761cc0ea6d00 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Oct 3 09:37:09 2023 -0400 + + Update faceplate drawing tests for params changes + +commit 753ca331c43b39b8fa545728184be54a63733041 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 2 22:44:37 2023 -0400 + + Start working on finer grained control of params + + Ideally we should be able to turn on and off individual elements of + params to customize what's shown for specific applications. Need + to tweak CADViewSettings a little more, but this sets up the basic + capability. + +commit 18504e07b0c4871f086c10cfc19f997327dc00e7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Oct 2 15:05:21 2023 -0400 + + Add a way to adjust the faceplate params fontsize + +commit 5d4478e679795df617619352afb1c965dc6ab17f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 29 11:30:28 2023 -0400 + + Correct extinstall path in ExternalDeps + +commit 54424816ef95da910cbf194d2a06dd242348c591 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Sep 28 23:32:33 2023 -0400 + + Adjust bext output directory default name + +commit 4c0783d50a5de3fedf33cb9d02531468f0b370ad +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Sep 28 23:11:34 2023 -0400 + + Since we're already in a subdir, no need for the ext prefix + +commit 29dd3d252aec539db27d4c2a0526fd7dd546637b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 27 14:36:12 2023 -0400 + + Add a couple sanity checks for polygon input data. + +commit 717d78983185307e803b097e54743495f6709628 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 26 14:33:26 2023 -0400 + + If we have no contours, don't try to fill. + +commit bda538ab176fbf58c17d9ba92bdbdc4c646d03bc +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Sep 26 12:38:20 2023 -0400 + + Update pnts.xml fix typo + +commit d143ddf5701b72a690714c55494ee4c270ace9b8 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 20 17:33:43 2023 -0400 + + Don't use -E touch unless we have to, provide some feedback during processing. + +commit 7999f7cd76685564b784e7e47f0c300e7f3c1891 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 20 14:53:29 2023 -0400 + + Look for lower and upper case lib names + +commit c78a84c44fd4ffd71b524f620fb145d74606871d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 20 14:15:25 2023 -0400 + + configure_file follows symlinks, which isn't what we want here. Fall back on file(COPY) + +commit 477d9a84a0ca620a89af858b7a71d6a86b40fce4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 18 13:56:33 2023 -0400 + + PATH -> DIRECTORY + +commit 2c4ad3a4b91efa2f5b66a97c82dcd880e423f261 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 18 11:30:51 2023 -0400 + + Tweaks for building with latest Appleseed code. + +commit 96264d610df20096ead21129a2446a6cc9e18071 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Sep 17 21:26:01 2023 -0400 + + While we're testing possible approaches, look in multiple places. + +commit d656aa4ad209c0a56935a406e38d89ed06c96393 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Sep 17 21:20:52 2023 -0400 + + PATH -> DIRECTORY in get_filename_component - wasn't finding lempar.c if next to binary. + +commit 59f0ed36d7473fb8b829af4e10056abed4d423fc +Author: Christopher McGregor <54115478+f4alt@users.noreply.github.com> +Date: Fri Sep 15 15:04:36 2023 -0700 + + fix typo + +commit c77830dac82da506683ac6e435c1ea3d979aa39d +Author: f4alt +Date: Fri Sep 15 16:05:37 2023 -0400 + + trim trailing whitespace from pnts read + +commit ffffb937dcfa56221772632ce2d95c8ca139fb88 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 15 12:27:44 2023 -0400 + + Add Qt5 checks for qgmodel/qgview + +commit 46b4aa868abcbb0775a738798d6d9206c40d299d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 13 10:56:34 2023 -0400 + + Add notes to update add_custom_command post-3.20 + + CMake in 3.20 added some generator expression support for OUTPUT in + add_custom_command. Working around that limitation for multi-config + builds imposed some restrictions, and once we can require that version + (and confirm the expressions work successfully) there are some aspects + of our build logic that should be revisited for potential + simplification. However, we'll have to bear in mind the limitation that + expressions there can't refer to targets... + + https://cmake.org/cmake/help/latest/command/add_custom_command.html + https://gitlab.kitware.com/cmake/cmake/-/issues/21364 + +commit a4ea8e07371ec074434529784ab28aa693a91e65 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 13 09:58:25 2023 -0400 + + Correct u_data checks + +commit 2d39220054f689f36a53dabd054858c3263861a2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 13 00:38:16 2023 -0400 + + Need to support specifying objects for editing that match edit command names + +commit 37520b7bd60f6d234b6bbd7510274e951a069b1b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 13 00:32:30 2023 -0400 + + Refactor the subcmd2_help and base class up into the main ged library + +commit 12eb7d3b58b1babd0138f6933c69dbc0393ffec0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 12 17:08:58 2023 -0400 + + Try an experiment suggested by Chris McGregor to use C++ classes for subcommands so we don't have to use weird tricks with custom help options to build up subcommand help summaries. + +commit 37a0234499c40d8d641167fdeae8d8aa3ac70229 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 12 12:59:00 2023 -0400 + + Don't crash if we run brep without a database open + +commit 0f88fffa50c860837c4c68132b968f352a90a1b4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 12 10:20:50 2023 -0400 + + Report which Eigen we're using + +commit 12259dd435b2db0391a30a199c4ca9b50fdb2346 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 23:59:41 2023 -0400 + + Key off of the existence of the directory + +commit 711453a5679e4fcbe8156ea3cfc9914812b3acb7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 23:30:20 2023 -0400 + + If we're going to build needing brlcad_externals, explain the setup. + +commit 079e5942d6bbaa6a8a7aff3c260b0ca18e8b1c44 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 23:10:02 2023 -0400 + + Still need the Eigen3 dir with the new setup + + With this commit and the latest brlcad_externals, we can (in principle) + remove all of src/other + +commit d6ee36f4a9fc35726cfc874777bc89f8f138ee1d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 22:41:42 2023 -0400 + + Work on Eigen directory includes + +commit 8c817b8e1a5184cc7fca7304889b5be00c6e5ce2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 22:38:50 2023 -0400 + + Set the right variable + +commit e3fc95e07278f52ed99f668f4a980cce4f5521a1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 22:31:35 2023 -0400 + + Remove stray variable + +commit d3d716b09cb19f5a2c75b9c918a34515d7ebda41 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 20:58:49 2023 -0400 + + Make sure src/other is present + +commit ee1b3afd595740b6408c27f9baa1363ad72f3234 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 20:56:11 2023 -0400 + + More prep for brlcad_externals + +commit d48227d9777c11c2c29062ad8e6d1d36a25447db +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 21:02:48 2023 -0400 + + List files for distcheck + +commit 9ca049e66f7653c756e1608d68bebab8927a44ae +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 20:34:13 2023 -0400 + + Set up to use a brlcad_externals Eigen (needs testing) + +commit dd22f775105cf80b4db5b04be8cc348937819824 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 19:37:30 2023 -0400 + + gct moved repositories + +commit a23471f5f3bf3be4f2ae2deabf2c35488d95c561 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 17:12:49 2023 -0400 + + In new mode, look for a linenoise library + +commit 2677c8419ff77201ff4bff53c22ce0b692b8084a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 16:41:06 2023 -0400 + + Build linenoise as a library + +commit 455d5525d2b1161d0bd4d940b35d3311998c6fd5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 16:24:22 2023 -0400 + + Not using it yet, but start setting up to build linenoise as a library + +commit 72958b35ba7d5c2448fc5355cbcf132238ba8466 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 16:03:19 2023 -0400 + + Moved gct code to brlcad_externals for experimentation + +commit 2a5409317d4c99d6c28f1e76575b2554bb8bacab +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 15:41:43 2023 -0400 + + Use the library variable rather than the target + +commit 944464651046c27a6b317c62f77f7516f95dbc1b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 15:40:57 2023 -0400 + + Mods to prepare for external lmdb and osmesa + +commit 99f42deeb433ebb54cb50b0640f8f9ab32428ecc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 11:26:02 2023 -0400 + + Report openNURBS in the summary + +commit df2ac94a8ae49ee762443ccc530bf0f5ee95c80f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 11:18:00 2023 -0400 + + Adjust includes for potentially external openNURBS + +commit 55b10c307fd6af00cfc5447492bd15345aebacf6 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 11:05:04 2023 -0400 + + Conditionalize openNURBS add_subdirectory + +commit 8ce8cb5e8a2a5b470b17189233c5f229fdddd044 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 10:38:43 2023 -0400 + + Set up for externally supplied openNURBS in new config. + +commit c35b7cb6bc658add583f77a2e835ae02ba1fa0e5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 11 09:50:57 2023 -0400 + + List file for distcheck + +commit 662109be35c41f20710583d1c1b45d3181c29fcc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Sep 10 22:21:24 2023 -0400 + + Note to look into another approach to spotting bad OpenGL behavior for qged. + +commit 2b28f31e7ff7c406a0d405d48859c1025a413567 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Sep 9 13:41:25 2023 -0400 + + Treat libutahrle as a brlcad_external if src/other/libutahrle is removed. + +commit def049603d0a6268bbd3b981c8f9a9bd8f660ca0 +Merge: 8fcd2866f2 da5cdab300 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Sep 9 11:24:39 2023 -0400 + + Merge pull request #87 from kevinsmia1939/main + + Add metainfo for BRL-CAD + +commit 605280706a456d901dc57f25010c69d43e54a712 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Sep 9 00:05:11 2023 -0400 + + Quick test setting up to try https://github.com/elalish/manifold instead of IRMB + + Currently known not to work due to a bug currently being addressed per + discussion at https://github.com/elalish/manifold/issues/553 + + Will need to try again once that is addressed. + +commit 8fcd2866f22eefc6cf145d856e0e6c10cb5003a1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 8 14:30:22 2023 -0400 + + Set up qged open/close db callbacks. Probably these should be doing more work... + +commit 8133b45eefa15054256df5b81deb2f731ec0a7da +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 8 14:08:31 2023 -0400 + + Make sure we have the mesh LoD context before proceeding + +commit 11f61e91d968bbe86f947ca393791da25032afbe +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 8 14:04:20 2023 -0400 + + Correct argv index for filename + +commit 74166154a2c7376323287a343263948304709638 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 8 11:44:05 2023 -0400 + + Put back the perplex/lemon version of dplot until we can more carefully evaluate its potential replacement. + +commit 76efb89f825c565f15686dd52148b7b891eb744e +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Sep 7 14:12:49 2023 -0400 + + Clear old dplot cmd code + + Brep boolean logic isn't behaving very well for me, so it's hard to test + this properly, but I think the basics are in place. Side note: need to + check if qged's handling of the "GED_MORE" return code from ged commands + is working correctly, or if I need to adjust something on the dplot + end... + +commit 9dc7e611e1b9d3fa535b577e9bdc191d3043b3f9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Sep 6 21:07:28 2023 -0400 + + Checkpoint work on a version of the dplot command that won't need perplex/lemon. (Incidentally, existing version is broken - overlay call wasn't updated when the syntax changed.) + +commit 4b13c88cb8f00ba342c1e4ddc712006441c18481 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 5 17:16:05 2023 -0400 + + Remove the csg code stubs + + This work didn't end up maturing, and we're gradually working to clear + out the perplex/lemon/re2c toolchain usage as well - it didn't end up + being used more broadly. + +commit 95d8800fd7d6dbeef2befaad38955c7cd9908e4c +Author: f4alt +Date: Wed Sep 6 16:17:45 2023 -0400 + + fix pnts color reading + + Need to scale down rgb values when reading. pnts "write" (and user + expectations) are for the pnts file to have rgb values from 0-255. + However, when reading this value is stored in a bu_color which expects + values from 0-1 + +commit f47b443e10af267a5b951468f572fa08a838a8cf +Author: f4alt +Date: Wed Sep 6 16:17:11 2023 -0400 + + inverse logic: bu_color_to_rgb_chars returns 0 on failure + +commit 90e9c70b5c37d6f11d7fbbf7518b92ba5643bd99 +Author: f4alt +Date: Fri Sep 1 15:20:46 2023 -0400 + + need to close fp before returning error + +commit 4e37eee758edd4caa4ff8603f9d1e4032dfd319f +Author: f4alt +Date: Fri Sep 1 15:18:31 2023 -0400 + + fix wrong type setting + +commit 1d0d5c427fbd24cdd205bfb2d29a35fe37d70419 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 13:49:34 2023 -0400 + + Update bot.xml remove some typos/extra text + +commit 4f1169e5a37b23f2cd386a9b8d45a8df8e8dccce +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 13:44:35 2023 -0400 + + Update B.xml consistency + +commit 188db8e2d1e9e049bd3c929fb0f7edda22829a5c +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 13:28:14 2023 -0400 + + Update bot.xml fix minor issue with input statement + +commit 9720243b5b0ea1e24e8ff83ef04076b7ac2a2d20 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 12:52:04 2023 -0400 + + Update bot.xml add some examples + +commit 4364b501bb57c15d8232252676368fffef0aca83 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 12:45:29 2023 -0400 + + Update bot.xml update set potential values + +commit 5750a31d719d39ab0865bf974c0cb0b003991a25 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 12:39:41 2023 -0400 + + Update bot.xml Add subcommand notes + +commit 97e08d5a8fd7218c9ea18c47e8c5cd08aa8fbb76 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 11:15:36 2023 -0400 + + Update bot_face_sort.xml fix typo + +commit b07411e001ced622f82d584b7ebb672d80eed4e9 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Sep 6 08:15:00 2023 -0400 + + Update bot.xml Add subcommand syntaxes + +commit 4fa92aa13952164d6b09aa9d30dffc2eeed2fb24 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Sep 5 10:31:24 2023 -0400 + + Stash an alias for printing the date a tag was created in Git + +commit 9c2a3ff1cc559392c15d0799b6c05eb4e3c9c923 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Sep 4 17:05:11 2023 -0400 + + Usability thoughts. + +commit ae110d5067372f732242e4fbd1c8db395bc9f243 +Merge: bdcc3a5d1f ab8930bc7c +Author: Daniel Rossberg <33295041+drossberg@users.noreply.github.com> +Date: Sat Sep 2 16:53:08 2023 +0200 + + Merge pull request #97 from GregoryLi0/nurbs_editing + + Nurbs editing Milestone 3 + - Rearrange NURBS module into geometry parts and topology parts. + - Simple line editing operations in 2D parameter space. + - Support for topology edges, faces, loops, and trimmes. + +commit bdcc3a5d1fef8013d4925a2b79d8df1675aadc03 +Author: f4alt +Date: Fri Sep 1 11:53:27 2023 -0400 + + oops - need to move this print too + + same reason as 4b4efea + +commit 5a0b4eda9ea3a1ec129e25b7b920b218213ca8eb +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Sep 1 11:28:29 2023 -0400 + + Add some logic for printing help + +commit 4b4efeaa7be0fc986613377ac4e7ae748ee39038 +Author: f4alt +Date: Fri Sep 1 11:21:52 2023 -0400 + + reorder print line to before memory is freed + + GED_DB_PUT_INTERNAL frees 'intern' which is the memory 'pnts' is + pointing to + +commit 085a52bf0960e4061b202b546ea9f5bf4521f6d5 +Author: f4alt +Date: Thu Aug 31 16:15:15 2023 -0400 + + looks like this was forgotten from stubbing-in phase + + RT_PNT_TYPE_X handlers appear to all be accounted for + +commit 36433a60ec8f0aca8699b42c10c6bee2e2c9a4f1 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 11:11:52 2023 -0400 + + Update nirt.xml remove some redundant text in examples + +commit ef89380495e0134c76fc22a092591af8f4ed7d22 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 11:05:30 2023 -0400 + + Update pnts.xml formatting options + +commit 5a2c39d907c933fed31de3b71cafa91d8694a592 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 11:00:14 2023 -0400 + + Update tol.xml remove excess option + +commit ba70e47fac736e913d055bd42fb42c10813443c4 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:54:39 2023 -0400 + + Update viewdir.xml (fix dots in usage) + +commit ef0611318b1a4d72e0c17f0ea7cc9fd380652f11 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:45:20 2023 -0400 + + Update viewdir.xml (add note) + +commit d2a96aa82355b4cb2a7dee12c2a0651286add076 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:07:43 2023 -0400 + + Update dump.xml (add note on location of file) + +commit 7b1d05608b07c7cff366b1509eef61414b8518a0 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:03:01 2023 -0400 + + Update pwd.xml (fix typo) + +commit 7c6d204f24be6523eb37ab3cbafce428af2958f4 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:02:29 2023 -0400 + + Update cd.xml (fix typo) + +commit 3209f22390c828ebbf8dbcffd6fb6cf3df363b06 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Sep 1 10:01:19 2023 -0400 + + Update e_id.xml fix typo + +commit e91f99747b8b11420a394f591af3a31f87634b04 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 22:37:08 2023 -0400 + + Stub in an edit2 command for qged + + As with draw vs draw2, the edit command in qged is probably going to be + a challenge that requires some extensive and invasive experimentation. + Stub in an edit2 that is activated by the same mechanism as the other *2 + commands so we can make contained changes. + +commit 3789c46c332e96f5c44c19d8396f9667420e3014 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 22:34:56 2023 -0400 + + qged needs to call opendb, not open + +commit 4fbc1dd231f0ad49112df47ba348232bc2c80207 +Author: Christopher Sean Morrison +Date: Thu Aug 31 22:30:36 2023 -0400 + + re-enable, now with the necessary commas. + + appears I got it right on the first attempt, all bn_vec_ae() tests passing. + +commit c400bb78ff7d64ed554449faa1a1cff667a93538 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 16:38:01 2023 -0400 + + Hide the details of the printing from the refresh function + +commit f90c8e86363eb8f6cd8f99673dde4b5bef82a329 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 16:18:34 2023 -0400 + + Remove stray code + +commit 7db9ad2b8a41914948d76c2596fa8cb607ccd01c +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 15:29:34 2023 -0400 + + Try moving MGED's Tcl printing of bu_log output to the main loop + + Per Tcl's documentation (https://www.tcl.tk/doc/howto/thread_model.html) + "errors will occur if you let more than one thread call into the same + interpreter (e.g., with Tcl_Eval)". This is a problem for MGED and + bu_log, since there is no guarantee in BRL-CAD's code base that multiple + threads won't call bu_log (this happens, for example, if bu_log is + called by any of the core librt routines during a parallel raytrace.) + The standard gui_output callback registered for MGED commands calls + Tcl_Eval, which puts us in the danger zone per the Tcl docs. + + This commit tries an experiment where the hook's responsibility is + simply to append the output string to a vls, and then the main Tcl + thread (i.e. the thread that IS allowed to call Tcl_Eval) handles + actually putting the text output onto the Tcl command prompt. The + hook's role is reduced to accumulating output in the correct variable, + and both the hook and the output routine use the same semaphore lock to + avoid any strange states when doing the printing. + +commit 478a7dda06f1df87a7d707a067a0286d2a4d4f1d +Author: Christopher Sean Morrison +Date: Thu Aug 31 15:44:53 2023 -0400 + + disable until testing is complete + +commit f2f5aed0494502f3265c260050358d9c25039b18 +Author: Christopher Sean Morrison +Date: Thu Aug 31 15:39:57 2023 -0400 + + need to be able to snap two entities together. + + the bullet physics engine might be a good general way to achieve this, or even simple direct ray tracing using a newton walk. main use case is being able to put an object into a scene and have it rest naturally, even if the ground is uneven or occluded. + +commit 8e34728d3f62d814eb24a049ccd34d1d442fff57 +Author: Christopher Sean Morrison +Date: Thu Aug 31 14:31:12 2023 -0400 + + add slew of bn_vec_ae tests. + + still waiting on compilation to confirm, but this adds 24 new tests that check all 90 degree axis alignments. done off the cuff, so have to check for a typo still. + +commit 568aa4f5868001ba3d5ca6d1f520d54eb81dc599 +Merge: d86435e722 9d084ecaee +Author: Christopher Sean Morrison +Date: Thu Aug 31 14:18:41 2023 -0400 + + resolved merge conflict, basically same edits reordered. + +commit 9d084ecaeef253e7e2651af2d2c53dfae753aadc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 14:15:19 2023 -0400 + + Looks like the new approach does work on Windows + +commit e59e35b2ff6a2951b9725d09ff19e593846ba297 +Author: f4alt +Date: Thu Aug 31 12:16:30 2023 -0400 + + eliminate duplicate functionality + + replace AZEL_FROM_V3DIR macro with bn_ae_vec + +commit fd4b6023296430b0e7c621804a43d9204fde376c +Author: f4alt +Date: Wed Aug 30 16:11:54 2023 -0400 + + eliminate duplicate functionality + + replace V3DIR_FROM_AZEL macro with bn_vec_ae + +commit 914c56a20bda1b0cc7aaacfa8aea9624d8d5be7d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 13:37:15 2023 -0400 + + Initialize ret + +commit b56798a3f7ce1b046576ae206959e91d50800876 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 12:53:58 2023 -0400 + + Correct Tcl return code + +commit 225f1f3ed0e841a362cad5be74dd04302eac39c2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 31 11:51:55 2023 -0400 + + We do need the callback on the create round - just count to make sure we don't end up in a loop + +commit d86435e722e4fabcaa4d501b8c45be90dea82134 +Author: Christopher Sean Morrison +Date: Wed Aug 30 19:35:53 2023 -0400 + + note intent to drop two vmath.h macros that duplicate libbn functions + + AZEL_FROM_V3DIR() and V3DIR_FROM_AZEL() were added back in 2007 despite there being bn_vec_ae() and bn_ae_vec(). there are subtle differences like the functions needing pointers to az/el and bn_ae_vec() returning degrees instead of radians, but the macros are still functionally duplicate API (despite a likely bug and obvious deg2rad inconsistency with AZEL_FROM_V3DIR). + + stub a section for 7.34 too.. seems highly unlikely nothing changed. + +commit 7336612e6a041fcd8e20cb7a23f2a9e7ed8c929b +Author: Christopher Sean Morrison +Date: Wed Aug 30 19:26:54 2023 -0400 + + FMIN() ftw. (see common.h) + +commit f4328c7e216f2ee6546cae989a4099b47baa6751 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 30 16:24:55 2023 -0400 + + Need to see if we can use the top level GEDP here - these temporary instances are going to be missing most of the correct MGED initializations, and commands aren't going to work as expected... + +commit ae39633fa57da8a0217a925674b04b9c38e0a866 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 30 16:12:51 2023 -0400 + + Rework MGED f_opendb/f_closedb functions to use GED + + The garbage_collect command exposed an interesting problem with how we + were managing the database open/close process. The db_i struct + maintains a dbi_uses slot where applications can note their use of a + database instance, which will in turn instruct db_close to not + completely eliminate a dbip until the use count has been reduced to + zero. This offers a form of protection from dbips becoming invalid + unexpectedly, and is used by MGED when defining Tcl interfaces to the + database. + + However, this mechanism causes a problem when attempting to garbage + collect a database. The current GC mechanism involves creating a new + version of the database and swapping it in for the old version. + However, doing so inevitably requires a full close operation on the + currently open database, and if the application has multiple uses of the + dbip registered libged lacks the information to properly close it. + While Linux will allow the file rename to succeed anyway (which is why + this issue wasn't caught in initial testing), Windows (correctly) + identifies the .g file as still being fopened and refuses to remove or + rename to overwrite it - the garbage collection itself succeeds, but we + can't stage the file to replace the old copy and re-open it without + breaking the dbi_uses rules. + + Because libged itself can't know what the application needs, we add + callbacks to libged that the application can register in order to + execute necessary additional logic before and after the GED opendb and + closedb operations. Thus far this is still only minimally tested on + Linux, so we need to confirm it truly solves the problem on Windows. We + also need to confirm it correctly handles the various failure cases and + user interactions wrapped up with database I/O. + +commit a03f61493a95d08f2a0ab4bd0c58245294eaf37b +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 30 15:34:51 2023 -0400 + + Update CMakeLists.txt (add pnts.xml) + +commit 7625dc76681072b02983ebd187e23b7f151fd336 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 30 15:34:24 2023 -0400 + + Create pnts.xml + +commit d9bdc95d5c3f9cdb0d13a6a09cd354e52bbd0cac +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 30 15:19:59 2023 -0400 + + Even if the open call fails, we want the post_opendb callback to trigger since the app may want to handle that case. + +commit 9cf1e528800199b9e505d2a556724925b7f86cb6 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 30 14:09:38 2023 -0400 + + Update make_pnts.xml + + add see also note for pnts command + +commit e0384c3abc29a6b470869b607ef92aaa6fce6b11 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 19:45:04 2023 -0400 +Date: Wed Aug 30 12:02:38 2023 -0400 - Define static assert for Ghost BSD + Add flip and create options to GED open + +commit 3e667f7303a064332de9435ba803d3eba50a524a +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 30 10:28:27 2023 -0400 + + Whoops - remove debugging exit + +commit 9720c5c5fac9d4daf84c43c67f4c45f1dee69302 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 30 08:36:25 2023 -0400 + + Update vmath.h - Similar to https://github.com/apache/mynewt-core/issues/2040#issuecomment-554571476 + update azel_from_v3dir - remove negative sign on X. Tested using dir2ae and it now returns the correct answer. -commit 703c261a6c428deefd68401ce92e2bb728915424 +commit 3c7b542dd00afec05793ba3fe781b1935645f1d9 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 16:32:52 2023 -0400 +Date: Tue Aug 29 20:50:44 2023 -0400 - More advanced variables + Ditto MGED - don't hardcode 5 -commit 028ba3e64c724ea2533b3846145d5990b775a7fd +commit 90e2388955664534f36c87831a0b4d0d7c8592e3 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 16:10:36 2023 -0400 +Date: Tue Aug 29 20:47:28 2023 -0400 - Mark various variables as advanced for CMake + Rather than hardcoding 5 as the BRL-CAD db format to create, use a define -commit f9079cf1c46382d82932c5a12236b9638edcc644 +commit cb0df48966efaf430f10001b647488c71133d05b Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 14:35:25 2023 -0400 +Date: Tue Aug 29 16:56:48 2023 -0400 - Remove odd_pathnames from distcheck-full set - - Too problematic with 3rd party builds - we'll just keep it as a - stand-alone test when conditions are right to run it. We may be able to - make it standard again if we fully separate src/other/ext into its own - repository and make it a separate build, but that's down the road. + For easier working, break f_opendb and f_closedb out of mged.c -commit 40f38f89ce4ae6d84378ba70b99ee66cf00f1a79 +commit bbbbb75b0abad2fcdf04164f9e3ef7405da8764f Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 13:03:33 2023 -0400 +Date: Tue Aug 29 16:56:00 2023 -0400 - Ah, apparently 1.6.40 png has this covered already... + define min if we don't have it (saw on Linux) -commit b6f71f4bec72d8d0781705056eab65dd7117b999 +commit 246dd707100010fac17cafea3f668b33e948f8f2 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 12:55:52 2023 -0400 +Date: Tue Aug 29 16:28:57 2023 -0400 - Add a way to suppress the PNG use of 'd' suffix + Rough in ged opendb/closedb callbacks, cleanup - Grr. If build type gets set to Debug, instead of being left empty, - Linux is also throwing in the 'd' suffix on debug build libs from png. - Add a way to specify at configure time not to do that - it really messes - with our build logic. Should probably try to upstream this or something - like it. + The opendb command was repeating a lot of the work of the closedb + command - just have opendb call closedb first if needed. + + As a first cut, give applications a chance to take action both + immediately before and immediately after the open and close operations + take place - it's conceivable they'll want to record info about the old + state, and they'll almost always want to respond to the new data from a + successful open. -commit c5e99fcc9ba931e109a1cbbbcac4a102715855fb -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 11:32:34 2023 -0400 +commit 9094488b8fc96221a0d8dc221a9d3dd701432fdd +Author: f4alt +Date: Tue Aug 29 16:05:19 2023 -0400 - Fix executable permission on sh files + fix mged crash when listeval path exceeds max len - Looks like we lost executable settings in the 2023-02-02 year updating - commit. Was manifesting in a distcheck failure when the check target's - invocation of benchmark clobber wasn't succeeding due to benchmark not - being executable, leaving behind files. That calling of the benchmark - script didn't prefix with an explicit ${SH_EXEC} call, and thus relied - on benchmark being directly executable on its own. + avoid writing to and accessing unallocated array positions -commit 8da7ea79d1740fba20d0f77d401247ded98cbe71 +commit 9bf31c356898a8ab43de2a7bb76126d7441407eb Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 11:10:22 2023 -0400 +Date: Tue Aug 29 15:54:59 2023 -0400 - List perplex outputs for distclean + open_db -> opendb, close_db -> closedb -commit 8d7db5bab5fbc0087e55ed32e279ffb32e871890 +commit a7bba28a948a1939e53ab224fdc4e4a381cddb23 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 10:04:46 2023 -0400 +Date: Tue Aug 29 12:51:00 2023 -0400 - Update log with commits since 2023-02-27 + Thanks Sean - open and close need the _db suffix for the command line so we don't conflict with Tcl commands + +commit 16df83f1d1a875b8619786c5e7c5528136063ab2 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 29 11:06:10 2023 -0400 + + Update bot_flip.xml + + add note about orientation. + +commit 0bc6a765b1f6fd5645cd29de4080001b197e3675 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 29 09:56:27 2023 -0400 + + Update help.tcl + + note e_id draws objects (not edits) -commit 3ed4f9a66ef72ba32fa9a696b3a66afcaf47af88 +commit a409904bb10e40e577de4bed0bf5edb00afff87d +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 29 09:33:30 2023 -0400 + + Update helplib.tcl + + adjust note about orientation to note that it sets az/el/twist + +commit 71873f8b235b844b2c2dc9bc2180e14d94acee44 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 10:03:37 2023 -0400 +Date: Mon Aug 28 16:55:43 2023 -0400 - HACKING step 06: Update the version numbers + Report OpenCV in summary -commit f6a4d2c29d55a4352f3c6461850c8a066b93a843 +commit c39d68e34bd6171f8476007fde1bda2d0a2f27fb Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 09:59:18 2023 -0400 +Date: Mon Aug 28 16:45:00 2023 -0400 - Set the NEWS release date + OpenCV detection works similarly to the style used for Qt6 - find the directory with the config file, and use the definitions provided by the project. -commit eff35d92dbc2fbb3b5389ee81c9570f84d8e8573 +commit cfaac7f61c52e996061bdfce9b654d65cf807c3e Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 09:52:11 2023 -0400 +Date: Mon Aug 28 12:47:03 2023 -0400 - Move the TODO entries down + Fix archer crash with "make arb8.s arb" + + libtclcad/Archer implicit assumptions strike again. The libtclcad view + creation command assigns some custom structures to u_data, and the + default ged bview we were creating didn't have that. The libtclcad + logic then got the default view, assumed something was there that + wasn't, and crashed. - Moving the TODO entries we weren't able to address this release to the - queue for later reassessment. + For now we won't create the default view and will instead alter the + codes that had been assuming it to provide their own instead. I can see + arguments both ways for providing a default. If we CAN provide a + default view with a ged_open, a whole lot of commands that would + otherwise have to bail unless/until the app provides a view will work + out of the box... On the other hand, it may be reasonable to expect + applications to manage their own views - after all, that's what Archer + is doing. Nor does qged rely on a ged provide view... + +commit e4b6a1128131be4de97664b9821bfe86876ff75d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 28 12:40:55 2023 -0400 + + Sanity check invent_solid gedp inputs + +commit 30df5d85c8900640e8e94a6ca32372ddfcd4742b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 28 12:36:18 2023 -0400 + + Like the externals repo, try a couple options for home dir + +commit 6f41a3473dc7cd4fc1e309931302aa18741d5a70 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 28 11:52:29 2023 -0400 + + Don't add a view to a set more than once -commit d1a9f7acd7479d62eeb4f108306909964f3694b8 -Merge: 22d115d677 f7f03baa55 +commit ab8930bc7c2fdfee8eef6ba2d4fef4515fee66b0 +Author: GregoryLi0 +Date: Sun Aug 27 10:47:21 2023 +0800 + + 🌈 style(libged): tab format + +commit afa2a3cdc85473bfe5f6d7330a2291b96de73852 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 26 22:44:17 2023 -0400 + + Track files even if QT is off + +commit 7ab8dd8857f6ef93cbc1a42d76b4ce3e9279cdc5 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 26 15:44:04 2023 -0400 + + Shouldn't need to remove the rpath first - set-rpath should replace the old path (unlike the OSX tools). + +commit 86dc3e2207605c5df87730b75df63a33a9375a3b Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 09:46:32 2023 -0400 +Date: Sat Aug 26 15:43:13 2023 -0400 - merge of main f7f03baa55 to RELEASE branch + Look in subdirecory by default -commit f7f03baa55f03718e62e5ae83ed470c75dcfc985 +commit 3ef32f824a3fd5d01e5023aaf38642d001fb7d23 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 09:45:40 2023 -0400 +Date: Sat Aug 26 14:19:31 2023 -0400 - Stray 'a' character + Watch extnoinstall contents for CMake triggering purposes as well. -commit 767e96ebdddd101e0506b023285d649791623928 +commit 9026b2f9868568c22d5a60582d96dcf27399d7e2 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 26 09:37:42 2023 -0400 +Date: Sat Aug 26 13:50:53 2023 -0400 - Release mode with newer compilers on Linux wasn't seeing localtime_r without specifying POSIX... + Look for the new LIEF based tool first, then patchelf -commit fda0db542eb9bc2b3c03d60f38bcf3dc99c83ea4 +commit f3e5cf862f53011e60469f1d5770020675878b1e Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Jul 24 15:31:26 2023 -0400 +Date: Fri Aug 25 19:47:48 2023 -0400 - Neither branch of the code frees memory, so we don't need to call out not doing it here. + More work on organizing the ext copy/rpath logic for the new scheme -commit 8d5ce782a5da4051a10b8272401fe0dd305cb54f +commit d4417c4c563443f7a4661ead59ba25b3c4b5da2d Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jul 19 09:50:48 2023 -0400 +Date: Fri Aug 25 16:59:02 2023 -0400 - Back out survey tool experiment + Try to be more selective about copy-on-repeat-config - VCS has this if it proves useful, but going to need to think about how - to output data in a way that allows for useful queries. May warrant - dumping an SQLite database, but if we go that route we'll need to give - some thought to table designs so we can construct useful queries... + With current CMake features we should be able to do a pretty decent job + of recognizing what needs updating between the build dir and the + extinstall dir - make a stab at a more judicious approach to updating + the build dir after the first initial copy is complete. -commit f901b0a8935d78b23ea58c7a6bf647bf8339214f +commit fac307283cd46c6d2277707d35b3431be303b783 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Jul 18 16:33:04 2023 -0400 +Date: Fri Aug 25 15:05:39 2023 -0400 - First introspection into the .g contents + QApplication takes a char** array, not a const char ** - shows up in Linux release building -commit b4a379837d345f25069d0773aaffa764f8e374ec +commit 8102f44bc2c3e676ee17566976888d2011415e49 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Jul 18 15:43:41 2023 -0400 +Date: Fri Aug 25 14:55:44 2023 -0400 - Checkpoint some experiments with a tool to walk through a directory hierarchy, identify .g files, and analyze/compare their contents. + Like Archer, qged is GUI only on Windows -commit 2f405a7271c499da9c1bc3034861701981762474 +commit 32dd2fad418ba3a2711fb3c418a7038ed43d7a98 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Jul 18 14:17:41 2023 -0400 +Date: Fri Aug 25 14:06:25 2023 -0400 - Add a minimal 'is this a .g file' function, so we can quickly sort through a large pile of files to ID the .g databases based on headers. + Don't enable the test Qt targets unless we have the component -commit d76e12bcd05cbd3355ef56ff98a78d4f65700614 +commit 531838ef78dccc8ee5e13495de32200bac215b13 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Jul 18 13:45:01 2023 -0400 +Date: Fri Aug 25 13:55:03 2023 -0400 - Document an MGED crash opening a .tif file that mis-identifies as a v4 .g file + OpenGLWidgets isn't one of the Qt5 components -commit ef51671bbd3c680561a13f123cec67277a07d188 +commit 2b80aae0e89fc6ac6f0b60ad4f8dfef66ef44c49 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Sat Jul 1 19:06:10 2023 -0400 +Date: Fri Aug 25 13:53:25 2023 -0400 - Initialize and free memory for static analyzer + EXPAND_TILDE is pretty new, can't use it yet. -commit 27b0b4c402cf478fc878c8e0e2bfa8dcf74dadc4 +commit 9f59d8835c4c5d27854cb707363d4867428c1d35 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Sat Jul 1 17:53:39 2023 -0400 +Date: Thu Aug 24 21:16:16 2023 -0400 - Wstrict-prototypes change + First successful running of mged/qged from an OSX TGZ package + + @executable_path appears to be the closest conceptual mapping to + $ORIGIN, and this appears to do what we want - was able to launch qged + and mged on OSX from a TGZ package built using the new external + repository scheme. -commit 3631cef6bb3b68a01343d4809c773e0729696e05 -Merge: f5de8feb5a 0b1a95f95a -Author: Daniel Rossberg <33295041+drossberg@users.noreply.github.com> -Date: Sat Jul 1 18:44:50 2023 +0200 +commit ca9d3028f9f3299c66f286277688f3727852a8c1 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 24 20:51:44 2023 -0400 + + Checkpoint some work on OSX RPATH settings... + +commit 74650c7c26674bd8aeede37e57b9f7783c81d0b3 +Author: f4alt +Date: Thu Aug 24 17:48:53 2023 -0400 + + revert from ee0562a + +commit 3f60bb69a5e1cfd5dc0ef80de3126227adc67e47 +Author: f4alt +Date: Thu Aug 24 13:54:29 2023 -0400 + + create man page for 'put' + +commit f03306be1c48c753e46c97b393ed08ee4fde9ec9 +Author: f4alt +Date: Wed Aug 23 16:20:42 2023 -0400 + + material adjust handler + +commit 2b449633a342f9abc7b8eb7b9bb9d8ec304dc226 +Author: f4alt +Date: Wed Aug 23 12:52:40 2023 -0400 + + minimal creation func for material + +commit 93e051f8f0d2a47fd90566eaac954da78b68b291 +Author: f4alt +Date: Wed Aug 23 12:11:13 2023 -0400 + + minimal creation func for script + +commit 3ffab3314dae7519c39fe0418b17fe1ba329d8b8 +Author: f4alt +Date: Mon Aug 21 16:42:52 2023 -0400 + + basic constraint functionality + +commit 6a2318adf76d17c3a1638a95671bd7525f4d0f66 +Author: f4alt +Date: Thu Aug 17 13:33:54 2023 -0400 - Merge pull request #80 from GregoryLi0/nurbs_editing + minimal creation func for brep - Nurbs editing Milestone 1: Perform simple operations on brep geometries using command line. + change adjust function return expectations to allow for empty 'put' + default creation + +commit bb356085bfd558f442590484fb29e0445f03af98 +Author: f4alt +Date: Thu Aug 17 12:56:51 2023 -0400 + + minimal creation func for metaball + +commit 8dba8fc0b53888ef1d59be69e0131abbbc3b5303 +Author: f4alt +Date: Thu Aug 17 12:43:18 2023 -0400 + + make unused table entries uppercase - Curve operations: - create (using a pre-determined template) - in (given detailed description) - move - set control vertex - flip - insert knot - trim - join (join end of curve 1 to start of curve 2) + code that iterates over the table checks against all lowercase. Rename + unused entries to uppercase so they cannot be accessed by accident. + +commit f46b77a646801a63fcda294784602ae896e46d79 +Author: f4alt +Date: Thu Aug 17 12:06:39 2023 -0400 + + avoid malloc(0) - ensure theres bodys to convert + +commit ee0562a971a198a891765c49c16658266f77d78e +Author: f4alt +Date: Wed Aug 16 12:48:28 2023 -0400 + + minimal creation func for submodel - Surface operations: - create (using a pre-determined template) - birail (create a surface between two curves) - move - set control vertex - trim + also correct some edge case allocation assumptions + +commit 2b7bbf07e075900cdcece9834703e77a07ae71bd +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 24 11:40:40 2023 -0400 + + Update help.tcl - It's a work in progress... + add dir2ae -commit 0b1a95f95ad78768cdb39dd7db61a48b2bd48c18 -Author: GregoryLi0 -Date: Sat Jul 1 14:43:08 2023 +0800 +commit 101b219f21799133f3a4193e8346bf222fd85495 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 24 11:39:08 2023 -0400 - 🎈 perf(libbrep): delete one if() + Update CMakeLists.txt + + add dir2ae.xml -commit 6c1d88b6f5f2a22b22c9cc9014db80c3f517e1a7 -Author: GregoryLi0 -Date: Sat Jul 1 14:40:37 2023 +0800 +commit 1e01b67c17b56eabd6d4cc3a9f3241abe8a96081 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 24 11:38:27 2023 -0400 - 🌈 style: extern "C" to static + Create dir2ae.xml -commit 3808b03a9f8ad30b3c53e12e3c69488b7619c90e -Author: GregoryLi0 -Date: Sat Jul 1 14:33:56 2023 +0800 +commit 143331c26a71ce7611d0946c4b4baf73b8de3734 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 24 11:33:07 2023 -0400 - 🌈 style: - - spacing + Update ae2dir.xml -commit a83faaf4840f649b7e49445d9b44ca1def17f79b +commit 5515ae787e017c8b43803c6f46c7997635a7a32c Author: GregoryLi0 -Date: Sat Jul 1 14:29:16 2023 +0800 +Date: Thu Aug 24 21:54:32 2023 +0800 - 🌈 style: file end + 🌈 style(libbrep/libged): code format -commit 96b2287ea5d7fa4041c816f0e13a82f9defb2d19 -Author: GregoryLi0 -Date: Sat Jul 1 14:27:40 2023 +0800 +commit 04a83b31ea9f836414fc209ca0387f5e89d5176e +Merge: 69d5f9adbd bb05ad9fd6 +Author: Gregory Li <974749051@qq.com> +Date: Thu Aug 24 21:40:05 2023 +0800 + + Merge branch 'BRL-CAD:main' into nurbs_editing - 🌈 style: copyright year +commit bb05ad9fd6b50a172e80b73ba2a6e4e6957d0940 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 23 17:03:45 2023 -0400 + + Apparently I'm not supposed to remove the signature before using install_name_tool? -commit f5de8feb5a6d0ad26d54dde37920a0033a7112b1 +commit f3ad99aa70c99f1734be7cffcf9ed378e7638252 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Jun 30 18:38:32 2023 -0400 +Date: Wed Aug 23 16:45:33 2023 -0400 - Fixes for older gcc building + Seem to be running into problems with Apple's hardened runtime when trying to mod dependencies? -commit 992cd3585fd545010593d4a2fa12e9f7cc8521f9 +commit 29ff42ca959b66ae59ea27fec72b4eaf6b4fe53d Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Jun 30 12:02:56 2023 -0400 +Date: Wed Aug 23 11:05:19 2023 -0400 - Only do the fallback isascii define if we actually have it... + Should be able to rely on the global CMAKE_INSTALL_RPATH default unless it's wrong for a specific target. -commit d2b206254db649984fd436cad7cecd0e7ed611f9 +commit 867bcc3eed4d1af6628673ae260c1ed58f221d5a Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Jun 30 11:19:00 2023 -0400 +Date: Wed Aug 23 10:57:49 2023 -0400 + + First steps towards cleaning up RPATH handling + + Looks like using INSTALL_RPATH to override the global RPATH value for + specific targets is going to be the right way to go. Need to see if + we can get away with just using the INSTALL_NAME_DIR setting on OSX. + +commit 69d5f9adbdbedcd4895ce0b2304b425b7c57b9bd +Author: GregoryLi0 +Date: Wed Aug 23 22:43:46 2023 +0800 + + ✨ feat(libbrep/libged): reverse face + + Add 'brep .. topo f_rev .." cmd - Update compile tests for -Wstrict-prototypes +commit 1ea45485eccc504fa467218be3e316005a47b7c4 +Author: GregoryLi0 +Date: Wed Aug 23 18:59:11 2023 +0800 + + 🌈 style(libbrep): function rename + +commit b59078dd2720b34207be3d9626a81eb4f801979e +Author: GregoryLi0 +Date: Wed Aug 23 18:53:48 2023 +0800 + + ✨ feat(libbrep/libged): remove curve2d - The bu_file realpath regression test was failing with clang 16. Upon - investigation, the realpath detection proved to not be succeeding due to - the following error: + Add 'brep .. geo c2_remove ..' cmd + +commit 80744f8ab8f67f9f91523f940b6d97f41e9b2244 +Author: GregoryLi0 +Date: Wed Aug 23 18:45:25 2023 +0800 + + ✨ feat(libbrep/libged): remove vertex - error: a function declaration without a prototype is deprecated in all - versions of C [-Werror,-Wstrict-prototypes] - int main() {(void)realpath; return 0;} - ^ - void - 1 error generated. + Add 'brep .. geo v_remove' func + +commit 0badeb1e1fe6773e28d8509d357132d81bd5e664 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Tue Aug 22 23:40:16 2023 -0400 + + Note a problem with current ORIGIN rpath logic - This is a more general issue with our tests that define functions - without arguments, and is also triggered by CMake's own - CheckStructHasMember.cmake test. Apparently - (https://stackoverflow.com/a/76371638) this has to do with support - for void func() style functions being obsolete for a long time, and - the compilers are now adding warnings about them. + With the introduction of plugins and more complicated hierarchies, the + ORIGIN/../lib pattern isn't correct in all cases. Shows up when testing + a tar.gz build without the install in its /usr/brlcad location - we're + not finding plugins correctly. - Looking in CMakeErrors.log for the warning message, we can identify - various cases in our code where tests were failing because of this - issue. It's a little hard to check for by pattern searching, so tests - not run on this particular machine/configuration may still have issues - (and I've not checked at all to see if the third party build tests have - high enough strictness flags to hit this issue...) + Need to think about how to handle this - probably need to process the + relative paths of the target objects and come up with the correct ORIGIN + path on a case by case basis. -commit fc2352bfa98f38056b6a54a26f4338b55c6bc5eb +commit 92e8ba762af6c618481a35a2848efc240b0ba554 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Jun 30 10:45:45 2023 -0400 +Date: Tue Aug 22 22:28:28 2023 -0400 - Changes to itcl3, itk3, tkhtml and tktable sources for building with clang 16 + Because bundled Qt is now a possibility with the new ext setup, add it to the reporting -commit b0b8ed655071d0353b4ea88271fb87e696c685d4 +commit 7b492fae92602554b6eb026954ca103452187b1b Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Jun 30 10:18:47 2023 -0400 +Date: Tue Aug 22 15:21:02 2023 -0400 - Add a few build fixes for clang 16 + Linux with stepcode + Look for a bundled Qt6 instance if we're using the new ext repository -commit 47f93477674e8ed61aca5dc807c0ff88fd242eb7 +commit d988f01288a023a5e4b492becee8ade368aabc13 Author: GregoryLi0 -Date: Thu Jun 29 10:55:03 2023 +0800 +Date: Wed Aug 23 00:50:13 2023 +0800 - ✨ feat(libbrep/libged): curve interpolation + 🦄 refactor(libged): rename cmd names - add cmd "brep ... curve interp ..." to create a cubic nurbs curve by interpolating a set of points + rename brep topology cmd names -commit f1bc14c073d651fbcb7ef4de1424548648bfdf72 +commit 1d319ac0804c761cb14d2e1781c2f7c920004c5a Author: GregoryLi0 -Date: Thu Jun 29 09:33:24 2023 +0800 +Date: Wed Aug 23 00:41:58 2023 +0800 - 🌈 style(libbrep): rename func + ✨ feat(libged): move surf operations + + move 'brep .. surf ..' cmds to 'brep .. geo s_..' -commit 9b19a1acf093abe08f6fe4f0c3b57bf6bb430e45 +commit c31c68d9bfd8a97e57fec1de372b7d52c143e484 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jun 28 11:06:54 2023 -0400 +Date: Tue Aug 22 12:33:06 2023 -0400 - Minimize the amount of disabled code for the experimental option - goal is to avoid it getting stale, so we want it compiling. + No need to stash timestamps. Also, clear multiconfig copies of files as well. -commit 6328c99eb9f6e31bb615ac8d16ba9af4d377d100 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jun 28 10:41:58 2023 -0400 +commit 1d477283e69340e13db3ffd835e69cd766d03425 +Author: GregoryLi0 +Date: Wed Aug 23 00:22:06 2023 +0800 - Stash experimental code testing InteractiveAndRobustMeshBooleans - - The InteractiveAndRobustMeshBooleans research project at - https://github.com/gcherchi/InteractiveAndRobustMeshBooleans seeks to - implement fast and robust boolean operations on triangle meshes. The - changes being merged here use the 'libirmb' branch in the fork located - at https://github.com/starseeker/InteractiveAndRobustMeshBooleans to try - this approach with a BRL-CAD CSG tree. - - This logic, combined with the libirmb branch, works to trigger the - boolean attempt. However, it currently fails almost immediately on any - non-trivial CSG input due to how the upstream code is generating output - when coplanar faces (commonly found in CSG models) are involved. They - don't currently generate manifold outputs in those cases - (https://github.com/gcherchi/InteractiveAndRobustMeshBooleans/issues/13) - which means (for example) a coplanar arb subtraction will likely result - in an open mesh, which is in turn invalid for subsequent processing. + ✨ feat(libged): move brep c3 cmd - I'm mostly stashing this into main in the hopes that we might be - able to interest someone wanting to do follow-on IRMB work for the "need - manifold output" use-case. In theory, it might be possible to use the - available info in the boolean to assemble a manifold output in those - cases. The idea would be to extending the original IRMB code to "fill - in" the currently produced non-manifold areas resulting from coplanar - interactions, which should be available (in principle) if the code is - able to "bite out" the areas producing the non-manifold outputs in the - first place. Doing so would require a fairly deep understanding of the - IRMB processing code to identify the necessary information for coplanar - "patching" and injecting the results output mesh assembly logic. + move 'brep .. curve ..' cmd to 'brep .. geo c3_' + +commit d6f05149159700b95f3de9d99d34d52d7f6651b5 +Author: GregoryLi0 +Date: Tue Aug 22 23:56:15 2023 +0800 + + ✨ feat(libbrep/libged): reclassify nurbs ops - There appears to be work going on by the upstream team to improve - general robustness with the IRMB code, so we don't want to get too far - away from it - in an ideal world we could implement an "always produce - manifold output" mode that could be contributed back upstream to the - main IRMB codebase. + Plan to reclassify nurbs editing operations into geometric and topological operations + 1. create 'brep .. geo' subcmd + 2. move 'create_v' cmd to geo subcmd -commit a9ce2c24a2058dda75fa5739a3058a943c00c374 +commit b20680429a7b491a6800fd89c2b7caf4d2e93735 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jun 28 11:42:31 2023 -0400 +Date: Tue Aug 22 10:22:15 2023 -0400 - distcheck fixes for Creo plugin code + Whoops, wrong logic ordering in if check -commit 0cc7665244a14006fabec2199fc30609376ad6cb +commit 507470a3623376bae1d14c74c1f39affa2eba243 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Jun 28 09:51:37 2023 -0400 +Date: Tue Aug 22 10:19:43 2023 -0400 - Correct shim building for Creo plugin + Newer CMake's are getting noisier about this being set to old... -commit ab358bef2579bd132cea643505a00b31f173b1a7 -Merge: 68b0d503de 33f816854d -Author: Red Carrera <80796073+redcarrera@users.noreply.github.com> -Date: Mon Jun 26 08:50:31 2023 -0400 +commit cc1f2660c42254c251f1fdd1bccd6bff6fea3d5d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 22:15:44 2023 -0400 - Merge pull request #68 from redcarrera/20230322 + Add necessary Tk headers to build dm-wgl - Creo to BRL-CAD Converter as of 3/22/2023 + Preparing for src/other/ext to move to an external repository, we expose + the fact that dm-wgl is using internal Tk functionality requiring + non-public headers. Put just the necessary includes in with wgl to make + this self contained and avoid requiring the ext repository's source + location just for wgl. -commit 3661e50e534cb3b21b9d90bcea3fa1f705ce6501 -Author: GregoryLi0 -Date: Mon Jun 26 12:06:20 2023 +0800 +commit e7614acb782173622e7b3e8fe252dc72a1c7a79b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 20:40:05 2023 -0400 - 🎈 perf(libged): rename birail func - - change 'brep surface create_from_curves' to 'brep surface birail' + Adjust FindASSETIMPORT.cmake -commit 21d08e0d06165b023bc5f3c2296eda98be18516f -Author: GregoryLi0 -Date: Mon Jun 26 11:55:05 2023 +0800 +commit 5e22556c0a95d13a64488c0905086ab45b40ab53 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 19:31:32 2023 -0400 - 🌈 style(libbrep/libged): modify whitespace + Right - on Windows we have to do the lib prefix to avoid collisions... -commit b7dde9cdba550e2c83940de53db077cdeba51045 -Author: GregoryLi0 -Date: Mon Jun 26 11:04:49 2023 +0800 +commit 4320ac170ead54aaec59d4993303b37b36c7da89 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 17:10:28 2023 -0400 + + Make sure our code knows about Z_PREFIX_STR if we're using local zlib + +commit 5a6fc55d5e9f5d40a33a61377c51c9d3cb39f8bc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 16:54:30 2023 -0400 + + Tk vars need to be reset as well for FindTCL + +commit f8ced1a663552fbb72ea7f29acb940e878557754 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 16:52:26 2023 -0400 + + More PNG resetting to do for find_package reset + +commit 9f5527d5411f9a88a28e65272c5b560a02ac23e0 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 16:47:55 2023 -0400 + + Make CMake configure depend on extinstall contents to force the update process if extinstall files change. Not perfect in that it won't spot additions with no alterations or removals, but should help. + +commit 3aa0e92b44102b1eab64aad0e10976421fe7c806 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 16:31:21 2023 -0400 + + Reset find_package states if extinstall changes + +commit 03ee5ffcd8311567a5d5917c02fc5b44b31fbf9f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 16:01:59 2023 -0400 + + If configure is re-run, detect changes in extinstall and redo. Not fully working yet - for this to do what is expected, we also need to reset find_package results. + +commit bcffd18018ac7d6e0cca3b981a0d2103a0912cf7 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 15:02:54 2023 -0400 + + Improve filtering system for skipping select extinstall files + +commit 77d117a7cddfd2077830a746193a4f98440d1678 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 21 12:25:40 2023 -0400 - 🎈 perf(libbrep/libged): check styles: Braces + Do all the initial processing once, on first copy - only the install(CODE) steps need to be repeated each configure -commit e209b605ee5512975abda01ae10473f42dd3ef27 +commit 85b508f5cb92c26863a5a12098d9343e6c375d48 Author: GregoryLi0 -Date: Sun Jun 25 10:48:01 2023 +0800 +Date: Mon Aug 21 22:29:34 2023 +0800 - 🎈 perf(libged): perf log outputs + ✨ feat(libbrep/libged): crete loop and trim + + 1. Add 'brep .. topo create_l ..' + 2. Add 'brep .. topo create_t ..' cmd + 3. Add id check for create_f + +commit 016ee2f4079017170b4cb37592154ae4361b7312 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Aug 20 14:04:08 2023 -0400 + + Adjust how we're processing extinstall for path correction -commit 4e85d1dcbe35f6a1dbfcb8005a0326fd9f0a0e2b +commit f3c8064b1ddfc9bf456478ae0f06c042d0f8321f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sun Aug 20 11:03:01 2023 -0400 + + Remove strclear from main repo - looks like it'll make more sense in the external repo. + +commit 552f96d4f1149eab26ad17109a78cf89a976c9ba Author: GregoryLi0 -Date: Sat Jun 24 12:00:50 2023 +0800 +Date: Sun Aug 20 16:37:08 2023 +0800 - 🎈 perf(libbrep): perf func names + ✨ feat(libbrep/libged): create 2d param line - Canonical function names and parameters + Add 'brep .. curve make_2dline ..' cmd -commit 75fda0b379ece611cf54e30e0888fa2f28614e50 -Merge: 0dfc169bbc 68b0d503de -Author: Gregory Li <974749051@qq.com> -Date: Sat Jun 24 11:17:37 2023 +0800 +commit 9004c445b0fe10ff2bb5ec30e7ebef805b721097 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 21:32:05 2023 -0400 - Merge branch 'BRL-CAD:main' into nurbs_editing + Note possible change in approach to the string scrubbing + +commit 766983ee01b12d887d0b4de1d42e81840a6e5999 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 21:27:39 2023 -0400 + + Checkpoint + +commit 5c80ab8a96aa03cf7b83f02ec65d46b5da266439 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 20:23:46 2023 -0400 + + Improve stale string scrubbing - still have some leftovers from the Tcl *Config.sh files, but those might be better handled in the brlcad_externals build as they're a bit of a special case... -commit 0dfc169bbc773f1e89754ad4265642a9b858e85d +commit 656302fa52055ccb6be71ccc72d165ca3b71ae53 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 09:53:16 2023 -0400 + + Add strclear to misc/tools CMakeLists.txt file, set up use for non executable files in test logic. + +commit 0f15181633b5ad669b952fe1c3dd8dbc53cf24f9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 09:42:17 2023 -0400 + + Actually, for the use case in question if we have detect a binary file we want to go ahead and clear the string. + +commit 6a93d55d5fe57852af936cd236c7d67a8f2aced2 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Sat Aug 19 09:33:38 2023 -0400 + + Add a mode for text string replacment as well (for things like tkConfig.sh...) + +commit 49efb58517c3bccb2ae70b44878d5273bb677db3 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Aug 18 21:22:13 2023 -0400 + + Add a utility to null out stale paths in third party bin files + +commit 5acf5f9fd11157ee7c52565837cf4a80c92e2dcb +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Aug 18 14:33:10 2023 -0400 + + If a file is explicitly in the BINARY_FILES list, install it accordingly. + +commit d9f69d91cbdb81f012cc25a93e8a98bcbc77368f Author: GregoryLi0 -Date: Thu Jun 22 12:03:23 2023 +0800 +Date: Fri Aug 18 23:17:18 2023 +0800 - 🎈 perf(libbrep): make clamped knot + 🐞 fix(libbrep): set vertex tol -commit ae67a3f89c0fd6ce7a86476bf101c9a08d14059c +commit 39f07bc0af76465004d1a601523d79f6ee6780fc Author: GregoryLi0 -Date: Tue Jun 20 10:57:30 2023 +0800 +Date: Fri Aug 18 23:14:21 2023 +0800 - ✨ feat(libbrep,libged): join curves + ✨ feat(libbrep/libged): create loop - join two curves. Join the end of curve_id_1 to the start of curve_id_2. - Remark: the index of C3 is changed after join!!! + Add 'brep .. topo create_l ..' func -commit 7b67769a32c0b51e26bbe2a1a650ac9a8c83ac2c +commit 6a4a15f6803399aed6dee92c2150cfb793393f08 Author: GregoryLi0 -Date: Thu Jun 15 20:18:47 2023 +0800 +Date: Fri Aug 18 23:05:18 2023 +0800 - 🌈 style(libbrep, libged): code auto format + ✨ feat(libbrep/libged): ext v from surf - code auto format using VScode + 1. Add 'brep .. surface ext_v ..' function + 2. shorten cmd length, optimize purpose string + 2. some code refactor about variable names -commit 50ec62699af7925332ce588d0b9f41bcafd1731e +commit 14cae326c29e1237882cde4a381d6e56b0b74d0a Author: GregoryLi0 -Date: Thu Jun 15 20:13:10 2023 +0800 +Date: Fri Aug 18 22:33:46 2023 +0800 - ✨ feat: create ruled surf + ✨ feat(libbrep/libbged): extract c3 from face - add cmd `brep .. surface create_from_curves ..``. cmd Name shall be checked + Add 'brep .. surface extract_curve ..' function -commit 85d6c2bd87877c5d6311634e300ba89ea78e22fc -Author: GregoryLi0 -Date: Wed Jun 14 12:17:25 2023 +0800 +commit 05b3e750ce0701eb272d9a1ed4788a88a417bb6d +Author: Christopher Sean Morrison +Date: Fri Aug 18 03:04:40 2023 -0400 - 🦄 refactor: change args to edit + spent few hours reviewing and rewriting rtwizard's manual page. - change args passed to libbrep/edit as (On_brep*, ...) + goal was to improve the readability, eliminate some of the technical detail and caveats, and make it more easily skimmed for information. really pushed down (in some spots eliminated) all the distracting commentary about the implicit option support, now relegated to its own section at the end. less emphasis on what tool underpins a given output style and speak more directly to the user-facing feature. completely rewrote the intro to delineate the two operating modes. mostly kept options and examples as-is. -commit 88c6e26bf397d0cae6023fe8d205dd14765cf3b2 -Author: GregoryLi0 -Date: Tue Jun 13 10:37:07 2023 +0800 +commit ea82948984aa3491cfd378bcc9386e7fa797ee5c +Author: Christopher Sean Morrison +Date: Thu Aug 17 18:37:49 2023 -0400 - feat: add `surface trim` cmd + remove the cop-out, irrelevant to reader -commit d778b8ecec2b06d7eca1de1fb0dd2b77d5fc216d -Author: GregoryLi0 -Date: Tue Jun 13 10:21:04 2023 +0800 +commit e42a316fab73cd4ffbae188fd8f28f2f13c7de73 +Author: Christopher Sean Morrison +Date: Thu Aug 17 18:36:35 2023 -0400 - feat: add `surface move_cv` function - fix: wrong judgement about curve and surface index id + clean up indentation for readability -commit 40b1881cfd239c8f7b3ff23c2167cd7c179c57b1 -Author: GregoryLi0 -Date: Tue Jun 13 09:59:32 2023 +0800 +commit ae902f1e6b8f0fdaad95d1d3b96e47d75ca5c95d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 20:54:31 2023 -0400 - feat: add `surface move` cmd + Use -l rather than -L, eliminate message printing -commit 9cd6c1c8e127e04253719fa3073c6ea97bd748dc -Author: GregoryLi0 -Date: Tue Jun 13 09:44:56 2023 +0800 +commit 14a4c621cd8fda02c3bb0967c5200b44db6d3bbf +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 20:48:19 2023 -0400 - feat: add `curve move` cmd + Hmm - OSX isn't getting a define for panic here... -commit fa393c93abb3e3f52ce4ced3adce79442abb2842 -Author: GregoryLi0 -Date: Tue Jun 13 09:29:19 2023 +0800 +commit 5429cbaa6fbb1f2cb55501f4084e013cd2fd9e04 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 20:45:13 2023 -0400 - style: rename surface make function + It's fine if delete_rpath doesn't find anything - not all extinstall binaries may have the path we're trying to remove set -commit 9b26986cf470e299289b115641e66c21bf338e78 -Author: GregoryLi0 -Date: Tue Jun 13 09:22:49 2023 +0800 +commit 50864b474555582c6779fcbb5faee381addabbb4 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 20:35:55 2023 -0400 - feat: change `surface create` parameter of libbrep + Skip the symlinks -commit 8d31f286f6092ca7715584d47771229103eddf52 -Author: GregoryLi0 -Date: Mon Jun 12 14:24:51 2023 +0800 +commit 481ac2af2d1c037f42d784de20c06d3831aa4da9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 20:29:02 2023 -0400 - feat: 1. add surface subcmd of brep - 2. add `brep .. surface create command` to create a nurbs surface + Correct options to install_name_tool -commit 8b4e98d5a4123e1a2da65088637e0df90b5e116c -Author: GregoryLi0 -Date: Mon Jun 12 10:56:47 2023 +0800 +commit 80822004fce04a404faae39e191aa35377147667 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 19:48:59 2023 -0400 - feat: add brep curve trim function + Start thinking about how RPATH updating will look on OSX -commit 995d1937b2c9bdd3ff46ab3b8079422c26f3d811 -Author: GregoryLi0 -Date: Mon Jun 12 10:31:04 2023 +0800 +commit a027b5ac595a97ddc7c736ba0322f7f524b17575 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 13:17:41 2023 -0400 - feat: add curve insert_knot function + INSTALL and configure change if we switch to new ext repo, so for now conditionalize this check -commit 68b0d503de5e69c3f11be553e6ac6b906f69ed44 -Author: f4alt -Date: Thu Jun 8 15:52:21 2023 -0400 +commit bd5f4c962c561b70e177594aabeea35b954cc0ad +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 13:06:20 2023 -0400 - fix option handling for 'in' command + Update rt.xml - when shifting the command string forward by however many flags found, - the command name ('in') gets removed. ged_exec is then confused. Need to - instead remove the flags from argv before passing along. + slight tweak to usage (need space after double dash) -commit 925cdaeb314af41e5043b1d7e71a2a2248a59b3b -Author: f4alt -Date: Thu Jun 8 15:51:59 2023 -0400 +commit 9f950e847692f17d6229173aee32f1a127ace5f8 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 13:05:53 2023 -0400 - fix libpng debug building on windows + Update rtedge.xml -commit 52b0b499a434f8485905e68bdc32326d904d487d -Author: GregoryLi0 -Date: Wed Jun 7 14:12:55 2023 +0800 +commit 8e5e79f41b22f80f82f03d273fcc5e8f95b5aa2c +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 13:04:51 2023 -0400 - feat: add curve flip subcommand. No topology involved + Since our return type is int, document using integer values -commit 51876fbf84461e4e6a870a7e8d1b604584ed59b9 -Author: GregoryLi0 -Date: Wed Jun 7 10:57:34 2023 +0800 +commit e118c7d820f4f7b128bbc8bd60dd98619c7e3674 +Merge: a87b3561f0 c59dcc4754 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 13:03:25 2023 -0400 + + Merge pull request #95 from redcarrera/20230817 + + Document meaning of return values from bg_trimesh_solid - feat: move curve_move_cv to libbrep - style: change curve editing function name +commit a87b3561f08110f6cf5c3f95a4d354e79b042f66 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 13:00:24 2023 -0400 -commit d9e9cfabcb06253672fd9026937bb4026973e92e -Author: GregoryLi0 -Date: Tue Jun 6 16:00:02 2023 +0800 + Update rt.xml + + Add note on default (said it was -s50 but should be -s512) + +commit c59dcc4754331276d5faa5252ccb72fd166a40c1 +Author: redcarrera +Date: Thu Aug 17 11:55:27 2023 -0400 + + Updates to: trimesh.h, trimesh.cpp + + Signed-off-by: redcarrera - feat: move `curve in` function to libbrep - perf: optimize help command lines +commit 5739187f1093e9888c5abff3e09063276a0ca6df +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 09:19:38 2023 -0400 + + Spoof ZLIB_LIBRARY for updated FindZLIB + +commit d5437a9d650ba63f7ed72f6717ced36923f0ddb6 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 17 00:04:10 2023 -0400 + + Make sure misc/tools/ext exists before adding + +commit 8b6ba61f822cad15cfc6327021e1904370064812 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 08:03:13 2023 -0400 + + Update rt.xml + + typo - add dash before M (as far as I can tell the default is -s50 -M) + +commit 44f445ef61ab2a6fa629ba165d8ee7b69c79313f +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 07:47:18 2023 -0400 + + Update CMakeLists.txt + + add rtedge + +commit badf533724daded3071d217a601e257347f8cc05 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 07:46:48 2023 -0400 + + Create rtedge.xml + +commit 39861dab6e8abfba61106bcce7c5f74199cf5033 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Thu Aug 17 07:36:26 2023 -0400 + + Update rt.xml + + fix typo/note -commit f05b5ac70f2f757d8587716b4d80ad69c70ec265 +commit 6058e30c196ae5655809c82c2a9384ed0cfd3d0e Author: GregoryLi0 -Date: Tue Jun 6 14:55:13 2023 +0800 +Date: Thu Aug 17 18:01:20 2023 +0800 - feat: add brep_make_curve() in libbrep + ✨ feat(libbrep/libged): + + temp commmit for create loop -commit d8774995b8862379d354cc657794b418682e4700 +commit 199a10ff50d4776b32d8cf93ce8ff7023fb9a3c9 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Jun 5 09:31:21 2023 -0400 +Date: Wed Aug 16 23:58:24 2023 -0400 - Adjust syntax + Prepare our step converter codes to work with FindSTEPCODE results rather than assuming build targets and an in-src-dir stepcode source tree. -commit 8387a412255c3ec9804b3bbc4805cfe1aeed26ca +commit 971e04f95c9bbeb65c7cabfc9ba925a6e03d74db Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Jun 5 09:15:41 2023 -0400 +Date: Wed Aug 16 23:49:10 2023 -0400 - See if we can add a multi-config build check - - For Windows, the Ninja build is fast and efficient but doesn't really - test the Debug/Release multi-config logic the way Visual Studio users - encounter it. See if we can do a multi-config build with just MGED and - its dependencies to try and exercise that aspect of the build logic on a - regular basis. - - Immediate motivation is a re-emergence of the "different names for debug - and release libraries" causing a problem with a Debug Visual Studio - build. Problem was observed in draw_rework branch, but most likely - cause is build changes due to reverting back to an almost completely - vanilla libpng. The problem isn't fixed yet, so the expected result for - this is that the Debug build fails when the libpng naming triggers a - copy failure. If not we'll have to see if there's another way to - trigger the issue... + Use *_ROOT directories if we have them for lemon/re2c/perplex hunting -commit e52221f19bdaada555f65a27d8fab36e4db4b7e4 -Author: GregoryLi0 -Date: Mon Jun 5 16:24:39 2023 +0800 +commit 8a6e4f219c4de8c51d8862ae386975b39537a4c9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:47:03 2023 -0400 - feat:1. create ON_Brep instead of rt_brep_interval in libbrep - 2. rename brep_create() - fix: 1. fix error in strict mode - style: 1. adapt the headers - 2. recreate the includes + av is not defined unless we have TK -commit df861f1bd356a411376ca007a9258b5fd5b34c6d -Author: GregoryLi0 -Date: Mon Jun 5 15:43:32 2023 +0800 +commit 89f5f187027e13d0326ed856cc6dc21e1a03685d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:43:58 2023 -0400 - Revert "feat: create rt_brep_internal instead of ON_Brep in edit.cpp" + Look for xsltproc/xmllint in new locations, if set - This reverts commit 9e18293ed8983ade0a50d0c541bd38282ba38228. + Note that with this change and looking for astyle in BRLCAD_Targets, + we will be able to remove FindASTYLE.cmake, FindXSLTPROC.cmake and + FindXMLLINT.cmake once the shift is complete. -commit 9e18293ed8983ade0a50d0c541bd38282ba38228 -Author: GregoryLi0 -Date: Sun Jun 4 13:02:58 2023 +0800 +commit 2ddb306683fce0d9f07fda2ff2ab65cd704b96ec +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:42:03 2023 -0400 - feat: create rt_brep_internal instead of ON_Brep in edit.cpp + Add new summary reporting for bundled vs. system, conditionalizing on src/other/ext being missing -commit 2db59c9bf17dc56e8c57509c71ae4c74aab0a3e1 -Author: GregoryLi0 -Date: Sat Jun 3 15:48:18 2023 +0800 +commit c4cc6af7d8b341c228a9e92eee07912fcfb12675 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:30:11 2023 -0400 - perf: remove rt_brep_create_brep() in librt + Modify OpenMesh find logic, add ZLIB and PNG tweaked to support custom filenames used by BRL-CAD deps. -commit 3aca3bdf5523ba4f9f1a931bb289867d7224345b -Author: GregoryLi0 -Date: Sat Jun 3 15:15:43 2023 +0800 +commit 76e3409c284aa6d6faafe558a97a5df61c117c8d +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:18:55 2023 -0400 + + Add the (currently inactive) core of the new ext bundling approach + + In broad outlines, this is the proposed approach to supporting an + external ext repository: + + 1. BRLCAD_EXT_DIR is used to locate the directories we want. Right now + the convention is an extinstall subdirectory holds what we want + bundled and an extnoinstall subdirectory holds build-only tools like + astyle and patchelf. If BRLCAD_EXT_DIR is not set, see if those + directories are present in the user's HOME directory. + + 2. BRLCAD_ExternalDeps uses CMake and patchelf to find, analyze and + stage the extinstall contents for building and install. + Because we need at least some of the extinstall contents to be + staged relative to the build directory executables to run at build + time, we go ahead and do so for all extinstall contents rather than + encoding any specific knowledge about special cases. + + 3. We use patchelf and install(CODE) to finalize all the extinstall bin + and lib file RPATHs. (We'll need to implement a different solution + for the Mac - see src/other/ext/ExternalProject_Target.cmake for + the details on what OSX needs.) + + One requirement of this approach is that find_package logic MUST work + correctly for all of our dependencies - even bundled copies of libs are + now identified for the build with that logic. *_ROOT variables must be + respected, and if we have custom, non-standard filenames we need + Find*.cmake scripts that can locate those filenames. (ZLIB and PNG are + examples.) + +commit eca57c3c2b0d436f7e19f0dbca3fb9086cb0e905 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:13:44 2023 -0400 - perf: rename create_empty_brep() - fix: extern "C" for brep_create_empty_brep() + Add the first pieces of an alternate ext approach + + If we're going to have src/other/ext become its own repository, the + logic managing bundled copies of libraries will change significantly. + To try and ease into this, stage some of the new logic and key its + activation on the absence of src/other/ext from the tree. -commit 0b9331233feb39018009f6b44537c9249841d605 -Author: GregoryLi0 -Date: Sat Jun 3 13:48:50 2023 +0800 +commit 121d37147ed095bc5551ffbbcfa9d2a5f2fa93ec +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 23:07:15 2023 -0400 - feat: add create_empty_brep in libbrep + Use a more modern FindREGEX, update FindSTEPCODE to reflect removal of base -commit 3de3f74e7555965564fc1469a732a65b6150fc82 +commit 3d32c2f410c4bd059affade0319584376da2155e Author: GregoryLi0 -Date: Wed May 31 13:32:21 2023 +0800 +Date: Thu Aug 17 11:05:55 2023 +0800 - feat: move `brep .. create_curve` to sub cmd as `brep .. curve create` + ✨ feat(libbrep/libged): create topo face + + Add 'brep . topo create_f .' function -commit 78c79ddbea43390de7d602a366942188413d24e7 -Author: GregoryLi0 -Date: Wed May 31 11:10:19 2023 +0800 +commit ea638e9b802560d762af14cc49d8a05b7e5afe45 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 22:27:31 2023 -0400 - feat: add brep [name] curve entry + Call out Eigen as an isystem include -commit a84f16657280610c872d63006ff63dacba3c4d19 -Author: GregoryLi0 -Date: Wed May 31 10:18:25 2023 +0800 +commit 77cc22d07610b55b59d1114e21c87923d29d87ba +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 22:23:31 2023 -0400 - perf: delete unused test codes + Shift include-only deps back to src/other -commit 62b3a07483102fe9192598f004c4e45d0f271968 -Author: GregoryLi0 -Date: Wed May 31 09:53:23 2023 +0800 +commit 7a9fec8d513facf466c64ddc0e007b8d4890074f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 16 15:30:28 2023 -0400 - perf: Optimize the parameter number description of in_curve cmd + Add a note to look into reusable primitive editing filters -commit 0545e77fe7159a89e66031e1cb365abf53d08365 -Author: GregoryLi0 -Date: Wed May 31 09:44:06 2023 +0800 +commit 319b8c668d4b2206206e4027400cc84f1cc88aca +Author: f4alt +Date: Wed Aug 16 15:22:31 2023 -0400 - feat: make uniform knot vector. Now the created curve is valid + refname needs to match filename (case sensitive) -commit cfca0447c692c768f042481a9c23f754e38c12cc -Author: GregoryLi0 -Date: Wed May 31 09:36:02 2023 +0800 +commit c0d884eae759cd4de727915f4366217fc9134959 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 15:03:09 2023 -0400 - feat: check arg number and set cv of nurbs + Update ae2dir.xml -commit 71aec4f965319c69c8da0ca434ec6102143380f6 -Author: GregoryLi0 -Date: Tue May 30 18:59:38 2023 +0800 +commit 08eb25ebe638e025ea256751bb8e096b2bb81497 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 11:55:28 2023 -0400 - feat: add an entry and usage of brep [name] in .. + Update bb.xml (fix typo) -commit 5320e0f4dd6ec3cf416d2e58c7de3ed324e43877 -Author: GregoryLi0 -Date: Sun May 28 18:31:42 2023 +0800 +commit 6b56ee7144dc2da952f4dae92eb326dca7e718b0 +Author: f4alt +Date: Wed Aug 16 11:52:12 2023 -0400 - feat: add `brep move_curve_CV ...` command + correct typo -commit 3c57fdbd99e52ee3baccfbd345debeae372a926e -Author: GregoryLi0 -Date: Sun May 28 18:03:52 2023 +0800 +commit 18636bf9104573efe00c49fc02328b0f90c99f35 +Author: f4alt +Date: Wed Aug 16 10:43:40 2023 -0400 - feat: if position is specified, translate the curve to that position + fix parenthesis warning -commit 262452b1ec828de0fba464bb9746d12c569fc3f8 -Author: GregoryLi0 -Date: Fri May 26 12:50:19 2023 +0800 +commit 4815b29dc19e92177b32569afaa060691d477dab +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:34:47 2023 -0400 - feat: add subcommand `create_curve` of `brep`. Now generate curves only for pre-specified parameters. + Update CMakeLists.txt + + add e_id, remat, relos -commit 3c4044baed37dd7ee0789b86ac24f256dbc1666f -Author: GregoryLi0 -Date: Thu May 25 15:04:31 2023 +0800 +commit f37a463d0741bb531323aefa42622c4f839d030e +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:33:58 2023 -0400 - add "make [name] brep" command to create an empty brep object + Update relos.xml -commit 5c6cdb42151176a29d63e28c994c557befd41937 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue May 23 14:31:45 2023 -0400 +commit f3b04bd49b1ac3531624a2289814ac941bb4de7a +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:33:22 2023 -0400 - For bu_hook deleting, if we're deleting the last entry in the array there's nothing to shift downward. Clears another valgrind report cropping up on MGED exit. + Create remat.xml -commit f3f6e76e9a3debe5920ca97c6e5557604d746325 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue May 23 14:30:04 2023 -0400 +commit 01022cb5b54ca83c4731f123e7cd54bff3e65fd4 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:31:27 2023 -0400 - After closing, NULL out the GEDP pointer. valgrind reported that doEvent was calling set_curr_dm after this ged_close, so we need to make sure the NULL GEDP check gets the right answer. + Create relos.xml -commit 442c2aa69902ac39ecdbef7d1d1de241c65b1a6d -Author: Christopher Sean Morrison -Date: Mon May 22 16:20:41 2023 -0400 +commit 918ea8c6be79622ecc2ab8b8bbbc444b558b299d +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:23:39 2023 -0400 - mged command window disappears when you cancel File->Open + Create e_id.xml -commit c89320f72c61a0fa2e0e89ba7666cffbea8904a5 -Author: Christopher Sean Morrison -Date: Mon May 22 16:19:17 2023 -0400 +commit 3991518139b5bedd193b5bac93adfef229f4ee34 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 09:08:37 2023 -0400 - mac build segfaults randomly.. + Update help.tcl - appears to be happening during tclscript processing. crashes appear to be random. workaround is to keep re-running make until all the index files are generated. + add a number of missing commands, alphabetize existing commands. -commit ba3567860b1ea3f3224d8d1ebed57ae078e3084e -Author: Christopher Sean Morrison -Date: Mon May 22 15:30:00 2023 -0400 +commit 66619058a40b936dd2782b3a7f076411bd00b2a0 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Wed Aug 16 07:42:54 2023 -0400 - denote system includes separately. + Update help.tcl - this changes compiler warning emission, so we don't get things like documentation warnings in system headers. in theory, all our includes should be separated this way and would likely make a lot of pragmas go away. + add ae2dir and viewdir help statements -commit 59bb81848d775abd8eebfec3b4c47bbd4e60f449 -Author: Christopher Sean Morrison -Date: Mon May 22 15:18:33 2023 -0400 +commit e445191c1e5397a9fc74f151487b356b7cb4a7e8 +Author: GregoryLi0 +Date: Wed Aug 16 15:02:29 2023 +0800 - make tk's configure line match tcl's - - the addition of --enable-64bit in particular causes tk to test for arm64e on Mac M2 platofrms. that in turn results in an incompatible arch flag when linking against X11 and even Tcl libs. + 🌈 style(libged): change comments -commit adea154ebaf0c2a2e282de41da00ebc562586f23 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon May 22 10:48:18 2023 -0400 +commit 5b28f53d27816b3d02620dfd4bf90b7db49ed355 +Author: GregoryLi0 +Date: Wed Aug 16 14:56:17 2023 +0800 - Vanilla png build assigns lib prefix with MSVC + ✨ feat(libbrep): create topo edge -commit cefc33c232f92df97423ec86f5b5cd75de8ade14 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon May 22 10:03:54 2023 -0400 +commit 20452e4aacd0296e44022cd08801dd19d210e82c +Author: GregoryLi0 +Date: Wed Aug 16 14:55:39 2023 +0800 - Reapply use of targets, rather than files - needed for parallel building with a PNG_PREFIX set + 🐞 fix(libged): error id judgement -commit e057a6f03a61712430e54ffda32596907f050c4f -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon May 22 10:01:29 2023 -0400 +commit 47459bee74c4d0e8927a89d5be0ca59f484c3e46 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 15:19:48 2023 -0400 - Use vanilla libpng sources from upstream + Update viewdir.xml (add -i flag info) -commit 1bdeb01f33ce79598f178a81ce1973f0a438c551 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed May 3 16:42:03 2023 -0400 +commit 04a632ccdc691b4966e16433232aa4c8cc00fb1c +Author: f4alt +Date: Tue Aug 15 15:16:48 2023 -0400 - Another new GCC error - dangling-reference - - error: possibly dangling reference to a temporary [-Werror=dangling-reference] - (cherry picked from commit f39d68704d1febee6165510a2817668988b74533) + better help printing for showmats -commit f271bdf1c132e230fba7d35c1fe339cc420d1ca0 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed May 3 16:40:56 2023 -0400 +commit 933ec9366e3151f42a93feb830b360ec729318f3 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 14:54:44 2023 -0400 - A lot of the fastgen4_write checks have the same problem with Werror=nonnull-compare - - (cherry picked from commit b0783f14bbf0064d7c58af3aace7846fb2b87207) + Update showmats.c (add flag to usage statement) -commit 8c7e5340ee0a97e8cf479a88e8cf632802a2592d -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed May 3 16:35:39 2023 -0400 +commit 4cfe299f66d5863568a5e272c55aed0b52e5497f +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 14:51:47 2023 -0400 - With new gcc, -Werror=nonnull-compare trips up on the magic check here - &db will never be NULL, and the BU_CKMAG macro expands to check for null args. - - (cherry picked from commit 3f99e0a194b80d03a56909d752538d32eb6e04aa) + Update helplib.tcl (add flag for showmats) -commit 0d7f70a77513cf9f071f62676efd2f1daad1f31f -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed May 3 16:32:15 2023 -0400 +commit f2fdf8ddab355f95ed787b6ece0c656ac598819b +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 13:52:13 2023 -0400 - gcc v13.0.1 doesn't like the std::move here + Update showmats.xml - Error: moving a temporary object prevents copy elision [-Werror=pessimizing-move] - note: remove ‘std::move’ call - (cherry picked from commit b848c7fd6dbc1fa869d20a5031a3ee49edad4633) + add -a option to notes -commit 024109a0108fe8226da7ce60cfa285ea426e7cc7 +commit 11cc94edbdd31a0fe64808de266333c1b6f81795 Author: f4alt -Date: Tue May 16 15:30:53 2023 -0400 +Date: Tue Aug 15 13:32:02 2023 -0400 - remove .txt extension + fix xml validation -commit dac151df5c4a2b44b45c187acda210bfecee12a4 +commit e66e39d76ab9d93cdc39b8f654f310747e3a1474 Author: f4alt -Date: Tue May 16 15:26:06 2023 -0400 +Date: Mon Aug 14 16:47:26 2023 -0400 - first draft for NEWS release writeup + minimal creation func for extrude -commit 5c2227b80a4f8f9474a50874ba9921e719197fc1 +commit 9458a1a59857fa02079b7a67a0a7ec745c661f30 Author: f4alt -Date: Tue May 16 15:24:40 2023 -0400 +Date: Mon Aug 14 15:41:32 2023 -0400 - improve clarity on testing status + minimal creation func for joint -commit 28266771469ab183d33902646762efb1f2d2e1e7 +commit daa6e7beb1717c1d105cb017a82720a852023e62 Author: f4alt -Date: Mon May 15 15:55:52 2023 -0400 +Date: Mon Aug 14 15:25:29 2023 -0400 - track companion files for distclean + minimal creation func for eto -commit 08bc039f6ae2d90c26057404a3880a40bbd900b3 +commit 2842463c16fd406669963548c37ef7ecc4b5b7d2 Author: f4alt -Date: Mon May 15 15:21:12 2023 -0400 +Date: Mon Aug 14 15:18:43 2023 -0400 - fix parallel gcv regress failures - - removing globbed files was deleting too many files and mimicing a fail - due to no file generation + minimal creation func for ehy -commit e6b195b405bb68266ed112e9431082a73354af92 +commit a2900e3d5c67ae9e80d33508117f4ad5334aead1 Author: f4alt -Date: Mon May 15 15:20:52 2023 -0400 +Date: Mon Aug 14 15:14:55 2023 -0400 - fix stp regress check size + minimal creation func for epa -commit a55d4f86d12943dc4240e590e771c5190e818e24 +commit bfeed507084924025d68fb92608a4b9ff17582c7 Author: f4alt -Date: Mon May 15 12:22:49 2023 -0400 +Date: Mon Aug 14 15:07:01 2023 -0400 - need to track sqlite3ext.h on BSD + minimal creation func for rhc -commit 7a61b3f714b79eb932699cdb297fbbf87dd66fc5 -Author: Christopher Sean Morrison -Date: Sat May 6 10:27:42 2023 -0400 +commit 875e5c3d0ff3a88f86cbbe55659e7f6fdbdf2ee6 +Author: f4alt +Date: Mon Aug 14 15:01:49 2023 -0400 - tighten up the language on headers + minimal creation func for rpc -commit d91a3d5b37ec8d7d1e65c4b061dbb5a2838e8521 -Author: Christopher Sean Morrison -Date: Sat Apr 29 11:35:03 2023 -0500 +commit 2b91630defc0b38f035ec13d32a6b03571df027c +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 11:23:37 2023 -0400 - need to document tops options, and dbconcat could do better + Update prcolor.xml + + remove extra lines for options (no options specified and it doesn't appear to require/take any options). -commit 1fc2e38e850e5ed94e320a2e9fa7b6cfbe6af444 -Author: f4alt -Date: Thu May 4 15:44:51 2023 -0400 +commit 51b56a5106164d4ad34554f0bcf143933b7ed4ff +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:39:29 2023 -0400 - track added files + Update opendb.xml + + add note on current directory and example using full path. Update note on behavior (if database.g not found it prompts to create new database). -commit f7d469a8d8526c21242871d6c80f98d78f40e2fe -Author: f4alt -Date: Thu May 4 13:31:14 2023 -0400 +commit d95ebff1b419a77cf1c1555116e9f8ff3a45bc9d +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:31:15 2023 -0400 - add a note for current test status + Update CMakeLists.txt (remove open) + + Mistakenly added open thinking it worked like opendb. -commit 7fc90ed6984e036f66a1d18a5243f4a57852f26d -Author: f4alt -Date: Thu May 4 13:30:12 2023 -0400 +commit 553d6e80e2bf0aa09524e0f782ef2b0ed0025084 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:30:36 2023 -0400 - make gcv recognize assetimport types we have testing for and no - conflicting converter + Delete open.xml + + Added this before realizing I was mistaken in its usage -commit f2aabf201cf4090c29e7584776a12f8636c0be7a -Author: f4alt -Date: Thu May 4 13:29:43 2023 -0400 +commit b308e2c1d19531a2d660bb119ff456edad5b7e19 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:21:00 2023 -0400 - add a few more gcv regression tests + Update CMakeLists.txt (add open) -commit 3e8ba49a7e998851b21e20c1156fd43bbff4eeaa -Author: f4alt -Date: Fri Apr 28 11:53:36 2023 -0400 +commit ab61e64692822d9e19b6afad40f6f520334a092d +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:20:02 2023 -0400 - document a few more NEWS items + Create open.xml man page -commit 22d115d6774bdd1f76d0f5bef63527fb7219535f -Merge: b343d98eb0 40ca15985b -Author: f4alt -Date: Fri Apr 28 09:47:07 2023 -0400 +commit 59833f1bb4953aef3f9a193338dc38000013f563 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:17:44 2023 -0400 - merge of main 40ca15985ba to RELEASE branch + Update source.xml (slight tweak to usage) -commit 40ca15985b91888e4f877a2315fdb9225781e38a -Merge: d9162946b1 e229b27f94 -Author: Christopher McGregor <54115478+f4alt@users.noreply.github.com> -Date: Thu Apr 27 14:19:31 2023 -0500 +commit ac701d03d1af7ef849b9cc9f7199e674a50aeff9 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:13:04 2023 -0400 - Merge pull request #71 from BRL-CAD/msvc-patch - - removed the "d" in MS Windows Debug binaries + Update CMakeLists.txt (add source) -commit d9162946b1b3c9d58ba082d8adcb83d8b132f9d6 -Author: f4alt -Date: Thu Apr 27 15:14:40 2023 -0400 +commit 9ae961cace8740b50bd010f899e1c74d82fe97b8 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:12:38 2023 -0400 - update ply test file - - our converter didn't like 'alpha' property + Create source.xml man page -commit 66cc961102909108569a14d6f6b16542bf6bb956 -Author: f4alt -Date: Thu Apr 27 15:14:25 2023 -0400 +commit bfdf552d6446260bff2c4b6e86a4d12e4de4ab63 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:02:14 2023 -0400 + + Update CMakeLists.txt (add shaded_mode) - better log message +commit d0388c34f1712e61c6b3dffd375e07d528f8dd04 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Tue Aug 15 09:01:35 2023 -0400 -commit 4c62fffc535d28bfab0aae1d1b6be50c2264e337 + Create shaded_mode.xml man page + +commit d3e4dabe295edd3d549b23aa8c8db2409eb8b755 Author: f4alt -Date: Thu Apr 27 13:20:53 2023 -0400 +Date: Mon Aug 14 16:59:04 2023 -0400 - use consistent type for key size + fix xml validation - on different systems (specifically 32 windows), sizeof(long) = 4 and - sizeof(long *) = 8. So our bu_hash_get were seeing a key size different - than bu_hash_set and never returning coordinates. + amper is an escape character -commit faa0fec1686e8568eb3831dc5bebbdadfe076afa -Author: f4alt -Date: Mon Apr 24 11:26:39 2023 -0400 +commit 4c71bdae4cf0ca8d58f4800e6faaf84cff177543 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 15:33:14 2023 -0400 - currently non-used test formats. Remove + Update killrefs.xml (add see also killall) -commit 719f36cecc22a184b1914c849c210f05f11180ea -Author: f4alt -Date: Mon Apr 24 09:34:32 2023 -0400 +commit 908d0c5d715b129684bec7fadf01d6c5195e8b4c +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 15:32:30 2023 -0400 - first pass at assetimport exporters + Update killall.xml (add killrefs see also). -commit 2a0bfe7662320922e10ae9ef8c871394af23a0b5 -Author: f4alt -Date: Thu Apr 20 15:18:12 2023 -0400 +commit 74acd3093013e5d7090860adf7112684d848efbf +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 15:31:04 2023 -0400 - generalize to work for exporters + Update CMakeLists.txt (add killrefs.xml) -commit 9c1773469977654b725a27793f9f9cdc4ce583f1 -Author: f4alt -Date: Thu Apr 20 11:33:40 2023 -0400 +commit 2722f8f0fac34bf3e57eaaaf20171efa1733f145 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 15:30:30 2023 -0400 - first pass at new assetimport regression tests - - Still quite a few formats to go, but working through in order of - popularity and availability. - - add option to specify converters for file types which support multiple - hammer on some options for gcv_to_g_util to allow maximum flexibility - for all tests. + Create killrefs.xml man page -commit ad5bc308fee690ae7fbda16fb348438db36f5077 -Author: f4alt -Date: Tue Apr 18 13:36:39 2023 -0400 +commit ffbc3e56609651a2f270e8175782bc063da3aca2 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 14:53:11 2023 -0400 - handle more edge cases in gcv regress function - - check both src and build dir for input files, - flexible dependencies input for formats not following gcv-[fmt] + Update CMakeLists.txt (add mirror.xml) -commit e7293a9bb00d21e8ddd149542c75dac30ab2711b -Author: f4alt -Date: Thu Apr 13 08:36:16 2023 -0400 +commit 7d5f14b233297ab7a825fd20876851ab99362f3a +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 14:52:43 2023 -0400 - first attempt at simplifying gcv regression tests - - pattern the cmake.in file setup into a function to allow for easier - regression test additions in preparation for all the new file types - supported by asset import lib. + Create mirror.xml + +commit 3181090230ca3903ed7f02c3d91ecf82b57a3eec +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 14:06:57 2023 -0400 -commit be355cae12edb8316aca52b8a79b72e8b0f5b4a0 + add man pages for ae2dir and viewdir + +commit b7235fac9046f6c63d2f57890497005108d118c3 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Apr 7 10:48:41 2023 -0400 +Date: Mon Aug 14 13:15:50 2023 -0400 - Make a note about OpenMesh decimation work - - Need to figure out how to set up the bot decimate subcommand to have - sensible default behavior using OpenMesh's capabilities. Might make a - good small-ish scale student project. + Fix docbook validation errors -commit 8b9de7c6663bab41fc517fa64918d007229685b7 +commit 0925166981648edd51d23368a753a572ef9878db +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 14 12:48:53 2023 -0400 + + Add a handful of commands to the manual + +commit be72d518e1e23e779237fb55a18a550d19f445de Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Thu Apr 6 15:09:45 2023 -0400 +Date: Mon Aug 14 11:31:24 2023 -0400 - Increase default timeout on 16384 mappedfile tests + Initialization value isn't read - set to NULL -commit 7550b3373c807f90a1d260e15bf514f1371235ad +commit 0a8c638d7f8a24f7f5947218ab2aa3f01db2c37e Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Apr 5 16:53:51 2023 -0400 +Date: Mon Aug 14 11:30:01 2023 -0400 - Update GDAL/PROJ news item version + Initialization values aren't read - set to NULL -commit fc7141ad4b9cf0b5d94106992d0b0c220007798f +commit f7cf4628c7ad84399077e8edf55025eeee128e8e Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Apr 5 16:52:36 2023 -0400 +Date: Mon Aug 14 11:28:59 2023 -0400 - Reapply 7d00f7264a. + Initialization values are not read - just set to NULL -commit 14c4b4ac5e04d4fbc2c5f4b90003987ed8e3ff9f +commit 6c7d4a60916fb17fb3f5afe5ad3fc52bc3a2668a Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Apr 5 16:29:25 2023 -0400 +Date: Mon Aug 14 11:26:04 2023 -0400 - Dependency updates for SQLite3, PROJ and GDAL - - Versions: - SQLite3 3.41.2 - PROJ 9.2.0 - GDAL 3.6.3 + Initialize dbip to NULL -commit e229b27f9451d89afc0cd3329a126eb3cebc0a73 -Author: Daniel Rossberg <33295041+drossberg@users.noreply.github.com> -Date: Sat Apr 1 13:05:53 2023 +0200 +commit 8eaa88ee91c654f2cdd20125450a2d04e6847f2f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Mon Aug 14 11:25:45 2023 -0400 - removed the "d" for MS Windows Debug binaries - - in 3rd party libraries - they were in the way in post-processing + Set the flag on the variable actually being used. -commit b343d98eb0b9a360d54c78351c67108ffece8b99 -Author: f4alt -Date: Thu Mar 30 13:00:32 2023 -0400 +commit 19a1ea7820d960910a599dfd9ac4825f580d9316 +Author: GregoryLi0 +Date: Sun Aug 13 23:36:53 2023 +0800 - oops. Get 64fd674 to build clean + ✨ feat(libbrep/libged): add topo module - (cherry picked from commit d779aabea8bb6ecf7d32887c5e34a828d1f185d3) + Add topology editing module + Add create vertex func -commit b4a291bef6a6113cbbc8c56a742c6476fe8d669f -Author: f4alt -Date: Thu Mar 30 11:17:36 2023 -0400 +commit abe83b1f8ae67551395408cb81121282200000f2 +Merge: c5dcd0ba13 5ce3b02ac6 +Author: Daniel Rossberg <33295041+drossberg@users.noreply.github.com> +Date: Sun Aug 13 17:27:38 2023 +0200 - fix nirt with a lot of output locking mged + Merge pull request #92 from GregoryLi0/nurbs_editing - Since we were reading from stderr before stdout, when nirt wrote more - than a page worth to stdout the read from mged locked indefinitely. - - Add a helper function in process.c to check if there is data to be read - from a file descriptor + NURBS editing Milestone 2: Perform advanced operations on brep geometries using command line, as well as some simple ones. + **Curve operations:** + - curve remove + - curve split + - curve copy + **Surface operations:** + - surface remove + - surface split + - surface copy + - create by tensor product + - create by rotating a curve around an axis by an angle + - global surface interpolation with C2 continuity + +commit c5dcd0ba131a8e2ff13c7932d1d434c4529c0d48 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Fri Aug 11 20:07:44 2023 -0400 + + Turn off some of the bv_init setup for Archer - Add error checking in nirt.c to check if there is any data to read - before blindly trying. Add sandwiching stderr reads to avoid future - locks. + Commit 2af2030752121 introduced some logic to ensure a bv_init created a + workable initial view name, as well as initializing the dmp pointer to + NULL. Unfortunately, BOTH of these changes seem to be causing problems + for Archer initialization (individually, not simply in tandem.) - (cherry picked from commit 64fd6748d9843346f4bc61c5eda9c34b3f4fed34) + Until it's clearer what's going on with Archer, disable the setup code. -commit d779aabea8bb6ecf7d32887c5e34a828d1f185d3 -Author: f4alt -Date: Thu Mar 30 13:00:32 2023 -0400 +commit 5ce3b02ac6a6f7a7fb44fdae367c61dc1d8e767a +Author: GregoryLi0 +Date: Fri Aug 11 21:50:03 2023 +0800 - oops. Get 64fd674 to build clean + 🐞 fix(libbrep): memory management -commit 64fd6748d9843346f4bc61c5eda9c34b3f4fed34 -Author: f4alt -Date: Thu Mar 30 11:17:36 2023 -0400 +commit 188ea6d76663191c13c5857594ffbea92abdfed7 +Author: GregoryLi0 +Date: Fri Aug 11 21:29:23 2023 +0800 - fix nirt with a lot of output locking mged - - Since we were reading from stderr before stdout, when nirt wrote more - than a page worth to stdout the read from mged locked indefinitely. + 🐞 fix(libged): remove 'kill' - Add a helper function in process.c to check if there is data to be read - from a file descriptor + remove some other 'kill' + +commit a41ab71f647a00d407fa92e60bd2507a4dacf0e0 +Author: GregoryLi0 +Date: Fri Aug 11 21:23:44 2023 +0800 + + 🐞 fix(libged): remove 'kill' - Add error checking in nirt.c to check if there is any data to read - before blindly trying. Add sandwiching stderr reads to avoid future - locks. + no more delete old object. Functions are unaffected. + Passed tests by brep_curve_edit.sh and brep_surface_edit.sh on zulip. -commit 02144ddce9c8eaae3ff88dbe7d65544c825de96c +commit 0c0b2f01798b294fad28d0237cb7ebbdc870ff17 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Thu Mar 30 09:54:15 2023 -0400 +Date: Thu Aug 10 16:31:29 2023 -0400 - Stash an example of using 'git bisect' to hunt a bug in the commit history. + Add a drawing test to check view behavior + + The idea of this test is to check that the view settings are stable + across dm events (such as resize) and bv_update calls. Probably not + stressful enough as it stands, but it does at least check the resize + behavior of a dm, which is useful in and of itself. -commit 63b117c7f83a741cdce5cdd3687f07381382fb47 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Thu Mar 30 07:43:14 2023 -0400 +commit 7d13995e56b24c914f97ba6785d07c4eb163fdbc +Author: f4alt +Date: Thu Aug 10 15:43:09 2023 -0400 - Spotted by Daniel Roßberg - correct case in CMake arguments specifying SQLite3 info. + minimal creation func for pipe -commit 3c3e41ebb49341e8b32f3a9001f5b4b2e6cb842b +commit 3a68f72fbf5e4836eff4e6a0203a6326463d8e43 +Author: f4alt +Date: Thu Aug 10 13:59:46 2023 -0400 + + minimal creation func for arbn + + arbn's need atleast 1 eqn to be valid + +commit 1bc71b762411bbf78dcda3ad17359e32e536e96c Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 29 07:43:06 2023 -0400 +Date: Thu Aug 10 13:45:03 2023 -0400 - Update discussion of mime_types (or more precisely their absense) and Git + Apply Eigen's normalize (appears to be equivalent to a VUNITIZE) to a libbn vect_t. -commit 6199b28c17749b2f65a2fd2de5d020e9df577fc5 +commit bb0e42e5603869ecb2641c6cac483c9aa664a44d Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Thu Mar 23 16:43:46 2023 -0400 +Date: Thu Aug 10 13:39:30 2023 -0400 - Report on Mac that the X11 headers are causing a Wdocumentation problem. See if we can suppress the warning just for the external headers. + Demonstrate Eigen Map on a vect_t as well + +commit 005698e224a87dd137da75617572f1ee015ba9e4 +Author: f4alt +Date: Thu Aug 10 13:30:59 2023 -0400 + + can't malloc 0 + + it's possible to create an empty bspline with 0 surfaces (with 'put' + namely) - don't worry with bu_calloc when this is the case -commit 33f816854d2a4382f4cde9e2f47f714c5c3000ac -Author: Red Carrera -Date: Wed Mar 22 20:03:55 2023 -0400 +commit 6a81a2abf6c68358567399cf268d3d5dc20de56f +Author: f4alt +Date: Thu Aug 10 12:02:12 2023 -0400 - Creo to BRL-CAD Converter as of 3/22/2023 + fix stack corruption - Signed-off-by: Red Carrera + bad creation can set many (or all) points equal. Catch indices trying to + write past the arrays size. -commit f97a72bba166120acac5da0557d0cd85d4c6dcf6 +commit 2e66983f4ef5a95ab94ec1ef2d4201ae4619b9b5 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 22 08:53:03 2023 -0400 +Date: Thu Aug 10 11:12:40 2023 -0400 - Make a note to revisit use of re2c/lemon/perplex + Add an actual verification of the identity status post-Eigen -commit 04430833b27d6b8a9e2667d404e93729b1c473d9 +commit 7f29410539a3e681ba26297c8fbbf1db515ac144 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 22 08:03:00 2023 -0400 +Date: Thu Aug 10 11:04:26 2023 -0400 - List the generated .h file explicitly - - We're still getting occasional compile problems with libexpress that - appear to be an attempt to compile an incompletely generated input. + Test using Eigen's Map to operate on a mat_t - It looks like the stepcode versions of these files are different than - the ones in BRL-CAD proper - probably would make sense to check which - ones are the newer versions and sync up. + Set up a basic example of using Eigen's Map capability (see + https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html to + manipulate vmath data directly. -commit 10125c24a128b638a9f78faca771ba1173b100e3 +commit 9af913cb5398f74668d9ccb6f964e98deaca0718 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Mar 20 15:43:05 2023 -0400 +Date: Thu Aug 10 10:14:01 2023 -0400 - Don't need wdb_close here - db_close covers it + Revert "Stash a quick try at getting screengrab to use GL2PS" + + This reverts commit 144912126126d374792e42d3e5e1610ef6c0668b. -commit 68d703816955f5a882e3278ff884f44313fd9720 -Author: Christopher Sean Morrison -Date: Sun Mar 19 03:12:22 2023 -0400 +commit 0550834360efd1c5ce2b2e70ceb8c4a8fe0fcfd9 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Thu Aug 10 10:12:02 2023 -0400 - seeing bus errors on exit. + Stash a quick try at getting screengrab to use GL2PS - variety of tools will randomly fail, but specific one is asc2g crashing. crash happens after return from main(). crash does not happen in debugger implying race condition. checked libbu atexit handlers (they're fine) so may need to bisect. - -commit 55bd3738b6c35bb45df8003ff2041b57c5f3b0fd -Author: Christopher Sean Morrison -Date: Sun Mar 19 02:50:53 2023 -0400 + Not working properly, but this is at least some of what will be needed + to hook GL2PS (https://gitlab.onelab.info/gl2ps/gl2ps) up to be a + PDF/Postscript output option for screengrab. Right now it doesn't + produce correct output, but it does at least create a file. Will revert + this commit right away - just saving the initial setup work for + potential later reference. + +commit 66a747c5e296c791dbf0416f6cda6b0aa2209bfb +Author: f4alt +Date: Wed Aug 9 16:28:55 2023 -0400 - codeql workflow was removed, so don't try to ignore it. otherwise we gets an error. + fix docbook install failure + + rename e_command page to e.xml. This has a case insensitive naming + conflict with E.xml on some platforms but big E is slotted to be + replaced by a drawing mode, so move it's man page out of the way + temporarily to bigE.xml -commit c81be2bf5391c543ef1a4c72454fb2cae80a8283 -Author: Christopher Sean Morrison -Date: Sun Mar 19 02:46:07 2023 -0400 +commit 7c3176bd4fe3f77fc4bcbaa6f137f78ebc9f7c5f +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 9 14:30:51 2023 -0400 - ugh, save typo + ADD_DOCBOOK should be a function, not a macro -commit a0dc2e526dc7d2451211cd0aa81085c81a83cfff -Author: Christopher Sean Morrison -Date: Sun Mar 19 02:41:40 2023 -0400 +commit 9e34e57d32df78c110bdd77a84f97bfb4da65b2b +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 9 14:20:58 2023 -0400 - fix an infinite loop condition during raytracing. + Schedule big E command to be replaced by a drawing mode option to 'draw' - rendering goliath, encountered an infinite loop in camo_render()->bn_noise_fbm()->bn_noise_perlin()->filter_args() due to Inf values in the source point. when computing a noise position, an Inf results after a multiply operation that messed with the spacing folding logic. this clamps Inf and NaN values to the maximum value we're folding over. + The "big E" command for evaluated wireframes is seldom used with modern + geometry, and conflicts with the 'e' man page for the draw command's + abbreviation on case insensitive filesystems. + + Make the same capability available as a "mode" option to the draw + command (at the moment, the option is -m5) and schedule "E" for removal + as a top level command. -commit 2e1d0db675d3092646e37fdc458de4031610914d -Author: Christopher Sean Morrison -Date: Sun Mar 19 02:22:17 2023 -0400 +commit f41ec4503ac5fcccfb142e0aac2f3097105b8acc +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 9 13:54:29 2023 -0400 - update docs before fixing an infinite loop condition + If we can't get sp it's also a no-go -commit 402686475bf790bff1566a3bd3fa2c8f350ff6ce -Author: Christopher Sean Morrison -Date: Sun Mar 19 00:04:26 2023 -0400 +commit d956c4ec6a18fb7e2768c54d37e3301b4a8b1931 +Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> +Date: Wed Aug 9 13:53:29 2023 -0400 - plug memory leak + While we're at it, don't crash here if the client isn't set up correctly... -commit 96cfa79ca343d68ad3e66303ef0a7ceb8a1f4161 +commit 382d466bb00b66a7dac038d425ea09d51e224fdf Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Sat Mar 18 23:00:50 2023 -0400 +Date: Wed Aug 9 13:50:19 2023 -0400 - Temporarily remove CodeQL workflow + Fix E (i.e. "big E") evaluated wireframe command in MGED - Getting what appears to be an internal error from their processing. + View wasn't getting set properly in the client data structure, resulting + in a crash. -commit a752111783c09bdbd2d22d208554bb193cd992f8 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Sat Mar 18 12:29:20 2023 -0400 +commit 6cd4f4f8bf133b8710c0637451ff4f050f2d5321 +Author: f4alt +Date: Mon Aug 7 16:34:00 2023 -0400 - part.cpp is also using max + can't use inside + + replace with literallayout -commit cb786f1cfae7f48f32befe8eec07cadc767dbf20 -Author: Erik Greenwald -Date: Fri Mar 17 22:40:51 2023 -0400 +commit 0ddf2796481325a3e561803eaa0ca5e3a97b396e +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 15:42:38 2023 -0400 - re-add misc/docker/dev/docker-compose.yaml to CMakeLists.txt + update x man page -commit d9cf9fc3a07e3668705198db7cb4fade2c555dfa -Author: Erik Greenwald -Date: Fri Mar 17 21:54:10 2023 -0400 +commit a85fb0a770b29700918e79ba90b77d7a96dfd19d +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 14:50:19 2023 -0400 - rename docker build targets so they don't conflict with directories. Update user dockerfile to 7.34.3. Reorg user dockerfile + man update, remove bolt, all_sf from mann, add unhide, dbfindtree, correct some minor typos. -commit b4f32c97d0be8bdbc60173c4362d27ec78021cf9 -Author: Erik Greenwald -Date: Fri Mar 17 20:00:02 2023 -0400 +commit a335c0983c1014987e080864e624f88cafd22d7a +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 14:33:18 2023 -0400 - Docker - remove common target. Remove build scripts. Embed all logic in Dockerfile. + a handful of manual updates -commit 00f2d7f9fa99ac73040f77c887a25d1064f84364 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 14:39:56 2023 -0400 +commit 10bb43321c8600debc1abd43f8234137b95cc371 +Author: f4alt +Date: Mon Aug 7 14:16:45 2023 -0400 - Hmm... try https://stackoverflow.com/a/30924806 + Revert "Make filename consistent with man name" + + File name needs to remain e_command to not conflict with big E.xml + This reverts commit 665dc8b9a8b082f152f7cb8c1beb793f929a47ac. -commit 5fc19dedc36590cdccca65d9617087eda6ffe0a6 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 13:42:51 2023 -0400 +commit eac09c6c8c7432b17d6bf935043812ca062b60f1 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 14:04:31 2023 -0400 - Clear a few clang analyzer warnings + update opendb man page -commit e83eed1c31c7d7b8693f58995e760c167f58a599 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 12:05:43 2023 -0400 +commit 92482f54227ed33224963c456be4d699401f9613 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 13:54:47 2023 -0400 - Add algorithm header for std::min and std::max + Update npush man page with examples -commit 7834cc0d96bab1eb3f5ec238e5f31a09cdd1d3cb -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 09:24:36 2023 -0400 +commit aee08fd76800dc415c6edcd0404e4b8c99120651 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 13:41:26 2023 -0400 - Clear various Linux compiler warnings + Update ill.xml (remove extra >) -commit f2860cfd83596eec9c849e30edcf390b4f9c7de7 +commit 665dc8b9a8b082f152f7cb8c1beb793f929a47ac Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 09:13:25 2023 -0400 +Date: Mon Aug 7 12:46:10 2023 -0400 - More tweaks for regress and distcheck-repo_verify + Make filename consistent with man name -commit d83a3dd0b7e05b09eff4b4151f71662f50a1cd4e -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 09:06:07 2023 -0400 +commit 056eb579891ba29593564de0d3848e3de7270fa4 +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Mon Aug 7 10:20:12 2023 -0400 - We need the CREO2BRL_SOURCES list in both modes + Update mann page for nirt.xml + + Add options and examples to the mann page for nirt (mostly taken from the man1 page). Update description to reflect current default behavior. -commit 6b963fa7dadf20f40e7536675dc6c95347d50017 -Merge: 79d7ad833a a07862ff70 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 08:46:08 2023 -0400 +commit 24b707d165937591ae28fee1e3bc4a20eaac7d1a +Author: Christopher Sean Morrison +Date: Sat Aug 5 23:26:55 2023 -0700 - Merge pull request #63 from redcarrera/20221213 - - Creo to BRL-CAD Converter as of 12/13/2022 + indent cleanup -commit 79d7ad833ae06b513bb0dba735b648cc19474f9f -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 17 07:36:31 2023 -0400 +commit 6dce5467c298e940b3570143402f4793a0618801 +Author: Christopher Sean Morrison +Date: Sat Aug 5 23:25:02 2023 -0700 - Oh, right - NULL filename outputs are valid (dumping to stdout) so we need to be a little more careful about when we use ofilename. Fixes regress-dsp + use a preprocessor symbol so we're warned when it's expanded -commit 6b552e98f9e910b4c8e0cc0715df942a841a8e4e -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Thu Mar 16 18:52:28 2023 -0400 +commit f107acede4b5f8d5641d95c7f4c3236133f2742e +Author: Christopher Sean Morrison +Date: Sat Aug 5 13:09:42 2023 -0400 - What the heck... icv_operations test wasn't handling png image as input. + general indent cleanup -commit 880d2df785fe1caaedd11e6965161a995287bbf2 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 14:05:45 2023 -0400 +commit c365077279384bf005c8f54bce6278bf06f7e835 +Author: Christopher Sean Morrison +Date: Sat Aug 5 12:04:30 2023 -0400 - Expose bot flipping as a bot subcommand + add the new misc directory to the build - Make the bot_flip functionality (defined in rt with rt_bot_flip) - available as a "flip" subcommand of the "bot" command. + intentionally installing and intentionally NOT indexing the scripts hers. there meant to be curated bundled examples that can be perused by users and/or isolated examples we can point them at. -commit d66a4d782434dee34d1cdb10ff046da9b473788e -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 13:56:55 2023 -0400 +commit df305ae61ca7629c256482e42570e4417781e286 +Author: Christopher Sean Morrison +Date: Sat Aug 5 11:43:20 2023 -0400 + + Create a space for self-contained code snippet examples + + This initial script being added was created for a user that had + imported geometry using myriad methods resulting in regions with + less-than-ideal object names and incorrect IDs set. The script fixed + those regions and is a simple general pattern for how to iterate over + a set of objects to perform an action not (yet) achievable with + "search -exec". + + The intention here is to create a space for curating brief but useful + and easily understood code snippets that users might be able to adapt + and learn from. As such, this script is succinctly documented with an + example how to run the script and what effect it has on a sample tree. + This is intended to be a pattern for future scripts that get added. + Scripts should be short enough (ideally less than 100 lines) to be + fully understood but longer than 1-liners typically provided via + manual pages. + +commit e0dce6fbb0ffa0e0d70f804193f44c65e54f37dc +Author: Christopher Sean Morrison +Date: Fri Aug 4 21:22:46 2023 -0400 - Another input object validation check + get rid of mac store files -commit 0d4c51c5f9050cb7e1303a49c356d4b299783d33 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 13:49:21 2023 -0400 +commit efa715bbf9408957a09b68267dc2939f9691728e +Author: Christopher Sean Morrison +Date: Fri Aug 4 20:54:51 2023 -0400 - Various improvements to analyze inside/outside testing based commands - - Fixed an outright crasher when invalid object names were passed in, as - well as a more subtle problem where points were sometimes incorrectly - reported as not inside during testing due to checking only the first - partition along the ray rather than all partitions (resulting in - "shadowing" where geometry with a leading "in-out" segment in the - z direction would miss points above that segment that were still inside - the solid.) + fix validation issues + fix prompting display a different way since just removing term doesn't - Also added a direct point-inside-object test where the user specifies - the object and x y z coordinates of the test point. + term is not valid in a para context, only in a varlist, but looks like we don't even really want that. simplify the tagging and update the indent while we're in there, particularly for the three variants of gqa and check. this ensures the prompts line up right with their output, and there's a space after the prompt (as they're all in literallayouts) for better readability. passes build checks. -commit 139668d5643e86584322d4bcd25b71074ecec475 +commit 38e43ad1a4b1a4a1bf05c0b34fd58f92b32427c1 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 07:43:19 2023 -0400 +Date: Fri Aug 4 19:23:33 2023 -0400 - Correct stepcode configure vars for perplex/lemon + Have a QgGL resizeEvent also update the width and height -commit 7f7f18d19f23d10c31d03c1997e3062d7cff5a03 +commit 8f694c640429d442ba6b1f6b1e0346b6fd1fae67 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 07:08:23 2023 -0400 +Date: Fri Aug 4 19:19:45 2023 -0400 - Correct ordering of misc/tools and src/other build - - Ah - PATCHELF_EXECUTABLE wasn't set when we got to src/other/ext when we - moved it to misc/tools, since we weren't building misc/tools first. As - it happens, right now we can do misc/tools first since no code in that - directory is using src/other libraries. - - If we ever get into the situation where a tool in misc/tools requires a - src/other library, we're going to have to reconsider how we're - organizing misc/tools and src/other (or at least, how we maintain the - "don't install" vs "to be installed" distinction), but for now the - reordering should work. + When setting the view, update the view's current notion of width and height from the dmp -commit 33d109254de2a83649b80d97d569d64e2e1c08c4 +commit 462735d80fbf15b87de90ab9ffd7847ec77fbc6d Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 14 06:46:14 2023 -0400 +Date: Fri Aug 4 19:18:11 2023 -0400 - Reapply "Reorganize build tools in hierarchy" - - This reverts commit 697e70c727b0703f31ebea586a6050c7b8c183f8. - - Ah - we were building misc/tools after src/other, which (given the way - we're going to structure this) doesn't work. - - If anything in misc/tools needs a library in src/other we're going to - have a problem, but at least right now I don't think that's the case - - libxml is being built without ZLIB support since we don't need it for - Docbook processing. + The Docbook tag is used inside -commit 3ac436d8cd1cb70db5cf9e95abea1b3d20bf60de +commit 04a80b25a524b2059f3bd360f78856b4ad481780 Author: Christopher Sean Morrison -Date: Tue Mar 14 03:58:53 2023 -0400 +Date: Fri Aug 4 16:35:23 2023 -0400 - convert version conditional to a switch, constify. - - this should give the compiler and code sanitizers a bit more knowledge and ability to warn/report when a new value ends up unhandled. + Update bb.xml, add missing tags -commit a938fe3f0a25596c69541d3d0822b5602fb72c4b +commit 2c25145f4d13c816d0e0077fa86ad95217f1be0b Author: Christopher Sean Morrison -Date: Mon Mar 13 16:41:37 2023 -0400 +Date: Fri Aug 4 12:25:12 2023 -0400 - go through db_version() since this should match flipped too. + added line for josh's manpage pr -commit e4e1227bdd04b5a702e2debd2cea4e76ef4f099a +commit 01247b198e106f6ca232327356548bf0d0142864 Author: Christopher Sean Morrison -Date: Mon Mar 13 16:40:35 2023 -0400 +Date: Fri Aug 4 11:42:36 2023 -0400 - stale dbi_version mention + Update CMakeLists.txt with new dbfindtree.xml stub -commit 6f835a7714eb59732c53c40a0214396bb49730fd +commit 2739bc884589b0f89c1846a6fd9802a8ea75d29a Author: Christopher Sean Morrison -Date: Mon Mar 13 16:29:17 2023 -0400 +Date: Fri Aug 4 11:36:49 2023 -0400 - don't look directly at dbi_version, use db_version(). - - negative value is how binary database flipping is encoded, so can't just assume negative means we need to stop. going through the function, we get the desired indication of error. + Create dbfindtree.xml stub -commit c5b9805d8dcfc4129ba5b16e9c36dbc6c0346ea3 +commit a9bcf1711db5f2bba77ac848b0640acfb4acbf10 Author: Christopher Sean Morrison -Date: Mon Mar 13 16:26:54 2023 -0400 +Date: Fri Aug 4 11:30:04 2023 -0400 - actually returns abs(ver) so comment was correct. - - document it on the field though. + tweaked working -commit f4d8c2151b7dc6bf5916c4bf3de5c1f60117196e +commit d5e30792912e8af1669481af368258aaa6771f1f +Merge: b51cd5f8e6 e3c91b89a1 Author: Christopher Sean Morrison -Date: Mon Mar 13 16:15:40 2023 -0400 +Date: Fri Aug 4 11:28:25 2023 -0400 - go through db_version() instead of direct, comment on the negation + Merge pull request #93 from joshbaker22/typos-1 + + Fix a variety of typos in the manual -commit 4ed4839c3ccc333350c796d99b8216b992717e1e -Author: Christopher Sean Morrison -Date: Mon Mar 13 16:14:10 2023 -0400 +commit e3c91b89a15889812292f5f8b3a954867f9e3bcb +Author: joshbaker22 <141415098+joshbaker22@users.noreply.github.com> +Date: Fri Aug 4 11:21:21 2023 -0400 - setting var to anything turned off flipping, but name implies otherwise. - - make it so only setting a false value turns off database flipping. + Fix a variety of typos in the manual -commit 477200a6517b6ffb1a91a2fbb2555fa8972d3e20 +commit b51cd5f8e64b6ccac44dcd145911f55408be2145 Author: Christopher Sean Morrison -Date: Mon Mar 13 16:10:48 2023 -0400 +Date: Fri Aug 4 11:01:55 2023 -0400 - document the negative value on flipped databases + Update README, nix IRC for now until watching more regularly -commit 697e70c727b0703f31ebea586a6050c7b8c183f8 +commit de61c3a0f6432557d0a860a246df3fa0ffee0958 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Mar 13 14:35:54 2023 -0400 +Date: Thu Aug 3 16:52:15 2023 -0400 - Revert "Reorganize build tools in hierarchy" - - This reverts commit a93dcab8eca4d935a5af17d446414ecdc1925b55. - - CI reports breakage with rpath setting on Ubuntu + Remove burst tool (deprecated 7.32) -commit a93dcab8eca4d935a5af17d446414ecdc1925b55 +commit 3bebbd8029d4b16f87fa27d1960b2aeb1682182a Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Mar 13 11:28:40 2023 -0400 +Date: Thu Aug 3 16:40:05 2023 -0400 - Reorganize build tools in hierarchy - - Sean spotted where I wasn't grouping the various codes correctly - - move some "build only" tools to misc/tools, as well as various - adjustments and clean-ups. + Strip down libtermio code, eliminate public header - While we're at it, remove the unused dom2dox code and conditionally - activate the inactvhdrs compilation if the compiler explicitly supports - a C++17 option. That check can go away once we bump to a broad C++17 - requirement, but in the meantime this will check that inactvhdrs - compiles on at least some platforms. - -commit 60168f20df6e6d611c563e281794670fe2e24c88 + This doesn't quite get rid of libtermio completely, but it strips the + code down to the minimum in current use and makes it internal. Next + step is to see if linenoise can be used with btclsh and the fb tools to + completely eliminate the need for the last termio functions (and maybe + even get those tools working on Windows). However, as that change has + functional implications do this scrubbing first as a quick, lower risk + intermediate step. + +commit 9f9eb63642108028f460bce983f81ee04d4ae2b5 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 10 23:28:38 2023 -0500 +Date: Wed Aug 2 13:16:17 2023 -0400 - Define the set of valid man sections once + set_lib_Vars is specific to src/other/ext - move -commit 17aef2a4242808a30f671e105ecf09a956e71d4b +commit df35cbe4036c8eaccd7b28f5c218b0186ecca49c +Merge: 7b44938152 7848a4795d Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 10 23:21:32 2023 -0500 +Date: Wed Aug 2 13:15:38 2023 -0400 - Make a stab at having the GED man cmd launch brlman + Merge branch 'main' into draw_rework -commit 97edac8eccbd69d25bf35448e45206c5ab9c3759 +commit 7848a4795d68d6513035bb970e65728db713a7d9 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 8 17:13:01 2023 -0500 +Date: Wed Aug 2 11:15:36 2023 -0400 - Almost... off by one. Index into array starts at 0, not one... Add a couple explicit limit tests to check this behavior. + Break out the cmakefiles and distclean functions + + These functions (for identifying source files and build outputs + respectively) aren't actually specific to BRL-CAD - break them out into + their own file to make it easier to (potentially) reuse them in an + external 3rd party repository. -commit 8c50e75d1d9c87b7dbef889793d51d859e985521 +commit 7b449381526afa1bb88105a805958a2f564e3bee +Merge: 74ce48abcb 3e64c88022 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 8 17:02:06 2023 -0500 +Date: Wed Aug 2 09:23:08 2023 -0400 - Correct limit test + Merge branch 'main' into draw_rework -commit 976b690d716c8e5cf86b20fdf8dbc87e536da6a3 -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 8 12:09:18 2023 -0500 +commit de0feef3c13e05b5eb02d8b22f2c1db3520b2ffc +Author: GregoryLi0 +Date: Tue Aug 1 15:58:01 2023 +0800 - Enhance GED search cmd to accept values w/ spaces - - We had a user report that MGED's command line wouldn't allow users to - specify a search for attributes with spaces in their names. Initial - testing confirmed this, with multiple contributing factors. - - The pipeline for the search command uses bu_argv_from_string to break - string arguments into argv arrays. This operation is also performed by - the standard MGED command line, so to protect arguments with spaces as - active content it is necessary to quote them. While the user can do - this on the command line itself, internal processing in the GED search - command was re-assembling arguments to pass to the librt db_search - function without providing similar protections where needed. - - Beyond libged, the bu_argv_from_string function itself appeared to be - somewhat lacking in its handling of quoting behaviors. This commit - makes an attempt to rework the command to improve its overall processing - in such situations, as well as introducing various libbu unit tests to - ensure correct bu_argv_from_string behavior for various combinations of - quoted arguments with spaces. + 🐞 fix(libbrep): fix get_nurbs_surf + +commit 9259b50bcc3c6ecce684704bcfe03baffc5ad5c0 +Author: GregoryLi0 +Date: Tue Aug 1 14:48:16 2023 +0800 + + 📃 docs(libbrep): change comments + +commit a932131acc0991764489bd34f712555908873626 +Author: GregoryLi0 +Date: Mon Jul 31 15:55:48 2023 +0800 + + 📃 docs(libbrep/libged): add some comments + +commit 6bee31f7e999f5095eecd1f1006945efeca895e7 +Author: GregoryLi0 +Date: Mon Jul 31 15:50:01 2023 +0800 + + 🎉 init(libbrep/libged): surf interp - This warrants checking from others both for correct behavior and desired - behavior, but regression tests are passing and the following test on the - sample moss.g database was successful: + implement global surface interpolation with C2 continuity + +commit 1031b1b4f4406f1fe57dd0290b72d6a54b00810a +Author: GregoryLi0 +Date: Mon Jul 31 14:14:23 2023 +0800 + + ✨ feat(libbrep/libged): surf interp knot - mged> attr set platform.r "test 1" "val1" - mged> attr set tor.r "test 2" "val 2" - mged> attr set cone.r "test3" "val 3" - mged> search -attr \\"test 1\\" - platform.r - mged> search -attr \\"test*\\" - cone.r - platform.r - tor.r - mged> search -attr \\"test *\\" - platform.r - tor.r - mged> search -attr \\"* *\\" - platform.r - tor.r - mged> search -attr \\"test*=val*\\" - cone.r - platform.r - tor.r - mged> search -attr \\"test *=val*\\" - platform.r - tor.r - mged> search -attr \\"test *=val *\\" - tor.r - mged> search -attr \\"test *=val1\\" - platform.r - mged> search -attr \\"test*=val *\\" - cone.r - tor.r + Caculate knot vector while interpolating bicubic surface -commit a184e332242d5a7a3663b104742c9dc460fa216f -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 7 23:02:46 2023 -0500 +commit da5cdab300f5fdce7ec2a3685a58cd1f870a463c +Author: Kavin Teenakul +Date: Fri Jul 28 16:24:31 2023 +0200 - Set up to test bu_argv_from_string + Update brlcad-doc.desktop -commit fbdbf042b2db4c7d46839a17bbf4985cdb81f0ae -Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 7 22:18:37 2023 -0500 +commit 4ae989bb4f5a66448fee7b258bced5ee827d23a2 +Author: Kavin Teenakul +Date: Fri Jul 28 16:24:15 2023 +0200 + + Update brlcad-doc-mged.desktop + +commit 08faa606d7cc2a28f9bf9f0c948b5399321df3c6 +Author: Kavin Teenakul +Date: Fri Jul 28 16:24:03 2023 +0200 + + Update brlcad-db.desktop - Vanilla Tcl build doesn't provide a tclsh executable without version info - use an install copy to provide one. +commit 84b7b232e0f761216b325d2d9a9ab0a13a93f187 +Author: Kavin Teenakul +Date: Fri Jul 28 16:23:48 2023 +0200 -commit 1c4d46a3e26a44bfe908950e6118d0c66d4f5055 + Update archer.desktop + +commit 3e64c8802276def5fe3e6078157760a8c4d15578 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 7 20:32:17 2023 -0500 +Date: Wed Jul 26 22:03:28 2023 -0400 - Remove [source -rsrc]. Only in Tcl 8.3 and only works on Max OS 9. - (Itcl3 94d9228227 ) + Bump to next development revision after tagging the 7.36.0 release -commit 1466cbbb64202fda3d296966ab24230a94eab180 +commit 76f35fd2fc0c78ccd27ee400cd816be9f43c2b90 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Tue Mar 7 20:29:16 2023 -0500 +Date: Wed Jul 26 21:56:29 2023 -0400 - [SF Bug 279] Drop surplus quote. (Itcl 9c5d63471a) - - Per https://core.tcl-lang.org/itcl/tktview?name=171b58b82b the problem - Archer is having with Itcl 3.4.4 is specific to one change. We'll grab - the other fixes from Itcl and apply them to our 3.4.3 copy. + Update log with commits since 2023-02-27 -commit 2d9f909ec1d35e9eedef2260dceed676842bff54 +commit 834994a075da397c581499ce41662d2f9d878ef2 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Mar 6 10:16:01 2023 -0500 +Date: Wed Jul 26 19:45:04 2023 -0400 - Remove the news item for Itcl3 version bump + Define static assert for Ghost BSD + + Similar to https://github.com/apache/mynewt-core/issues/2040#issuecomment-554571476 -commit 5b243b5a78f52b60863179340fecb3181e9fe880 +commit 703c261a6c428deefd68401ce92e2bb728915424 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Mon Mar 6 10:15:19 2023 -0500 +Date: Wed Jul 26 16:32:52 2023 -0400 - Itcl 3.4.4 appears to be what breaks things - reverting back to our 2023-02-08 version lets Archer run again. + More advanced variables -commit b8680d830ce679574bf18dda8cd161225ff89a30 +commit 028ba3e64c724ea2533b3846145d5990b775a7fd Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 3 20:47:03 2023 -0500 +Date: Wed Jul 26 16:10:36 2023 -0400 - Add TODO notes + Mark various variables as advanced for CMake -commit d5572ca6f99323d783e023fcbd0edf9cadba38ed +commit f9079cf1c46382d82932c5a12236b9638edcc644 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 3 20:20:36 2023 -0500 +Date: Wed Jul 26 14:35:25 2023 -0400 - Should technically be depending on ZLIB_TARGET on Windows too + Remove odd_pathnames from distcheck-full set + + Too problematic with 3rd party builds - we'll just keep it as a + stand-alone test when conditions are right to run it. We may be able to + make it standard again if we fully separate src/other/ext into its own + repository and make it a separate build, but that's down the road. -commit d17194ca536b604184bca3057c8fcbbf31957edc +commit 40f38f89ce4ae6d84378ba70b99ee66cf00f1a79 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Fri Mar 3 19:00:27 2023 -0500 +Date: Wed Jul 26 13:03:33 2023 -0400 - See if the zlib deltas in Tcl's makefile.vc from the upgrade are what broke the build. + Ah, apparently 1.6.40 png has this covered already... -commit ee446de2cd615eec6931457b6250b2c8fb6b94eb +commit b6f71f4bec72d8d0781705056eab65dd7117b999 Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 1 11:33:14 2023 -0500 +Date: Wed Jul 26 12:55:52 2023 -0400 - Set version numbers for expected next release + Add a way to suppress the PNG use of 'd' suffix + + Grr. If build type gets set to Debug, instead of being left empty, + Linux is also throwing in the 'd' suffix on debug build libs from png. + Add a way to specify at configure time not to do that - it really messes + with our build logic. Should probably try to upstream this or something + like it. -commit ca4742994e72675b0d5d7839f63aef427499ab52 -Merge: 1307e0d6ab dc828f826d +commit c5e99fcc9ba931e109a1cbbbcac4a102715855fb Author: Clifford Yapp <238416+starseeker@users.noreply.github.com> -Date: Wed Mar 1 11:30:53 2023 -0500 +Date: Wed Jul 26 11:32:34 2023 -0400 - Merge branch 'RELEASE', bump PATCH number + Fix executable permission on sh files + + Looks like we lost executable settings in the 2023-02-02 year updating + commit. Was manifesting in a distcheck failure when the check target's + invocation of benchmark clobber wasn't succeeding due to benchmark not + being executable, leaving behind files. That calling of the benchmark + script didn't prefix with an explicit ${SH_EXEC} call, and thus relied + on benchmark being directly executable on its own. diff --git a/HACKING b/HACKING index 0c90cb2142d..67ec68321ef 100644 --- a/HACKING +++ b/HACKING @@ -297,10 +297,6 @@ libtclcad: The Tcl-CAD library is a thin interface that assists in the binding of an image to a Tk graphics context. Depends on: libbn libbu libfb libtcl libtk -libtermio: The terminal I/O library is a TTY control library for -managing a terminal interface. - Depends on nothing - libwdb: The "write database" library provides a simple interface for the generation of BRL-CAD geometry files supporting a majority of the various primitives available as well as combination/region support. diff --git a/NEWS b/NEWS index 11c48ce3d52..0c8fa89972e 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,48 @@ first and are grouped by release. Each release also includes optional descriptive text that emphasizes or further describes significant changes made. See document footer for additional details. +---------------------------------------------------------------------- +--- 2023-11-06 Release 7.38.0 --- +---------------------------------------------------------------------- +This major release of BRL-CAD introduces significant improvements to +the robustness of the facetize command by leveraging the Manifold +library for boolean evaluation of meshes. Facetization is an operation +that converts boolean CSG hierarchies to evaluated triangle meshes, +commonly used as a preliminary step in geometry export. As an +example, the following results show before-and-after differences when +processing high level assemblies in BRL-CAD's example geometry files: + +% success, old: 88.9% (249 of 280) Time elapsed: 7256 seconds +% success, new: 98.9% (277 of 280) Time elapsed: 1044 seconds + +Also in this release is an alpha version of the new "gist" tool, which +leverages the OpenCV library to create one page summaries of the +geometric information present in .g files. + +* add 'brep dump' subcommand to write out brep objects - Cliff Yapp +* improve 'x' default behavior in MGED - Chris McGregor +* fixed 'edcolor' and 'color -e' on Windows - Chris McGregor +* ported fbcolor, fblabel, fbpoint, fbzoom to Windows - Sean Morrison +* new 'gist' tool for generating 1-page geometry info summary reports + - Allyson Hoskinson, Andrew Plant, Mark Sturtevant, + - Danny Chen, Michael Tao, Sean Morrison +* add support for dbconcat -O (overwrite) - Chris McGregor +* improved 'lc' -d and -m interactions with aircodes - Chris McGregor +* fixed 'make bot' inverted face normals - Chris McGregor +* fixed 'l' evaluation for pathed objects - Chris McGregor +* improved MGED faceplate params control, added font_size - Cliff Yapp +* fix MGED 'brep' command crashing without database open - Cliff Yapp +* fix MGED 'pnts read' and 'make_pnts' commands - Chris McGregor +* improved NURBS editing functionality - Gregory Li +* fix MGED 'listval' crashing with max path lengths - Chris McGregor +* fixed garbage_collect MGED command on Windows - Cliff Yapp +* fixed archer crashing with 'make' command - Cliff Yapp +* improved and restructured rtwizard's manual page - Sean Morrison +* fixed E command in MGED - Cliff Yapp +* made improvements to a variety of manual pages - Josh Baker +* remove bundled burst tool (DEPRECATED 7.32) - Cliff Yapp + + ---------------------------------------------------------------------- --- 2023-07-26 Release 7.36.0 --- ---------------------------------------------------------------------- diff --git a/README b/README index 381701ccd96..366e1dbd1a3 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ BRL-CAD - Release 7.36.0 + Release 7.38.0 http://brlcad.org/ BRL-CAD is a powerful cross-platform open source combinatorial @@ -103,10 +103,9 @@ announcement list: http://sourceforge.net/mail/?group_id=105292 -For interactive discussion, there is Zulip chat and IRC available: +For interactive discussion, please join our Zulip chat: https://brlcad.zulipchat.com - https://brlcad.org/wiki/IRC BUG REPORTS AND FEATURE REQUESTS diff --git a/TODO b/TODO index 2c251cb683c..a612f3fbc23 100644 --- a/TODO +++ b/TODO @@ -28,6 +28,26 @@ THESE TASKS SHOULD HAPPEN WITHIN TWO RELEASE ITERATIONS THESE ARE UNSCHEDULED BACKLOG TASKS ----------------------------------- +* explore whether we can write a command to replace bad brep + 3d edge curves with ON_BezierCurve::Loft approximations of + 3d points evaluated from a valid 2d parametric curve associated + with the same edge. Hoping to use this to repair geometry + that has valid face and 2D parametric info but bad 3d edge curves. + Preliminary work is in the brep repair subcommand. + +* ability to draw lines, boxes, and text on rendered outputs/images. + we sort of have this ability through plot3 and composition tools + but end-user request was integration with rt* tools so, for + example, there could be a way to specify a coordinate frame overlay + on images output by rtwizard, using stippled lines. + + some existing APIs with similar functionality include opencv, + matplotlib, matlab, and processing + +* ability to place/align/mate objects tangentially, e.g., having a + vehicle rest on a piece of terrain or putting one object next to + another object. + * race condition causing bus errors on exit * re-enable regress-asc and regress-weight @@ -237,12 +257,6 @@ THESE ARE UNSCHEDULED BACKLOG TASKS once), but really should as it's the starting point for discovering what is in databases that are opened or imported. -* nburst appears to be missing logging output (bounding volume lines) - and isn't outputting units (outputs NULL). can run regress-burst - and regress-nburst to compare (have to manually save files). the - ktank test isn't comprehensive, really should tests all the primary - options. - * add metaball scaling feature (presently in a tclscript) * ability to visualize metaball centerpoints and with/without diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 1e561531f9c..f5dfaa815f1 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -17,6 +17,9 @@ configure_file(run.sh "${CMAKE_CURRENT_BINARY_DIR}/benchmark" COPYONLY) install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/benchmark" DESTINATION ${BIN_DIR}) DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/benchmark") +# TODO - with CMake 3.20, add_custom_command supports generator expressions in +# OUTPUT, so once we can require that version we should look at retiring this +# use of CMAKE_CFG_INTDIR add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/benchmark-${CMAKE_CFG_INTDIR}-done COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/run.sh $/benchmark diff --git a/doc/README.Linux b/doc/README.Linux index 6bcd6b320a7..0c4ae0b88ee 100644 --- a/doc/README.Linux +++ b/doc/README.Linux @@ -34,6 +34,17 @@ cmake ../brlcad -DBRLCAD_WORD_SIZE=64BIT * Note that in both of the above situations you need both a compiler that works in the alternate mode and system libraries of the correct type. +Alpine Linux +------------ + +Alpine is an interesting test platform in that it does not use +glibc but instead relies on mucl. + +At a minimum, will need the following packages: +apk add cmake git gcc g++ make linux-headers + +TODO - look into setup-xorg-base + Arch Linux ---------- diff --git a/doc/docbook/CMakeLists.txt b/doc/docbook/CMakeLists.txt index 53634e3f5dc..6914cfbd318 100644 --- a/doc/docbook/CMakeLists.txt +++ b/doc/docbook/CMakeLists.txt @@ -20,6 +20,9 @@ if(BRLCAD_EXTRADOCS_PDF) DISTCLEAN("${CMAKE_BINARY_DIR}/doc/docbook/fop.xconf") endif(BRLCAD_EXTRADOCS_PDF) +# TODO - with CMake 3.20, add_custom_command supports generator expressions in +# OUTPUT, so once we can require that version we should look at retiring this +# use of CMAKE_CFG_INTDIR # For the html files, we need brlcad.css add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/brlcad_css-${CMAKE_CFG_INTDIR}-done diff --git a/doc/docbook/articles/main_menu.xml b/doc/docbook/articles/main_menu.xml index 60c425e7c72..d387d775d15 100644 --- a/doc/docbook/articles/main_menu.xml +++ b/doc/docbook/articles/main_menu.xml @@ -2814,11 +2814,6 @@ CAD Parea - - - Canonize - - Cell FB @@ -2939,11 +2934,6 @@ Fbcolor - - - Fbed - - Fbfade @@ -3525,16 +3515,6 @@ Png Pix - - - PP FB - - - - - Proe-g - - Random diff --git a/doc/docbook/system/man1/CMakeLists.txt b/doc/docbook/system/man1/CMakeLists.txt index 21538b9c099..9bbc6781141 100644 --- a/doc/docbook/system/man1/CMakeLists.txt +++ b/doc/docbook/system/man1/CMakeLists.txt @@ -13,7 +13,6 @@ set(man1_EN brep_simple.xml brlcad-config.xml brlcad.xml - burst.xml bw-fb.xml bw-pix.xml bw-png.xml @@ -32,12 +31,10 @@ set(man1_EN bwthresh.xml cad_boundp.xml cad_parea.xml - canonize.xml coil.xml comgeom-g.xml conv-vg2g.xml cv.xml - db.xml dbclean.xml dbupgrade.xml decimate.xml @@ -53,7 +50,6 @@ set(man1_EN fbclear.xml fbcmap.xml fbcolor.xml - fbed.xml fbfade.xml fbframe.xml fbfree.xml @@ -95,12 +91,9 @@ set(man1_EN icv.xml iges-g.xml imgdims.xml - ir-X.xml - irdisp.xml loop.xml mac-pix.xml mged.xml - morphedit.xml nastran-g.xml nirt.xml obj-g.xml @@ -121,7 +114,6 @@ set(man1_EN pixborder.xml pixbustup.xml pixclump.xml - pixcmp.xml pixcolors.xml pixcrop.xml pixdiff.xml @@ -156,8 +148,6 @@ set(man1_EN png-bw.xml png-fb.xml png-pix.xml - pp-fb.xml - proe-g.xml random.xml remrt.xml reshoot.xml diff --git a/doc/docbook/system/man1/brlcad.xml b/doc/docbook/system/man1/brlcad.xml index 75010477624..c8b7dc94ba9 100644 --- a/doc/docbook/system/man1/brlcad.xml +++ b/doc/docbook/system/man1/brlcad.xml @@ -108,13 +108,6 @@ etc. TCP-based network server which implements remote frame-buffer services. - - - - libtermio - -A library to handle terminal mode setting -on both Berkeley or SystemV machines. @@ -199,21 +192,12 @@ See pixstat1, pixtile1, plot3-fb1, -pp-fb1, rle-fb1, rle-pix1, wavelet1, bw5, pix5, plot35. - - - - fbed - -An interactive, termcap-based frame-buffer image editor. -See -fbed1. diff --git a/doc/docbook/system/man1/burst.xml b/doc/docbook/system/man1/burst.xml deleted file mode 100644 index 382495a1299..00000000000 --- a/doc/docbook/system/man1/burst.xml +++ /dev/null @@ -1,1124 +0,0 @@ - - - - BURST - 1 - BRL-CAD - BRL-CAD User Commands - - - - burst - - Prepare shotline and burst point library inputs for PDAM. - - - - - - - burst - -P - input_file - - - - DESCRIPTION - - - burst uses LIBRT raytracing to prepare inputs to the - Point Burst Damage Assessment Model (PDAM) in the form of shotline files - and burst point library files. For more information about PDAM, see - ARL-CR-69: - A Guide to FASTGEN Target Geometric Modeling. - - - The burst program is designed to allow many options to be - configured before any outputs are calculated. Unless otherwise stated in the - individual command descriptions, a given command will nullify any previous - occurrence of the same directive until an execute command - is given. For instance, the command target-file - tank1 followed by - target-file tank2 will - nullify the reference to tank1. It is also important to remember that the - units command impacts how subsequent physical quantities - are read by other commands, and the output from an execute - command will use whatever units are current. Once the input parameters are specified, - the execute command will start a run. Output will be - reported using the current setting for units at the - time the execute is run. Many runs may occur during an instance of - the burst program. One such instance is referred to as a session. - - - - OPTIONS: - - - - - - - Plot points (default). - - - - - - - - Plot lines. - - - - - - - - COMMANDS - - Commands are defined via an input file and passed to burst when it is first invoked. - All commands to burst are composed of one or more words connected by hyphens and each command - may require one or more arguments that must be separated by either spaces or tabs. A line that - begins with the ‘#’ symbol is considered a comment and will be ignored. The following table - provides a brief overview of the available commands, with subsequent sections covering key - areas in more detail. In the table, flag arguments have yes or no values, an angle is expressed - in degrees as a floating-point quantity, distances and coordinates such as X, Y, Z, left, - right, etc. are also floating-point numbers, and count represents an integer. Square brackets - delimit optional arguments. - - - Burst Commands - - - - Command - Arguments - Description - - - - - attack-direction - azim_angle elev_angle - specify azimuth and elevation of attack relative to target - - - - burst-air-file - file - input burst air idents from file - - - - burst-armor-file - file - input burst armor idents from file - - - - burst-coordinates - X Y Z - input single burst point location in target coordinates - - - - burst-distance - distance - offset burst point along shotline - - - - burst-file - file - output burst point library to file - - - - cell-size - distance - specify shotline separation (equidistant horizontal and vertical) - - - - color-file - file - input ident to color mapping from file (for graphics) - - - - cone-half-angle - angle - specify limiting angle for spall ray generation - - - - critical-comp-file - file - input critical component idents from file - - - - deflect-spall-cone - flag - deflect axis of spall cone half way towards exit normal - - - - dither-cells - flag - if yes, randomly offset shotline within grid cell - - - - enclose-target - - generate rectangular grid of shotlines for full target envelope - - - - enclose-portion - left right bottom top - generate partial envelope by specifying grid boundaries - - - - error-file - file - divert all diagnostics to file - - - - execute - - initiate a run (no output produced without this command) - - - - grid-file - file - save shotline locations (Y' Z') in file - - - - ground-plane - flag [Z +X -X +Y -Y] - if yes, burst on ground - - - - help - display a list of available commands - - - - histogram-file - file - write hit frequency histogram to file - - - - image-file - file - generate frame buffer image on a specified file or device - - - - input-2d-shot - Y' Z' - input single shotline location as grid offsets - - - - input-3d-shot - X Y Z - input single shotline location in target coordinates - - - - max-barriers - count - specify the maximum number of components to report along spall ray - - - - max-spall-rays - count - specify the desired number of spall rays generated per burst point - - - - plot-file - file - generate plot data in file - - - - quit - quit the application - - - - read-2d-shot-file - file - read shot locations from file as grid offsets (see input-2d-shot) - - - - read-3d-shot-file - file - read shot locations from file in target coordinates (see input-3d-shot) - - - - read-burst-file - file - read burst point locations from file (see burst-coordinates) - - - - read-input-file - file - read key word commands from file - - - - report-overlaps - flag - if yes, log overlap diagnostics - - - - shotline-burst - flag - if yes, generate burst points along shotlines - - - - shotline-file - file - output shot line data to file - - - - target-file - file - read BRL-CAD database from file - - - - target-objects - object0 [object1 object2 ...] - list objects from BRL-CAD database to interrogate - - - - units - name - linear units (inches, feet, millimeters, centimeters,meters) - - - - write-input-file - file - save script of commands in file - - - - # - - any line beginning with the '#' character is a comment - - - - -
-
-
- - - User Preferences - - - Units of Measure - - The units command will set the linear units for input and - output. This command should be used before any scalar quantities such as - coordinates, distances, or sizes are input. The units may be changed to accommodate - input files of differing units, but the output from a particular run will reflect - whatever the units were set to when the execute command was - given. One argument is expected out of the following list and must be spelled - correctly: millimeters, centimeters, meters, inches and feet. The default units are - millimeters. - - - Note that when specifying angles as options to commands angles are always expressed - in degrees, not radians. - - - - - Region Overlap Reporting - - It is considered an error if two regions in a BRL-CAD .g file occupy the same space; we - call this an overlap. The ray tracing library (librt) will report overlapping regions - that are intersected by shotlines or burst rays to the burst application and the program - will, by default, print out any that have a line of sight thickness of at - least 0.25 millimeters (see Error Log). Although a target - may only have a small number of overlapping regions, an error will be reported for each - ray that intersects one of them. Generally this results in the messages being repetitious. - Although these diagnostics are important for fixing problems in the geometric description - of the target, the user may wish to proceed with a production run and the printing of - these errors can slow the execution time considerably. A yes or no argument to - the report-overlaps command will turn the diagnostics on or off. - Regardless of whether or not individual overlaps are reported, the total number detected - will be logged. - - - When overlap reporting is enabled, the full path name of both regions is printed as seen in the - following example: - - -OVERLAP: -reg=/component/turret/tur.ext/tur.armor/tur.bot{{0}} isol=s2, -reg=/component/hull/hull.ext/hull.armor/r1.top{{0}} osol=ss4, -depth 544.21mm at (-471.784,812.8,0) x-2 y1 lvl0 purpose=shotline -OVERLAP: -reg=/component/turret/tur.ext/tur.ring{{0}} isol=ss2, -reg=/component/turret/tur.ext/tur.armor/tur.bot{{0}} osol=s2, -depth 25.39mm at (-418.907,812.8,0) x-2 y1 lvl1 purpose=normal thickness -OVERLAP: -reg=/component/turret/tur.ext/tur.ring{{0}} isol=ss2, -reg=/component/turret/tur.ext/tur.armor/tur.bot{{0}} osol=s2, -depth 52.88mm at (-418.907,-812.8,0) x-2 y1 lvl1 purpose=spall ray - - - The zero enclosed in double curly brackets is intended to discriminate between instances. - Theoretically, isol and osol are the names of the starting and ending solids associated - with the boolean operations on the overlapping partition. In practice these solid names - are typically not helpful in diagnosing the problem, but the region names should be - sufficient. The depth is the line-of-sight thickness of the overlapping partition in - millimeters. In parentheses, are printed the target coordinates of the intersection of - the ray with the overlap. The x-2 and y1 reveal that the grid indices of the shotline - are -2, 1; this means that the shotline was 2 cells to the left, and one cell above the - grid origin. If lvl (meaning ray tracing recursion level) is zero, then the overlap - resulted from a shotline, but if it is one, it could represent either a burst ray - intersection or a probe to calculate the normal thickness of a component intersected by - the shotline. The real purpose of the ray is stated last. - - - - - - Shotlining Options - - Shotlining is a technique whereby lines are described in the target coordinate system - and information is requested about the geometry that intersects those lines in 3-space. - This technique is useful for analysis programs that must simulate threat/target - interactions, and therefore must sample the geometry along the threat path. Typically the - lines are specified discretely, by a point and a direction, or a grid of lines is - generated that is oriented perpendicular to the direction of attack. A grid is rectangular, - but is subdivided along its height and width uniformly resulting in square cells. - Gridding techniques include passing a line called a shotline through the center of each - cell, or alternatively, dithering each shotline’s position within its respective - cell’s boundaries (see Dithering Shotlines). - - - The user is faced with several choices for generating shotlines; full-target envelope, - partial envelopes, or discrete shots. No matter what shotlining method is used, a grid - always exists as a frame of reference for specifying 2-dimensional coordinates in the - plane normal to the direction of attack. This 2-dimensional coordinate system is a - projection of the shotline coordinate system (also referred to as the primed coordinate - system). For the simple case of a zero azimuth, zero elevation attack, the X’, Y’, and Z’ - axes in the shotline coordinate system coincide with the X, Y, and Z axes of the target - coordinate system and the shotline direction is parallel to the X’ axis and headed toward - decreasing coordinates. Other orientations are described by rotating the X’, Y’, and Z’ - axes to keep the shotline direction always down the X’ axis. This transformation involves - two rotations; first a rotation of the primed coordinate system about the coincident Z and - Z’ axes by the specified azimuthal angle, followed by a rotation about the new Y’ axis by - the specified elevation angle. Since the grid is a 2-d projection of the shotline - coordinate system, it has no X coordinate; if the user’s viewpoint is from the direction - of attack, the Y’ axis can be thought of as horizontal with increasing coordinates to the - right, and the Z’ axis as vertical and increasing in the upward direction. - - - - Attack Direction - - The orientation of shotlines with respect to the coordinate system of the target are - described by azimuth and elevation angles. These angles must be specified in degrees - as floating-point numbers via the attack-direction. - - - - - Gridding - - An envelope refers to a grid that is dimensioned such that its rectangular area, - projected normal to the grid, will cover optionally all or part of the target. - The enclose-target option will generate a grid that is guaranteed - to cover the entire target. Since BRL-CAD uses combinatorial solid geometry as one of - its shape representation methods, the dimensions of the target are not known in advance. - Therefore, a worst case bounding rectangular parallel piped (RPP) is used to generate the - grid and the grid may be larger than necessary. In addition, depending on the attack - aspect, the presented area of some targets may not fill up a rectangular grid well. This - should not be a problem since ray tracing outside the target boundaries is cheap, but - if desired the grid can be trimmed down with the partial envelope option - enclose-portion. The grid origin is always aligned with the target origin. - - - The enclose-portion option allows the user to generate a sub-grid by - specifying the distances from the grid origin to the sub-grid’s left, right, top, and - bottom boundaries. - - - - - Cell Size - - The dimensions of a grid cell are input as floating-point values that represent the - distances between the centers of adjacent cells. cell-size also - expresses the projected area of influence associated with a shotline or burst ray. - Therefore, cell-size must be specified even when a grid will not - be generated, such as with discrete shot or discrete burst point selection (see - Input Discrete Shots and - Input Discrete Burst Points). - - - - - Dithering Shotlines - - When gridding, shotlines normally pass through the center of each cell, however, they - may be also be dithered via the dither-cells command. If the user - chooses the latter, 2 random numbers are selected for each cell that are used to offset - the shotline in both parametric directions of the grid plane, but within the respective - cell’s boundaries. - - - - - Input Discrete Shots - - If the user wants to fire at a known point on the target, he or she may wish to describe - the shotline location in target coordinates. When coupled with the attack direction, each - 3-dimensional coordinate uniquely specifies a shotline. The input-3d-shot - command allows the user to type in a single shot location as an X, Y, and Z coordinate that - is run when the execute command is given, but remember that no queueing - of shots occurs in this mode; the last set of coordinates entered will be used. For inputing - multiple shots, read-3d-shot-file can be used to loop through every set - of target coordinates in the named file after the execute command is run. - The file should contain three floating-point numbers on each line separated by white space - (blanks or tabs). - - - Another way to describe a shot location is in the shotline coordinate system. Since the X’ - location of the shot is irrelevant (the shotline is parallel to the X’ axis) a shot may be - specified as a Y’ and Z’ coordinate. These coordinates can also be referred to as horizontal - and vertical grid offsets. The input-2d-shot option allows the user to - type in a single shot location as a Y’, and Z’ coordinate which will be run when the - execute command is given, but like the 3d case no queueing of shots occurs - in this mode and only the last set of grid offsets entered will be used. To input multiple - shots, the read-2d-shot-file can be used; execute will - loop through every set of grid offsets in the named file. The file should contain three - floating-point numbers on each line separated by white space (blanks or tabs). - - - - - - - Bursting Options - - Bursting is a technique for sampling a target’s geometry with the use of ray tracing. As - opposed to shotlining involving parallel rays, bursting employs a distribution of rays - that emanate from a single point. The burst program generates rays that approximate a uniform - distribution over a user-specified solid angle (see - Sampling Cone Half Angle) and having a density (see - Number of Sampling Rays) that is also under control of - the user. The user also has a choice between several mechanisms for setting up burst point - locations depending on the particular threat he is attempting to emulate. - - - - Method of Locating Burst Point - - Depending on threat type, burst points may be located using two basic techniques. The - first technique is simply to input the burst point coordinates. This method can be used - to compare vulnerability analysis results with empirical results from the firing range - or combat field. The second technique available to the user is to burst along a shotline. - This option is used more for predicting the burst point location based on target geometry, - given certain parameters that describe the target/threat interactions. - - - - Input Discrete Burst Points - - The input of explicit burst point coordinates can be accomplished either by typing them - in one at a time or by reading a file of target X, Y, and Z coordinates. - - - The burst-coordinates command allows the user to type in a single - burst point location as an X, Y, and Z coordinate. When the execute - command is given, that one burst point will be run. No queueing of burst points occurs - in this mode, the last set of coordinates entered will be used. - - - The read-burst-file command allows the user to specify a number of - burst points from a file; this option will, after submission of an execute directive, - loop through every set of target coordinates in the named file. The file should contain - three numbers on each line separated by white space (blanks or tabs). - - - - - Burst on Contact - - The shotline-burst command can be given a yes or no argument to either - enable or disable this method of generating burst points. When a yes argument is given, - a second yes or no argument is also required (see Burst on Armor). - Bursting along a shotline can be done different ways depending on the combination of - several options. The location of the burst point is based on the triggering mechanism that - is selected with the burst distance parameter. - - - - Burst on Armor - - If the burst-distance parameter is set to a negative or zero value, then - interior burst points will be generated (see Burst Distance). - This method of bursting requires the input of burst armor idents and, by default, burst - air idents are also required. If the user does not want to require that certain air be - present to trigger a burst point, the shotline-burst command has a second argument. When this - second argument is set to no, bursting will occur as long as burst armor is followed by any - air or void (empty space), and the burst air file is not required. For more information see - Burst Armor and Burst Air Ident Files. - - - - - Ground Plane Bursting - - Ground plane bursting is a vehicle for evaluating the effect of fragmenting warheads - on light-armored vehicles when they strike the ground in close proximity to the target. - The ground-plane command is only relevant when bursting along a - shotline is selected. The ground is modeled as a rectangle lying in a plane parallel to - the target X-Y plane with edges parallel to the X and Y axes. The grid will be enlarged - to include the ground plane; it is important for efficiency to limit the size of the - ground plane to match the range of the fragments that may be generated by the particular - threat being modeled. When enabling this option, the ground-plane - command is given a yes argument followed by the height of the target above the ground, - and the distances that the ground rectangle extends out positive X, negative X, positive - Y, and negative Y axes. - - - - - - - - - Bursting Parameters - - The following parameters influence both the triggering mechanism for burst points, as well - as the characteristics of the cone of rays generated from each point. - - - - Burst Distance - - The burst-distance parameter is modeled after the BDIST parameter - used by the Air Force’s PGEN code. The role of this parameter is overloaded, however it - was retained to aid PGEN users in transitioning to the burst program. - If it is zero or negative, then interior bursting is enabled, otherwise, if it is greater - than zero, exterior bursting will occur, subject to certain conditions (see below). - The magnitude of this parameter is used to offset the burst point location along the - shotline relative to the geometry that triggered the burst. - - - - Interior Bursting - - Burst armor refers to a component whose ident code is found in the list input by - the burst-armor-file command. Similarly, burst air refers to a - component whose ident code is found in the list input by the - burst-air-file directive. If interior bursting is enabled and - a burst armor component is encountered along a shotline that is immediately followed - by burst air, then a burst point will be located the absolute value of burst distance - beyond the exit of the shotline from the component. This means that if burst distance - is zero, the burst point will lie at the burst armor/air interface, and if it’s - -5.5, the burst point will lie 5.5 units inside the air compartment from the back - surface of the armor. - - - - - Exterior Bursting - - If burst distance is greater than zero, the first component encountered along the - shotline will trigger a burst point, regardless of its ident code, that will be - located burst distance in front of the shotline entry point. This technique simulates - the behavior of a fragmenting munition with a standoff fuzing such that detonation - is triggered before the collision of the warhead with the target. The burst distance - is set to imitate the built in standoff of the warhead. When employing exterior - bursting methods, burst armor and burst air are not used. - - - - - - - Sampling Cone Half Angle - - To limit the solid angle within which burst rays will be generated, the user may - specify a cone half angle. This angle represents the degrees (in floating point) from - the axis of the cone to its limiting surface. The default value for the cone half - angle is 45 degrees. - - - - - Deflected Sampling Cone - - The spall cone axis is, by default, aligned with the shotline. In reality, the center - of mass of the spall cloud would be between the shotline direction and the exit - normal of the shotline from the spalling component. By aligning the spall cone axis - with a vector halfway between the shotline and the exit normal, a narrower cone half - angle can be used and still sample within the solid angle of interest. This technique - can therefore be used to cut down on the number of rays calculated without lowering - the sampling density. The deflect-spall-cone command takes a yes - or no argument about whether or not to divert the cone axis. - - - - - Number of Sampling Rays - - The sampling ray density within the spall cone is controlled by specifying the maximum - number of rays desired with the max-spall-rays command. Due to the - uniform distribution algorithm employed, the number of rays calculated will be slightly - less. - - - - - Maximum Barriers - - For munitions known to have limited penetration capability, the user may set a limit - on the number of burst ray intersections reported with the - max-barriers command. The effect of setting this parameter is to - reduce the size of the burst point library (see - Burst Point Library) by limiting the number of - components that will be reported per burst ray. By default, up to 100 components - are reported, as it is not expected that this number will be reached under - normal circumstances. - - - - - - - - - Input File Options - - - Target-Related Input Files - - This group of commands is for specification of target-specific input files. - - - - Target Data Base File - - The input of the target’s BRL-CAD .g file is accomplished with the target-file - command. Note that only one data base may be read in during a given session. If the user wishes - to change the target once the execute command has been given, they must exit the burst program - and start a new session. - - - After specifying the BRL-CAD .g file, the user must list all of the objects in the .g - hierarchy that they wish to include in the analysis with the target-objects - command. The objects must be listed as arguments to one target-objects - command with spaces or tabs as separators. Note that only one list of objects may be loaded - per session, however, they do not get loaded until the execute command is - given. - - - - - Ident List Input Files - - Idents refer to the region ident code from the BRL-CAD .g file. Lists of idents may be specified - singly or as ranges. Individual idents must appear as one per line, but ranges are specified - by two numbers on a line that are separated by one or more of the following characters: - comma, hyphen, colon, semicolon, space, or tab. For example: - -600-999 -1011 -4002-4050 -8000 -9001 -9004 -9005 - - - - - Burst-Armor and Burst-Air Ident Files - - When interior burst points are to be generated along a shotline (see - Interior Bursting) a file of burst armor - idents must be specified with the burst-armor-file command. Additionally - a burst air idents file must be specified with the burst-air-file command. - If a shotline intersects a component whose ident has been input as a burst armor and it is - immediately followed by burst air a burst point will be triggered. - - - - - Critical Component Idents - - Whether interior or exterior bursting is being employed, information about components - hit by burst rays will only be output for rays that hit critical components. The file name - containing a list of critical component idents must therefore be specified by the - critical-comp-file command if burst points are to be generated. - - - - - - - Color Mapping Input Files - - The color-file command allows users to assign colors to component - idents for graphics options, in particular, the image-file and - plot-file commands. The format of this file is 5 numbers per line - separated by blanks or tabs. The first number is the low end of an ident range and the - second number is the high end of the range (both numbers are inclusive). This range is - mapped to the color specified by the last 3 numbers on the line that are red, green, - and blue components of the color (values for these components must be between 0 and - 255 inclusive). For example: - -4001 4003 255 255 0 # Fuel -4050 4050 255 255 0 # Fuel -8000 8001 255 100 255 # Ammo -100 165 150 255 100 # Hull armor -610 619 220 150 100 # Commander -720 729 220 150 100 # Gunner -830 839 220 150 100 # Loader -940 949 220 150 100 # Driver - - - - - - - - Project-Related Input Files - - - Reading Session Files - - The read-input-file command reads an input file of commands. These - files can be generated manually by using a text editor or saved from a session file - with the write-input-file command. See - Command Input for the format of this file. - - - - - Shotline and Burst Point Input Files - - For an explanation of commands for reading in files of shotline or burst point coordinates, - see Input Discrete Shots and - Input Discrete Burst Points. - - - - - - - - - Output File Options - - The following commands will turn on optional output. By default, no output is produced - except error logging (see Error Log), unless an output - file is specified with the appropriate command. Any combination of output options may be - specified for a particular run. Note that specifying an output file will cause an existing - file with that name to be truncated to zero length. Therefore, only one such command should - be entered per session for a particular file name. Multiple runs during a session will append - to the same files if intervening commands to change the output file name are not given, - except for the graphics files as explained below. Note that there is no way to append to a - file created by a previous session of the burst program, but these files may be concatenated - after the fact. - - - - Burst Point Library File - - The burst-file command will open the named file for creating a burst - point library. If the file exists, it will be truncated by this command. - - - - - Shotline File - - The shotline-file command will open the named file for creating a - shotline file. If the file exists, it will be truncated by this command. - - - - - Plot File - - The plot-file command generates a plot file, using BRL-CAD extensions - to the standard format. This option is useful for examining the shotline and burst ray - information graphically as a three-dimensional vector plot. Due to constraints inherent - in the plot format, these plots must be displayed as a post-process step by using a - BRL-CAD plotting utility such as pl-fb. Because some of these display - programs do not support multiple plots per file, the file name should be changed between - runs. The following table describes the color mapping associated with these plots: - - - Color Key for Plots - - - - Color - R - G - B - Representation - - - - - yellow - 255 - 255 - 0 - grid cell centers - - - - red - 255 - 0 - 0 - burst cone - - - - blue - 0 - 0 - 255 - default component intersection - - - - lt blue - 100 - 100 - 255 - default outside air intersection - - - - lt green - 100 - 255 - 100 - default inside air intersection - - - - purple - 255 - 0 - 255 - default critical component intersection - - - - -
-
- - - If the user has specified a color mapping file with the color-file command, - then those colors will be used rather than the above colors for all shotline/ray intersections. - -
- - - Frame Buffer Image - - The image-file command will generate a color image that provides the - user with immediate feedback about a run. The grid is displayed graphically and each cell - location is dynamically color coded to show its current status. The following table describes - the color mapping associated with the grid: - - - Color Key for Frame Buffer Image - - - - Color - R - G - B - Representation - - - - - red - 255 - 0 - 0 - axis of grid - - - - black - 0 - 0 - 0 - grid cell boundaries - - - - blue - 0 - 0 - 255 - outside of grid - - - - lt grey - 200 - 200 - 200 - shot missed target - - - - white - 255 - 255 - 255 - shot hit target - - - - lt green - 200 - 255 - 200 - burst occurred but hit no critical components - - - - pink - 255 - 200 - 200 - burst occurred and hit some critical components - - - - purple - 255 - 0 - 255 - a ground burst occurred - - - - -
-
- - In addition to the above cell colors, hits on critical components by burst rays are - depicted as a colored pixel projected into grid space from the intersection point - where the ray enters the component. Colors for the components are mapped from ident - numbers according to the table specified by the user with the color-file - command and shaded using a lighting model illuminated from the viewing direction. - -
- - - Grid File - - The grid-file command will store each shotline coordinate generated - during the run as grid offsets. These files can later be read in to replicate a previous - run’s grid or discrete shots by using the read-2d-shot-file command. - This capability is especially useful when dithered shotlines have been used and it is - desired that the same shotlines be used in another run. Note that the shotline intersection - information is not saved, just the grid offsets for each shotline. - - - - - Script File - - During a session, all commands are saved in a temporary file. The - write-input-file command will create a snapshot of this session file, - that can later be used to recreate the current session up to the point when the file was - written. The session or input files can later be used in one of two ways: either read in - with the read-input-file command, or supplied on the standard input of - the burst program. Note that the write-input-file - and read-input-file commands will not be included in the input files, - but the commands read in by the latter will. - - - - - Error Log - - The error-file command is useful to save errors in a log file and prevent - copious ray tracer diagnostics from scrolling by on the screen. This option is especially - useful if using the batch mode of execution so that the terminal is not tied up by program - output. If no error log is specified, diagnostic messages will appear in the scrolling window - or, if in batch mode, on the burst program’s standard error output. - - - - - Histogram File - - The histogram-file command generates a frequency histogram to the named - file. The file format is simply one number per line; each number is a count of critical - components hit by an individual burst ray. This file can easily be post-processed to display - a histogram, for instance, how many rays hit zero, one, two, three, etc. components. - - - -
- - - SEE ALSO - - burst_point_library5 - burst_shotline_files5 - - - - AUTHOR - BRL-CAD Team - - - COPYRIGHT - This software is Copyright (c) 1984-2023 United States Government as - represented by the U.S. Army Research Laboratory. - - - BUG REPORTS - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - -
diff --git a/doc/docbook/system/man1/canonize.xml b/doc/docbook/system/man1/canonize.xml deleted file mode 100644 index de7d288e85b..00000000000 --- a/doc/docbook/system/man1/canonize.xml +++ /dev/null @@ -1,265 +0,0 @@ - - - - - CANONIZE - -1 -BRL-CAD -BRL-CAD - - - -canonize -queue a pix file to a printer using MDQS - - - - - canonize - -ah - -s squarefilesize - - -w filewidth - -n fileheight - - -g cgrgbscan - - -t ulm - -C numcopies - -q queue - - -R dpi - -M xmag:ymag - -m - - -X page_xoff - -Y page_yoff - - -N printheight - -W printwidth - - -v - -q queue - file.pix - - - - -DESCRIPTION -canonize -is a user agent for printing -pix5 -format files using a Canon(tm) CLC500 and the MDQS queuing system. -It can read the image from the standard input, or can send one or -more files whose names are specified on the command line. - -By default, the image is printed using the "cg" gamma map (computer graphics), -with paper from the "upper" paper tray, and the image proportionally -scaled to fill the print area on the page. - - - -OPTIONS - - - -a - -Causes -canonize -to attempt to determine the size of the image to find out the number -of bytes in the file. This option cannot be used if the image is -provided on the standard input. - - - - -h - -indicates that the input image is 1024 pixels square. - - - - -s squaresize - -sets the image width and height to the size given. - - - - -w filewidth - -sets the image width to be -filewidth -pixels. By default the image is assumed to be 512 pixels wide. - - - - -n fileheight - -sets the image height to be -fileheight -pixels. By default the image is assumed to be 512 pixels high. - - - - -g gammatype - -Select the gamma correction map to apply to the image before printing. -There are three gamma compensation maps in the CLC500. Canon -recommends the "cg" map for computer graphics images which have not -been gamma corrected. The "rgb" gamma map is said to be designed -for images which have already been gamma corrected. The "scan" -gamma map is the one used by the CLC500 when printing images -obtained from the built in scanner. - - - - -t trayname - -selects the tray from which paper should be taken to -produce the print. The options are "u" for the upper tray, "l" for -the lower tray, and "m" for manual feed. - - - - -C numcopies - -Specifies the number of prints of the image desired. -This number must be in the range 1-99. - - - - -q queuename - -queue job to MDQS queue "queuename". By default, the job is -queued to the queue "canon". - - - - -R dpi - -Print image with dpi dots-per-inch on the output page. This option disables -the automatic scaling of the image. - - - - -M xmag:ymag - -Print the image with a magnification of "xmag" in the -X dimension and "ymag" in the y dimension. - - - - -X page_xoff - -Specifies the offset of left side of the image from the left side of the -output page. -This option is available only when - -or - -have been specified, and are especially useful in conjunction with the - -option. - - - - -Y page_xoff - -Specifies the distance from the top of the page to the top of the image. -This option is available only when - -or - -have been specified, and are especially useful in conjunction with the - -option. - - - - -N - -Specifies the height of the image on the output page. -This option is available only when - -AutoScaling (on by default). -The image is scaled equally in the X and Y dimensions to make it fit the -available print area as closely as possible. - -or - -have been specified, and are especially useful in conjunction with the - -option. - - - - -W - -Specifies the width of the image on the output page. -This option is available only when - -or - -have been specified, and are especially useful in conjunction with the - -option. - - - - -m - -causes the image to be repeated across the page. - - - - -v - -Turn on debugging output. - - - - - -Notes -The Canon CLC500(tm) prints at 400dpi on the output page. This results -in approximately 2550 by 3300 pixels on an 8.5 inch by 11 inch page. Images of -less than 1024 by 1024 pixels do not look especially pleasing when printed -using AutoScaling. This is because the pixels become enlarged enough to be -annoying. - -Because high resolution images occupy a substantial amount of disk space, it -is relatively easy to run the MDQS queue server out of disk space by queuing -many images at once. - - - -SEE ALSO -pix-fb1, pix-ipu1, IPU Programmer's Manual - - -DIAGNOSTICS -If the - -option is specified when the image is being redirected from the standard input, -canonize -will abort. -This avoids wasting paper (printing an image using incorrect dimensions). - - -AUTHOR -Lee A. Butler - - - -COPYRIGHT -This software is Copyright (c) 1992-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/db.xml b/doc/docbook/system/man1/db.xml deleted file mode 100644 index 8bb6b4bd0dd..00000000000 --- a/doc/docbook/system/man1/db.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - DB - - 1 - BRL-CAD - BRL-CAD User Commands - - - - db - - Provides an interface to a number of database manipulation - routines. - - - - - - - db - command - arguments - - - - DESCRIPTION - - - Provides an interface to a number of database manipulation - routines. Note that this command always operates in units of millimeters. The - command must be one of the following with appropriate arguments: - - - - - match - - - Returns a list of all objects in that database that match the list of regular - expressions. - - - - - - get shape_or_path - - - Returns information about the primitive shape at the end of the shape_or_path. - If a path is specified, the transformation matrices encountered along that path will - be accumulated and applied to the leaf shape before displaying the information. If - no attribute is specified, all the details about the shape are returned. - If a specific attribute is listed, then only that information is returned. - - - - - - put shape_name shape_type attributes - - - Creates shape named shape_name of type shape_type - with attributes as listed in attributes. The arguments to the - put command are the same as those returned by the get - command. - - - - - - adjust shape_name attribute new_value1 - - - Modifies the shape named shape_name by adjusting the value of its - attribute to the new_values. - - - - - - form object_type - - - Displays the format used to display objects of type object_type. - - - - - - tops - - Returns all top-level objects. - - - - - close - - Closes the previously opened database and deletes the associated command. - - - - - - EXAMPLES - - - The following examples show the uses of the db command to list various - objects and attributes from the database, as well as to create new TGC shapes, adjust a vertex attribute, - and display command formats. - - List all objects in the database that end with ".s" - - mged> db match *.s - Gets a list of all objects in the database that end with ".s". - - - List all attributes and their values for <emphasis>cone.s</emphasis> - - mged> db get cone.s - - Gets a list of all the attributes and their values for shape cone.s. - - - - Get the value of the vertex attribute of <emphasis>cone.s</emphasis> - - mged> db get cone.s V - - Gets the value of the V (vertex) attribute of shape cone.s - - - - Create a new TGC shape named <emphasis>new_cone.s</emphasis> with specified attributes. - - mged> db put new_cone.s tgc V {0 0 0} H {0 0 1} A {1 0 0} B {0 1 0} C {5 0 0} D {0 5 0} - - Creates a new TGC shape named new_cone.s with the specified attributes. - - - - Adjust the vertex attribute of <emphasis>new_cone.s</emphasis> to a given value. - - mged> db adjust new_cone.s V {0 0 10} - - Adjusts the V (vertex) attribute of new_cone.s - to the value {0 0 10}. - - - - Display the format used by the <command>get</command> and <command>put</command> commands - for the TGC shape type. - - mged> db form tgc - - Displays the format used by the get and put commands - for the TGC shape type. - - - - - AUTHOR - BRL-CAD Team - - - COPYRIGHT - This software is Copyright (c) 1984-2023 United States Government as - represented by the U.S. Army Research Laboratory. - - - BUG REPORTS - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - diff --git a/doc/docbook/system/man1/fbed.xml b/doc/docbook/system/man1/fbed.xml deleted file mode 100644 index 327d9d168b9..00000000000 --- a/doc/docbook/system/man1/fbed.xml +++ /dev/null @@ -1,683 +0,0 @@ - - - - - FBED - -1 -BRL-CAD -BRL-CAD - - - -fbed -frame buffer editor - - - - - fbed - -pH - - - - -DESCRIPTION -fbed -is an editor for frame buffer images, designed to facilitate the -manipulation of existing images for the preparation of presentation quality -graphics. Although it does have the potential to generate fairly complex -images, it is meant mainly for touching up existing images; adding titles, -captions or other labels; cutting and pasting of one or more images; and -reducing images or portions thereof. -fbed -uses the frame buffer library -libfb3 -and therefore is available on all graphics devices which are supported -by this package. On start up, the program always attempts to open the -default frame buffer. This device is specified by the frame buffer library, -and is configurable on a per system basis. Often the user will want to -override this default by setting the environment variable -FB_FILE -(see -brlcad1). -The - -option is for editing -1024x1024 or high resolution -(HIRES) -images; the default is low resolution, 512x512 -(LORES). -The frame buffer's state can be toggled back and forth between -HIRES -and -LORES -at any time during execution of the program. - - -The option turns on the "pad" flag. - - -fbed -allows function-to-key bindings and macro definition facilities -in a fashion similar to some of the more versatile EMACS-style -screen editors, such as -jove1. - - -Cursor Movement - -When -fbed -is running on a graphics device, a cursor will appear on the screen. -The position of the cursor points to the -current pixel. - - -Terminal Display - -When run interactively, -with the standard input attached to a terminal, -the screen will be divided into 5 areas: -the top line will be referred to as the -option line; -the second line from the top will be called the -header line; -the bottom line of the screen will be the -status line; -the second line from the bottom will by the -prompt line; -and the rest of the screen is devoted to scrolling text output. -The -option line -contains the current -pixel -color and -paint -color, -stride -and -brush size. -Colors are expressed as a combination -of red, green, and blue intensity values; ranging from 0 to 255. The -pixel -color refers to the -current pixel -which is pointed to by the -cursor on the graphics device. -paint -color is used by functions that -require a color rather than prompting for it every time. -The -stride -indicates how many pixels the cursor will move per keystroke -during key-activated cursor movement. Finally, -brush size -refers to -the size of the square of pixels filled in by the -put-pixel -command. -The -header line -is displayed in reversed video, -and contains the program name and version number as well as the current -cursor position. -The -prompt line -is where the user will see prompts when the program requires -information. -The -status line -is used to print messages, -indicating to the user that an operation is on-going. - - -Modes of Input - -The user interface consists of a list of provided commands, referred to as -functions; -and user-defined commands, called -macros. -In general, every key-stroke will immediately be processed (this is often -popularly called -raw -mode input) and therefore, virtually every -function or macro is executed by striking a particular key, -without having to enter it by hitting -RETURN. -The key that activates a particular function or macro is said to be -bound -to that operation. - -Many of the functions will require the user to type some additional -information or -arguments, -and a prompt will appear in the lower left corner of the screen. -When responding to such prompts, -the style of input resembles that of Bourne and C Shell derivatives -with in-line EMACS-style editing. -This means that the following -control -keys have special meaning: - - - - - - - - key - editing function - - - ^A - cursor to beginning of line - - - ^B - cursor back one character - - - ^D - delete character under cursor - - - ^E - cursor to end of line - - - ^F - cursor forward one character - - - ^G - abort this function - - - ^K - erase from cursor to end of line - - - ^P - fetch last input typed to this prompt - - - ^U - erase from start of line to cursor - - - ^R - redraw line as it currently exists - - - ^V - escape special meaning of next character typed - - - Back Space - move cursor backward one character - - - Delete - delete character behind cursor - - - - - - - -When attempting to fetch the last input typed, -the user should keep in mind that this is specific to the particular -function which is doing the prompting and to that particular question -being asked by that function. -Most of the prompts are intended to appear self-explanatory, -but there are a couple of exceptions. -The -execute-function-or-macro -function places the user in the prompted mode of input -for the purpose of typing the name of the command. -This is useful when the key binding is not known off-hand or a key -binding does not exist, -but the name of the command is known (or can be guessed at). -In any case, -it is an alternative to key-activated execution of a function or macro. -When entering the prompted mode of command input, -a `:' will appear in the bottom left of the terminal screen and the -terminal's cursor will appear just ahead of it. -Now, -all of the above control key functions are in force, -and command-completion is implemented as well. -At any time while typing the name of the function or macro, -the space bar may be hit to attempt command-completion. -The command-completion logic will look at what has been typed, -and if it represents the beginning of an existing function or macro, -the remainder of that name which can be uniquely matched will appear. -If there is no match, -the portion of the name that has been typed that does not match -will be deleted, -starting at the end and working back. -In other words, -the user only needs to type the unambiguous root of the name. -If the user has done so, -hitting the space bar will show the complete name, -or hitting the -RETURN -key will -enter the command. -If the -RETURN -key is struck, -and there is no unique match, -nothing will happen. -Whenever the user is prompted for the name of a function or macro, -and there are other functions that prompt for this specifically, -then command-completion is provided. -Another atypical prompt is generated by the -argument-count -function, -and looks like -M-. -The cursor will appear right after the hyphen, -and the user is expected to type a number (sequence of digits). -This sequence of digits must be terminated by a command key-stroke. -This number represents an count of how many times to execute the command -bound to that final key-stroke. -If a digit is bound to a function or macro, -it will not be recognized by the -argument-count -function. - - - -User-defined Macros and Key Bindings - -The user may define a macro as a series of key-strokes. -This is initiated by executing the -start-macro-definition -function. -The message "Remembering..." will appear on the -status line, -and the user then types the key-strokes which will represent -the macro definition. -These key-strokes will be executed as the macro is defined. -To end the macro definition, -the user executes the -stop-macro-definition -function. -Sometimes, -the user will want to defer specifying the answers to prompts -when defining a macro, so that he can supply the information when the -macro is executed. -In order to incorporate this into his macro, -the user would type a '@' at the prompt. -This will cause the function to fail while the user is defining the macro, -but this will hopefully not cause any fatal side-effects. -Immediately after defining the macro, -or before defining another, -the user should enable its execution by giving it a name with the -name-keyboard-macro -function. -If the user desires, -he may bind it to a key with the -bind-macro-to-key -function, -or it may be executed by name only. - -Another way of customizing the frame buffer editor is to change the binding -of keys to functions. -This is done by executing either -bind-key-to-name -or -bind-key-to-key. -The former will bind a key to either a function or macro by specifying its name, -and the latter refers to the function or macro by a key that is currently -bound to it. - -Both key bindings and macro definitions can be saved in a file using -write-macros-to-file -and read back with -read-macros-from-file. -Whenever the frame buffer editor starts up, -it looks for a file called -.fbed_macros -in the user's home directory, -and reads it if it exists. -A list of functions and macros and their key bindings can be obtained by -executing the -print-bindings -function which is bound to `?' by default. -Here is the standard listing: - - - - - - - - key - function - - - - - ^H - move-window-left - - - ^J - move-window-down - - - ^K - move-window-up - - - ^L - move-window-right - - - Return - reset-view - - - ^R - redraw-tty-screen - - - ^X - execute-function-or-macro - - - ^Z - stop-program - - - Esc - argument-count - - - space - pick-point - - - , - decrement-brush-size - - - - < - decrement-step-size - - - > - increment-step-size - - - ? - print-bindings - - - A - start-macro-definition - - - B - bind-macro-to-key - - - C - shrink-image-by-half - - - E - clear-framebuffer-memory - - - F - flip-framebuffer-resolution - - - - - - - - - - - - - key - function - - - - - G - get-current-rectangle - - - H - jump-cursor-left - - - J - jump-cursor-down - - - K - jump-cursor-up - - - L - jump-cursor-right - - - N - name-keyboard-macro - - - P - put-saved-rectangle - - - R - read-rle-fle - - - S - write-rle-file - - - T - replace-pixel-current-rectangle - - - U - write-macros-to-file - - - V - fill-bounded-region - - - W - fill-current-rectangle - - - X - bind-key-to-key - - - Y - bind-key-to-name - - - Z - stop-macro-definition - - - a - enter-macro-definition - - - b - set-current-rectangle - - - c - window-center - - - d - draw-line - - - f - read-font - - - g - set-paint-to-current-pixel - - - h - move-cursor-left - - - i - zoom-in - - - j - move-cursor-down - - - k - move-cursor-up - - - l - move-cursor-right - - - m - set-monitor - - - n - set-tolerance-color-match - - - o - zoom-out - - - p - set-paint-from-key - - - q - quit - - - r - read-framebuffer - - - s - put-string - - - t - change-region-color - - - u - read-macros-from-file - - - v - draw-rectangle - - - w - put-pixel - - - x - set-cursor-y-pos - - - y - set-cursor-x-pos - - - - - - - - -Macros and functions which are not bound to a key will not be displayed. - - -HINTS -This program may require a little practice; -be sure to save a copy of the input files until you are confident. -If you are using the program for the first time, you should start by -listing the menu, finding the command for saving your image, and using -such command if you don't already have a copy. - - -FILES - - - /usr/lib/vfont/* - -Berkeley font files - - - - $HOME/.fbed_macros - -Startup configuration file - - - - - -SEE ALSO -fb-rle1, rle-fb1, libfb3 - - -KNOWN BUGS -This program is currently under development. - -It is known that aborting -the execution of the certain functions will at times display bogus -messages like "I seem to have lost my bindings." - -There is currently a hard limit of 10 times -BUFSIZ -(defined in -stdio.h) -for the length of the macro startup file. - - -AUTHOR -BRL-CAD Team - - -COPYRIGHT -This software is Copyright (c) 1986-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/fblabel.xml b/doc/docbook/system/man1/fblabel.xml index 63e7f70483f..37fb3ae08e2 100644 --- a/doc/docbook/system/man1/fblabel.xml +++ b/doc/docbook/system/man1/fblabel.xml @@ -101,7 +101,7 @@ to avoid having to create a font converter. SEE ALSO -brlcad1, fbed1, fbpoint1, libfb3, pix5 +brlcad1, fbpoint1, libfb3, pix5 diff --git a/doc/docbook/system/man1/fbline.xml b/doc/docbook/system/man1/fbline.xml index 57eaa6abb7e..520a0744911 100644 --- a/doc/docbook/system/man1/fbline.xml +++ b/doc/docbook/system/man1/fbline.xml @@ -89,7 +89,7 @@ options. SEE ALSO -brlcad1, fbed1, fblabel1, fbpoint1, plot3-fb1, libfb3, pix5 +brlcad1, fblabel1, fbpoint1, plot3-fb1, libfb3, pix5 diff --git a/doc/docbook/system/man1/gqa.xml b/doc/docbook/system/man1/gqa.xml index 85994485f5f..93ba6b63d8c 100644 --- a/doc/docbook/system/man1/gqa.xml +++ b/doc/docbook/system/man1/gqa.xml @@ -141,9 +141,7 @@ An example file might look like the following: - - - + @@ -152,8 +150,7 @@ - mged> mater -d import - filename + mged> mater -d import filename @@ -682,8 +679,8 @@ wheel.r from the geometry database model.g and reports the weight and volume, and checks for overlaps. - gqa model.g - wheel.r + + gqa model.g wheel.r @@ -695,8 +692,8 @@ for overlaps and report exposed air. The grid starts at 1 cm and is refined to 1 mm unless overlaps or exposed air are detected before the grid is refined to 1 mm. - gqa -g 1cm-1mm -A oe model.g hull - turret suspension + + gqa -g 1cm-1mm -A oe model.g hull turret suspension @@ -707,88 +704,75 @@ The following computes volume and weight of hull, turret, and suspension. Results are reported in cubic centimeters (cc) and ounces (oz). The grid spacing starts at 5 in. and will not be - refined below 0.3 mm spacing. gqa - -g5in-0.3mm -Avw -u ft, cc, oz test.g hull turret - suspension + refined below 0.3 mm spacing. + + gqa -g5in-0.3mm -Avw -u ft, cc, oz test.g hull turret suspension + Different Analysis Types + For an example of each independent analysis type, consider - the following: - - - %gqa -u m, m^3, kg -Ao geometry.g overlaps - - - Units: - length: m volume: m^3 weight: kg - grid spacing 50mm 199 x 199 x 199 - Summary: - list Overlaps: - /overlaps/overlap_obj.r /overlaps/closed_box.r count:32039 dist:8m @ (9050 1000 1000) - - - - - %gqa -u m, m^3, kg -Ae geometry.g exposed_air.g - - - Units: - length: m volume: m^3 weight: kg - grid spacing 50mm 199 x 199 x 199 - Summary: - list Exposed Air: - /exposed_air.g/exposed_air.r count:25921 dist:9m @ (10000 1000 1000) - - - - - %gqa -u m, m^3, kg -Ag geometry.g gap.g - - - Units: - length: m volume: m^3 weight: kg - grid spacing 50mm 199 x 199 x 199 - Summary: - list Gaps: - /gap.g/closed_box.r /gap.g/closed_box.r count:26082 dist:8m @ (9000 1000 1000) - /gap.g/adj_air2.r /gap.g/closed_box.r count:25921 dist:4m @ (1000 5000 1000) - - - - - %gqa -u m, m^3, kg -Av geometry.g closed_box.r - - - Units: - length: m volume: m^3 weight: kg - setting volume tolerance to 1 m^3 - grid spacing 50mm 199 x 199 x 199 - grid spacing 25mm 399 x 399 x 399 - grid spacing 12.5mm 799 x 799 x 799 - Summary: - closed_box.r 484.195 m^3 - Average total volume: 488.327 m^3 - - - - - %gqa -u m, m^3, kg -Aw geometry.g closed_box.r - - - Units: - length: m volume: m^3 weight: kg - setting weight tolerance to 768000 kg - grid spacing 50mm 199 x 199 x 199 - Summary: - Weight: - closed_box.r 3.6375e+06 kg - Average total weight: 3.67541e+06 kg - - - - + the following: + + +gqa -u m, m^3, kg -Ao geometry.g overlaps +Units: +length: m volume: m^3 weight: kg +grid spacing 50mm 199 x 199 x 199 +Summary: +list Overlaps: +/overlaps/overlap_obj.r /overlaps/closed_box.r count:32039 dist:8m @ (9050 1000 1000) + + + +gqa -u m, m^3, kg -Ae geometry.g exposed_air.g +Units: +length: m volume: m^3 weight: kg +grid spacing 50mm 199 x 199 x 199 +Summary: +list Exposed Air: +/exposed_air.g/exposed_air.r count:25921 dist:9m @ (10000 1000 1000) + + + +gqa -u m, m^3, kg -Ag geometry.g gap.g +Units: +length: m volume: m^3 weight: kg +grid spacing 50mm 199 x 199 x 199 +Summary: +list Gaps: +/gap.g/closed_box.r /gap.g/closed_box.r count:26082 dist:8m @ (9000 1000 1000) +/gap.g/adj_air2.r /gap.g/closed_box.r count:25921 dist:4m @ (1000 5000 1000) + + + +gqa -u m, m^3, kg -Av geometry.g closed_box.r +Units: +length: m volume: m^3 weight: kg +setting volume tolerance to 1 m^3 +grid spacing 50mm 199 x 199 x 199 +grid spacing 25mm 399 x 399 x 399 +grid spacing 12.5mm 799 x 799 x 799 +Summary: +closed_box.r 484.195 m^3 +Average total volume: 488.327 m^3 + + + +gqa -u m, m^3, kg -Aw geometry.g closed_box.r +Units: +length: m volume: m^3 weight: kg +setting weight tolerance to 768000 kg +grid spacing 50mm 199 x 199 x 199 +Summary: +Weight: +closed_box.r 3.6375e+06 kg +Average total weight: 3.67541e+06 kg + + + diff --git a/doc/docbook/system/man1/ir-X.xml b/doc/docbook/system/man1/ir-X.xml deleted file mode 100644 index c4cb2b81a7c..00000000000 --- a/doc/docbook/system/man1/ir-X.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - IR-X - -1 -BRL-CAD -BRL-CAD - - - -ir-X -reads the file created by showtherm and draws a picture on the screen, in an X-windows environment, giving an appropriate color to each pixel based on the temperature - - - - - ir-X - - - - -DESCRIPTIONS -ir-X is an interactive program that reads the information in the file -created by showtherm and then draws an image on the screen. The color -of each pixel is based on the temperature of the region that pixel -belongs to. - -ir-X is designed to be run in an X-windows environment. - - -EXAMPLE -The following is an example from an interactive session. - - - $ ir-X - Enter name of file to be read (26 char max) - veh.dis - Indicate type of color shading to use. - 0 - gray - 1 - red - 2 - black-blue-cyan-green-yellow-white - 3 - black-blue-magenta-red-yellow-white - 0 - Do you wish to create a pix file (0-no, 1-yes)? - 0 - Zeroing color info array - finished zeroing. - Setting up color scale - shades of gray - finished. - Reading file - file read. - Width: 512 - Height: 512 - Finding min & max. - Minimum: 22.590000 - Maximum: 46.830000 - Finding pixel bins - found pixel bins. - Putting color info in arrays - color info in arrays. - $ - - - - -SEE ALSO -firpass1, secpass1, shapefact1, all_sf1, showtherm1, ir-sgi1, pictx1, -pictsgi1, User's Manual for IRPREP (BRL-SP-96), Computer Programs -for Generating an Input File for PRISM and Displaying PRISM Results -(BRL report in progress) - - -AUTHOR -Susan A. Coates - - - -COPYRIGHT -This software is Copyright (c) 1994-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/irdisp.xml b/doc/docbook/system/man1/irdisp.xml deleted file mode 100644 index e14624f1eb6..00000000000 --- a/doc/docbook/system/man1/irdisp.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - IRDISP - -1 -BRL-CAD -BRL-CAD - - - -irdisp -combines the two programs showtherm and ir-sgi or ir-X - - - - - irdisp - - - - -DESCRIPTIONS -irdisp is an interactive program that -combines the two programs showtherm and ir-sgi or ir-X . Ultimately it can -read a temperature output file and display the image on the screen -without having the user call two different programs. - - -EXAMPLE -The following is an example from an interactive session. - - - $ irdisp - This takes a BRL-CAD mged model with a PRISM - temperature output file and raytraces and/or - displays it. Make your selection. - 0 - raytrace & store file - 1 - raytrace, store, & showtherm file - 2 - showtherm file - 1 - Enter .g file to be raytraced (15 char max). - test.veh.g - Enter the number of groups to be raytraced. - 1 - Enter group 0 (25 char max). - vehicle - - The program showtherm is now being run. - - Type of output file to be read 0=>PRISM, 1=>generic. - 0 - Enter name of the PRISM output file to be read (26 char max). - veh.prm - Enter the number of regions in the PRISM file, must be more - than eight (not including the background). - 18 - Enter name of region # & name file to be read (26 char max). - veh.f.rnn - Enter name of output file (26 char max). - veh.dis - Enter the elapsed time to create graphical representation of. - 4 - Number of regions (including the background): 19 - 7/19/1984 7.000000:0.000000 - Prism out file read. - Region # & name file opened. - The number of regions read from the output file and the region # & name - file was the same, 18 (does not include background in number). - Building directory. - File: test.veh.g - Database Title: test vehicle for use with irprep programs - vehicle loaded - The number of regions read from the output - file, the region # & name file, and the .g - file are all equal. The number of regions - read, including the background is 19 - Preparation started. - - Minimum & maximum X: -3001.000000 - 3714.000000 - Minimum & maximum Y: -1350.000000 - 1350.000000 - Minimum & maximum Z: 0.000000 - 2500.000000 - Center of bounding sphere: 356.500000, 0.000000, 1250.000000 - Radius of bounding sphere: 3829.551456 - Enter multiplication factor for radius. - .75 - Enter grid size. - 512 - Enter azimuth & elevation. - 35 25 - gridsize: 512 x 512 - azimuth: 35.000000 degrees - elevation: 25.000000 degrees - - Select display ('X' or 'sgi') ->sgi - - The program ir-sgi is now being run. If option - 0 or 1 was used when the name of a file is asked - for enter the name of the file that was just - stored. - - Enter name of file to be read (26 char max) - veh.dis - Indicate color scale to be used. - 0 - gray - 1 - black-blue-cyan-green-yellow-white - 2 - black-blue-magenta-red-yellow-white - 0 - Print scan line number (0-yes, 1-no)? - 1 - Do you wish to create a pix file (0-no, 1-yes)? - 0 - Setting color scale - gray scale - set. - Reading file - file read. - Width: 512 - Height: 512 - Finding min & max. - Minimum: 22.590000 - Maximum: 46.830000 - Finding pixel bins - pixel bins found. - Setting color for each pixel - colors found. - Press 'z' return to end. z - THE END - - $ - - - - -SEE ALSO -firpass1, secpass1, shapefact1, all_sf1, showtherm1, -ir-X1, -ir-sgi1, -pictx1, User's Manual for IRPREP (BRL-SP-96), Computer Programs -for Generating an Input File for PRISM and Displaying PRISM Results -(BRL report in progress) - - -AUTHOR -Susan A. Coates - - - -COPYRIGHT -This software is Copyright (c) 1994-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/morphedit.xml b/doc/docbook/system/man1/morphedit.xml deleted file mode 100644 index 7682f196a53..00000000000 --- a/doc/docbook/system/man1/morphedit.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - MORPHEDIT - -1 -BRL-CAD -BRL-CAD - - - -morphedit -set up line segment correspondences between pix(5) images - - - - - morphedit.tcl - -w width - -n height - picA.pix - picB.pix - linesfile - - - - -DESCRIPTION -morphedit -allows the user to set up line segment correspondences to be used -by the utility -pixmorph . - - -First, the program displays the two images and presents a dialog box -in which the user can enter values for -a, b, -and -p -(see -pixmorph(1) -for details on these constants). -[Note: after replacing these values, the user must press <Enter> for -the new values to be recorded.] - -The user is now editing the lines file -linesfile. -The purpose of writing a lines file is to set up correspondences between -the two images to improve the quality of morphed images produced by -utilities such as -pixmorph . -To set up a correspondence, the user must create a (directed) line segment -for each image that specifies which feature of the first image -corresponds to which feature of the second. These directed line segments -are created in the following fashion. - -To create the first endpoint of a new line segment, the user presses -the left mouse button -at the desired location in either image. The point appears at the same -location in the other image. While the mouse button is held down, the -endpoint may be dragged to any location (including off of the image...please -do not misplace endpoints in this fashion -- they are very difficult to -recover). Releasing the mouse button deposits the endpoint at that location. - -To specify the second endpoint, the user presses the left mouse button at a -location in the image currently unoccupied by endpoints. The line segment -is drawn between the first and second endpoints; and, as before, -this endpoint may be dragged to any location. - -Endpoints may be created in pairs in this fashion. Additionally, endpoints -and line segments can be selected (by pressing the left mouse button while in -the vicinity of the point or segment) and moved (by moving the mouse -while the button is held) in either image as desired. - -To display the orientation of a line segment, the user moves the mouse -cursor until it is over the line segment in question. The first endpoints -of the segments of both images appear white, and the second endpoints of the -segments of both images appear black. Specifying the wrong orientation -of a line segment usually results in a poor -- albeit somewhat -psychedelic -- morphed image, so users are encouraged to take advantage -of this feature to verify that their line segment correspondences make sense. - -The "Save" button writes the currently displayed line segment correspondence -set, along with the constants -a, -b, -and -p, -to the file -linesfile. -The "Quit" button closes all associated windows and terminates the program. - -The "Preview" button, with corresponding -fraction -entry box, spawns a process to display the morph specified by the -given fraction and the last *saved* version of -linesfile. -(Note: this currently uses the utilities -pixmorph -and -pix-fb. -If the "Preview" button fails, verify that the paths to these -utilities (specified in the first few lines of -morphedit.tcl) -are correct. - -Note: -morphedit.tcl -uses -bwish -instead of the standard Tcl/Tk -wish, -since -bwish -supports -pix -images while -wish -does not. If you have difficulty running -morphedit.tcl, -make sure the first line of -morphedit.tcl -(giving the path to -bwish) -is correct. - - -EXAMPLES - morphedit.tcl face1.pix face2.pix lf - - -SEE ALSO -brlcad1, pixmorph1, pix5 - - -BUGS -At this time, line segments cannot be deleted. -Unwanted correspondences should be recycled elsewhere. - - - -AUTHOR -BRL-CAD Team - - - -COPYRIGHT -This software is Copyright (c) 1996-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/pixcmp.xml b/doc/docbook/system/man1/pixcmp.xml deleted file mode 100644 index 9d8c24e6f4a..00000000000 --- a/doc/docbook/system/man1/pixcmp.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - - PIXCMP - -1 -BRL-CAD -BRL-CAD - - - -pixcmp -compare two pix image files pixel by pixel - - - - - pixcmp - OPTIONS - FILE1 - FILE2SKIP1SKIP2 - - - - -DESCRIPTION - -pixcmp is a program to compare two BRL-CAD -pix image files pixel by pixel (or byte by byte), optionally skipping -initial pixels (or bytes) in one or both input files. The following -OPTIONS are available: - - - - - - Use bytes instead of pixels for both processing and output. - This can be useful for comparing BW images or other data files. - With this option, the SKIP values should be - specified as bytes instead of pixels. - - - - - - Output a line per pixel (or per byte if using the - option) where the values are the same. Each - line includes the pixel (or byte) number counting from 1, the - respective input values, and a label. - - - - - - Output a line per pixel (or per byte if using the - option) where the values are different. Each - line includes the pixel (or byte) number counting from 1, the - respective input values, and a label. - - - - - - Be more quiet, suppressing additional printing typically - sent to standard error. With the and/or - options, respective lines will still be - printed to standard output, but without header and summary - information getting sent to standard error. - This option has no affect on error printing that can result - during abnormal exit of pixcmp. - - - - SKIP - - Skip the first SKIP pixels (or bytes if using the option) of input for FILE1 and FILE2. - - - - SKIP1:SKIP2 - - Skip the first SKIP1 pixels (or bytes if using the - option) of FILE1 and first SKIP2 pixels in - FILE2. - - - - -SKIP1 and SKIP2 are the number of pixels (or bytes if using the - option) to skip in each file. - -If FILE is `-` or missing, -pixcmp reads from the standard input. If FILE1 and -FILE2 are both standard input, then values must be interleaved (e.g., -r1r2g1g2b1b2r1r2g1g2b1b2...etc... for r1g1b1 and r2g2b2 from two -separate input streams). - - -RETURN VALUES -The pixcmp utility returns -0 if there are no differences, 1 -if there are only off-by-one differences, 2 if -there are off-by-many errors, 126 if there are file -processing problems, and 127 if there are argument -processing or usage errors. - - -EXAMPLES - - - pixcmp -d file1 file2 - - - The two files are compared pixel by pixel with each - difference printed instead of just the summary. - - - - - pixdiff file1.pix file2.pix | pixcmp - file3.pix - - - The pixdiff tool compares the - pixels in file1.pix with those in file2.pix and then outputs a - resulting `diff` image which is then processed by - pixcmp as input and compared against file3.pix, - reporting on the differences. - - - - - echo -n "aabcddeg" | pixcmp -b -s -d - - - - - Here, pixcmp reads interleaved data from the system - echo command (-n avoids a trailing newline) - provided via standard input. For each pair of characters (i.e., - bytes), it reports their status: - - - -#Byte FILE1 FILE2 LABEL -1 97 97 MATCHING -2 98 99 OFF_BY_ONE -3 100 100 MATCHING -4 101 103 OFF_BY_MANY -pixcmp bytes: 2 matching, 1 off by 1, 1 off by many - - - - - - - - -SEE ALSO -brlcad1, pixdiff1, pix5, bw5 - - - -AUTHOR -BRL-CAD Team - - -COPYRIGHT -This software is Copyright (c) 2007-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/pp-fb.xml b/doc/docbook/system/man1/pp-fb.xml deleted file mode 100644 index e37a7290f3e..00000000000 --- a/doc/docbook/system/man1/pp-fb.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - PP-FB - -1 -BRL-CAD -BRL-CAD - - - -pp-fb -display a GIFT pretty-picture file on a frame buffer - - - - - pp-fb - -F framebuffer - -W out_width - -N out_height - file.pp - - - - -DESCRIPTION -pp-fb -reads -file.pp, -determines the size, -and displays a color shaded image represented therein -on a frame buffer. -The -.pp -files are the output of the pretty-picture option of the -gift1V -ray-tracing program. -The options are standard -brlcad1 -options specifying framebuffer, output width, and output height. -Some information pertaining to the color assignment of region identification -numbers and the background color is prompted for on the standard input. -The environment -variable -FB_FILE -is used to select the display device (see -brlcad1). -If this variable is not set, the default device for your system will -be used. -Commands for manipulating the display are documented on-line. -The file format is not documented anywhere. - - -SEE ALSO -gift1V, brlcad1 - - - -AUTHOR -BRL-CAD Team - - - -COPYRIGHT -This software is Copyright (c) 1986-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - diff --git a/doc/docbook/system/man1/proe-g.xml b/doc/docbook/system/man1/proe-g.xml deleted file mode 100644 index 9a93e4e7cef..00000000000 --- a/doc/docbook/system/man1/proe-g.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - PROE-G - -1 -BRL-CAD -BRL-CAD -User Commands - - - -proe-g -Pro/Engineer Translator (Pro/Engineer to BRL-CAD) - - - - - proe-g - -darS - -i initial_ident - -I constant_ident - -m material_code - -u reg_exp - -x RT_DEBUG_FLAG - file.brl - file.g - - - - -DESCRIPTION -proe-g -converts the specified -file.brl -to a BRL-CAD -file.g -file. -The - -option prints debugging information. -The - -option implies that all the parts in the Pro/E model should be converted to -BRL-CAD -air -regions. -The - -option sets the starting ident number for the regions created. As each -new region is created, this number will be incremented before assigning -the next ident number (conflicts with - -). The - -option sets a constant ident number that will be assigned to all the regions created (conflicts with - -). -The - -option sets a material code that will be assigned to all the regions created (default is 1). -The - -flag indicates that the model should not be rotated, translated, or scaled, but left in -the same orientation and size as it was created in -Pro/E. -This allows the user to convert parts that are referenced by previously converted -assemblies, so that the transformation matrix in the referencing assembly will -size and position the part. -The - -option sets an RT debug flags (see raytrace.h). -The -file.brl -file is expected to be output from the -BRL-CAD -menu option of the Pro/Engineer -EXPORT -menu. This menu option is a Pro/Develop application produced by the USARL. - -Note that the routine documented here is obsolete, and only maintained for compatibility with -older versions of Pro/Engineer. The current method of converting from Pro/Engineer to BRL-CAD -is still a two step process, but a newer Pro/Toolkit application must be installed (see “install.doc” -in the “pro-engineer” directory of the BRL-CAD distribution). From within Pro/Engineer, the “proe-brl” -option must be selected from the “File” menu, and the user will be prompted for an output file name, -a starting ident number, a maximum tessellation error, and an additional curvature correction. -The output from this new routine, is a Tcl script that may be converted to a BRL-CAD model using “asc2g” -or by sourcing the file during an MGED session. - - -EXAMPLE - -$ proe-g sample.brl sample.g - - - -SEE ALSO -Pro/Engineer Modeling User's Guide, -Version 13.0, -Parametric Technology Corporation - - -DIAGNOSTICS -Error messages are intended to be self-explanatory. - - - -AUTHOR -BRL-CAD Team - - - -COPYRIGHT -This software is Copyright (c) 1994-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man1/rtwizard.xml b/doc/docbook/system/man1/rtwizard.xml index c26f8ecd9ae..14344ca3e42 100644 --- a/doc/docbook/system/man1/rtwizard.xml +++ b/doc/docbook/system/man1/rtwizard.xml @@ -1,7 +1,7 @@ - RTWIZARD - + RTWIZARD + 1 BRL-CAD BRL-CAD User Commands @@ -20,451 +20,528 @@ - DESCRIPTION + + DESCRIPTION - rtwizard is a tool that automates the use of several - BRL-CAD graphical programs to produce complex images. There are two primary modes of operation - - a graphical client to guide users through the process of creating images, and - a command line mode to allow users who already know what options they wish to - use to quickly and automatically produce images. Graphical - mode is used when insufficient information is supplied to produce an image (unless - an option specifically ruling out graphical mode is passed) and command line mode - (used automatically when there is enough information - to produce an image, unless GUI mode is specifically requested.) - When in graphical mode, rtwizard is self explanatory. This manual documents the command - line options available when not operating in - graphical mode. + RtWizard is a tool that + orchestrates several BRL-CAD utilities to produce complex images + of geometry in prescribed styles. There are two primary modes + of operation. - Images produced by rtwizard use three primary elements - - standard full color raytracings produced by rt, "line drawing" style - images produced by rtedge, and a faded greyscale version of color - raytracings produced with a variety of image manipulation tools included with BRL-CAD. + The first mode of operation is a graphical client to guide users + through the process of creating images interactively. To invoke + that mode, simply run rtwizard and a + wizard-style GUI should appear. Graphical mode has integrated + documentation and workflows, and is intended to be discoverable + and self-explanatory. - When specifying options on the command line, it is usually better practice to fully qualify what a particular item is - for example, - using to specifically identify the input file instead of relying on the .g suffix. There is a limited ability to recognize - common usage patterns (for example, "rtwizard file.g output_image.png geometry_object" will - generate an image of geometry_object in the file output_image.png) but the most unambigous specification uses the options. + The second mode of operation is a command line mode to allow + users who already know what options they wish to use to quickly + and automatically produce images. It is also useful for + programmatic scripting and bulk rendering of images. + - The following options are recognized. + RtWizard generates and composites + images in a variety of styles including full-color images, edge + line drawings, and "ghosted" images with options for + highlighting and emphasizing model features and subsets of + models. Color ray tracings are produced by + rt, "hidden-line drawings" produced by + rtedge, and semi-transparent / faded + greyscale "ghosted" ray tracings are produced with + rt and a variety of image manipulation tools + included with BRL-CAD. GUI-mode presents workflows for setting + up each image type, and command-line mode provides the + , described below. - Input/Output Options - - geometry_file.g - - - The first argument without an option flag (the leftmost argument is regarded as the first) that - identifies an existing file with a .g suffix will be used to specify the working geometry database, - unless overridden by the option. Remember that some option flags accept multiple - arguments and can create ambiguities about the meaning of a .g option and in such situations - should be used. - - - - - geometry_file - geometry_file - - - Specifying the geometry database containing the objects to be raytraced. The option - will override a non-flagged geometry file specification. - - - + + + The following command-line options are recognized by + rtwizard: + + + Input/Output Options + - output_file.imgformat - - - The name and image format of the final output image generated by rtwizard. When specifying the - output file name without using a flag, a .pix or .png image format extension is necessary. The first - valid, unflagged output file name will be used unless overridden by the . If the - output filename uses a .png image format extension, the Portable Network Graphics image format - will be used when writing out the file. Otherwise, a standard BRL-CAD pix image will be generated. - Remember that some option flags accept multiple - arguments and can create ambiguities about the meaning of a image name option and in such situations - should be used. - - + geometry_file + geometry_file + + + Specifying the geometry database containing the objects to + be raytraced. The option will override + a non-flagged geometry file specification. + + - output_file[.imgformat] - output_file[.imgformat] - - - The name (and optionally the image format) of the final output image generated by rtwizard. If the - output filename uses a .png file extension, the Portable Network Graphics image format - will be used when writing out the file. Otherwise, a standard BRL-CAD pix image will be generated. - - + output_file[.imgformat] + output_file[.imgformat] + + + The name (and optionally the output image format) of the + final image generated by rtwizard. If the output filename + uses a .png file extension, the Portable Network Graphics + image format will be used when writing out the file. + Otherwise, a standard BRL-CAD pix image will be generated. + + - framebuffer_device - framebuffer_device - - - The type of framebuffer to use when running fbserv to establish a framebuffer. By default, - "/dev/mem" is used for a non-graphical framebuffer - other options include /dev/X, /dev/ogl, - and (Windows only) /dev/wgl. A /dev/mem framebuffer created by rtwizard - will be closed after the image generation is complete. - - + framebuffer_device + framebuffer_device + + + Under the hood, fbserv is run to assist + with processing. The option specifies + the type of framebuffer fbserv should + use in lieu of the default memory-only interface + (/dev/mem). See fbhelp for a listing + of available device options. Framebuffer servers started + by rtwizard are automatically closed + after image generation is complete. + + - port_number - port_number - - - The number of the framebuffer port to use when running fbserv to establish a framebuffer. An - existing framebuffer may also be specified and used. In the case of a pre-existing non-graphical framebuffer, - rtwizard will not close the framebuffer automatically after the raytracing process is complete. - - + port_number + port_number + + + The option specifies the framebuffer + port number to use when running fbserv + to establish a framebuffer. An existing framebuffer + server port be specified. In the case of a pre-existing + framebuffer servers, rtwizard will not + close the framebuffer automatically after the raytracing + process is complete. + + - - - - Run rtwizard's graphical interface, even if the command line options specify enough information - to produce an image. - - + + + + Run rtwizard's graphical interface, even if the command + line options specify enough information to produce an + image. + + - - - - Run rtwizard on the command line, even if the command line options do not specify enough - information to produce an image. Overridden by --gui option if both are specified. - - + + + + Run rtwizard on the command line, even if the command line + options do not specify enough information to produce an + image. Overridden by --gui option if both are specified. + + - Model View Options - - When it comes to preparing the view for an RtWizard image, there are two options. One - is to use the "user level" controls, which reflect the view manipulations used by users - on the command line. The other is to use the "low level" specifiers, which are more - typically used when rtwizard is run by automated scripts. The two - methods are mutually exclusive. - + + Model View Options + + When it comes to preparing the view for an RtWizard image, there are two options. + One is to use the "user level" controls, which reflect the + view manipulations used by users on the command line. The + other is to use "low level" specifiers, which are more + typically used when rtwizard is run by + automated scripts. The two methods are mutually exclusive. + - angle (degrees) - angle (degrees) - - Set azimuth angle. - + angle + angle) + + Set azimuth angle (in degrees). + - angle (degrees) - angle (degrees) - - - Set elevation angle. - - + angle + angle + + + Set elevation angle (in degrees). + + - angle (degrees) - - - Set twist angle. - - + angle + + + Set twist angle (in degrees). + + - angle (degrees) - angle (degrees) - - - Set the perspective angle. - - + angle + angle + + + Set the perspective angle (in degrees). + + - value - value - - - Set the zoom factor (smaller factor results in a smaller object in the view, and vice versa). - - + value + value + + + Set the zoom factor, specified as a multiplier on the + default view size. Values less than one result in a + smaller object in the view. Values greater than one + result in larger objects (due to the view being zoomed). + + - - X Y Z - - - Set the xyz coordinates of the center of the view. - - + + X Y Z + + + Set the xyz coordinates of the center of the view. + + - Image Generation Options - - The three options that are used to input geometry object lists need to parse - multiple arguments, so any options immediately following either of them need to use - an explicit argument flag to signal termination of the input list to the option - parser - for example, an input .g file needs to be specified with - the if it comes after a list of ghost objects. - + + Image Generation Options - obj1[,...] - obj1[,...] - - - Specify objects to render using full color using a comma separated list. - - + obj1[,...] + obj1[,...] + + + Specify objects to render using full color using a + comma-separated list. The entire list may be enclosed in + double-quotes if object names have spaces (e.g., -c + "obj1,obj 2"). + + - value - value - - - Set the background color to use when raytracing full color objects. May use R/G/B or hex style color specification. - - + value + value + + + Set the background color to use when raytracing full color + objects. May use R/G/B or hex style color specification. + + - obj1[,...] - obj1[,...] - - - Specify objects to be rendered using ghosting using a comma separated list. - - + obj1[,...] + obj1[,...] + + + Specify objects to be rendered using ghosting using a + comma-separated list. The entire list may be enclosed in + double-quotes if object names have spaces (e.g., -g + "obj1,obj 2"). + + - value - value - - - Control the degree of visibility to use when rendering ghost objects. - - + value + value + + + Control the degree of visibility to use when rendering + ghost objects. + + - obj1[,...] - obj1[,...] - - - Specify objects to render lines with using rtedge using a comma separated list. - - + obj1[,...] + obj1[,...] + + + Specify objects to render edge lines for using a + comma-separated list. The entire list may be enclosed in + double-quotes if object names have spaces (e.g., -l + "obj1,obj 2"). + + - value - - - Specify color to use when rendering edge lines. In addition to R/G/B and hex color specifications, the keyword "region" is also supported - in the latter case, region colors will be used for lines. - - + value + + + Specify color to use when rendering edge lines. In + addition to R/G/B and hex color specifications, the + keyword "region" is also supported - in the latter case, + region colors will be used for lines. + + - value - - - Specify color rtedge will use for non-line rendering. - - + value + + + Specify the color to use for non-line rendering. + + - value - value - - - Specify the height of the generated image in pixels. - - + + value + value + + + Specify the height of the generated image in pixels. + + - value - value - - - Specify the occlusion mode rtedge will use for line rendering. - - + value + value + + + Specify the occlusion mode to use for line rendering. See + rtedge manual page for value options. + + - value - value - - - Specify the width and height of the generated image in pixels. Width can be overridden by the option and height by the option. - - + value + value + + + Specify the width and height of the generated image in + pixels. Width can be overridden by the + option and height by the option. + + - image_type - image_type - - - Specify the type of image to be rendered. The images produces by rtwizard - are categorized by picture type - there are six picture types - built on full color raytracing, ghosting, and rtedge line renderings. - If a type is specified and insufficient information is supplied to generate that particular - image type, rtwizard will exit with an error. - - RtWizard Image Types - - - - - Type - Name - Description - - - - - A - Simple Full-Color Image - Standard rt image. - - - B - Simple Line Drawing - Standard rtedge image. - - - C - Highlighted Image - Full Color rt image enhanced with rtedge lines. - - - D - Mixed Full Color and Edges - Like Type C, except objects may be selectively enhanced with rtedge lines. - - - E - Ghost Image with Inserts - A combination of Full Color elements and faded greyscale raytracings for context. - - - F - Ghost Image with Inserts and Edges - A Type E image further enhanced with rtedge lines. - - - - -
-
-
+ image_type + image_type + + + Specify the type of image to be rendered. The images + produced by rtwizard are categorized by + picture type. There are + six picture types built on full color raytracing, + ghosting, and edge line renderings. + + + NOTE: If a type is specified and insufficient information + is supplied to generate that particular image type, + rtwizard will exit with an error. + + + + + RtWizard Image Types + + + + + Type + Name + Description + + + + + A + Simple Full-Color Image + Standard rt + image. + + + B + Simple Line Drawing + Standard rtedge + image. + + + C + Highlighted Image + Full Color rt image + enhanced with rtedge + lines. + + + D + Mixed Full Color and Edges + Like Type C, except objects may be + selectively enhanced with + rtedge lines. + + + E + Ghost Image with Inserts + A combination of Full Color elements and + faded greyscale raytracings for context. + + + F + Ghost Image with Inserts and Edges + A Type E image further enhanced with + rtedge lines. + + + +
+
+
- value - value - - - Specify the width of the generated image in pixels. - - + value + value + + + Specify the width of the generated image in pixels. + + +
+ + + Compatibility Options + + geometry_file.g + + + For usage compatibility with rt and + other tools, the first (leftmost) argument without an + option flag that identifies an existing .g file is assumed + to be the input geometry database. Note, some argument + configurations can result in ambiguity (e.g., objects with + a .g suffix). As such, The is + preferred for specifying the input geometry database. + + + + + output_image.{pix|png} + + + This specifies the file name and image format of the + resulting image to be output by rtwizard. When specifying + the output file name without using a flag, a .pix or .png + image format extension is necessary. The first valid, + unflagged output file name will be used unless overridden + by the . Note that some option flags + accept multiple arguments and can create ambiguity. In + such situations should be used. + + +
- EXAMPLES + + EXAMPLES Introduction - Basic Color Image + + Simple Full-Color Image - rtwizard m35.g component + rtwizard -i m35.g -c component -o m35.png - Results in a default color image of the m35 truck, output to rtwizard.pix + Results in a default color image of the m35 truck object named + 'component' with output saved to m35.png - Line Drawing Image + + Simple Line Drawing Image - rtwizard -d /dev/ogl m35.g -l component + rtwizard -d /dev/wgl -i m35.g -l component - Results in a line drawing of the m35 truck being display in an OpenGL framebuffer + Results in a line drawing of the m35 truck being display in a + Windows-specific OpenGL window instead of saving to a file. - Complex Image + + Ghost Image with Inserts and Edges - rtwizard -d /dev/ogl -i m35.g -c component/power.train -g component -l component + rtwizard -i m35.g -c component/power.train -g component -l component - Results in a view of the m35 truck highlighting the engine (in color) with the truck being shown as a ghosted, edged background. + Results in a view of the m35 truck highlighting the engine (in + color) with the truck being shown as a ghosted, edged + background, with output saved to a default rtwizard.pix file. - Complex Image with Non-Default View + + Complex Image with Non-Default View - rtwizard -d /dev/ogl -i m35.g -c component/power.train -g component -l component -a -35 -e 15 -z 1.6 + rtwizard -i m35.g -c component/power.train -g component -l component -a -35 -e 15 -z 1.6 - Same as the previous image, except viewing the truck from a different direction and zoomed in closer. + Same as the previous image, except viewing the truck from a + different direction and zoomed in closer, with output saved to + a default rtwizard.pix file. - Multiple Color Objects + + Multiple Color Objects - rtwizard -d /dev/ogl -i m35.g -c component/power.train,component/suspension -z 1.6 + rtwizard -d /dev/ogl -i m35.g -c component/power.train,component/suspension -z 1.6 - View the power train and suspension of the truck as color objects. + View the power train and suspension of the truck as color + objects in a Mac-/Linux-specific OpenGL window. - SEE ALSO + + SEE ALSO - rt1, rtedge1 + rt1,rtedge1,fbhelp1,fbserv1 - COPYRIGHT + + COPYRIGHT - This software is Copyright (c) 2001-2023 United States Government as - represented by the U.S. Army Research Laboratory. + This software is Copyright (c) 2001-2023 United States + Government as represented by the U.S. Army Research + Laboratory. - AUTHOR - BRL-CAD Team - - - BUGS - - Most deficiencies observed while using the rtwizard - program are a consequence of problems in commands used by rtwizard to generate - images, such as rtedge. + + AUTHOR + BRL-CAD Team - BUG REPORTS + + BUG REPORTS - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org + Reports of bugs or problems should be submitted via + electronic mail to devs@brlcad.org
diff --git a/doc/docbook/system/man3/CMakeLists.txt b/doc/docbook/system/man3/CMakeLists.txt index a0f67159cda..2978549b2b4 100644 --- a/doc/docbook/system/man3/CMakeLists.txt +++ b/doc/docbook/system/man3/CMakeLists.txt @@ -1,6 +1,5 @@ set(man3_EN - libfb.xml - libplot3.xml + libbv.xml libpkg.xml librt.xml libwdb.xml diff --git a/doc/docbook/system/man3/libbv.xml b/doc/docbook/system/man3/libbv.xml new file mode 100644 index 00000000000..af9f7b5e98b --- /dev/null +++ b/doc/docbook/system/man3/libbv.xml @@ -0,0 +1,292 @@ + + + + + LIBBV + +3 +BRL-CAD +BRL-CAD + + + +libbv +BRL-CAD view graphics interface subroutines + + + + + + +void pl_3box + FILE *fp + int x0 + int y0 + int z0 + int x1 + int y1 + int z1 + + + +void pl_3cont + FILE *fp + int x + int y + int z + + + +void pl_3line + FILE *fp + int x0 + int y0 + int z0 + int x1 + int y1 + int z1 + + + +void pl_3move + FILE *fp + int x + int y + int z + + + +void pl_3point + FILE *fp + int x + int y + int z + + + +void pl_3space + FILE *fp + int x0 + int y0 + int z0 + int x1 + int y1 + int z1 + + + +void pl_arc + FILE *fp + int xc + int yc + int x0 + int y0 + int x1 + int y1 + + + +void pl_box + FILE *fp + int x0 + int y0 + int x1 + int y1 + + + +pl_circle + FILE *fp + int x + int y + int r + + + +void pl_color + FILE *fp + int r + int g + int b + + + +void pl_cont + FILE *fp + int x + int y + + + +void pl_erase + FILE *fp + + + +void pl_label + FILE *fp + const char *s + + + +void pl_line + FILE *fp + int x0 + int y0 + int x1 + int y1 + + + +void pl_linmod + FILE *fp + const char *s + + + +void pl_move + FILE *fp + int x + int y + + + +void pl_point + FILE *fp + int x + int y + + + +void pl_space + FILE *fp + int x0 + int y0 + int x1 + int y1 + + + + + + + +DESCRIPTION +These subroutines +generate +graphic output commands for processing +with the +plot(1) +plotting filters. +They are slightly more general than those in +libplot +as these take a file pointer. They also include +the BRL 3-D extensions to the plot intermediate code. + +Pl_space +or +pl_3space +must be used before any of the graphic primitives to declare the +amount of space necessary. +See +plot3(5). + +Pl_box +or +pl_3box +draws a box between the two given opposite points. +The ''pen'' will be left at the second point. + +Pl_circle +draws a circle of radius +r +with center at the point +(x, +y). +Note that +circle +and +arc +cannot be transformed in three space if one is using a +filter to do that. + +Pl_arc +draws an arc of a circle with center at the point +(x, +y) +between the points +(x0, +y0) +and +(x1, +y1). + +String arguments to +pl_label +and +pl_linmod +are terminated by nulls and do not contain new-lines. + +There are also 2-D and 3_D double-precision versions, with arguments +identical to their counterparts above. The naming conventions are to +change the prefix to "pd"; examples are thus +pd_point +and +pd_3point. +Vector versions for 3_D (also double-precision) are prefixed "pdv", as in +pdv_3point. + +See +plot3(5) +and +plot(5) +for a description +of the effect of the remaining functions. + + + +FILES +/usr/brlcad/lib/libbv.a produces output for +plot1G +filters + + + +WARNINGS +In order to compile a program containing these functions +in +file.c +it is necessary to use +``cc +file.c +-lplot3''. + +Color +specification and +three-dimensional primitives +are BRL extensions to the "unix plot" language +that are not generally found on other systems. + + +SEE ALSO +plot1, pl-fb1, +plot35, plot5 + + + +AUTHOR +BRL-CAD Team + + + +COPYRIGHT +This software is Copyright (c) 1989-2023 by the United States +Government as represented by U.S. Army Research Laboratory. + + +BUG REPORTS +Reports of bugs or problems should be submitted via electronic +mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/man3/libdm.xml b/doc/docbook/system/man3/libdm.xml index 9011af92858..0dafa61b03c 100644 --- a/doc/docbook/system/man3/libdm.xml +++ b/doc/docbook/system/man3/libdm.xml @@ -927,4 +927,435 @@ cwish> .d drawEnd + + + + Generic frame buffer routines + + + + + fb *fb_open + * fbfile + int fb_close ( fbp ) fb * fbp + int fb_read ( fbp , x , y , addr , count ) fb * fbp + RGBpixel *addr; + long count; + + + + int fb_write + * fbp + RGBpixel * addr + long count + int fb_rmap ( fbp , cmap ) fb * fbp + ColorMap * cmap + + + + int fb_wmap + * fbp + ColorMap * cmap + + + + int fb_clear + * fbp + RGBpixel * colorp + + + + char *fb_gettype + * fbp + + + + int fb_getwidth + * fbp + + + + int fb_getheight + * fbp + + + + + + + + Hardware specific frame buffer routines + + + + + int fb_cursor + * fbp + int fb_scursor ( fbp , mode , x , y ) fb * fbp + int fb_setcursor ( fbp , bits , xbits , ybits , xorig , yorig ) fb * fbp + unsigned char bits[] + int xbits, ybits; + int xorig, yorig; + + + + int fb_window + * fbp + int fb_zoom ( fbp , x , y ) fb * fbp + / *Buffered frame buffer I/O: */ int fb_ioinit ( fbp ) fb * fbp + + + + int fb_seek + * fbp + void fb_tell ( fbp , xp , yp ) fb * fbp + int *xp , * yp + + + + int fb_rpixel + * fbp + RGBpixel * pixelp + + + + int fb_wpixel + * fbp + RGBpixel * pixelp + + + + int fb_flush + * fbp + + + + void fb_log + format [ + arg ] ... + + + + + + + + DESCRIPTION + + + These routines are designed to provide a device-independent + method of using frame buffers or files containing frame buffer + images. The coordinate system used is first-quadrant (0..width-1, + 0..height-1), with integer addressing. Translation to hardware + coordinate systems is handled by the library. + + + This version of the library assumes that red, green, and blue + intensities are described by unsigned 8-bit bytes in the range (0..255). + The library interface uses arrays of RGBpixels, + which is a typedef for an array of three unsigned chars (this was + done to avoid structure padding). Note that a pointer to an + RGBpixel + is thus the name of the RGBpixel + itself, i.e. no ampersand is needed. + + + The exact interpretation of color maps tends to be somewhat device + specific. The three ColorMap arrays each have 256 entries of unsigned + 16-bit values. In order to accommodate color maps with differing amounts + of output resolution, the color map entries are fixed-point fractions + in the range (0.0..1.0). In integer notation, the range is (0..65525). + For devices with less than 16 bits of output from their color maps, + the left-most portion of each entry is used. + + Fb_open is used to open a frame buffer + file fbfile. The file may be either the + name of a supported frame buffer interface, referenced as "/dev/interface", + or the name of a UNIX file. The routine will try to determine if the + file opened was a real frame buffer by examining the name, and if so + will perform whatever initialization actions are necessary. + If the value of fbfile is + NULL and the environment variable + FB_FILE is set, then the value of FB_FILE + is used; otherwise the default frame buffer device for the system is used. + See below for more details. The width + and height parameters specify the initial + size of display desired. If these are zero the default sizes for that + device will be used. On a successful open, the frame buffer I/O (fb) + structure pointer is returned. This structure contains size you were + actually given, as well as the maximum possible size for the selected + device. A return of FB_NULL indicates failure. + + Fb_close simply closes the frame buffer. + + Fb_read reads + count pixels from the frame buffer + starting at the location specified by x + and y, and places them at program + memory address specified by addr. + Fb_read returns the number of + pixels actually read, or -1 on error. + + Fb_write writes + count pixels from program address + addr into the frame buffer starting + at the location specified by x + and y. Fb_write + returns the number of pixels actually written, or -1 on error. + + Fb_rmap + reads in the color map from the frame buffer and + leaves at the location pointed to by + cmap. + + Fb_wmap + writes the color map pointed to by + cmap + into the frame buffer. If the value of + cmap + is + NULL + then a linear color map is used as the default. + + Fb_clear + erases the frame buffer by setting all pixels to the given + color. If the color pointer is NULL, black will be used. + On a UNIX file, this entails writing the entire file, + which is an expensive operation, whereas on most + frame buffer displays + this can be done in less than a second by a special command. + + Fb_gettype + returns a pointer to a string describing the frame buffer + specified by the fb pointer. + + Fb_getwidth + and Fb_getheight + returns the current size of the fb frame buffer. + + + The following routines work in conjunction with those described above + to provide functions which only apply if the frame buffer + file is actually a hardware frame buffer display. + + Fb_cursor + places the cursor at the image space coordinates given by + x + and + y. + If the mode is non-zero, the cursor is made visible, and + if mode is zero, the cursor is turned off. + + Fb_scursor + is the same as + fb_cursor + except that it + places the cursor at the + screen + space coordinates given by + x + and + y. + + Fb_setcursor + allows the user to set the bitmap used to represent the cursor, + thereby changing the cursor shape. This is not necessarily supported + by all hardware. The argument bits + is a pointer to an array of unsigned chars containing the bits of the cursor. + The arguments xbits + and ybits + specify the size of the cursor bitmap. The number of bytes in the + bits array will be the width rounded + up to a multiple of eight (so that the cursor "scanlines" are byte aligned) + times the height. + bits[0] + is the lower left corner, + bits[1] + is to the right of it, etc. The next line of the + bits + array goes above the current one. Within a byte the most significant + bit is the leftmost. The values + xorig + and yorig + specify which bit in the bitmap actually gets placed at the location + specified in the cursor move routines. Again, a first quadrant coordinate + system is used. + + Fb_window + sets the frame buffer window center position to the image space coordinates + given by x and y. + This command is usually used in conjunction with the + fb_zoom routine. + + Fb_zoom + sets the zoom factor for the X coordinate to + x + and the zoom factor for the Y coordinate to + y. + Zooming is generally done by pixel replication in hardware. + + + The following routines work in conjunction with those described above + to provide buffered reading and writing of frame buffer images + either to a real frame buffer or a UNIX file. + The routines use a simple paging strategy to hold “bands” of + the image in core. Since horizontal bands are buffered, the + ideal motion is to scan left to right, then bottom to top. + + Fb_ioinit + should be called before using any of the other buffered I/O routines and + repeated whenever the frame buffer is reopened. + + Fb_seek + is used to position the current read/write pointer to + the location to the next position to be read or written. + It is not necessary to do a fb_seek + after every read or write since both fb_rpixel + and fb_wpixel imply an automatic move to + the next pixel. If you read or write the last pixel on a scan line, + the pointer will automatically move to the beginning + of the following scan line. + + Fb_tell + returns the current location of the read write pointer + in terms of (X,Y) coordinates on the frame buffer. + The X and Y values are returned into the integers pointed to + by xp and yp. + + Fb_rpixel + reads the pixel at the current frame buffer location + and returns it into the location specified + by pixelp. + + Fb_wpixel + writes the pixel pointed to by pixelp + at the current frame buffer location. + + Fb_flush + caused any current buffered frame buffer pages to be written out. + Unnecessary writes are avoided by the use of page reference bits. + + + The following is a printing routine which this library uses to + indicate errors. + + Fb_log will convert, format and print its + args under control of + format to the standard error output. + For more detailed information on the specification of the control string, + see printf3S. + This function may be supplied by the application if different behavior + is desired. + + + + + + FB_FILE DEVICES + + + The following devices are supported by the library; not all may + be available on any given system. New device support can be + incorporated by the addition of a single module to the library. + + + + + /dev/debug + [num] + + + The "/dev/debug" interface prints one line to logs each call + to the frame buffer library. + + num + is a bitvector indicating the levels of verbosity of the output. See + fb.h + for the bit definitions. + + + + + filename + + + Disk file interface + + + + + hostname: + [devicename] + + + TCP-based network links to a remote framebuffer, where + devicename + is any from this list, for example, + fictitious.brlcad.org:/dev/ik0 or fictitious.brlcad.org:/dev/sgi. + A hostname + with a nulldevicename + will select the default display device on that host. + If explicitly specifying a remote device, + be careful not to omit the colon between the host and device name, + or you will be specifying a local disk file as the result. + Note that for security reasons, it is not permitted to access a + disk file via the remote interface. + + + + + + + + EXAMPLES + + Libfb + can be loaded with any C program: + + + $  /bin/cc  program.c  -lfb -l\<system-library...\> + + + where <system-library> + denotes specific libraries necessary on a particular machine. All machines + with networking will require the "-lpkg" option. Machines which support the + X Windows(tm) system will require the "-lX11" option. + + + + + + RETURN VALUES + + fb_close, + fb_write, + fb_read, + fb_wmap, + fb_rmap, + fb_clear, + fb_cursor, + fb_scursor, + fb_setcursor, + fb_window, + fb_zoom, + fb_ioinit, + fb_seek, + fb_wpixel, + fb_rpixel + and + fb_flush + return -1 to indicate failure. + Fb_open + returns FB_NULL to indicate failure, and a non-null fb structure pointer + upon success. + fb_read, + and + fb_write + return the number of pixels actually read or written. + fb_gettype + returns a pointer to a NULL terminated description string. + + + + diff --git a/doc/docbook/system/man3/libfb.xml b/doc/docbook/system/man3/libfb.xml deleted file mode 100644 index 4c479d788ad..00000000000 --- a/doc/docbook/system/man3/libfb.xml +++ /dev/null @@ -1,469 +0,0 @@ - - - - libfb - FrameBuffer Library - 3 - BRL-CAD - BRL-CAD Libraries - - - - libfb - - multiple device, generic frame buffer library - - - - - - - Generic frame buffer routines - - - - - fb *fb_open - * fbfile - int fb_close ( fbp ) fb * fbp - int fb_read ( fbp , x , y , addr , count ) fb * fbp - RGBpixel *addr; - long count; - - - - int fb_write - * fbp - RGBpixel * addr - long count - int fb_rmap ( fbp , cmap ) fb * fbp - ColorMap * cmap - - - - int fb_wmap - * fbp - ColorMap * cmap - - - - int fb_clear - * fbp - RGBpixel * colorp - - - - char *fb_gettype - * fbp - - - - int fb_getwidth - * fbp - - - - int fb_getheight - * fbp - - - - - - - - Hardware specific frame buffer routines - - - - - int fb_cursor - * fbp - int fb_scursor ( fbp , mode , x , y ) fb * fbp - int fb_setcursor ( fbp , bits , xbits , ybits , xorig , yorig ) fb * fbp - unsigned char bits[] - int xbits, ybits; - int xorig, yorig; - - - - int fb_window - * fbp - int fb_zoom ( fbp , x , y ) fb * fbp - / *Buffered frame buffer I/O: */ int fb_ioinit ( fbp ) fb * fbp - - - - int fb_seek - * fbp - void fb_tell ( fbp , xp , yp ) fb * fbp - int *xp , * yp - - - - int fb_rpixel - * fbp - RGBpixel * pixelp - - - - int fb_wpixel - * fbp - RGBpixel * pixelp - - - - int fb_flush - * fbp - - - - void fb_log - format [ - arg ] ... - - - - - - - - DESCRIPTION - - - These routines are designed to provide a device-independent - method of using frame buffers or files containing frame buffer - images. The coordinate system used is first-quadrant (0..width-1, - 0..height-1), with integer addressing. Translation to hardware - coordinate systems is handled by the library. - - - This version of the library assumes that red, green, and blue - intensities are described by unsigned 8-bit bytes in the range (0..255). - The library interface uses arrays of RGBpixels, - which is a typedef for an array of three unsigned chars (this was - done to avoid structure padding). Note that a pointer to an - RGBpixel - is thus the name of the RGBpixel - itself, i.e. no ampersand is needed. - - - The exact interpretation of color maps tends to be somewhat device - specific. The three ColorMap arrays each have 256 entries of unsigned - 16-bit values. In order to accommodate color maps with differing amounts - of output resolution, the color map entries are fixed-point fractions - in the range (0.0..1.0). In integer notation, the range is (0..65525). - For devices with less than 16 bits of output from their color maps, - the left-most portion of each entry is used. - - Fb_open is used to open a frame buffer - file fbfile. The file may be either the - name of a supported frame buffer interface, referenced as "/dev/interface", - or the name of a UNIX file. The routine will try to determine if the - file opened was a real frame buffer by examining the name, and if so - will perform whatever initialization actions are necessary. - If the value of fbfile is - NULL and the environment variable - FB_FILE is set, then the value of FB_FILE - is used; otherwise the default frame buffer device for the system is used. - See below for more details. The width - and height parameters specify the initial - size of display desired. If these are zero the default sizes for that - device will be used. On a successful open, the frame buffer I/O (fb) - structure pointer is returned. This structure contains size you were - actually given, as well as the maximum possible size for the selected - device. A return of FB_NULL indicates failure. - - Fb_close simply closes the frame buffer. - - Fb_read reads - count pixels from the frame buffer - starting at the location specified by x - and y, and places them at program - memory address specified by addr. - Fb_read returns the number of - pixels actually read, or -1 on error. - - Fb_write writes - count pixels from program address - addr into the frame buffer starting - at the location specified by x - and y. Fb_write - returns the number of pixels actually written, or -1 on error. - - Fb_rmap - reads in the color map from the frame buffer and - leaves at the location pointed to by - cmap. - - Fb_wmap - writes the color map pointed to by - cmap - into the frame buffer. If the value of - cmap - is - NULL - then a linear color map is used as the default. - - Fb_clear - erases the frame buffer by setting all pixels to the given - color. If the color pointer is NULL, black will be used. - On a UNIX file, this entails writing the entire file, - which is an expensive operation, whereas on most - frame buffer displays - this can be done in less than a second by a special command. - - Fb_gettype - returns a pointer to a string describing the frame buffer - specified by the fb pointer. - - Fb_getwidth - and Fb_getheight - returns the current size of the fb frame buffer. - - - The following routines work in conjunction with those described above - to provide functions which only apply if the frame buffer - file is actually a hardware frame buffer display. - - Fb_cursor - places the cursor at the image space coordinates given by - x - and - y. - If the mode is non-zero, the cursor is made visible, and - if mode is zero, the cursor is turned off. - - Fb_scursor - is the same as - fb_cursor - except that it - places the cursor at the - screen - space coordinates given by - x - and - y. - - Fb_setcursor - allows the user to set the bitmap used to represent the cursor, - thereby changing the cursor shape. This is not necessarily supported - by all hardware. The argument bits - is a pointer to an array of unsigned chars containing the bits of the cursor. - The arguments xbits - and ybits - specify the size of the cursor bitmap. The number of bytes in the - bits array will be the width rounded - up to a multiple of eight (so that the cursor "scanlines" are byte aligned) - times the height. - bits[0] - is the lower left corner, - bits[1] - is to the right of it, etc. The next line of the - bits - array goes above the current one. Within a byte the most significant - bit is the leftmost. The values - xorig - and yorig - specify which bit in the bitmap actually gets placed at the location - specified in the cursor move routines. Again, a first quadrant coordinate - system is used. - - Fb_window - sets the frame buffer window center position to the image space coordinates - given by x and y. - This command is usually used in conjunction with the - fb_zoom routine. - - Fb_zoom - sets the zoom factor for the X coordinate to - x - and the zoom factor for the Y coordinate to - y. - Zooming is generally done by pixel replication in hardware. - - - The following routines work in conjunction with those described above - to provide buffered reading and writing of frame buffer images - either to a real frame buffer or a UNIX file. - The routines use a simple paging strategy to hold “bands” of - the image in core. Since horizontal bands are buffered, the - ideal motion is to scan left to right, then bottom to top. - - Fb_ioinit - should be called before using any of the other buffered I/O routines and - repeated whenever the frame buffer is reopened. - - Fb_seek - is used to position the current read/write pointer to - the location to the next position to be read or written. - It is not necessary to do a fb_seek - after every read or write since both fb_rpixel - and fb_wpixel imply an automatic move to - the next pixel. If you read or write the last pixel on a scan line, - the pointer will automatically move to the beginning - of the following scan line. - - Fb_tell - returns the current location of the read write pointer - in terms of (X,Y) coordinates on the frame buffer. - The X and Y values are returned into the integers pointed to - by xp and yp. - - Fb_rpixel - reads the pixel at the current frame buffer location - and returns it into the location specified - by pixelp. - - Fb_wpixel - writes the pixel pointed to by pixelp - at the current frame buffer location. - - Fb_flush - caused any current buffered frame buffer pages to be written out. - Unnecessary writes are avoided by the use of page reference bits. - - - The following is a printing routine which this library uses to - indicate errors. - - Fb_log will convert, format and print its - args under control of - format to the standard error output. - For more detailed information on the specification of the control string, - see printf3S. - This function may be supplied by the application if different behavior - is desired. - - - - - - FB_FILE DEVICES - - - The following devices are supported by the library; not all may - be available on any given system. New device support can be - incorporated by the addition of a single module to the library. - - - - - /dev/debug - [num] - - - The "/dev/debug" interface prints one line to logs each call - to the frame buffer library. - - num - is a bitvector indicating the levels of verbosity of the output. See - fb.h - for the bit definitions. - - - - - filename - - - Disk file interface - - - - - hostname: - [devicename] - - - TCP-based network links to a remote framebuffer, where - devicename - is any from this list, for example, - fictitious.brlcad.org:/dev/ik0 or fictitious.brlcad.org:/dev/sgi. - A hostname - with a nulldevicename - will select the default display device on that host. - If explicitly specifying a remote device, - be careful not to omit the colon between the host and device name, - or you will be specifying a local disk file as the result. - Note that for security reasons, it is not permitted to access a - disk file via the remote interface. - - - - - - - - EXAMPLES - - Libfb - can be loaded with any C program: - - - $  /bin/cc  program.c  -lfb -l\<system-library...\> - - - where <system-library> - denotes specific libraries necessary on a particular machine. All machines - with networking will require the "-lpkg" option. Machines which support the - X Windows(tm) system will require the "-lX11" option. - - - - - - RETURN VALUES - - fb_close, - fb_write, - fb_read, - fb_wmap, - fb_rmap, - fb_clear, - fb_cursor, - fb_scursor, - fb_setcursor, - fb_window, - fb_zoom, - fb_ioinit, - fb_seek, - fb_wpixel, - fb_rpixel - and - fb_flush - return -1 to indicate failure. - Fb_open - returns FB_NULL to indicate failure, and a non-null fb structure pointer - upon success. - fb_read, - and - fb_write - return the number of pixels actually read or written. - fb_gettype - returns a pointer to a NULL terminated description string. - - - - - - SEE ALSO - - fbhelp1, brlcad1. - - - - AUTHOR - BRL-CAD Team - - - - - BUG REPORTS - - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - - - diff --git a/doc/docbook/system/man3/libplot3.xml b/doc/docbook/system/man3/libplot3.xml deleted file mode 100644 index f6b21152eab..00000000000 --- a/doc/docbook/system/man3/libplot3.xml +++ /dev/null @@ -1,292 +0,0 @@ - - - - - LIBPLOT3 - -3 -BRL-CAD -BRL-CAD - - - -libplot3 -graphics interface subroutines - - - - - - -void pl_3box - FILE *fp - int x0 - int y0 - int z0 - int x1 - int y1 - int z1 - - - -void pl_3cont - FILE *fp - int x - int y - int z - - - -void pl_3line - FILE *fp - int x0 - int y0 - int z0 - int x1 - int y1 - int z1 - - - -void pl_3move - FILE *fp - int x - int y - int z - - - -void pl_3point - FILE *fp - int x - int y - int z - - - -void pl_3space - FILE *fp - int x0 - int y0 - int z0 - int x1 - int y1 - int z1 - - - -void pl_arc - FILE *fp - int xc - int yc - int x0 - int y0 - int x1 - int y1 - - - -void pl_box - FILE *fp - int x0 - int y0 - int x1 - int y1 - - - -pl_circle - FILE *fp - int x - int y - int r - - - -void pl_color - FILE *fp - int r - int g - int b - - - -void pl_cont - FILE *fp - int x - int y - - - -void pl_erase - FILE *fp - - - -void pl_label - FILE *fp - const char *s - - - -void pl_line - FILE *fp - int x0 - int y0 - int x1 - int y1 - - - -void pl_linmod - FILE *fp - const char *s - - - -void pl_move - FILE *fp - int x - int y - - - -void pl_point - FILE *fp - int x - int y - - - -void pl_space - FILE *fp - int x0 - int y0 - int x1 - int y1 - - - - - - - -DESCRIPTION -These subroutines -generate -graphic output commands for processing -with the -plot(1) -plotting filters. -They are slightly more general than those in -libplot -as these take a file pointer. They also include -the BRL 3-D extensions to the plot intermediate code. - -Pl_space -or -pl_3space -must be used before any of the graphic primitives to declare the -amount of space necessary. -See -plot3(5). - -Pl_box -or -pl_3box -draws a box between the two given opposite points. -The ''pen'' will be left at the second point. - -Pl_circle -draws a circle of radius -r -with center at the point -(x, -y). -Note that -circle -and -arc -cannot be transformed in three space if one is using a -filter to do that. - -Pl_arc -draws an arc of a circle with center at the point -(x, -y) -between the points -(x0, -y0) -and -(x1, -y1). - -String arguments to -pl_label -and -pl_linmod -are terminated by nulls and do not contain new-lines. - -There are also 2-D and 3_D double-precision versions, with arguments -identical to their counterparts above. The naming conventions are to -change the prefix to "pd"; examples are thus -pd_point -and -pd_3point. -Vector versions for 3_D (also double-precision) are prefixed "pdv", as in -pdv_3point. - -See -plot3(5) -and -plot(5) -for a description -of the effect of the remaining functions. - - - -FILES -/usr/brlcad/lib/libplot3.a produces output for -plot1G -filters - - - -WARNINGS -In order to compile a program containing these functions -in -file.c -it is necessary to use -``cc -file.c --lplot3''. - -Color -specification and -three-dimensional primitives -are BRL extensions to the "unix plot" language -that are not generally found on other systems. - - -SEE ALSO -plot1, pl-fb1, -plot35, plot5 - - - -AUTHOR -BRL-CAD Team - - - -COPYRIGHT -This software is Copyright (c) 1989-2023 by the United States -Government as represented by U.S. Army Research Laboratory. - - -BUG REPORTS -Reports of bugs or problems should be submitted via electronic -mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/man5/CMakeLists.txt b/doc/docbook/system/man5/CMakeLists.txt index 1068231078a..d1155a9cf2f 100644 --- a/doc/docbook/system/man5/CMakeLists.txt +++ b/doc/docbook/system/man5/CMakeLists.txt @@ -24,8 +24,6 @@ set(man5_EN dsp.xml ${CMAKE_CURRENT_BINARY_DIR}/attributes.xml benchmark.xml - burst_point_library.xml - burst_shotline_files.xml bw.xml cmap.xml idents.xml diff --git a/doc/docbook/system/man5/burst_point_library.xml b/doc/docbook/system/man5/burst_point_library.xml deleted file mode 100644 index 39a6b1df8f4..00000000000 --- a/doc/docbook/system/man5/burst_point_library.xml +++ /dev/null @@ -1,251 +0,0 @@ - - - - Burst Point Library File Format - 5 - BRL-CAD - BRL-CAD - - - - burst_point_library - Data output by the burst-file command from the burst tool. - - - - FORMAT - - - Burst point library files are composed of single-line records. Each line begins with a - digit that identifies the type of record it represents. The file is composed of one or more runs that - begin with a run header. Each shotline that intersects the target will result in a shotline header that is - followed by one or more shotline intersection records. If a burst point occurs along a shotline, the burst ray header will - immediately follow that shotline's last intersection record. Each burst ray header records will be - immediately followed by burst ray intersection records, one for each ray that strikes a critical component. - - - Burst Point Library File Format - - - - Record Description - Field Format - Field Description - - - - - - run header - '1' - record number 1 - - - - - 1x,f9.4 - attack azimuth (degrees) - - - - - 1x,f8.4 - attack elevation (degrees) - - - - - 1x,f5.2 - burst distance - - - - - 1x,f10.2 - projected area associated with burst point - - - - - 1x,6a - units (mm,cm,inches,feet,meters) - - - - - 1x,f9.6 - ray solid angle (steradians) - - - - shotline header - '2' - record number 2 - - - - - 1x,f8.3 - Y' coordinate of shotline - - - - - 1x,f8.3 - Z' coordinate of shotline - - - - shotline intersections - '3' - record number 3 - - - - - 1x,f8.2 - X' coordinate of component intersection - - - - - 1x,f8.2 - line-of-sight thickness of component - - - - - 1x,i4 - component code number - - - - - 1x,i2 - space code - - - - - 1x,f7.3 - sine of fallback angle of exit normal - - - - - 1x,f7.2 - rotation angle of exit normal (degrees) - - - - - 1x,f7.3 - cosine of obliquity angle at entry - - - - - 1x,a1 - burst flag ('1' for yes, '0' for no) - - - - burst ray header - '4' - record number 4 - - - - - 1x,f8.3 - azimuth angle WRT shotline (radians) - - - - - 1x,f8.3 - sine of elevation angle WRT shotline - - - - - 1x,i6 - sequential ray number for this burst point - - - - burst ray intersections - '5' - record number 5 - - - - - 1x,f10.3 - distance to first contact with component - - - - - 1x,f9.3 - line-of-sight thickness of component - - - - - 1x,f9.3 - normal thickness of component - - - - - 1x,i4 - space code - - - - - ix,i4 - component code number - - - - - ix,f6.3 - cosine of obliquity angle at entry - - - - -
-
-
- - SEE ALSO - - burst1 - - - - - AUTHOR - BRL-CAD Team - - - - COPYRIGHT - - This software is Copyright (c) 1989-2023 by the United States - Government as represented by U.S. Army Research Laboratory. - - - - - - BUG REPORTS - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - -
diff --git a/doc/docbook/system/man5/burst_shotline_files.xml b/doc/docbook/system/man5/burst_shotline_files.xml deleted file mode 100644 index ce9c69f677c..00000000000 --- a/doc/docbook/system/man5/burst_shotline_files.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - - Burst Shotline File Format - 5 - BRL-CAD - BRL-CAD - - - - burst_shotline_files - Data output by the shotline-file command from the burst tool. - - - - FORMAT - - - Burst shotline files are composed of single-line records. Each line begins with a - digit that identifies the type of record it represents. The file is composed of one or more runs that - begin with a run header. Each shotline that intersects the target will result in a shotline header that is - followed by one or more shotline intersection records. - - - Shotline File Format - - - - Record Description - Field Format - Field Description - - - - - - run header - '1' - record number 1 - - - - - 1x,f9.4 - attack azimuth (degrees) - - - - - 1x,f8.4 - attack elevation (degrees) - - - - - 1x,f7.2 - shotline separation - - - - - 1x,f7.2 - maximum Y' coordinate of target - - - - 1x,f7.2 - minimum Y' coordinate of target - - - - 1x,f7.2 - maximum Z' coordinate of target - - - - 1x,f7.2 - minimum Z' coordinate of target - - - - - 1x,6a - units (mm,cm,inches,feet,meters) - - - - shotline header - '2' - record number 2 - - - - - 1x,f8.3 - Y' coordinate of shotline - - - - - 1x,f8.3 - Z' coordinate of shotline - - - - shotline intersections - '3' - record number 3 - - - - - 1x,f8.2 - X' coordinate of component intersection - - - - - 1x,f7.3 - sine of fallback angle of exit normal - - - - - 1x,f7.2 - rotation angle of exit normal in degrees - - - - - 1x,i4 - component code number - - - - - 1x,f8.2 - normal thickness of component - - - - - 1x,f8.2 - line-of-sight thickness of component - - - - - 1x,i2 - space code following component - - - - - 1x,f7.2 - obliquity angle at entry to component in degrees - - - - - 1x,f7.2 - obliquity angle at exit from component in degrees - - - - -
-
-
- - SEE ALSO - - burst1 - - - - - AUTHOR - BRL-CAD Team - - - - COPYRIGHT - - This software is Copyright (c) 1989-2023 by the United States - Government as represented by U.S. Army Research Laboratory. - - - - - - BUG REPORTS - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - -
diff --git a/doc/docbook/system/mann/B.xml b/doc/docbook/system/mann/B.xml index 0417fc3bb7f..70338d59a1c 100644 --- a/doc/docbook/system/mann/B.xml +++ b/doc/docbook/system/mann/B.xml @@ -38,10 +38,10 @@ objects provided in the parameter list. Equivalent to the Z command followed by the command draw <objects>. The -C option provides the user a way to specify a color that overrides all other color specifications including - combination colors and region id-based colors. The -A and -o + combination colors and region id-based colors. The -A and -o options allow the user to select objects by attribute. The -s option specifies that subtracted and intersected objects should be drawn with solid lines rather than dot-dash lines. - The -R option means do not automatically resize the view if no other objects are displayed. + The -R option means do not automatically resize the view if no other objects are displayed. See the draw command for a detailed description of the options.
diff --git a/doc/docbook/system/mann/CMakeLists.txt b/doc/docbook/system/mann/CMakeLists.txt index a9ed12e2df7..d9c766cd124 100644 --- a/doc/docbook/system/mann/CMakeLists.txt +++ b/doc/docbook/system/mann/CMakeLists.txt @@ -1,12 +1,12 @@ set(mann_EN 3ptarb.xml B.xml - E.xml + bigE.xml M.xml Z.xml adc.xml ae.xml - all_sf.xml + ae2dir.xml analyze.xml animmate.xml apropos.xml @@ -24,7 +24,6 @@ set(mann_EN bev.xml bo.xml bot.xml - bolt.xml bot_condense.xml bot_decimate.xml bot_face_fuse.xml @@ -41,8 +40,10 @@ set(mann_EN build_region.xml c.xml cat.xml + cd.xml center.xml check.xml + clear.xml clone.xml color.xml comb.xml @@ -53,9 +54,10 @@ set(mann_EN cpi.xml d.xml db.xml - dbfind.xml db_glob.xml dbconcat.xml + dbfind.xml + dbfindtree.xml dbupgrade.xml debug.xml debugbu.xml @@ -64,10 +66,13 @@ set(mann_EN debugnmg.xml decompose.xml delay.xml + dir2ae.xml dm.xml draw.xml + dump.xml dup.xml - e_command.xml + e.xml + e_id.xml eac.xml echo.xml edcodes.xml @@ -77,6 +82,7 @@ set(mann_EN edit.xml edit_translate.xml edmater.xml + env.xml eqn.xml erase.xml ev.xml @@ -113,6 +119,7 @@ set(mann_EN keypoint.xml kill.xml killall.xml + killrefs.xml killtree.xml knob.xml l.xml @@ -131,6 +138,7 @@ set(mann_EN material.xml matpick.xml mirface.xml + mirror.xml mrot.xml mv.xml mvall.xml @@ -150,6 +158,7 @@ set(mann_EN paths.xml permute.xml plot.xml + pnts.xml postscript.xml prcolor.xml prefix.xml @@ -160,8 +169,10 @@ set(mann_EN ps.xml pull.xml push.xml + put.xml put_comb.xml putmat.xml + pwd.xml q.xml qorot.xml qray.xml @@ -181,6 +192,8 @@ set(mann_EN regions.xml reid.xml release.xml + relos.xml + remat.xml rfarb.xml rm.xml rmater.xml @@ -192,18 +205,21 @@ set(mann_EN rt.xml rtarea.xml rtcheck.xml + rtedge.xml saveview.xml sca.xml screengrab.xml search.xml sed.xml setview.xml + shaded_mode.xml shader.xml shells.xml showmats.xml simulate.xml size.xml solids.xml + source.xml sph-part.xml stat.xml status.xml @@ -220,10 +236,12 @@ set(mann_EN track.xml translate.xml tree.xml + unhide.xml units.xml vars.xml vdraw.xml view.xml + viewdir.xml viewsize.xml vnirt.xml voxelize.xml diff --git a/doc/docbook/system/mann/E.xml b/doc/docbook/system/mann/E.xml deleted file mode 100644 index e84de0df59b..00000000000 --- a/doc/docbook/system/mann/E.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - E - nged - BRL-CAD - BRL-CAD User Commands - - - - E - - Display objects in an evaluated form. - - - - - - - E - object - -s - - - - DESCRIPTION - - - Displays objects in an evaluated form. All the Boolean operations indicated - in each object in objects will be performed, and a - resulting faceted approximation of the actual objects will be displayed. - Note that this is usually much slower than using the usual - draw command. The -s option provides - a more accurate, but slower, approximation. - - - - EXAMPLES - - - Display faceted approximation of an object. - - Display <emphasis>objects</emphasis> in an evaluated form - - - - mged> E some_object - - - Displays a faceted approximation of some_object. - - - - - - - - AUTHOR - BRL-CAD Team - - - BUG REPORTS - - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/mann/M.xml b/doc/docbook/system/mann/M.xml index 2f513ab72f0..43af4a92fc7 100644 --- a/doc/docbook/system/mann/M.xml +++ b/doc/docbook/system/mann/M.xml @@ -52,7 +52,7 @@ - mgedM 1 100 100 + mged> M 1 100 100 The point at screen coordinates (100,100)is repositioned to the diff --git a/doc/docbook/system/mann/ae2dir.xml b/doc/docbook/system/mann/ae2dir.xml new file mode 100644 index 00000000000..dee071fd02e --- /dev/null +++ b/doc/docbook/system/mann/ae2dir.xml @@ -0,0 +1,61 @@ + + + + AE2DIR + nged + BRL-CAD + BRL-CAD MGED Commands + + + + ae2dir + Returns the direction vector using the provided azimuth and elevation (AE). + + + + + + + ae2dir + -i + azimuth + elevation + + + +DESCRIPTION + + Returns the direction vector using the provided azimuth and elevation as input. If + the -i option is used the commmand will return the inverse + directional vector. See also the viewdir, dir2ae, + and qvrot commands. + + + + +EXAMPLES + + The example shows the use of the ae2dir command to get the direction vector. + + + Find the direction vector using the provided azimuth and elevation. + + + mged> ae2dir 35 25 + + Returns the direction vector using an azimuth of 35 and elevation of 25. + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/all_sf.xml b/doc/docbook/system/mann/all_sf.xml deleted file mode 100644 index ac49eade35f..00000000000 --- a/doc/docbook/system/mann/all_sf.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - ALL_SF - nged - BRL-CAD - BRL-CAD User Commands - - - - all_sf - - obtain shape factors between named regions of an entire mged database - - - - - - - all_sf - model.g - objects - - - -DESCRIPTIONS - - - all_sf is an interactive program used to create - a file containing shape factors between all regions of the named objects. - The shape factor from region i to region j is the fraction of total energy - radiated from region i that is intercepted by region j. This program finds - the shapefactors for all regions in an mged model not just shapefactors - between engine regions. - - - - All_sf uses a Monte Carlo simulation, so increasing the number of - significant digits in the answer by one requires about a 100-fold - increase in the number of rays fired. - - - - Three different files are created by all_sf: an output file, a - longwave radiation exchange file, and an error file. The output file lists the - shapefactors between each region. The longwave radiation exchange - file is for use with PRISM. This file is not quite PRISM ready so the - user must fill in the missing parameters if it is to be used with - PRISM. The error file is basically used for checking errors in the - program and probably will not be used by the average user. - - - -EXAMPLE - - - The following is an example from an interactive session. - - - - $ all_sf con.sph.g all.air - Enter name of output file (25 char max). - cs.out - Enter name of longwave radiation exchange file (25 char max). - cs.lwx - Enter the name of the error file (25 char max). - cs.err - Database Title: concentric spheres for use with - Number of regions: 3 - Min & max for entire model. - X: -2300.000000 - 2300.000000 - Y: -2300.000000 - 2300.000000 - Z: -2300.000000 - 2300.000000 - Center: 0.000000, 0.000000, 0.000000 - - Radius: 3984.216857 - Surface Area: 199478365.653926 - - Enter the number of rays to be fired. - 50000000 - Region names in structure. - Do you wish to enter your own seed (0) or use the default of 1 (1)? - 1 - Seed initialized - $ - - - -SEE ALSO - - - - firpass - 1 - , - - secpass - 1 - , - - showtherm - 1 - , - - ir-X - 1 - , - - ir-sgi - 1 - , - - pictx - 1 - , - - pictsgi - 1 - , - - shapefact - 1 - , - User's Manual for IRPREP (BRL-SP-96), Computer Programs - for Generating an Input File for PRISM and Displaying PRISM Results - (BRL report in progress) - - - -AUTHOR - Susan A. Coates - - diff --git a/doc/docbook/system/mann/arb.xml b/doc/docbook/system/mann/arb.xml index 6dbd0eb2aa8..9d51c59fdc8 100644 --- a/doc/docbook/system/mann/arb.xml +++ b/doc/docbook/system/mann/arb.xml @@ -17,7 +17,7 @@ arb - arb_name> + arb_name rotation fallback diff --git a/doc/docbook/system/mann/attach.xml b/doc/docbook/system/mann/attach.xml index 01c7a2f8a07..d9800dae9bf 100644 --- a/doc/docbook/system/mann/attach.xml +++ b/doc/docbook/system/mann/attach.xml @@ -59,7 +59,7 @@ - mgedattach ogl + mged> attach ogl Opens an ogl display window named .dm_ogl1. diff --git a/doc/docbook/system/mann/bb.xml b/doc/docbook/system/mann/bb.xml index d127b048b7d..865ec44ee3b 100644 --- a/doc/docbook/system/mann/bb.xml +++ b/doc/docbook/system/mann/bb.xml @@ -1,4 +1,4 @@ - + BB nged @@ -117,14 +117,14 @@ - bb havoc - + +mged> bb havoc Bounding Box Dimensions, Object(s) havoc: X Length: 1988.4 cm Y Length: 1683.6 cm Z Length: 625.0 cm Bounding Box Volume: 2092246392.4 cm^3 - + @@ -132,10 +132,10 @@ Bounding Box Volume: 2092246392.4 cm^3 - bb -q -e havoc - + +mged> bb -q -e havoc min {-759.447479 -8437.866455 -890.000000} max {19124.621094 8397.693207 5360.000000} - + @@ -143,33 +143,33 @@ min {-759.447479 -8437.866455 -890.000000} max {19124.621094 8397.693207 5360.00 - bb havoc_front havoc_middle havoc_tail - + +mged> bb havoc_front havoc_middle havoc_tail Bounding Box Dimensions, Object(s) havoc_front, havoc_middle, havoc_tail: X Length: 1775.9 cm Y Length: 358.0 cm Z Length: 536.0 cm Bounding Box Volume: 340782488.9 cm^3 - + - Create Bounding Box ARB8 in database - + Create ARB8 Bounding Box - bb -c havoc_parts_bbox.s havoc_front havoc_middle havoc_tail - -mged> bb -c havoc_parts_bbox.s havoc_front havoc_middle havoc_tail + +mged> bb -c havoc_parts_bbox.s havoc_front havoc_middle havoc_tail Bounding Box Dimensions, Object(s) havoc_front, havoc_middle, havoc_tail: X Length: 1775.9 cm Y Length: 358.0 cm Z Length: 536.0 cm Bounding Box Volume: 340782488.9 cm^3 + + - -havoc havoc_tail havoc_middle havoc_parts_bbox.s havoc_front -mged> l havoc_parts_bbox.s + + +mged> l havoc_parts_bbox.s havoc_parts_bbox.s: ARB8 1 (-75.9447, -158, -4.86374e-06) 2 (-75.9447, -158, 536) @@ -179,8 +179,7 @@ havoc_parts_bbox.s: ARB8 6 (1700, -158, 536) 7 (1700, 200, 536) 8 (1700, 200, -4.86374e-06) - - + diff --git a/doc/docbook/system/mann/bigE.xml b/doc/docbook/system/mann/bigE.xml new file mode 100644 index 00000000000..cca36452be9 --- /dev/null +++ b/doc/docbook/system/mann/bigE.xml @@ -0,0 +1,69 @@ + + + + bigE + nged + BRL-CAD + BRL-CAD User Commands + + + + bigE + + Display objects in an evaluated form. + + + + + + + E + object + -s + + + + DESCRIPTION + + + Displays objects in an evaluated form. All the Boolean operations indicated + in each object in objects will be performed, and a + resulting faceted approximation of the actual objects will be displayed. + Note that this is usually much slower than using the usual + draw command. The -s option provides + a more accurate, but slower, approximation. See also: the ev command. + + + + EXAMPLES + + + Display faceted approximation of an object. + + Display <emphasis>objects</emphasis> in an evaluated form + + + + mged> E some_object + + + Displays a faceted approximation of some_object. + + + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/bolt.xml b/doc/docbook/system/mann/bolt.xml deleted file mode 100644 index 8fc23bb881c..00000000000 --- a/doc/docbook/system/mann/bolt.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - BOLT - nged - BRL-CAD - BRL-CAD User Commands - - - - bolt - - Creates a BRL-CAD .g file containing bolts. - - - - - - - bolt - options - - - -DESCRIPTION - - - bolt is a program to create a BRL-CAD data base of - one of four different kinds of bolts. Up to twenty-six bolts of one type - and size may be created. bolt uses libwdb to create a - database file. This program may be run interactively or the user may - specify options on a command line. If the user chooses to run the program - interactively he answers the questions as the program prompts him. Below - are the options that can be used on the command line. - - - - -OPTIONS - - - - - - - Type of bolt to be created: 1=>bolt head; 2=>bolt head and washer; 3=>bolt - head, washer, and bolt stem; and 4=>bolt head and bolt stem. - - - - - name.g - - - BRL-CAD file name. - - - - - - - - The number of bolts to be created. This number must be less than or equal to - 26 (or it will be set to 26). - - - - - - - - Diameter of bolt head, flat edge to flat edge, in millimeters. - - - - - - - - Height of bolt head in millimeters. - - - - - - - - Diameter of washer in millimeters. - - - - - - - - Height of washer in millimeters. - - - - - - - - Diameter of bolt stem in millimeters. - - - - - - - - Height of bolt stem in millimeters. - - - - - - -EXAMPLES - - Interactive <command>bolt</command> Session - - - -$ bolt -Enter option: - 1 - bolt head - 2 - bolt head & washer - 3 - bolt head, washer, & stem - 4 - bolt head & stem -1 -Enter name of mged file to be created (25 char max). - bolt.g -Enter the number of bolts to be created (26 max). - 3 -Enter diameter (flat edge to flat edge) & height of bolt head. - 30 10 - -option: 1 - bolt head -file: bolt.g -head diameter: 30.000000, & height: 10.000000 -washer diameter: 0.000000, & height: 0.000000 -stem diameter: 0.000000, & height: 0.000000 -number of bolts: 3 - - - - - Single-Line <command>bolt</command> Command - - - bolt -o1 -fbolt.g -n3 -hd30 -hh10 - - - - - Both examples produce the same output - the bolt heads (option 1) - are created with a diameter of 30mm and a height of 10mm in a database - file called bolt.g. - - - - -AUTHOR - Susan A. Coates - - -COPYRIGHT - - - This software is Copyright (c) 2005-2023 United States Government as - represented by the U.S. Army Research Laboratory. - - - -SEE ALSO - - - handle(1), window(1), window_frame(1), gastank(1) - - - -BUG REPORTS - - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/mann/bot.xml b/doc/docbook/system/mann/bot.xml index f377606a4ac..85375160ce8 100644 --- a/doc/docbook/system/mann/bot.xml +++ b/doc/docbook/system/mann/bot.xml @@ -1,4 +1,4 @@ - + BOT nged @@ -17,10 +17,60 @@ bot - subcommand - options + -v + -V + -C [0-255|0-255|0-255] + subcommand + subcommand arguments + + + check + + degen_faces + extra_edges + flipped_edges + open_edges + solid + + objname + + + + + + chull + input_bot + output_bot + + + + + + decimate + -f # + -e # + input_bot + output_bot + + + + + + extrude + input_bot + output_bot + + + + + + flip + objname + + + get @@ -32,29 +82,329 @@ type vertices - input_bot - - - - - chull - input_bot - output_bot - - - - - solid - input_bot + objname + + + + isect + objname + objname2 + + + + + + remesh + input_bot + output_bot + + + + + + set + + orientation + type + + objname + value + + + + + + smooth + -c [0|1|2] + -d [0|1|2] + -e # + -E # + -I # + input_bot + output_bot + + + + + + split + objname + + + + + + stat + objname + + + + + + subd + -A [1|2|3|4|5] + -l # + input_bot + output_bot + + + + + + sync + objname + + + DESCRIPTION - The bot command. + The bot command allows the user to initiate and number of subcommands on BoT primitives. The -v command turns on verbose output. + The -V command visualizes the results. The -C command sets the RGB plotting color. + + + SUBCOMMANDS + + + check + + + Performs the requested check on the provided solid. Checks are degen_faces, + extra_edges, flipped_edges, open_edges, or solid. The + command will return a 1 (if the specified check finds an issue) or 0. + + + + + chull + + + Generates the BoT's convex hull and store it in an object. + + + + + decimate + + + Decimates the BoT. The default error metric is Quadric. + + + + + + Specifies the features size (implies use of GCT decimater) + + + + + + Specifies the maximum allowed error introduced by decimation (OpenMesh). + + + + + + + extrude + + + Generates an ARB6 representation of the specified plate mode BoT object + + + + + + flip + + + Flips the BoT triangle normal directions (turns the BoT "inside out"). This will also change the handedness of + of the BoT, if set. So a right-handed (counter-clockwise) BoT will become a left-handed (clockwise) BoT. An + unoriented BoT's orientation will not change. + + + + + + get + + + Returns the requested parameter of the provided BoT solid. Valid parameters are faces, + minEdge, maxEdge, orientation, type, + or vertices. + + + + + + isect + + + Tests if the two provided BoTs intersect (work in progress). + + + + + + remesh + + + Creates a new meshed version of the provided object. + + + + + + set + + + Sets the specified property of the provided bot. Properties that can be set are + orientation and type. Potential values for orientation + are none (no), ccw (rh), or cw (lh). Potential values for type are + surface, solid, plate, or plate_nocos. + + + + + + smooth + + + Smooths the BoT using OpenMesh's Jacobi Laplace smoother. + + + + + + Specifies the continuity. The default value is 0, meaning shape is continuous, but not the tangent. A value of 1 means + the shape and tangent are continuous, and a value of 2 preserves curvature. + + + + + + + Specifies the direction. The default is 0,smoothing in tangential direction. A value of 1 smooths + in normal direction, and a value of 2 smooths in both tangential and normal directions. + + + + + + + Specifies the max local error. + + + + + + + + Specifies the max absolute error. + + + + + + + + Specifies the iterations for smoothing. + + + + + + + + + split + + + Splits the provided BoT into separate BoTs made of disjointed sections. + + + + + + stat + + + Returns information about the provided BoT. + + + + + + subd + + + Subdivides the provided BoT. + + + + + + Specifies the algorithm used to subdivide the BoT. The default is 1 which specifies the loop algorithm. + A value of 2 specfies the sqrt3 algorithm, a value of 3 specifies the sqrt3 interpolating algorithm, + a value of 4 specifies modified the butterfly algorithm, and a value of 5 specifies the midpoint alorithm. + + + + + + Specifies the level of subdivision refinement iterations. Note that the number of triangles generated grows very rapidly with + increasing iteration counts - it is recommended that users start with small refinements on the target + bot to get a feel for the tradeoff between triangle count and smoothness. + + + + + + + + sync + + + Synchronizes connected BoT triangle orientations. + + + + + +EXAMPLES + Set the orientation of a BoT to right-hand + + mged> bot set orientation bot_solid.s rh + + + Sets the orientation of solid bot_solid.s to right-handed (counter-clockwise). + + + Return the orientation of a solid. + + mged> bot get orientation bot_solid.s + + + Returns the orientation of bot_solid.s. Note that this will return ccw (right-handed), cw (left-handed) + or none (unoriented). + + + Return information of a solid. + + mged> bot stat bot_solid.s + + + Returns information about bot_solid.s. + + + + + AUTHOR BRL-CAD Team diff --git a/doc/docbook/system/mann/bot_face_sort.xml b/doc/docbook/system/mann/bot_face_sort.xml index 624facea029..aa7177ef11f 100644 --- a/doc/docbook/system/mann/bot_face_sort.xml +++ b/doc/docbook/system/mann/bot_face_sort.xml @@ -20,7 +20,7 @@ bot_face_sort triangles_per_piece - bot_primitive1> + bot_primitive1 bot_primitive2 bot_primitive3 diff --git a/doc/docbook/system/mann/bot_flip.xml b/doc/docbook/system/mann/bot_flip.xml index 96462deb496..3d189a61c38 100644 --- a/doc/docbook/system/mann/bot_flip.xml +++ b/doc/docbook/system/mann/bot_flip.xml @@ -29,6 +29,10 @@ command will flip the normals resulting in all exterior facets to become shaded and all interior facets to become black. It is recommended to run the commands 'bot_vertex_fuse' then 'bot_face_fuse' before running 'bot_flip'. + Note: using the bot_flip will toggle the orientation of + right and left-handed BOT primitives. The orientation of unoriented BOT + primitives will not change. + AUTHOR diff --git a/doc/docbook/system/mann/cd.xml b/doc/docbook/system/mann/cd.xml new file mode 100644 index 00000000000..060fc4096b8 --- /dev/null +++ b/doc/docbook/system/mann/cd.xml @@ -0,0 +1,92 @@ + + + + CD + nged + BRL-CAD + BRL-CAD User Commands + + + + cd + Change the directory to the given path. + + + + + + + cd + path + + + + DESCRIPTION + + + Change the directory to the given path. This can change to a given folder in the current directory or + change to a full path. Double periods (..) can also be used to go up one level. See also the pwd command. + + + + EXAMPLES + + + Change directory to the given folder located in the current directory. + + Use <command>cd</command> to change the directory. + + + + mged> cd test_folder + + Changes the current directroy to a folder named test_folder that is located within the current directory. + + + + + + + Change directory to the given folder using the full path. + + Use <command>cd</command> to change the directory. + + + + mged> cd C:/geometry/test_folder + + Changes the current directroy to a folder named test_folder located at C:/geometry/test_folder. + + + + + + + Change directory to the folder above the current folder. + + Use <command>cd</command> to change the directory. + + + + mged> cd .. + + Changes the current directroy to the folder above the current folder. + + + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/center.xml b/doc/docbook/system/mann/center.xml index 6a9a7c5f8ea..139bf7559e5 100644 --- a/doc/docbook/system/mann/center.xml +++ b/doc/docbook/system/mann/center.xml @@ -90,11 +90,11 @@ - mgedunits mm + mged> units mm - mgedeval center [vadd2[center] {2 0 0}] + mged> eval center [vadd2[center] {2 0 0}] Moves the center point 2 mm in the model + x direction. @@ -112,7 +112,7 @@ - mgeddb adjust sphere.s V [center] + mged> db adjust sphere.s V [center] diff --git a/doc/docbook/system/mann/check.xml b/doc/docbook/system/mann/check.xml index b2f432775c1..191d2260fd0 100644 --- a/doc/docbook/system/mann/check.xml +++ b/doc/docbook/system/mann/check.xml @@ -123,10 +123,12 @@ overlaps - This reports overlaps, when two regions occupy the same space. In the real world, - two objects may not occupy the same space. This check is sometimes also known as - interference checking. Two objects must overlap by at least overlap_tol_dist - (see the -t option below) to be considered to overlap. + This reports overlaps, when two regions occupy the same + space. In the real world, two objects may not occupy the + same space. This check is sometimes also known as + interference checking. Two objects must overlap by at + least overlap_tol_dist (see the -t option below) to be + considered to overlap.
@@ -142,10 +144,12 @@ unconf_air - This reports when a partition with nonzero air code follows or precedes another - partition and the space between them is more than overlap_tol_dist (see the -t option). - The data reported are the names of the two regions (and solids) involved, the - length of the gap along the ray, and the model coordinates of the ray's exiting + This reports when a partition with nonzero air code + follows or precedes another partition and the space + between them is more than overlap_tol_dist (see the -t + option). The data reported are the names of the two + regions (and solids) involved, the length of the gap along + the ray, and the model coordinates of the ray's exiting the first partition and entering the second @@ -163,17 +167,19 @@ MASS CALCULATION - If mass calculation is selected, a value is calculated and reported for each - object specified on the command line. - Note that if there are overlaps or other errors in the - geometry, the values reported will be invalid. + If mass calculation is selected, a value is calculated and + reported for each object + specified on the command line. Note that if there are overlaps or other errors in + the geometry, the values reported will be invalid. - For mass computation, the density of every region must be specified. - Densities are specified as an index in a table of density values. - This index is stored in the GIFTmater - attribute of each region (typically set with the edcodes + For mass computation, the density of every region must be + specified. Densities are specified as an index in a table of + density values. This index is stored in the GIFTmater attribute of each region + (typically set with the edcodes or adjust commands in MGED). @@ -186,8 +192,9 @@ An integer index value. - This is the value to which the GIFTmater attribute - will be set to select this material for the region. + This is the value to which the GIFTmater attribute will be set to + select this material for the region. @@ -224,39 +231,47 @@ The geometry editor MGED automatically assigns an index value of - 1 to a newly created region. While this default can be handy - when a vast majority of objects are made from the same material, it can lead to - surprising errors when objects which are supposed to have a - certain mass are computed to have different mass because one or two regions - were not set to the correct, non-default index value. As a result, it is advised that - the index value 1 never be used. If this practice is followed, - then an error message will be generated for any regions which have not had their - material index set to something other than the default. + 1 to a newly created region. While this + default can be handy when a vast majority of objects are made + from the same material, it can lead to surprising errors when + objects which are supposed to have a certain mass are computed + to have different mass because one or two regions were not set + to the correct, non-default index value. As a result, it is + advised that the index value 1 never be + used. If this practice is followed, then an error message will + be generated for any regions which have not had their material + index set to something other than the default. - The user will typically want to run gqa and verify the results using the - option (see below) before importing the table into the database. - For example, if a material index is left out of the table, it is easier to rectify - the situation using the external file. Once the table has been verified as correct - and complete, it is imported to the database as the binary object - _DENSITIES . - To import the text file into the database, the following command is used: + The user will typically want to run gqa and + verify the results using the option (see + below) before importing the table into the database. For + example, if a material index is left out of the table, it is + easier to rectify the situation using the external file. Once + the table has been verified as correct and complete, it is + imported to the database as the binary object _DENSITIES . To import the + text file into the database, the following command is used: - mged> bo -i u c _DENSITIES filename + +mged> bo -i u c _DENSITIES filename + GEOMETRY ERROR DETECTION - All of these calculations run until the grid refinement limit is reached. + All of these calculations run until the grid refinement limit is + reached. - For each pair of regions that cause an error, the tool reports the two - erroneous regions, the maximum line-of-sight thickness of the error, and - the in-hit location of the ray that caused that maximum error thickness. + For each pair of regions that cause an error, the tool reports + the two erroneous regions, the maximum line-of-sight thickness + of the error, and the in-hit location of the ray that caused + that maximum error thickness. OPTIONS @@ -265,9 +280,10 @@ azimuth_deg [deg|rad] - Sets a rotation (in degrees) of the coordinate system by a given amount about - the Z axis. When mentioned, check shoots only one grid of rays along the - azimuth/elevation angle. The default is 35. See also . + Sets a rotation (in degrees) of the coordinate system by a + given amount about the Z axis. When mentioned, check + shoots only one grid of rays along the azimuth/elevation + angle. The default is 35. See also . @@ -275,10 +291,11 @@ elevation_deg [deg|rad] - Sets a rotation (in degrees) of the coordinate system by a given elevation - from the XY plane (rotation about X axis?). When mentioned, check shoots only one - grid of rays along the azimuth/elevation angle. The default is 25. - See also . + Sets a rotation (in degrees) of the coordinate system by a + given elevation from the XY plane (rotation about X + axis?). When mentioned, check shoots only one grid of rays + along the azimuth/elevation angle. The default is 25. See + also . @@ -294,10 +311,12 @@ filename - Specifies that density values should be taken from an external file instead of from the - _DENSITIES object in the database. - This option can be useful when developing the density table with a text editor, - prior to importing it to the geometric database. + Specifies that density values should be taken from an + external file instead of from the _DENSITIES object in the database. + This option can be useful when developing the density + table with a text editor, prior to importing it to the + geometric database. @@ -306,32 +325,43 @@ [initial_grid_spacing,]grid_spacing_limit
- Specifies a limit on how far the grid can be refined and optionally the initial spacing - between rays in the grids. The first value (if present) indicates the initial spacing - between grid rays. The mandatory argument, grid_spacing_limit, - indicates a lower bound on how fine the grid spacing may get before computation is - terminated. In general, the initial_grid_spacing value - should be an integer power of the grid_spacing_limit. So - for example, if grid_spacing_limit has the value 1, - then any initial_grid_spacing specified should be in the - sequence 2, 4, 8, 16, 32... so that the grid will refine to precisely the lower limit. - The grid spacing may be specified with units. For example: + Specifies a limit on how far the grid can be refined and + optionally the initial spacing between rays in the + grids. The first value (if present) indicates the initial + spacing between grid rays. The mandatory argument, + grid_spacing_limit, + indicates a lower bound on how fine the grid spacing may + get before computation is terminated. In general, the + initial_grid_spacing value + should be an integer power of the grid_spacing_limit. So for example, + if grid_spacing_limit has + the value 1, then any initial_grid_spacing specified should + be in the sequence 2, 4, 8, 16, 32... so that the grid + will refine to precisely the lower limit. The grid + spacing may be specified with units. For example: 5 mm or - 10 in . If units are not provided, millimeters - are presumed to be the units. + 10 in . If + units are not provided, millimeters are presumed to be the + units. - The default values are 50.0 mm and 0.5 mm, which is equivalent to specifying: - or - on the command line. This is a hard limit. If other analysis constraints are not - met, the grid spacing will never be refined smaller than the minimum grid size to - satisfy another constraint. The initial grid spacing is divided in half at each - refinement step. As a result, if you desire a lower limit to actually be tested, then - the initial grid size must be a power of 2 greater. For example, specifying -g10mm,1mm - would result in grid spacings of 10, 5, 2.5, 1.25 being used. If the goal was - to exactly end at a 1mm grid, then values such as 8 or 16 should have been - chosen for the initial values. This would result in testing 16, 8, 4, 2, 1 - grid spacing values. + The default values are 50.0 mm and 0.5 mm, which is + equivalent to specifying: + or on the command line. + This is a hard limit. If other analysis constraints are + not met, the grid spacing will never be refined smaller + than the minimum grid size to satisfy another constraint. + The initial grid spacing is divided in half at each + refinement step. As a result, if you desire a lower limit + to actually be tested, then the initial grid size must be + a power of 2 greater. For example, specifying -g10mm,1mm + would result in grid spacings of 10, 5, 2.5, 1.25 being + used. If the goal was to exactly end at a 1mm grid, then + values such as 8 or 16 should have been chosen for the + initial values. This would result in testing 16, 8, 4, 2, + 1 grid spacing values. @@ -348,8 +378,9 @@ - Gets 'view information' from the view to setup the eye position of the single grid. - Used only for overlaps calculations. + Gets 'view information' from the view to setup the eye + position of the single grid. Used only for overlaps calculations. @@ -357,13 +388,16 @@ mass_tolerance[units] - This is like the volume tolerance, , but is applied to the mass - computation results, not the volume computation results. + This is like the volume tolerance, , + but is applied to the mass computation results, not the + volume computation results. - The mass computation tolerance is probably more appropriate when doing whole-vehicle analysis. - If mass computation is selected, it is set to a value equal to the mass of an object 1/100 - the size of the model, which is made of the most dense material in the table. + The mass computation tolerance is probably more + appropriate when doing whole-vehicle analysis. If mass + computation is selected, it is set to a value equal to the + mass of an object 1/100 the size of the model, which is + made of the most dense material in the table. @@ -371,15 +405,18 @@ num_hits - Specifies that the grid be refined until each region has at least - num_hits ray intersections. It applies only when - mass or volume calculations are being performed. This limit is not applied per-view, but - rather per-analysis. So, for example, it is accepted that a thin object might not be hit - at all from one view, but might be hit when it is shot from other views. + Specifies that the grid be refined until each region has + at least num_hits ray + intersections. It applies only when mass or volume + calculations are being performed. This limit is not + applied per-view, but rather per-analysis. So, for + example, it is accepted that a thin object might not be + hit at all from one view, but might be hit when it is shot + from other views. - The default is 1. Hence, each region must be intersected by a ray at least once during - the analysis. + The default is 1. Hence, each region must be intersected + by a ray at least once during the analysis. @@ -387,8 +424,9 @@ num_views - Specifies that only the first num_views - should be computed. This is principally a debugging option. + Specifies that only the first num_views should be computed. This + is principally a debugging option. @@ -396,7 +434,8 @@ - Specifies to display the overlaps as overlays. + Specifies to display the overlaps as overlays. @@ -404,11 +443,14 @@ - Specifies that check should produce plot files for each of the analyses - it performs. These can be overlaid on the geometry in mged - with the overlay command to help visualize the analysis results. - Each of the different analysis types write to a separate plot file and use different - colors for drawing. + Specifies that check should produce + plot files for each of the analyses it performs. These + can be overlaid on the geometry in mged with the overlay command to help visualize the + analysis results. Each of the different analysis types + write to a separate plot file and use different colors for + drawing. @@ -416,10 +458,13 @@ ncpu - Specifies that ncpu CPUs should be used for performing - the calculation. By default, all local CPUs are utilized. This option exists primarily to - reduce the number of computation threads from the machine maximum. Note that specifying more - CPUs than are present on the machine does not increase the number of computation threads. + Specifies that ncpu CPUs + should be used for performing the calculation. By default, + all local CPUs are utilized. This option exists primarily + to reduce the number of computation threads from the + machine maximum. Note that specifying more CPUs than are + present on the machine does not increase the number of + computation threads. @@ -435,8 +480,10 @@ - Indicates that check should print per-region statistics for mass, volume - and surface area as well as the values for the objects specified on the command line. + Indicates that check should print + per-region statistics for mass, volume and surface area as + well as the values for the objects specified on the + command line. @@ -444,8 +491,8 @@ - Disables the reporting of overlaps. Used only for overlaps - sub-command. + Disables the reporting of overlaps. Used only for + overlaps sub-command. @@ -453,10 +500,12 @@ surf_area_tolerance - Specifies a surface area tolerance value that the three - view computations must be within for computation to complete. If surface area calculation - is selected and this option is not set, then the tolerance is set to 1/1,000 of the - estimated surface area of the model bounding box. + Specifies a surface area tolerance + value that the three view computations must be + within for computation to complete. If surface area + calculation is selected and this option is not set, then + the tolerance is set to 1/1,000 of the estimated surface + area of the model bounding box. @@ -464,13 +513,16 @@ samples_per_model_axis - Specifies that the grid spacing will be initially refined so that at least - samples_per_axis_min will be shot along each axis of - the bounding box of the model. For example, if the objects specified have a bounding - box of 0 0 0 -> 4 3 2 and the grid spacing is 1.0, specifying the option - will cause the initial grid spacing to be adjusted to 0.5 so that - 4 samples will be shot across the Z dimension of the bounding box. The default is to ensure - 1 ray per model grid axis. + Specifies that the grid spacing will be initially refined + so that at least samples_per_axis_min will be shot + along each axis of the bounding box of the model. For + example, if the objects specified have a bounding box of 0 + 0 0 -> 4 3 2 and the grid spacing is 1.0, specifying + the option will cause the initial + grid spacing to be adjusted to 0.5 so that 4 samples will + be shot across the Z dimension of the bounding box. The + default is to ensure 1 ray per model grid axis. @@ -478,11 +530,14 @@ overlap_tolerance - Sets the tolerance for computing overlaps. The overlap_tolerance - must be a positive number equal to or greater than 0.0. Any overlap smaller than the value - specified will be ignored. The default value is 0.0, which causes any overlap to be - reported/processed. The value may be specified with a unit specifier such as: - or + Sets the tolerance for computing overlaps. The overlap_tolerance must be a positive + number equal to or greater than 0.0. Any overlap smaller + than the value specified will be ignored. The default + value is 0.0, which causes any overlap to be + reported/processed. The value may be specified with a unit + specifier such as: or @@ -490,13 +545,17 @@ use_air - Specifies the Boolean value (0 or 1) for use_air - which indicates whether regions which are marked as "air" should be retained and included - in the raytrace. Unlike other BRL-CAD raytracing applications, - the default is to retain air in the raytracing. The - option causes air regions to be discarded prior to raytracing. If you turn off use_air, and - request any analysis that requires it (see above), then the program will - exit with an error message. + Specifies the Boolean value (0 or 1) for use_air which indicates whether + regions which are marked as "air" should be retained and + included in the raytrace. Unlike other BRL-CAD raytracing applications, + the default is to retain air in the raytracing. + The option causes air regions to be + discarded prior to raytracing. If you turn off use_air, + and request any analysis that requires it (see + above), then the program will exit + with an error message. @@ -504,16 +563,21 @@ distance_units,volume_units,mass_units - Specify the units used when reporting values. Values must be comma delimited and provided - in the order distance_units,volume_units, - mass_units. For example: - or (The latter example sets only the mass units.) - Note that unit values with spaces in their names such as cu ft - must be contained in quotes for the shell to keep the values together. + Specify the units used when reporting values. Values must + be comma delimited and provided in the order distance_units,volume_units, mass_units. For example: or (The + latter example sets only the mass units.) Note that unit + values with spaces in their names such as cu ft must be contained in quotes for + the shell to keep the values together. - The default units are millimeters, cubic millimeters, and grams. + The default units are millimeters, cubic millimeters, and + grams. @@ -521,9 +585,10 @@ - Turns on verbose reporting of computation progress. This is useful for - learning how the computation is progressing, and what tolerances are causing - further computation to be necessary. + Turns on verbose reporting of computation progress. This + is useful for learning how the computation is progressing, + and what tolerances are causing further computation to be + necessary. @@ -531,12 +596,16 @@ volume_tolerance[units] - Specifies a volumetric tolerance value that the three view computations must be within for - computation to complete. If volume calculation is selected and this option is not set, then - the tolerance is set to 1/1,000 of the volume of the model bounding box. For large, complex objects - (such as entire vehicles), this value might need to be set larger to achieve reasonable - runtime (or even completion). Given the approximate sampling nature of the algorithm, the - three separate view computations will not usually produce identical results. + Specifies a volumetric tolerance value that the three view + computations must be within for computation to complete. + If volume calculation is selected and this option is not + set, then the tolerance is set to 1/1,000 of the volume of + the model bounding box. For large, complex objects (such + as entire vehicles), this value might need to be set + larger to achieve reasonable runtime (or even + completion). Given the approximate sampling nature of the + algorithm, the three separate view computations will not + usually produce identical results. @@ -548,8 +617,11 @@ Specifying Grid and Target Objects - The following will check objects hull, turret, and suspension for overlaps. The grid starts at 1 cm and is refined to 1 mm. - check overlaps -g 1cm-1mm hull turret suspension + The following will check objects hull, turret, and suspension + for overlaps. The grid starts at 1 cm and is refined to 1 mm. + +mged> check overlaps -g 1cm-1mm hull turret suspension + @@ -557,18 +629,23 @@ Specifying Using Non-Default Units - The following computes volume of hull, turret, and suspension. Results are reported in cubic centimeters (cc). The grid spacing starts at 5 in. and will not be refined below 0.3 mm spacing. - check volume -g5in-0.3mm -u ft,cc,oz hull turret suspension + The following computes volume of hull, turret, and suspension. + Results are reported in cubic centimeters (cc). The grid + spacing starts at 5 in. and will not be refined below 0.3 mm + spacing. + +mged> check volume -g5in-0.3mm -u ft,cc,oz hull turret suspension + - For an example of some independent analysis type, consider the following: - - - %check overlaps -g50,50 -u m,m^3,kg overlaps - - + Different Analysis Types + + For examples of some independent analysis types, consider the + following: + +mged> check overlaps -g50,50 -u m,m^3,kg overlaps Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 @@ -582,50 +659,38 @@ SUMMARY 1 unique overlapping pair (1 ordered pair) Overlapping objects: /overlaps/overlap_obj.r /overlaps/closed_box.r 2 unique overlapping objects detected - - - - - %check exp_air -u m,m^3,kg exposed_air.g - - + + + +mged> check exp_air -u m,m^3,kg exposed_air.g Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 list Exposed Air: /exposed_air.g/exposed_air.r count:25921 dist:9m @ (10000 1000 1000) - - - - - %check unconf_air -u m,m^3,kg unconf_air.g - - + + + +mged> check unconf_air -u m,m^3,kg unconf_air.g Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 list Unconfined Air: /unconf_air.g/air1.r /unconf_air.g/air2.r count:23921 dist:7m @ (10000 1000 1000) - - - - - %check gap -u m,m^3,kg gap.g - - + + + +mged> check gap -u m,m^3,kg gap.g Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 list Gaps: /gap.g/closed_box.r /gap.g/closed_box.r count:26082 dist:8m @ (9000 1000 1000) /gap.g/adj_air2.r /gap.g/closed_box.r count:25921 dist:4m @ (1000 5000 1000) - - - - - %check volume -u m,m^3,kg closed_box.r - - + + + +mged> check volume -u m,m^3,kg closed_box.r Units: length: m volume: m^3 weight: kg setting volume tolerance to 1 m^3 @@ -634,13 +699,10 @@ grid spacing 25mm 399 x 399 x 399 grid spacing 12.5mm 799 x 799 x 799 closed_box.r 484.195 m^3 Average total volume: 488.327 m^3 - - - - - %check surf_area -u m,m^3,kg closed_box.r - - + + + +mged> check surf_area -u m,m^3,kg closed_box.r Units: length: m volume: m^3 mass: kg Using estimated surface area tolerance 640000 mm^2 grid: (50, 50) mm, (278, 278) pixels @@ -650,13 +712,10 @@ Surface Area: closed_box.r 384.485 m^2 Average total surface area: 384.485 m^2 - - - - - %check weight -u m,m^3,kg closed_box.r - - + + + +mged> check weight -u m,m^3,kg closed_box.r Units: length: m volume: m^3 weight: kg setting weight tolerance to 768000 kg @@ -664,10 +723,10 @@ grid spacing 50mm 199 x 199 x 199 Weight: closed_box.r 3.6375e+06 kg Average total weight: 3.67541e+06 kg - - - - + + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/clear.xml b/doc/docbook/system/mann/clear.xml new file mode 100644 index 00000000000..2b4c6a0a814 --- /dev/null +++ b/doc/docbook/system/mann/clear.xml @@ -0,0 +1,61 @@ + + + + CLEAR + nged + BRL-CAD + BRL-CAD User Commands + + + + clear + Clear the mged command window. + + + + + + + clear + + + + DESCRIPTION + + + Clear the mged command window. + + + + EXAMPLES + + + Clear the mged command window. + + Enter <command>clear</command> to clear the <emphasis>mged</emphasis> command window. + + + + + mged> clear + + The mged command window is clear. + + + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/color.xml b/doc/docbook/system/mann/color.xml index f2eb512255d..c0bb8990337 100644 --- a/doc/docbook/system/mann/color.xml +++ b/doc/docbook/system/mann/color.xml @@ -18,7 +18,8 @@ color - low high r g b str + -e + low high r g b @@ -29,13 +30,12 @@ lookup table for displayed regions. The ident number for the region is used to find the appropriate color from the lookup table. The low and high values are the limits of region ident numbers to have the - indicated rgb color (0-255) applied. The str - parameter is intended to be an identifying character string, but is currently ignored. + indicated rgb color (0-255) applied. The current list of color table entries may be displayed with the prcolor command, and the entire color table may be edited using - the edcolor command. If a color lookup table exists, its entries - will override any color assigned using the mater - command. + the -e option and/or using the edcolor + command. If a color lookup table exists, its entries will override any color + assigned using the mater command. @@ -49,12 +49,22 @@ range of idents using the color red. - mged> color 1100 1200 255 0 0 fake_string + mged> color 1100 1200 255 0 0 Makes an entry in the color lookup table for regions with idents from 1100-1200 using the color red. + + Open the color table editor + + + mged> color -e + + + Opens a text editor which displays and allows editing for the current color table + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/dbconcat.xml b/doc/docbook/system/mann/dbconcat.xml index 05341875485..3682ee112ea 100644 --- a/doc/docbook/system/mann/dbconcat.xml +++ b/doc/docbook/system/mann/dbconcat.xml @@ -23,6 +23,7 @@ -u -c -s|-p + -O database_file affix @@ -44,10 +45,11 @@ command finds duplicate names, use the prefix option to both the dup and dbconcat commands to find a prefix that produces no duplicates. If duplicate names - are encountered during the "dbconcat" process, computer-generated prefixes - will be added to the object names coming from the database_file - (but member names appearing in combinations will not be modified, so this is a - dangerous practice and should be avoided). The -t option indicates that + are encountered during the "dbconcat" process, there is an option to overwrite the current object. + If the -O option is supplied, all conlicts will automatically be overwritten. + Otherwise, computer-generated prefixes will be added to the object names coming + from the database_file (but member names appearing in combinations will not + be modified, so this is a dangerous practice and should be avoided). The -t option indicates that the title of the database_file should become the title of the currently edited database. The -u option indicates that the units of the database_file should become the units of the currently edited database. Similarly, @@ -83,6 +85,16 @@ and color table. No suffix or prefix is added to the object names. + + Copy a database, overwriting objects in the current databse + + mged> dbconcat -O model_two.g + + Copies all the objects in model_two.g to the current database. No object names are changed while + conflicts in the current database are overwritten with objects from model_two.g + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/dbfindtree.xml b/doc/docbook/system/mann/dbfindtree.xml new file mode 100644 index 00000000000..c2853741dd4 --- /dev/null +++ b/doc/docbook/system/mann/dbfindtree.xml @@ -0,0 +1,60 @@ + + + + DBFINDTREE + nged + BRL-CAD + BRL-CAD User Commands + + + + dbfindtree + Displays the full path of all combinations that have any of the objects specified +as a member. + + + + + + + dbfindtree + objects + + + +DESCRIPTION + + Displays the full path of all combinations that have any of the objects specified + as a member. + + + +EXAMPLES + + The example shows the use of the dbfindtree command to display the full path of all combinations that refer to the specified object. + + Display the full path of all combinations that refer to a specified object. + + + + mged> dbfindtree shapea + + Lists the full path of all combinations that refer to shapea. + + + + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/dir2ae.xml b/doc/docbook/system/mann/dir2ae.xml new file mode 100644 index 00000000000..674001532e8 --- /dev/null +++ b/doc/docbook/system/mann/dir2ae.xml @@ -0,0 +1,59 @@ + + + + DIR2AE + nged + BRL-CAD + BRL-CAD MGED Commands + + + + dir2ae + Returns the azimuth and elevation (AE) using the provided direction vector. + + + + + + + dir2ae + -i + dx dy dz + + + +DESCRIPTION + + Returns the azimuth and elevation (AE) using the provided direction vector as input. If + the -i option is used the commmand will return the inverse + AE. See also the ae2dir and qvrot commands. + + + + +EXAMPLES + + The example shows the use of the dir2ae command to get the AE. + + + Find the AE using the provided direction vector. + + + mged> dir2ae 0.707107 0.707107 0 + + Returns the AE using a direction vector of 0.707107 0.707107 0. + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/dump.xml b/doc/docbook/system/mann/dump.xml new file mode 100644 index 00000000000..37588fab07b --- /dev/null +++ b/doc/docbook/system/mann/dump.xml @@ -0,0 +1,64 @@ + + + + DUMP + nged + BRL-CAD + BRL-CAD User Commands + + + + dump + Copies the entire database to the keep_file. + + + + + + + dump + keep_file + + + +DESCRIPTION + + Copies the entire dababase to the keep_file. + The keep_file is a BRL-CAD + database file and will be located in the current working direction + (use the pwd command to show the current working directory). Note the new + file might have a smaller filesize than the current + file as dumping the file has the same effect that the garbage_collect command has. + See also the keep command. + + + +EXAMPLES + + The example shows the use of the dump command to copy the entire database to a designated file. + + Copy the database to a designated file. + + + + mged> dump sample.g + + Creates sample.g file which is a copy of the current database. + + + + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/e.xml b/doc/docbook/system/mann/e.xml new file mode 100644 index 00000000000..ba6019741e6 --- /dev/null +++ b/doc/docbook/system/mann/e.xml @@ -0,0 +1,92 @@ + + + + e + nged + BRL-CAD + BRL-CAD User Commands + + + + e + Adds the objects in the argument list to the display list so + that they will appear on the MGED display. This is a + synonym for the draw command. + + + + + + + e + -A attribute name/value pairs + -s + -A -oattribute name/value pairs + -C#/#/# + -m1 + objects + + + +DESCRIPTION + + Adds the objects in the argument list to the display list so that + they will appear on the MGED display. This is a + synonym for the draw command; see that entry for a full + list of options. The -C option provides the user a way + to specify a color that overrides all other color specifications including + combination colors and region-id-based colors. The -A + and -o options allow the user to select objects by + attribute. The -s specifies that subtracted and + intersected objects should be drawn with solid lines rather than dot-dash + lines. The -m1 option will display BOTs shaded if the + display manager is OpenGL and the zbuffer and lighting is enabled. To + enable these settings, from the MGED GUI, choose + "Modes/Display Manager/OpenGL", "Misc/Z-buffer" and "Misc/Lighting". + If the zbuffer and lighting is already enabled, toggle them off then back + on to ensure they are enabled. + + +EXAMPLES + + The following examples show the use of the e + command to draw particular objects, to specify color, to draw with shape + lines rather than dot-dash lines, and to limit the objects to be drawn to + those having specific attribute names and value pairs. + + Draw specific objects in the <emphasis>MGED</emphasis> display. + + + + mged> e object1 object2 + + Draws object1 and object2 in the MGED display. + + + + + + Limit the objects to be drawn to those having specific attribute names and value pairs. + + + + mged> e -A -o Comment {First comment} Comment {Second comment} + + + Draws objects that have a "Comment" attribute with a value of either "First + comment" or "Second comment." + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/e_command.xml b/doc/docbook/system/mann/e_command.xml deleted file mode 100644 index e00e991abe9..00000000000 --- a/doc/docbook/system/mann/e_command.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - e - nged - BRL-CAD - BRL-CAD User Commands - - - - e_command - Adds the objects in the argument list to the display list so - that they will appear on the MGED display. This is a - synonym for the draw command. - - - - - - - e - -A attribute name/value pairs - -s - -A -oattribute name/value pairs - -C#/#/# - -m1 - objects - - - -DESCRIPTION - - Adds the objects in the argument list to the display list so that - they will appear on the MGED display. This is a - synonym for the draw command; see that entry for a full - list of options. The -C option provides the user a way - to specify a color that overrides all other color specifications including - combination colors and region-id-based colors. The -A - and -o options allow the user to select objects by - attribute. The -s specifies that subtracted and - intersected objects should be drawn with solid lines rather than dot-dash - lines. The -m1 option will display BOTs shaded if the - display manager is OpenGL and the zbuffer and lighting is enabled. To - enable these settings, from the MGED GUI, choose - "Modes/Display Manager/OpenGL", "Misc/Z-buffer" and "Misc/Lighting". - If the zbuffer and lighting is already enabled, toggle them off then back - on to ensure they are enabled. - - -EXAMPLES - - The following examples show the use of the e - command to draw particular objects, to specify color, to draw with shape - lines rather than dot-dash lines, and to limit the objects to be drawn to - those having specific attribute names and value pairs. - - Draw specific objects in the <emphasis>MGED</emphasis> display. - - - - mged> e object1 object2 - - Draws object1 and object2 in the MGED display. - - - - - - Limit the objects to be drawn to those having specific attribute names and value pairs. - - - - mged> e -A -o Comment {First comment} Comment {Second comment} - - - Draws objects that have a "Comment" attribute with a value of either "First - comment" or "Second comment." - - - - - -AUTHORBRL-CAD Team - -BUG REPORTS - - - Reports of bugs or problems should be submitted via electronic - mail to devs@brlcad.org - - - diff --git a/doc/docbook/system/mann/e_id.xml b/doc/docbook/system/mann/e_id.xml new file mode 100644 index 00000000000..6aa17556551 --- /dev/null +++ b/doc/docbook/system/mann/e_id.xml @@ -0,0 +1,75 @@ + + + + E_ID + nged + BRL-CAD + BRL-CAD User Commands + + + + e_id + + Draws objects whose region IDs are in the given range. + + + + + + + e_id + lower_bound + upper_bound + + + + DESCRIPTION + + + Draws all objects whose region ID falls within the given bounds. If only one input is given, e_id + will draw objects with that region ID. + + + + EXAMPLES + + + Draw all regions with a single region ID. + + Draw all regions with regionID 1000 + + + + mged> e_id 1000 + + + Draws all regions whose region ID is 1000. + + + + + + + Draw all regions whose region IDs are in the 2000s + + + mged> e_id 2000-2999 + + + Draws all regions who regions IDs fall between 2000 and 2999 inclusively. + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/edit.xml b/doc/docbook/system/mann/edit.xml index 930fa4aec8e..d9e4c86f6cb 100644 --- a/doc/docbook/system/mann/edit.xml +++ b/doc/docbook/system/mann/edit.xml @@ -259,14 +259,14 @@ - > + mged> edit - > + mged> edit help @@ -282,7 +282,7 @@ - > + mged> edit translate @@ -301,7 +301,7 @@ - > + mged> edit translate help @@ -309,7 +309,7 @@ - > + mged> edit help translate @@ -334,7 +334,7 @@ - > + mged> edit fake_subcmd -B 12 -k sph.s 1.5 7 -a 0 0 0 cube.s diff --git a/doc/docbook/system/mann/edit_translate.xml b/doc/docbook/system/mann/edit_translate.xml index bedb700d67f..75313d474c0 100644 --- a/doc/docbook/system/mann/edit_translate.xml +++ b/doc/docbook/system/mann/edit_translate.xml @@ -139,7 +139,7 @@ - > + mged> edit translate -k 0 0 0 -a . obj1 obj2 obj3 obj4 obj5 @@ -163,7 +163,7 @@ - > + mged> edit translate -a -z obj1 obj2 obj3 obj4 obj5 @@ -191,7 +191,7 @@ - > + mged> edit translate -k . -a -z obj1 obj2 obj3 obj4 obj5 @@ -215,7 +215,7 @@ - > + mged> edit translate -k . -a obj1 obj2 obj3 obj4 obj5 @@ -237,7 +237,7 @@ - > + mged> edit translate -a -z 7.8 obj @@ -260,7 +260,7 @@ - > + mged> edit translate -n -k . -a . obj1 obj2 obj3 @@ -283,7 +283,7 @@ - > + mged> edit translate -n -a -z obj2/obj3 obj1 @@ -309,7 +309,7 @@ - > + mged> edit translate -n -k obj1 -n -a -z obj2/obj3 obj1 @@ -318,7 +318,7 @@ - > + mged> edit translate -n -k . -n -a -z obj2/obj3 obj1 @@ -336,7 +336,7 @@ - > + mged> edit translate -a -x 8 -z 42 obj1/obj2/obj3 @@ -363,14 +363,14 @@ - > + mged> edit translate -k obj1 -r -z 5 obj2 - > + mged> edit translate -a -z obj1 0 0 5 obj2 @@ -398,7 +398,7 @@ - > + mged> edit translate -k -x c/obj1 1.5 -y c/obj2 0 3 -z c/obj3 0 0 10 -a -x b/c/obj4 2 -y b/c/obj5 0 4 -z b/c/obj6 0 0 20 obj7 obj8 @@ -419,7 +419,7 @@ - > + mged> edit translate -k -x c/obj1 1.5 -a -x b/c/obj4 2 obj7 obj8 @@ -428,7 +428,7 @@ - > + mged> edit translate -k -y c/obj2 0 3 -a -y b/c/obj5 0 4 obj7 obj8 @@ -437,7 +437,7 @@ - > + mged> edit translate -k -z c/obj3 0 0 10 -a -z b/c/obj6 0 0 20 obj7 obj8 diff --git a/doc/docbook/system/mann/env.xml b/doc/docbook/system/mann/env.xml new file mode 100644 index 00000000000..b798e7e138e --- /dev/null +++ b/doc/docbook/system/mann/env.xml @@ -0,0 +1,61 @@ + + + + ENV + nged + BRL-CAD + BRL-CAD User Commands + + + + env + Print the current environmental variables. + + + + + + + env + + + + DESCRIPTION + + + Print the current environmental variables. + + + + EXAMPLES + + + Print the current environmental variables. + + Enter <command>env</command> to display the current environmental variables. + + + + + mged> env + + The current environmental variables and their values are displayed. + + + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/eqn.xml b/doc/docbook/system/mann/eqn.xml index c5dd7314018..79b22139cf8 100644 --- a/doc/docbook/system/mann/eqn.xml +++ b/doc/docbook/system/mann/eqn.xml @@ -57,16 +57,6 @@ The user must be editing an ARB shape and be rotating a fac - - - <para> - <prompt/><userinput/> - </para> - <para> - - </para> - </example> - </refsection> <refsection xml:id="author"><title>AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/exists.xml b/doc/docbook/system/mann/exists.xml index 214f15cc006..36fa09a4d46 100644 --- a/doc/docbook/system/mann/exists.xml +++ b/doc/docbook/system/mann/exists.xml @@ -247,11 +247,11 @@ Example1 - - exists object1.s - - - + + +mged> exists object1.s + + diff --git a/doc/docbook/system/mann/eye_pt.xml b/doc/docbook/system/mann/eye_pt.xml index c161828e598..fcd53e81cff 100644 --- a/doc/docbook/system/mann/eye_pt.xml +++ b/doc/docbook/system/mann/eye_pt.xml @@ -18,7 +18,7 @@ eye_pt - x y z> + x y z diff --git a/doc/docbook/system/mann/facedef.xml b/doc/docbook/system/mann/facedef.xml index c3fbe157bc0..405dbada0b8 100644 --- a/doc/docbook/system/mann/facedef.xml +++ b/doc/docbook/system/mann/facedef.xml @@ -94,7 +94,7 @@ - mgedfacedef 5678 b 0 0 10 10 0 10 10 10 10 + mged> facedef 5678 b 0 0 10 10 0 10 10 10 10 Moves face 5678 such that it is in the plane formed by the three points (0 0 10), (10 diff --git a/doc/docbook/system/mann/facetize.xml b/doc/docbook/system/mann/facetize.xml index 65c99afab02..190a05060eb 100644 --- a/doc/docbook/system/mann/facetize.xml +++ b/doc/docbook/system/mann/facetize.xml @@ -25,6 +25,7 @@ -r -n -T + --MANIFOLD --NMG --CM --SPSR @@ -129,8 +130,8 @@ Facetize all regions in a hierarchy, attempting only NMG conversion. - This runs the per region conversion on all regions, but in the case of failure will not attempt - any fallback conversion methods. + This runs the NMG approach per region conversion on all regions, but in + the case of failure will not attempt any fallback conversion methods. mged> facetize -r --NMG model model.f @@ -141,7 +142,7 @@ Retry failed conversion objects in a previous facetization attempt with new methodology. This retries the per region conversion on all regions that didn't originally succeed in the initial - conversion attempt, attempting only CM reconstruction without first retrying NMG conversion. + conversion attempt, attempting only methods that haven't already been tried. mged> facetize -r --resume model.f @@ -194,9 +195,11 @@ CM: decimation succeeded, final BoT has 247642 faces very important to maximizing the success of a conversion. - By default, conversions will first attempt a standard NMG facetization and boolean evaluation of - the existing geometry. When it succeeds, NMG's output is generally the best quality output that - can be produced by any of BRL-CAD's available facetization methods. If NMG booleans fail, a fall-back method based + By default, conversions will first attempt facetization using the Manifold library to evaluate boolean + operations on individual meshes. If that fails, the libnmg boolean evaluation is tried instead. + When one of those two approaches succeeds, the output (based of of individual NMG conversion of primitives) + is generally the best quality output that can be produced by any of BRL-CAD's available facetization methods. + If NMG based boolean methods fail, a fall-back method based on Bloomenthal's continuation method (CM) polygonalizer will be attempted by default.Note that if any of the methodology flags (--NMG,--CM, or --SPSR) are explicitly enabled, the other methodologies will be disabled unless they @@ -204,7 +207,7 @@ CM: decimation succeeded, final BoT has 247642 faces While the facetize command does not itself expose options to adjust the behavior of - the NMG boolean methodology, it will respect MGED's settings for absolute (abs), + NMG-based methodologies, it will respect MGED's settings for absolute (abs), relative (rel), and normal (norm) tolerances which are set with the MGED tol command. These settings may be changed between repeated runs of the facetize command to attempt different NMG evaluations. @@ -234,8 +237,8 @@ CM: decimation succeeded, final BoT has 247642 faces the moss.g ellipsoid region. - Both NMG and CM assume a geometry hierarchy containing only - valid solid objects. Both methods will refuse to process any tree containing recognizably + MANIFOLD, NMG and CM assume a geometry hierarchy containing only + valid solid objects. Those methods will refuse to process any tree containing recognizably non-solid objects, as these tend to cause run-time problems and generate invalid outputs. For non-solid objects, the "--SPSR" methodology may be enabled - it will apply the Kazhdan et. al. Screened Poisson Surface Reconstruction (SPSR) process to a pseudo-randomly sampled point set generated from old_object. This diff --git a/doc/docbook/system/mann/g.xml b/doc/docbook/system/mann/g.xml index 0226cd363b2..90c2548a00d 100644 --- a/doc/docbook/system/mann/g.xml +++ b/doc/docbook/system/mann/g.xml @@ -38,9 +38,9 @@ - mged> g shape1.nmg f + mged> g group.c shape1.s - Creates or extends shape1.nmg by unioning in f. + Creates or extends group.c by unioning in shape1.s. diff --git a/doc/docbook/system/mann/get.xml b/doc/docbook/system/mann/get.xml index 8e97256e0a4..a00b6683404 100644 --- a/doc/docbook/system/mann/get.xml +++ b/doc/docbook/system/mann/get.xml @@ -40,9 +40,9 @@ - mged> make eto.s eto - mged> l eto.s +mged> make eto.s eto +mged> l eto.s eto.s: Elliptical Torus (ETO) V (0, 0, 0) N=(0, 0, 1) @@ -51,8 +51,10 @@ eto.s: Elliptical Torus (ETO) d=100 - mged> get eto.s r + + +mged> get eto.s r 800 diff --git a/doc/docbook/system/mann/gqa.xml b/doc/docbook/system/mann/gqa.xml index a40d25312b4..747a62bd943 100644 --- a/doc/docbook/system/mann/gqa.xml +++ b/doc/docbook/system/mann/gqa.xml @@ -23,54 +23,62 @@ DESCRIPTION - The gqa program computes and reports a variety of characteristics of the - objects specified from the given - model.g geometric description. - The characteristics which can be computed include - weight, volume, overlaps, exposed air, gaps/voids, - and adjacent air. Only the - objects from the database specified on the command line are - analyzed. + The gqa program computes and reports a + variety of characteristics of the objects specified from the given model.g geometric description. The + characteristics which can be computed include weight, volume, overlaps, exposed air, + gaps/voids, and adjacent air. Only the objects from the database specified on the + command line are analyzed. - It works by shooting grids of rays from the three axis-aligned directions (sometimes called - views). + It works by shooting grids of rays from the three axis-aligned + directions (sometimes called views). - For volume/weight calculations the resulting calculations for each view are compared to - each other. The grid of rays is progressively refined until the results from all three views - agree within a user-specifiable tolerance, or a limit on grid refinement is reached. + For volume/weight calculations the resulting calculations for + each view are compared to each other. The grid of rays is + progressively refined until the results from all three views + agree within a user-specifiable tolerance, or a limit on grid + refinement is reached. - For error and interface calculations, the grid is refined until an error is found or the - grid refinement limit is reached. + For error and interface calculations, the grid is refined until + an error is found or the grid refinement limit is reached. - When multiple calculations are performed, the most extensive path is taken. - For example, if weight and overlap calculations are performed, then the grid - will be refined until the refinement limit is reached, or an overlap is - detected. + When multiple calculations are performed, the most extensive + path is taken. For example, if weight and overlap calculations + are performed, then the grid will be refined until the + refinement limit is reached, or an overlap is detected. VOLUME AND WEIGHT CALCULATION - If volume or weight calculation is selected, a value is calculated and reported - for each object specified on the command line. - Note that if there are overlaps or other errors in the - geometry, the values reported will be invalid. + If volume or weight calculation is selected, a value is + calculated and reported for each object specified on the command line. + Note that if there are overlaps + or other errors in the geometry, the values reported will be + invalid. - For weight computation, the density of every region must be specified. - Densities are specified as an index in a table of density values. - This index is stored in the GIFTmater - attribute of each region (typically set with the edcodes + For weight computation, the density of every region must be + specified. Densities are specified as an index in a table of + density values. This index is stored in the GIFTmater attribute of each region + (typically set with the edcodes or adjust commands in MGED). @@ -83,8 +91,9 @@ An integer index value. - This is the value to which the GIFTmater attribute - will be set to select this material for the region. + This is the value to which the GIFTmater attribute will be set to + select this material for the region. @@ -108,46 +117,56 @@ - This information may be stored in the .g file or as a separate density file. + This information may be stored in the .g file or as a separate + density file. - To check if the .g file you are using has a density table, use the mater -d get * command to see if any information is already defined (if no density information is found, an error message will be returned.) If no pre-existing information is available, a density table may be defined in an external file using a text editor. - (Alternately, it may also be built up within MGED directly using the mater -d set command.) + To check if the .g file you are using has a density table, use + the mater -d get * command to see if any + information is already defined (if no density information is + found, an error message will be returned.) If no pre-existing + information is available, a density table may be defined in an + external file using a text editor. (Alternately, it may also be + built up within MGED directly using the mater -d + set command.) An example file might look like the following: - - - - + - To import an existing density file into the database, use the mater -d import - command: + To import an existing density file into the database, use the + mater -d import command: - mged> mater -d import filename + mged> mater -d import filename - If existing density values need to be corrected in the .g file, the mater -d set command may be used to alter them. For more about density information manipulation, see the materN manual page. + If existing density values need to be corrected in the .g file, + the mater -d set command may be used to alter + them. For more about density information manipulation, see the + materN + manual page. The geometry editor MGED automatically assigns an index value of - 1 to a newly created region. While this default can be handy - when a vast majority of objects are made from the same material, it can lead to - surprising errors when objects which are supposed to have a - certain weight are computed to have different weight because one or two regions - were not set to the correct, nondefault index value. As a result, it is advised that - the index value 1 never be used. If this practice is followed, - then an error message will be generated for any regions which have not had their - material index set to something other than the default. + 1 to a newly created region. While this + default can be handy when a vast majority of objects are made + from the same material, it can lead to surprising errors when + objects which are supposed to have a certain weight are computed + to have different weight because one or two regions were not set + to the correct, nondefault index value. As a result, it is + advised that the index value 1 never be + used. If this practice is followed, then an error message will + be generated for any regions which have not had their material + index set to something other than the default. @@ -155,20 +174,22 @@ GEOMETRY ERROR DETECTION - All of these calculations run until an error is detected, or until the grid - refinement limit is reached. + All of these calculations run until an error is detected, or + until the grid refinement limit is reached. OVERLAP DETECTION - For each pair of regions that overlap, the tool reports the two regions that - overlap, the maximum line-of-sight thickness of the overlap, and the in-hit location - of the ray that caused that maximum overlap thickness. + For each pair of regions that overlap, the tool reports the two + regions that overlap, the maximum line-of-sight thickness of the + overlap, and the in-hit location of the ray that caused that + maximum overlap thickness. - Other analyses in the error detection category behave in a similar manner. + Other analyses in the error detection category behave in a + similar manner. @@ -179,9 +200,10 @@ analysis_flags - Specifies which computations are to be performed and reported. - The analysis_flags - parameter is one or more of the following: + Specifies which computations are to be performed and + reported. The analysis_flags parameter is one or + more of the following: @@ -243,69 +265,83 @@ - Adjacent different air (a): - Detects air volumes which are next to each other but have different - air_code values applied to the region. This would typically indicate - that the regions are different types of air, such as crew_air (which - fills the crew compartment of a vehicle) and engine_air (which surrounds the engine). - When these different types of air adjoin each other, it is generally considered - a modeling error. + Adjacent different air + (a): Detects air volumes which are next to each + other but have different air_code values applied to the + region. This would typically indicate that the regions are + different types of air, such as crew_air (which fills the + crew compartment of a vehicle) and engine_air (which + surrounds the engine). When these different types of air + adjoin each other, it is generally considered a modeling + error. - Bounding box dimensions (b): - Reports the dimensions of an axis-aligned box which fully encloses the - objects. + Bounding box dimensions + (b): Reports the dimensions of an axis-aligned + box which fully encloses the objects. - Exposed air (e): - This causes checks to be made to see if the ray encounters air regions before - (or after all) solid objects. Typically, only the air inside a building or - vehicle is modeled if the purpose of the model is to support analysis of - that single structure/vehicle. There are exceptions, such as when modeling - larger environments for more extended analysis purposes. + Exposed air + (e): This causes checks to be made to see if + the ray encounters air regions before (or after all) solid + objects. Typically, only the air inside a building or + vehicle is modeled if the purpose of the model is to + support analysis of that single structure/vehicle. There + are exceptions, such as when modeling larger environments + for more extended analysis purposes. Gaps/voids (g): - This reports when there is more than overlap_tol_dist - (see the option below) between objects on the ray path. Note - that not all gaps are errors. For example, gaps between a wheel and a fender are - expected (unless external air is modeled). Typically, users should perform gap - analysis on contained subsets of a model (such as passenger compartments) - rather than on whole vehicles. + This reports when there is more than overlap_tol_dist (see the + option below) between objects on the + ray path. Note that not all gaps are errors. For + example, gaps between a wheel and a fender are expected + (unless external air is modeled). Typically, users should + perform gap analysis on contained subsets of a model (such + as passenger compartments) rather than on whole vehicles. Overlaps (o): - are two regions which occupy the same space. In the real world, two objects may - not occupy the same space. This check is sometimes also known as - interference checking. Two objects must overlap - by at least overlap_tol_dist (see the - option below) to be considered to overlap. Overlap testing - causes the grid spacing to be refined until the limit is reached, or an overlap - is detected. See the option below for details on setting the - grid spacing. Once overlaps have been detected, grid refinement is not done, and - processing stops. + are two regions which occupy the same space. In the real + world, two objects may not occupy the same space. This + check is sometimes also known as interference checking. Two objects + must overlap by at least overlap_tol_dist (see the + option below) to be considered to + overlap. Overlap testing causes the grid spacing to be + refined until the limit is reached, or an overlap is + detected. See the option below for + details on setting the grid spacing. Once overlaps have + been detected, grid refinement is not done, and processing + stops. - Visualize Overlaps (p): - In MGED, if overlaps are detected, this option causes the overlaps found to be - illustrated in the wireframe view via yellow lines. + Visualize Overlaps + (p): In MGED, if overlaps are detected, this + option causes the overlaps found to be illustrated in the + wireframe view via yellow lines. Volume (v): - Computes the volume of the objects - specified on the command line. + Computes the volume of the objects specified on the command + line. Weight (w): - Computes the weight of the objects - specified on the command line. + Computes the weight of the objects specified on the command + line. @@ -314,8 +350,9 @@ Not Implemented. - Sets a rotation (in degrees) of the coordinate system by a given amount about - the Z axis. The default is 0. See also: + Sets a rotation (in degrees) of the coordinate system by a + given amount about the Z axis. The default is 0. See + also: @@ -324,9 +361,9 @@ Not Implemented. - Sets a rotation (in degrees) of the coordinate system by a given elevation - from the XY plane (rotation about X axis?). The default is 0. - See also + Sets a rotation (in degrees) of the coordinate system by a + given elevation from the XY plane (rotation about X + axis?). The default is 0. See also @@ -334,10 +371,12 @@ filename - Specifies that density values should be taken from an external file instead of from the - _DENSITIES object in the database. - This option can be useful when developing the density table with a text editor, - prior to importing it to the geometric database. + Specifies that density values should be taken from an + external file instead of from the _DENSITIES object in the database. + This option can be useful when developing the density + table with a text editor, prior to importing it to the + geometric database. @@ -345,19 +384,26 @@ [initial_grid_spacing-]grid_spacing_limit - Specifies a limit on how far the grid can be refined and optionally the initial spacing - between rays in the grids. The first value (if present) indicates the initial spacing - between grid rays. The mandatory argument, "grid_spacing_limit," - indicates a lower bound on how fine the grid spacing may get before computation is - terminated. In general, the initial_grid_spacing value - should be an integer power of the grid_spacing_limit. So - for example, if grid_spacing_limit has the value 1, - then any initial_grid_spacing specified should be in the - sequence 2, 4, 8, 16, 32... so that the grid will refine to precisely the lower limit. - The grid spacing may be specified with units. For example: + Specifies a limit on how far the grid can be refined and + optionally the initial spacing between rays in the + grids. The first value (if present) indicates the initial + spacing between grid rays. The mandatory argument, + "grid_spacing_limit," + indicates a lower bound on how fine the grid spacing may + get before computation is terminated. In general, the + initial_grid_spacing value + should be an integer power of the grid_spacing_limit. So for example, + if grid_spacing_limit has + the value 1, then any initial_grid_spacing specified should + be in the sequence 2, 4, 8, 16, 32... so that the grid + will refine to precisely the lower limit. The grid + spacing may be specified with units. For example: 5 mm or - 10 in. If units are not provided, millimeters - are presumed to be the units. + 10 in. If units + are not provided, millimeters are presumed to be the + units. @@ -365,17 +411,20 @@ - The default values are 50.0 mm and 0.5 mm, which is equivalent to specifying: - or - on the command line. This is a hard limit. If other analysis constraints are not - met, the grid spacing will never be refined smaller than the minimum grid size to - satisfy another constraint. The initial grid spacing is divided in half at each - refinement step. As a result, if you desire a lower limit to actually be tested, then - the initial grid size must be a power of 2 greater. For example, specifying -g10mm,1mm - would result in grid spacings of 10, 5, 2.5, 1.25 being used. If the goal was - to exactly end at a 1mm grid, then values such as 8 or 16 should have been - chosen for the initial values. This would result in testing 16, 8, 4, 2, 1 - grid spacing values. + The default values are 50.0 mm and 0.5 mm, which is equivalent + to specifying: or on the command line. This is a hard + limit. If other analysis constraints are not met, the grid + spacing will never be refined smaller than the minimum grid size + to satisfy another constraint. The initial grid spacing is + divided in half at each refinement step. As a result, if you + desire a lower limit to actually be tested, then the initial + grid size must be a power of 2 greater. For example, specifying + -g10mm,1mm would result in grid spacings of 10, 5, 2.5, 1.25 + being used. If the goal was to exactly end at a 1mm grid, then + values such as 8 or 16 should have been chosen for the initial + values. This would result in testing 16, 8, 4, 2, 1 grid + spacing values. @@ -384,13 +433,16 @@ Not Implemented. - Specifies that the program should create new - assembly combinations in the geometry database to - represent the overlap pairs. This flag is meaningless if overlap reporting is not - turned on with the option. If regions - rod.r and disk.r - overlap, this option will cause the creation of an assembly called - _OVERLAP_rod.r_disk.r, which includes the following items: + Specifies that the program should create new assembly combinations in the geometry + database to represent the overlap pairs. This flag is + meaningless if overlap reporting is not turned on with the + option. If regions rod.r and disk.r overlap, this option will + cause the creation of an assembly called + _OVERLAP_rod.r_disk.r, which includes + the following items: rod.r @@ -404,8 +456,9 @@ - The last item is an object to represent the overlapping area so that it can be easily seen. - The default is that no groups are created. + The last item is an object to represent the overlapping + area so that it can be easily seen. The default is that + no groups are created. @@ -413,27 +466,31 @@ num_hits - Specifies that the grid be refined until each region has at least - num_hits ray intersections. It applies only when - weight or volume calculations are being performed. This limit is not applied per-view, but - rather per-analysis. So, for example, it is accepted that a thin object might not be hit - at all from one view, but might be hit when it is shot from other views. + Specifies that the grid be refined until each region has + at least num_hits ray + intersections. It applies only when weight or volume + calculations are being performed. This limit is not + applied per-view, but rather per-analysis. So, for + example, it is accepted that a thin object might not be + hit at all from one view, but might be hit when it is shot + from other views. - The default is 1. Hence, each region must be intersected by a ray at least once during - the analysis. + The default is 1. Hence, each region must be intersected by a + ray at least once during the analysis. num_views - Specifies that only the first num_views - should be computed. This is principally a debugging option. + Specifies that only the first num_views should be computed. This + is principally a debugging option. @@ -441,11 +498,14 @@ - Specifies that gqa should produce plot files for each of the analyses - it performs. These can be overlaid on the geometry in mged - with the overlay command to help visualize the analysis results. - Each of the different analysis types write to a separate plot file and use different - colors for drawing. + Specifies that gqa should produce plot + files for each of the analyses it performs. These can be + overlaid on the geometry in mged with the overlay command to help visualize the + analysis results. Each of the different analysis types + write to a separate plot file and use different colors for + drawing. @@ -453,10 +513,13 @@ ncpu - Specifies that ncpu CPUs should be used for performing - the calculation. By default, all local CPUs are utilized. This option exists primarily to - reduce the number of computation threads from the machine maximum. Note that specifying more - CPUs than are present on the machine does not increase the number of computation threads. + Specifies that ncpu CPUs + should be used for performing the calculation. By default, + all local CPUs are utilized. This option exists primarily + to reduce the number of computation threads from the + machine maximum. Note that specifying more CPUs than are + present on the machine does not increase the number of + computation threads. @@ -472,8 +535,9 @@ - Indicates that gqa should print per-region statistics for weight and - volume as well as the values for the objects specified on the command line. + Indicates that gqa should print + per-region statistics for weight and volume as well as the + values for the objects specified on the command line. @@ -481,13 +545,16 @@ samples_per_model_axis - Specifies that the grid spacing will be initially refined so that at least - samples_per_axis_min will be shot along each axis of - the bounding box of the model. For example, if the objects specified have a bounding - box of 0 0 0 -> 4 3 2 and the grid spacing is 1.0, specifying the option - will cause the initial grid spacing to be adjusted to 0.5 so that - 4 samples will be shot across the Z dimension of the bounding box. The default is to ensure - 1 ray per model grid axis. + Specifies that the grid spacing will be initially refined + so that at least samples_per_axis_min will be shot + along each axis of the bounding box of the model. For + example, if the objects specified have a bounding box of 0 + 0 0 -> 4 3 2 and the grid spacing is 1.0, specifying + the option will cause the initial + grid spacing to be adjusted to 0.5 so that 4 samples will + be shot across the Z dimension of the bounding box. The + default is to ensure 1 ray per model grid axis. @@ -495,11 +562,14 @@ overlap_tolerance - Sets the tolerance for computing overlaps. The overlap_tolerance - must be a positive number equal to or greater than 0.0. Any overlap smaller than the value - specified will be ignored. The default value is 0.0, which causes any overlap to be - reported/processed. The value may be specified with a unit specifier such as: - or + Sets the tolerance for computing overlaps. The overlap_tolerance must be a positive + number equal to or greater than 0.0. Any overlap smaller + than the value specified will be ignored. The default + value is 0.0, which causes any overlap to be + reported/processed. The value may be specified with a unit + specifier such as: or @@ -507,13 +577,17 @@ use_air - Specifies the Boolean value (0 or 1) for use_air - which indicates whether regions which are marked as "air" should be retained and included - in the raytrace. Unlike other BRL-CAD raytracing applications, - the default is to retain air in the raytracing. The - option causes air regions to be discarded prior to raytracing. If you turn off use_air, and - request any analysis that requires it (see above), then the program will - exit with an error message. + Specifies the Boolean value (0 or 1) for use_air which indicates whether + regions which are marked as "air" should be retained and + included in the raytrace. Unlike other BRL-CAD raytracing applications, + the default is to retain air in the raytracing. + The option causes air regions to be + discarded prior to raytracing. If you turn off use_air, + and request any analysis that requires it (see + above), then the program will exit + with an error message. @@ -521,16 +595,21 @@ distance,volume,weight - Specify the units used when reporting values. Values must be comma delimited and provided - in the order distance,volume, - weight. For example: - or (The latter example sets only the weight units.) - Note that unit values with spaces in their names such as cu ft - must be contained in quotes for the shell to keep the values together. + Specify the units used when reporting values. Values must + be comma delimited and provided in the order distance,volume, weight. For example: or (The + latter example sets only the weight units.) Note that + unit values with spaces in their names such as cu ft must be contained in quotes for + the shell to keep the values together. - The default units are millimeters, cubic millimeters, and grams. + The default units are millimeters, cubic millimeters, and + grams. @@ -538,9 +617,10 @@ - Turns on verbose reporting of computation progress. This is useful for - learning how the computation is progressing, and what tolerances are causing - further computation to be necessary. + Turns on verbose reporting of computation progress. This + is useful for learning how the computation is progressing, + and what tolerances are causing further computation to be + necessary. @@ -548,12 +628,16 @@ volume_tolerance[units] - Specifies a volumetric tolerance value that the three view computations must be within for - computation to complete. If volume calculation is selected and this option is not set, then - the tolerance is set to 1/1,000 of the volume of the model bounding box. For large, complex objects - (such as entire vehicles), this value might need to be set larger to achieve reasonable - runtimes (or even completion). Given the approximate sampling nature of the algorithm, the - three separate view computations will not usually produce identical results. + Specifies a volumetric tolerance value that the three view + computations must be within for computation to complete. + If volume calculation is selected and this option is not + set, then the tolerance is set to 1/1,000 of the volume of + the model bounding box. For large, complex objects (such + as entire vehicles), this value might need to be set + larger to achieve reasonable runtimes (or even + completion). Given the approximate sampling nature of the + algorithm, the three separate view computations will not + usually produce identical results. @@ -561,13 +645,16 @@ weight_tolerance[units] - This is like the volume tolerance, , but is applied to the weight - computation results, not the volume computation results. + This is like the volume tolerance, , + but is applied to the weight computation results, not the + volume computation results. - The weight computation tolerance is probably more appropriate when doing whole-vehicle analysis. - If weight computation is selected, it is set to a value equal to the weight of an object 1/100 - the size of the model, which is made of the most dense material in the table. + The weight computation tolerance is probably more + appropriate when doing whole-vehicle analysis. If weight + computation is selected, it is set to a value equal to the + weight of an object 1/100 the size of the model, which is + made of the most dense material in the table. @@ -579,65 +666,69 @@ Default Behavior - The following command computes the weight of an object called wheel.r - reports the weight and volume, and checks for overlaps. Assumes a _DENSITIES table object is present - in the database. - gqa wheel.r + The following command computes the weight of an object called + wheel.r reports the weight and + volume, and checks for overlaps. Assumes a _DENSITIES table + object is present in the database. + +mged> gqa wheel.r + Specifying Grid and Target Objects - The following will check objects hull, turret, and suspension for overlaps - and report exposed air. The grid starts at 1 cm and is refined to 1 mm unless overlaps or - exposed air are detected before the grid is refined to 1 mm. - gqa -g 1cm-1mm -Aoe hull turret suspension + The following will check objects hull, turret, and suspension + for overlaps and report exposed air. The grid starts at 1 cm + and is refined to 1 mm unless overlaps or exposed air are + detected before the grid is refined to 1 mm. + +mged> gqa -g 1cm-1mm -Aoe hull turret suspension + Specifying Using Non-Default Units - The following computes volume and weight of hull, turret, and suspension. Results are - reported in cubic centimeters (cc) and ounces (oz). The grid spacing starts at 5 in. and - will not be refined below 0.3 mm spacing. - gqa -g5in-0.3mm -Avw -u ft,cc,oz hull turret suspension + The following computes volume and weight of hull, turret, and + suspension. Results are reported in cubic centimeters (cc) + and ounces (oz). The grid spacing starts at 5 in. and will + not be refined below 0.3 mm spacing. + +mged> gqa -g5in-0.3mm -Avw -u ft,cc,oz hull turret suspension + - For an example of each independent analysis type, consider the following: - - - mged> gqa -u m,m^3,kg -Ao overlaps - - + Different Analysis Types + + For an example of each independent analysis type, consider + the following: + + +mged> gqa -u m,m^3,kg -Ao overlaps Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 Summary: list Overlaps: /overlaps/overlap_obj.r /overlaps/closed_box.r count:32039 dist:8m @ (9050 1000 1000) - - - - - mged> gqa -u m,m^3,kg -Ae exposed_air.g - - + + + +mged> gqa -u m,m^3,kg -Ae exposed_air.g Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 Summary: list Exposed Air: /exposed_air.g/exposed_air.r count:25921 dist:9m @ (10000 1000 1000) - - - - - mged> gqa -u m,m^3,kg -Ag gap.g - - + + + +mged> gqa -u m,m^3,kg -Ag gap.g Units: length: m volume: m^3 weight: kg grid spacing 50mm 199 x 199 x 199 @@ -645,13 +736,10 @@ Summary: list Gaps: /gap.g/closed_box.r /gap.g/closed_box.r count:26082 dist:8m @ (9000 1000 1000) /gap.g/adj_air2.r /gap.g/closed_box.r count:25921 dist:4m @ (1000 5000 1000) - - - - - mged> gqa -u m,m^3,kg -Av closed_box.r - - + + + +mged> gqa -u m,m^3,kg -Av closed_box.r Units: length: m volume: m^3 weight: kg setting volume tolerance to 1 m^3 @@ -661,13 +749,10 @@ grid spacing 12.5mm 799 x 799 x 799 Summary: closed_box.r 484.195 m^3 Average total volume: 488.327 m^3 - - - - - mged> gqa -u m,m^3,kg -Aw closed_box.r - - + + + +mged> gqa -u m,m^3,kg -Aw closed_box.r Units: length: m volume: m^3 weight: kg setting weight tolerance to 768000 kg @@ -676,10 +761,9 @@ Summary: Weight: closed_box.r 3.6375e+06 kg Average total weight: 3.67541e+06 kg - - - - + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/hide.xml b/doc/docbook/system/mann/hide.xml index 8288f3cb2f1..41576a63859 100644 --- a/doc/docbook/system/mann/hide.xml +++ b/doc/docbook/system/mann/hide.xml @@ -9,7 +9,7 @@ hide - Sets the “hidden” flag for the specified objects. + Sets the hidden flag for the specified objects. @@ -23,8 +23,11 @@ DESCRIPTION - Sets the “hidden” flag for the specified objects. When this flag - is set, the objects do not appear in t or ls command outputs. The -a option on the ls or t command will force hidden objects to appear in its output. + Sets the hidden flag for the specified objects. When this flag + is set, the objects do not appear in ls, t, or + tops command outputs. The -a option on the + ls, t, and tops + commands will force hidden objects to appear in its output. diff --git a/doc/docbook/system/mann/ill.xml b/doc/docbook/system/mann/ill.xml index 31eb65cc333..0a2910087f5 100644 --- a/doc/docbook/system/mann/ill.xml +++ b/doc/docbook/system/mann/ill.xml @@ -40,7 +40,7 @@ mged> ill shapea - Shapea> is selected for editing. + Shapea is selected for editing. diff --git a/doc/docbook/system/mann/killall.xml b/doc/docbook/system/mann/killall.xml index c0e8aab17e3..9bfe69ca40b 100644 --- a/doc/docbook/system/mann/killall.xml +++ b/doc/docbook/system/mann/killall.xml @@ -33,6 +33,7 @@ flag is passed. The flag causes the command to return a string of the objects that would be killed in a scriptable list format without actually killing them. + See also the killrefs command. Use this command with diff --git a/doc/docbook/system/mann/killrefs.xml b/doc/docbook/system/mann/killrefs.xml new file mode 100644 index 00000000000..96eabdfb925 --- /dev/null +++ b/doc/docbook/system/mann/killrefs.xml @@ -0,0 +1,98 @@ + + + + KILLREFS + nged + BRL-CAD + BRL-CAD User Commands + + + + killrefs + Removes all references to the specified objects from all + combinations in the database. + + + + + + + killrefs + -n + objects + + + +DESCRIPTION + + Removes all references to the specified objects from all + combinations in the database. Note that the + references are removed immediately unless the + flag is passed. The flag + causes the command to return a string of the objects that would be + affected in a scriptable list format without actually editing them. + See also the killall command. + + + Use this command with + caution. Killed objects cannot be recovered so + keep a backup. + + + + +EXAMPLES + + This example shows the use of the killrefs + command to remove all references to the + specified objects from the database. + + Remove all references to the specified objects from the database. + + + + mged> killref group1 + + Removes all references to group1 from the database. + + + + + + + This example shows the use of the killrefs + command to list all references to the + specified objects in the database. + + List all references to the specified objects in the database. + + + + mged> killref -n group1 + + Lists all references to group1 in the database. + + + + + + + + +SEE ALSO + + killnged + killtreenged + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/make_pnts.xml b/doc/docbook/system/mann/make_pnts.xml index 202e7348014..97192c8c9c2 100644 --- a/doc/docbook/system/mann/make_pnts.xml +++ b/doc/docbook/system/mann/make_pnts.xml @@ -41,7 +41,7 @@ Consecutive delimiters are treated as one delimiter. Text files can be used from Windows or Unix systems without conversion. Numerical values can be listed in any order but ordering must be consistent. Numerical values can - optionally be ignored. + optionally be ignored. See also the pnts command. OPTIONS diff --git a/doc/docbook/system/mann/mirror.xml b/doc/docbook/system/mann/mirror.xml new file mode 100644 index 00000000000..25b8dfcee48 --- /dev/null +++ b/doc/docbook/system/mann/mirror.xml @@ -0,0 +1,87 @@ + + + + MIRROR + nged + BRL-CAD + BRL-CAD User Commands + + + + mirror + Mirrors a shape or combination across a given axis. + + + + + + + mirror + -p "point" + -d "dir" + -x|-y-|-z + -o offset + from_object to_object + + + +DESCRIPTION + + Mirrors an object (shape or combination) across a given axis (x by default). + If from_object is a shape, then it is copied to a new shape named + to_object that is mirrored across the given axis. If from_object + is a combination, then a new combination is created that contains exactly the same members naned to_object. + Transformation matrices are added to mirror it across the requested axis. The -x, -y, & -z options tell the + command which axis to mirror the object. The -p can be used to specify a point to mirror about, and + the -d can be used to specify a direction vector to mirror about. + + + +EXAMPLES + + The example shows the use of the mirror command to mirror an object across the y axis. + + Mirror an object across an axis. + + + mged> mirror -y solid.s mir_solid.s + + Creates a copy of solid.s that is mirrored across the y axis and named mir_solid.s + + + + The example shows the use of the mirror command to mirror an object across a plane of x=100. + + Mirror an object across an plane parallel to an axis. + + + mged> mirror -x -o 100 solid.s mir_solid.s + + Creates a copy of solid.s that is mirrored across a plane parallel to the x axis at x=100 and named mir_solid.s + + + + The example shows the use of the mirror command to mirror an object about a given point. + + Mirror an object about a given point. + + + mged> mirror -p "0 1000 0" -y solid.s mir_solid.s + + Creates a copy of solid.s that is mirrored across a plane parallel to the y axis at the point 0, 1000, 0 and named mir_solid.s + + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/nirt.xml b/doc/docbook/system/mann/nirt.xml index 4cb888263f3..ae9653a97fe 100644 --- a/doc/docbook/system/mann/nirt.xml +++ b/doc/docbook/system/mann/nirt.xml @@ -25,20 +25,192 @@ intersect a single ray with the displayed objects. DESCRIPTION Runs the NIRT program that is distributed with BRL-CAD to -intersect a single ray with the displayed objects. By default, NIRT is run using the -current database and the currently displayed objects, and it uses the current eye point -as the ray start point and the current viewing direction as the ray direction. This +intersect a single ray with the displayed objects. By default, NIRT is run using the +current database and the currently displayed objects, backing out the start of the ray +from current center, and using the current viewing direction as the ray direction. This effectively fires a ray at the center of the MGED display. The resulting collection of intersections between the ray and the objects is listed. Additional arguments may be -supplied on the nirt command line. See the manpage -of nirt for more details. +supplied on the command line. When in the graphics window, the hot +key N will run nirt command with no arguments at the +center of the screen. See the man1 page of the nirt +for further description of some of the arguments. -EXAMPLES +Options + + + + + + Adds the attribute_name to the list of attributes that will be reported. + + + + + + + + Causes nirt to read the eye point and + either the orientation quaternion (new format) or the + view-rotation matrix (old format) from the standard input, + and fire a single ray from the point in the specified direction. + + + + + + + + (Default behavior) Causes nirt to backout + before firing the ray (rather than using the center + as the start of the ray). + + + + + rt_bot_minpieces + + + Causes nirt to adjust the setting of + rt_bot_minpieces + to the indicated value. A value of zero here indicates that + the "pieces" methodology should not be used. A value greater + than zero indicates that all BOT primitives containing more than + rt_bot_minpieces triangles should + be broken down into a separate piece for each triangle. This can result + in significant improvement in raytrace speed at the cost of more memory + use. + + + + + + + + Causes nirt to use the current center as the starting + point when firing the ray. + + + + + script + + + Causes nirt to run the script + string before reading the standard input. Multiple commands in + script may be separated with a semicolon ';'. + Scripts specified with either the or + options are executed in the order in which they are specified + on the command line. + + + + + format + + + Causes nirt to load the predefined format + (see ) format + or script file before reading standard input. + Scripts specified with either the or + options are executed in the order in which + they are specified on the command line. + + + + + + + + Causes nirt to ignore any or + options specified previously on the command line. + + + + + + + + List output formatting options. + + + + + + + + (Default behavior) Causes nirt to run in silent (that is, non-verbose) mode. + In this mode, which is useful in a pipeline, nirt + does not print its initial lines of output or the prompt. + + + + + + + + Causes nirt to run in verbose mode. + + + + + n + + + Set flag (n) for enable/disable informational header + (n=1 [on] by default, always off in silent mode). Useful + when combined with verbose mode (). + + + + + n + + + Reports air when n=1 (set to 0 by default). + + + + + n + + + Causes nirt to handle multiple regions' claims to segments of a ray + according to action n. The argument + n may be any of the values 0, 1, 2, or 3, + or their corresponding key words "resolve", "rebuild_fastgen", "rebuild_all", or "retain". + See the discussion of the overlap_claims + in the nirt entry of the man1 manual. + + + + + v + + + Sets the librt3 + debug flags to the hexadecimal bit vector v. + See the discussion of the libdebug + in the nirt entry of the man1 manual. + + + + + v + + + Sets nirt's own debug flags to the hexadecimal + bit vector v. See the discussion of the + debug in the nirt + entry of the man1 manual. + + + + + - The example shows the use of the nirt command to fire a single ray through the center of the MGED display. - +EXAMPLES Run the NIRT program to fire a ray through the MGED display. @@ -47,7 +219,23 @@ of nirt for more details. Fires a single ray through the center of the MGED display. - + + Run the NIRT program to fire a ray through the MGED display and report air. + + mged> nirt -u 1 + + Fires a single ray through the center of the MGED display and report air regions. + + + + Run the NIRT program to fire a ray through the MGED display and include LOS and material ID per region. + + mged> nirt -A LOS -A material_id + + Fires a single ray through the center of the MGED display and includes LOS and material ID per region. + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/npush.xml b/doc/docbook/system/mann/npush.xml index 67153c7e573..f989b7ed9cb 100644 --- a/doc/docbook/system/mann/npush.xml +++ b/doc/docbook/system/mann/npush.xml @@ -425,10 +425,22 @@ sph_016/ EXAMPLES - Default + Push all matrices under a group down to the region level - push sph1 + mged> npush -r group + Push all matrices under given group down to the region level (matrices will sit in group above regions). + + + + + + Push all matrices under a group down to the solid level + + mged> npush -s group + + Push all matrices under given group down to the solid level (matrices will sit below regions). + diff --git a/doc/docbook/system/mann/opendb.xml b/doc/docbook/system/mann/opendb.xml index 592ba6bb43b..3af70408dd7 100644 --- a/doc/docbook/system/mann/opendb.xml +++ b/doc/docbook/system/mann/opendb.xml @@ -26,8 +26,8 @@ Closes the current database file and opens database.g. - If database.g is not found, the current - database is left open. If database.g is not + If database.g is not found, the user is prompted to create a new + database of that name. If database.g is not specified on the command line, the name of the current database file is returned. @@ -40,6 +40,11 @@ auto-detected will be automatically converted if all resulting matrices are valid. + The opendbcommand will look in the current + working directory for the file. If the file is in another directory, + use the relative or full path to the file or use the pwd + and cd commands to navigate to the file's directory. + EXAMPLES @@ -71,8 +76,10 @@ Open and upgrade a binary-incompatible v4 file. - mged> opendb -f model.g - mged> dbupgrade + +mged> opendb -f model.g +mged> dbupgrade + Closes any currently open database and opens model.g as a binary-incompatible v4 @@ -80,6 +87,18 @@ + Open a database using the full path to the file. + + + + mged> opendb C:/cad_work/model.g + + + Closes any currently open database and + opens model.g located at C:\cad_work\. + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/orientation.xml b/doc/docbook/system/mann/orientation.xml index f0bb2628b9d..a512ff2c290 100644 --- a/doc/docbook/system/mann/orientation.xml +++ b/doc/docbook/system/mann/orientation.xml @@ -18,7 +18,7 @@ specified on the command line. orientation - x y z w + v1 v2 v3 v4 @@ -31,7 +31,8 @@ specified on the command line. EXAMPLES - The example shows the use of the orientation command to set the view direction for MGED from the specified quaternion. + The example shows the use of the orientation command + to set the view direction for MGED from the specified quaternion. Set the view direction for MGED. diff --git a/doc/docbook/system/mann/pnts.xml b/doc/docbook/system/mann/pnts.xml new file mode 100644 index 00000000000..7f021188574 --- /dev/null +++ b/doc/docbook/system/mann/pnts.xml @@ -0,0 +1,240 @@ + + + + PNTS + nged + BRL-CAD + BRL-CAD User Commands + + + + pnts + + Creates/writes/generates a "pnts" (i.e. point cloud) primitive. + + + + + + + pnts + subcommand + subcommand arguments + + + + + read + -f [xyzijksrgb] + -u unit + --size # + input_file + pnts_obj + + + + + write + -p # + --ply + pnts_obj + output_filepnts + + + + + gen + -t # + --surface + --grid + --rand + --sobol + --max-pnts + --max-time + obj + output_pnts + + + + + tri + -s # + + + + + +DESCRIPTION + Allows the user to create/write/generate "pnts" primitives. See also the make_pnts command. + + + SUBCOMMANDS + + + read + + + Reads point data from an input file. + + + + + + Specifies the format of input data + + + + + + Sepcifies the units - either a named unit (e.g. in), number, or a unit expression (.15mm). Assumes millemeters by default. + + + + + + + Sets the default size for each point (default is 0). + + + + + + + + write + + + Writes point data to an output file. + + + + + + Specifies the number of significant digits (defualt 17). + + + + + + Writes output in PLY format. + + + + + + + gen + + + Generates a point set from the object and stores the set in a "pnts" primitive. + + + + + + Specifies the sampling grid spacing (in mm) + + + + + + Saves only first and last points along a ray. + + + + + + + Samples using a gridded ray pattern. + + + + + + + + Samples using a random Marsaglia ray pattern on the bounding sphere. + + + + + + + + Samples using a Sobol pseudo-random Marsaglia ray pattern on the bounding sphere. + + + + + + + + Specifies the maximum number of pnts to return per non-grid sampling method. + + + + + + + + Specifies the maximum time to spend per method (in seconds) when using non-grid sampling. + + + + + + + + tri + + + Generates unit or scaled triangles for each pnt in a point set. If no normal + information is present, uses origin at avg of all set points to make normals. + + + + + + Specifies the scale factor to apply to unit triangles - scales the triangle to size with the triangle centered on the original point. + + + + + + + + +EXAMPLES + Read a point cloud file + + mged> pnts read -f xyz -u in --size 1 pointsfile.txt point_cloud.s1 + + + Creates a "pnts" primitive named "point_cloud.s1" using the data file + "pointsfile.txt" where the data file only contains the point + coordinates listed in the order "xyz." The units of the file data is "in" + and the default point size is set to "1.0" (in current model units). + + + Write a points file from a "pnts" primitive. + + mged> pnts write -p 3 point_cloud.s1 pointsfile.txt + + + Write the XYZ coordinates of the "pnts" primitive point_cloud.s1 to a file called "pointsfile.txt" and + and give 3 significant digits. + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/prcolor.xml b/doc/docbook/system/mann/prcolor.xml index 75e20a17b8f..1b81797e916 100644 --- a/doc/docbook/system/mann/prcolor.xml +++ b/doc/docbook/system/mann/prcolor.xml @@ -17,9 +17,6 @@ prcolor - - - diff --git a/doc/docbook/system/mann/prefix.xml b/doc/docbook/system/mann/prefix.xml index e1b08598ca8..e93b7ddd4cf 100644 --- a/doc/docbook/system/mann/prefix.xml +++ b/doc/docbook/system/mann/prefix.xml @@ -39,7 +39,7 @@ specified new_ prefix. Change the names of specified objects and references to them. - mgedprefix test_ group1 regiona shapeb + mged> prefix test_ group1 regiona shapeb Changes the names of objects group1, regiona, and shapeb to “test_group1,” “test_regiona,” and “test_shapeb.” All references to these objects will reflect the new names. diff --git a/doc/docbook/system/mann/put.xml b/doc/docbook/system/mann/put.xml new file mode 100644 index 00000000000..2034c14e43e --- /dev/null +++ b/doc/docbook/system/mann/put.xml @@ -0,0 +1,210 @@ + + + + put + nged + BRL-CAD + BRL-CAD User Commands + + + + put + + mged command which creates a new + object of indicated type with supplied attributes. + Similar to the in command, but without + prompting - making it especially useful for scripting. + + + + + + + put + object type + attrs + + + + + DESCRIPTION + + + Creates a new object of indicated + type. Objects attributes are + per-object dependent, although there are some + similarities among different object types + (i.e. both sph and ell have a vertex 'V'). Use the + form command for possible attributes + and correct paramater forming. Possible values for + type are: + + + + annot -- 2d annotations + + + arb8 -- ARB (eight vertices) + + + arbn -- ARB (n vertices) + + + ars -- Arbitrary faceted solid + + + binunif -- Uniform-array binary object + + + bot -- bag of triangles + + + brep -- Boundary Representation + + + cline -- Cline element + + + comb -- Combination + + + constrnt -- Constraint + + + datum -- Datum set + + + dsp -- Displacement map + + + ebm -- Extruded bitmap + + + ehy -- Elliptical Hyperboloid + + + ell -- Ellipsoid + + + epa -- Elliptical Paraboloid + + + eto -- Elliptical Torus + + + extrude -- 2d Extrusion + + + grip -- Support for joints + + + half -- Half space + + + hrt -- Heart + + + hyp -- Hyperboloid + + + joint -- Joint + + + material -- Material + + + metaball -- Metaball + + + nmg -- Non-Manifold Geometry + + + part -- Particle + + + pipe -- Pipe + + + pnts -- Collection of points + + + poly -- Polygon + + + rec -- Truncated General Cone (right elliptical cylinder) + + + revolve -- Truncated general revolve + + + rhc -- Right Hyperbolic Cylinder + + + rpc -- Right Parabolic Cylinder + + + script -- Procedural script + + + sketch -- 2d sketch + + + sph -- Ellipsoid (sphere) + + + submodel -- Instanced submodel + + + superell -- Superquadratic Ellipsoid + + + tgc -- Truncated General Cone + + + tor -- Torus + + + vol -- 3d volume + + + + + + EXAMPLES + + + The following are run from the MGED command prompt. + + + Create a sphere. + + + + + mged> + put ball sph V {0 0 0} A {100 0 0} B {0 100 0} C {0 0 100} + + + + Creates a sphere named "ball", centered at (0,0,0), and with radius 100 + + + + + + + + + AUTHOR + BRL-CAD Team + + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/pwd.xml b/doc/docbook/system/mann/pwd.xml new file mode 100644 index 00000000000..80729d4a0d9 --- /dev/null +++ b/doc/docbook/system/mann/pwd.xml @@ -0,0 +1,61 @@ + + + + PWD + nged + BRL-CAD + BRL-CAD User Commands + + + + pwd + Prints the current working directory. + + + + + + + pwd + + + + DESCRIPTION + + + Prints the current working directoy. See also the cd command. + + + + EXAMPLES + + + Print the current working directory. + + Type <command>pwd</command> to display the current working directory. + + + + + mged> pwd + + Returns the current working directory. + + + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/qvrot.xml b/doc/docbook/system/mann/qvrot.xml index 4089fb6cacb..b63c9627b92 100644 --- a/doc/docbook/system/mann/qvrot.xml +++ b/doc/docbook/system/mann/qvrot.xml @@ -27,7 +27,10 @@ DESCRIPTION Adjusts the current MGED viewing direction such that the eye - is positioned along the direction vector (dx dy dz) from the view center and is looking towards the view center. The angle (in degrees) allows for a twist about the viewing direction. The ae command provides a similar capability. + is positioned along the direction vector (dx dy dz) from the view center and is + looking towards the view center. The angle (in degrees) allows for a twist about the + viewing direction. The ae command provides a similar capability. See also the + ae2dir and viewdir commands. diff --git a/doc/docbook/system/mann/relos.xml b/doc/docbook/system/mann/relos.xml new file mode 100644 index 00000000000..1196c4281b1 --- /dev/null +++ b/doc/docbook/system/mann/relos.xml @@ -0,0 +1,58 @@ + + + + RELOS + nged + BRL-CAD + BRL-CAD User Commands + + + + relos + Sets the LOS percentage for all regions found in the given group. + + + + + + + relos + assembly + value + + + + DESCRIPTION + + + The relos sets the LOS value for all regions found under the given assembly to the inputted value. + If a region is given, it will set the LOS for just that region. + + + + EXAMPLES + + + Set the LOS + + Set the LOS to 50. + + mged> relos example.c 50 + + All regions under example.c will have their LOS value reset to 50. + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/remat.xml b/doc/docbook/system/mann/remat.xml new file mode 100644 index 00000000000..44934141d78 --- /dev/null +++ b/doc/docbook/system/mann/remat.xml @@ -0,0 +1,58 @@ + + + + REMAT + nged + BRL-CAD + BRL-CAD User Commands + + + + remat + Sets the material for all regions found in the given group. + + + + + + + remat + assembly + value + + + + DESCRIPTION + + + The remat sets the material for all regions found under the given assembly to the inputted value. + If a region is given, it will set the material for just that region. + + + + EXAMPLES + + + Set the material + + Set the material to 5. + + mged> remat example.c 5 + + All regions under example.c will have their material code reset to 5. + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/rt.xml b/doc/docbook/system/mann/rt.xml index f87f1068a8b..ba34d403e4e 100644 --- a/doc/docbook/system/mann/rt.xml +++ b/doc/docbook/system/mann/rt.xml @@ -10,7 +10,7 @@ rt Executes the BRL-CAD rt program with the default options of - "-s50 M." + "-s512 -M." @@ -20,39 +20,59 @@ rt options - --objects + -- objects DESCRIPTION Executes the BRL-CAD rt program with the default options of - "-s50 –M." If perspective is turned on, then the -p option will be included with the value of the perspective angle. The current database name is added to the end of the rt command line along with either the specified objects or, if none is specified, the list of currently displayed objects. The rt program is written such that options may be repeated, and the last occurrence of an option will override any earlier occurrences. This allows the user to specify other size (-s) options. The rrt command performs a similar function, but may be used to execute other programs as well. The -M option tells rt to read the viewing parameters from standard input. See the man page on rt for details. A related command is saveview, which can be used to create a shell script (batch job) to raytrace this view in the background. + "-s512 -M." If perspective is turned on, then the -p option will be + included with the value of the perspective angle. The current database name is added to the + end of the rt command line along with either the specified + objects or, if none is specified, the list of currently displayed objects. The + rt program is written such that options may be repeated, and the + last occurrence of an option will override any earlier occurrences. This allows the user + to specify other size (-s) options. The rrt command + performs a similar function, but may be used to execute other programs as well. The + -M option tells rt to read the viewing parameters + from standard input. See the man1 page on rt + for details. A related command is saveview, which can be used to + create a shell script (batch job) to raytrace this view in the background. EXAMPLES - The first example shows the use of the rt command to run the rt program to produce a color-shaded image of the current view. The second example shows the use of the rt command to produce a color-shaded image of an object using MGED's current viewing parameters. + The first example shows the use of the rt command to run the rt + program to produce a color-shaded image of the current view. The second example shows the + use of the rt command to produce a color-shaded image of an object using + MGED's current viewing parameters. - Run the <emphasis>rt</emphasis> program to produce a color-shaded image of the current view in MGED. + Run the <emphasis>rt</emphasis> program to produce a color-shaded image of the current + view in MGED. mged> rt -s1024 -F/dev/Xl - Runs the rt program to produce a color-shaded image of the current view in the MGED display. The image will be 1024 pixels square and will be displayed on a + Runs the rt program to produce a color-shaded image of the current + view in the MGED display. The image will be 1024 pixels square and will be displayed on a lingering X framebuffer. - Run the <emphasis>rt</emphasis> program to produce a color-shaded image of an object using MGED's current viewing parameters. + Run the <emphasis>rt</emphasis> program to produce a color-shaded image of an object + using MGED's current viewing parameters. mged> rt -C 200/200/255 -- roof - Runs the rt program to produce a color-shaded image of the object roof using MGED's current viewing parameters. The image will have a sky-blue background and will be displayed on the framebuffer specified by the FB_FILE shell variable. + Runs the rt program to produce a color-shaded image of the object + roof using MGED's current viewing parameters. The image will have a + sky-blue background and will be displayed on the framebuffer specified by the FB_FILE shell + variable. diff --git a/doc/docbook/system/mann/rtedge.xml b/doc/docbook/system/mann/rtedge.xml new file mode 100644 index 00000000000..e7283e6b431 --- /dev/null +++ b/doc/docbook/system/mann/rtedge.xml @@ -0,0 +1,85 @@ + + + + RTEDGE + nged + BRL-CAD + BRL-CAD MGED Commands + + + + rtedge + Executes the BRL-CAD rtedge program with the default options of + "-s512 -M." + + + + + + + rtedge + options + -- objects + + + +DESCRIPTION + + Executes the BRL-CAD rtedge program with the default options of + "-s512 -M." If perspective is turned on, then the -p option will be + included with the value of the perspective angle. The current database name is added to the + end of the rtedge command line along with either the specified + objects or, if none is specified, the list of currently displayed objects. The + rtedge program is written such that options may be repeated, and the + last occurrence of an option will override any earlier occurrences. This allows the user + to specify other size (-s) options. The + -M option tells rtedge to read the viewing parameters + from standard input. See the man1 page on rtedge + for details. + + + + +EXAMPLES + + The first example shows the use of the rtedge command to run the rtedge + program to produce an edge image of the current view. The second example shows the + use of the rtedge command to produce an edge image of an object using + MGED's current viewing parameters. + + + Run the <emphasis>rtedge</emphasis> program to produce an edge image of the current + view in MGED. + + + mged> rtedge -s1024 + + Runs the rtedge program to produce an edge image of the current + view in the MGED display. The image will be white lines on a black background and will be + 1024 pixels square. + + + + Run the <emphasis>rtedge</emphasis> program to produce an edge image with black lines + on a white background. + + + mged> rt -W + + Runs the rtedge program to produce an edge image of the currently drawn objects + using MGED's current viewing parameters. The image will have black lines on a white background. + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/shaded_mode.xml b/doc/docbook/system/mann/shaded_mode.xml new file mode 100644 index 00000000000..ebdc9ebc4f4 --- /dev/null +++ b/doc/docbook/system/mann/shaded_mode.xml @@ -0,0 +1,59 @@ + + + + SHADED_MODE + nged + BRL-CAD + BRL-CAD MGED Commands + + + + shaded_mode + + Changes the default behavior of draw, e, and B to use the + -m1 or -m2 options. + + + + + + + shaded_mode + 0|1|2 + + + + DESCRIPTION + + + The shaded_mode command changes the default behavior for the draw, e, + and B commands. An input of 1 makes -m1 the default and an input of 2 makes + -m2 the default. An input of 0 returns those commands to their default behavior. Lighting must be turned on + under the Misc dropdown for options 1 or 2 to work. + + + + EXAMPLES + + Change the default draw option to -m1 + + + mged> shaded_mode 1 + + The shaded mode is now set to 1 and any draw commands will use -m1 as a default option. + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/showmats.xml b/doc/docbook/system/mann/showmats.xml index e6ec825c585..0ce4f0244cc 100644 --- a/doc/docbook/system/mann/showmats.xml +++ b/doc/docbook/system/mann/showmats.xml @@ -17,6 +17,7 @@ showmats + -a path @@ -27,13 +28,16 @@ specified path and also lists the accumulated matrix at the end of the path. If any member occurs more than once in a combination along the path, then a matrix will be listed for each occurrence of that member, and the accumulated matrix will only use - the first occurrence. Related commands are putmat, copymat, and listeval . + the first occurrence. The -a option can be used to return the accumulated matrix as a space + delineated list with 6 significant digits (as opposed to the default 3). Related commands are + putmat, copymat, and listeval. EXAMPLES - The example shows the use of the showmats command to list the transformation matrices along the specified path and the accumulated matrix for the entire path. + The example shows the use of the showmats command to list the transformation matrices + along the specified path and the accumulated matrix for the entire path. List the transformation matrices along a path and the accumulated matrix for the path. @@ -41,7 +45,7 @@ mged> showmats head/skull/jaw - Lists the transformation matrices along the path “head/skull/jaw” and the + Lists the transformation matrices along the path head/skull/jaw and the accumulated matrix for the entire path. diff --git a/doc/docbook/system/mann/source.xml b/doc/docbook/system/mann/source.xml new file mode 100644 index 00000000000..280e95ade09 --- /dev/null +++ b/doc/docbook/system/mann/source.xml @@ -0,0 +1,68 @@ + + + + SOURCE + nged + BRL-CAD + BRL-CAD MGED Commands + + + + source + + Reads an external file and executes its contents. + + + + + + + source + example.txt + + + + DESCRIPTION + + + The source command reads and executes an external file. The command will look in + the current working directory for the file. If the file is in another directory, use the relative or full + path to the file or use the pwd and cd commands to navigate + to the file's directory. + + + + EXAMPLES + + Read in an external file. + + + mged> source example.txt + + Reads and executes the file example.txt located in the current working directory. + + + + Read in an external file using the full path to the file. + + + mged> source C:/cad_work/example.txt + + Reads and executes the file example.txt located at C:\cad_work\. + + + + + + AUTHOR + BRL-CAD Team + + + BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/summary.xml b/doc/docbook/system/mann/summary.xml index bbbf45697ff..5d5fc395f7d 100644 --- a/doc/docbook/system/mann/summary.xml +++ b/doc/docbook/system/mann/summary.xml @@ -18,7 +18,7 @@ summary - s + p r g @@ -27,8 +27,11 @@ DESCRIPTION The summary command with no arguments lists the number of primitive shapes, - regions, and nonregion combinations in the current database. If the s argument is - supplied, then the name of each primitive shape is also listed. Similarly, the r flag asks for the region names, and g asks for the names of all the combinations (including region). The flags may be concatenated to get combined output. + regions, and nonregion combinations in the current database. If the p argument is + supplied, then the name of each primitive shape is also listed. Similarly, the + r flag asks for the region names, and g asks + for the names of all the combinations (including region). The flags may be concatenated + to get combined output. @@ -40,7 +43,7 @@ List a summary of primitive shapes and regions for the current database. - mged> summary sr + mged> summary pr Lists a summary of primitive shapes and regions for the current database. diff --git a/doc/docbook/system/mann/title.xml b/doc/docbook/system/mann/title.xml index 3addedd6811..88ce0c03ae6 100644 --- a/doc/docbook/system/mann/title.xml +++ b/doc/docbook/system/mann/title.xml @@ -19,7 +19,6 @@ title string - @@ -40,7 +39,7 @@ mged> title This is my \\"database\\" - Sets the title of the current database to This is my “database.” + Sets the title of the current database to This is my "database." diff --git a/doc/docbook/system/mann/tol.xml b/doc/docbook/system/mann/tol.xml index 4f9ebda926f..35bc5a951e8 100644 --- a/doc/docbook/system/mann/tol.xml +++ b/doc/docbook/system/mann/tol.xml @@ -23,7 +23,7 @@ norm# dist# perp# - + diff --git a/doc/docbook/system/mann/tops.xml b/doc/docbook/system/mann/tops.xml index 41b88138fa2..9a167ed371d 100644 --- a/doc/docbook/system/mann/tops.xml +++ b/doc/docbook/system/mann/tops.xml @@ -16,20 +16,22 @@ tops - - + -a DESCRIPTION - Displays a list of all the top-level objects in the current database. The top-level objects are all those objects that are not referenced by some other combination. The hierarchical structure of BRL-CAD databases usually means that there will be a top-level object that includes all (or at least most) of the objects in the database. + Displays a list of all the top-level objects in the current database. The top-level objects are all those + objects that are not referenced by some other combination. The hierarchical structure of BRL-CAD databases usually means that there will + be a top-level object that includes all (or at least most) of the objects in the database. The -a option will show + hidden objects. EXAMPLES - The example shows the use of the tops command to list all the top-level objects in the current database. + These examples show the use of the tops command to list all the top-level objects in the current database. List all the top-level objects in the current database. @@ -42,6 +44,16 @@ + List all the top-level objects in the current database, including hidden objects. + + + mged> tops -a + + Lists all the top-level objects in the current database, including hiddent objects. + + + + AUTHORBRL-CAD Team diff --git a/doc/docbook/system/mann/translate.xml b/doc/docbook/system/mann/translate.xml index a339eeef6a9..6ee8ee617ab 100644 --- a/doc/docbook/system/mann/translate.xml +++ b/doc/docbook/system/mann/translate.xml @@ -27,23 +27,22 @@ both primitive edit and matrix edit modes. Used to precisely control the translation of an object in both primitive edit and matrix edit modes. The keypoint of the edited object or shape -is translated to the specified coordinates. +is translated by the specified vector. EXAMPLES - The example shows the use of the translate command to move a currently edited object to specified model coordinates. - + The example shows the use of the translate command to move a + currently edited object +10 units in the x direction, +20 units in the y direction, and + +30 units in the z direction. - Move a currently edited object to specified coordinates. + Move a currently edited object. mged> translate 10 20 30 - Moves a currently edited object to the model coordinates (10 20 30). - diff --git a/doc/docbook/system/mann/unhide.xml b/doc/docbook/system/mann/unhide.xml new file mode 100644 index 00000000000..5c452fe7548 --- /dev/null +++ b/doc/docbook/system/mann/unhide.xml @@ -0,0 +1,61 @@ + + + + UNHIDE + nged + BRL-CAD + BRL-CAD User Commands + + + + unhide + Removes the hidden flag for the specified objects. + + + + + + + unhide + objects + + + +DESCRIPTION + + Removes the hidden flag for the specified objects. When this flag + is set, the objects do not appear in ls, t or tops command outputs. The + -a option on the ls, t, and tops + commands will force hidden objects to appear in its output. + + + +EXAMPLES + + The example shows the use of the unhide command to remove the flag that specifies an object as hidden. + + Remove the flag that specifies an object as hidden. + + + + mged> unhide sol_a + + Removes the flag that marks sol_a as hidden. + + + + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/viewdir.xml b/doc/docbook/system/mann/viewdir.xml new file mode 100644 index 00000000000..82ac9cb59f2 --- /dev/null +++ b/doc/docbook/system/mann/viewdir.xml @@ -0,0 +1,58 @@ + + + + VIEWDIR + nged + BRL-CAD + BRL-CAD MGED Commands + + + + viewdir + Returns the direction vector using the current azimuth and elevation (AE). + + + + + + + viewdir + -i + + + +DESCRIPTION + + Returns the direction vector using the current azimuth and elevation as input. + If the -i option is used the commmand will return the + inverse directional vector. See also the ae2dir, dir2ae and + qvrot commands. + + + +EXAMPLES + + The example shows the use of the viewdir command to get the direction vector. + + + Find the current direction vector. + + + mged> viewdir + + Returns the direction vector using the current azimuth and elevation. + + + + + +AUTHORBRL-CAD Team + +BUG REPORTS + + + Reports of bugs or problems should be submitted via electronic + mail to devs@brlcad.org + + + diff --git a/doc/docbook/system/mann/vnirt.xml b/doc/docbook/system/mann/vnirt.xml index 4a6c7f1768f..a1fc3c1ce4c 100644 --- a/doc/docbook/system/mann/vnirt.xml +++ b/doc/docbook/system/mann/vnirt.xml @@ -33,36 +33,22 @@ them to nirt. All other arguments are passed to nirt without modification. EXAMPLES - + Shoot a ray at 1000 pixels up and centered left/right - - - - <variablelist> - <varlistentry> - <term><prompt/> <userinput/></term> - <listitem> - <para> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><prompt/> <userinput/></term> - <listitem> - <para> - - </para> - </listitem> - </varlistentry> - </variablelist> - </example> + <para> + <prompt>mged> </prompt><userinput>vnirt 0 1000</userinput> + </para> + <para>Shoots a ray 1000 pixels up from center. - <example><title/> + </para> + </example> + + <example><title>Shoot a ray centered top/bottom and 1000 pixels to the right. - + mged> vnirt 1000 0 - + Shoots a ray 1000 pixels to the right of center. diff --git a/doc/docbook/system/mann/vquery_ray.xml b/doc/docbook/system/mann/vquery_ray.xml index 8beab7e0f0c..8ae86625b52 100644 --- a/doc/docbook/system/mann/vquery_ray.xml +++ b/doc/docbook/system/mann/vquery_ray.xml @@ -33,36 +33,22 @@ them to nirt. EXAMPLES - + Shoot a ray at 1000 pixels up and centered left/right - - - - <variablelist> - <varlistentry> - <term><prompt/> <userinput/></term> - <listitem> - <para> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><prompt/> <userinput/></term> - <listitem> - <para> - - </para> - </listitem> - </varlistentry> - </variablelist> - </example> + <para> + <prompt>mged> </prompt><userinput>vquery_ray 0 1000</userinput> + </para> + <para>Shoots a ray 1000 pixels up from center. - <example><title/> + </para> + </example> + + <example><title>Shoot a ray centered top/bottom and 1000 pixels to the right. - + mged> vquery_ray 1000 0 - + Shoots a ray 1000 pixels to the right of center. diff --git a/doc/docbook/system/mann/x.xml b/doc/docbook/system/mann/x.xml index 5ad8a15d330..2bd61c91b8d 100644 --- a/doc/docbook/system/mann/x.xml +++ b/doc/docbook/system/mann/x.xml @@ -26,9 +26,8 @@ Lists all the primitive shapes currently drawn in the MGED display. The level determines how much detail should be included in the list. For level zero -(the default), only a list of paths to shapes in the display list is produced. Each shape -is prefixed by “VIEW” or “-no-,” indicating that the shape is actually being drawn or -that it is being skipped, respectively. If level is greater than zero, the center, size, +(the default), only a list of paths to shapes in the display list is produced. If +level is greater than zero, the center, size, ident number, RGB color assigned to the region, and the actual color used to draw the shape are also listed. If level is greater than one, the number of vlist structures and the number of points in each vlist structure are also listed for each shape. If level is diff --git a/doc/git/gitconfig b/doc/git/gitconfig index 3327e92cc71..450fd1b7902 100644 --- a/doc/git/gitconfig +++ b/doc/git/gitconfig @@ -38,6 +38,10 @@ # cherry-pick without making a commit, and when when recording the commit, append a line that says "(cherry picked from commit ...)" cpn = cherry-pick --no-commit -x + # Print the date a tag was made + # https://stackoverflow.com/questions/13208734/get-the-time-and-date-of-git-tags + tagdate = !"f() { git for-each-ref --format=\"%(creatordate)\" refs/tags/$@ ;};f" + # Compact log that also prints out stat summaries of how much individual # files changed. A good way to hunt for commits that altered particular # portions of the source tree diff --git a/doc/html/manuals/Install.html b/doc/html/manuals/Install.html index 1c4c897915c..935d514c50c 100644 --- a/doc/html/manuals/Install.html +++ b/doc/html/manuals/Install.html @@ -287,7 +287,6 @@

convASCII/binary database converters fbservRemote network frame-buffer server utilZillions of image-handling utilities and tools -fbedFrame-buffer image editor vdeckConvert mged models to GIFT-format card decks. toolsUtah Raster Toolkit tools @@ -298,7 +297,6 @@

libsplA B-spline library libpkgA "message-passing" interface to TCP network links libfbA generic frame-buffer library -libtermioA library to handle terminal mode setting libplot3A public-domain 2-D and 3-D UNIX-Plot library libtigSome plotting routines built on libplot3 librleA Run-Length-Encoding library (originally from UofUtah) diff --git a/doc/legal/CMakeLists.txt b/doc/legal/CMakeLists.txt index e2553893532..4f41a91f37f 100644 --- a/doc/legal/CMakeLists.txt +++ b/doc/legal/CMakeLists.txt @@ -3,7 +3,7 @@ set(doc_legal bdl.txt lgpl.txt ) -ADD_DOC(doc_legal legal) +BRLCAD_MANAGE_FILES(doc_legal ${DOC_DIR}/legal) add_subdirectory(embedded) add_subdirectory(other) diff --git a/doc/legal/embedded/CMakeLists.txt b/doc/legal/embedded/CMakeLists.txt index 7949a9a84c3..91aa9e75894 100644 --- a/doc/legal/embedded/CMakeLists.txt +++ b/doc/legal/embedded/CMakeLists.txt @@ -29,8 +29,8 @@ set(embedded_licenses hv3_combobox.txt hv3_snit.txt Inconsolata.txt + image-hash.txt json.txt - libtermlib.txt lod.txt lseg_lseg.txt lseg_pt.txt @@ -44,12 +44,13 @@ set(embedded_licenses osl.txt ParaView.txt pbrt.txt + picohash.txt point_in_polygon.txt polygonizer.txt pstdint.txt qconsolelistener.txt qsort.txt - QFlowLayout.txt + QgFlowLayout.txt QuickHull.txt rply.txt RTree.txt @@ -79,8 +80,7 @@ set(embedded_licenses xxhash.txt y2038.txt ) - -ADD_DOC(embedded_licenses legal/embedded) +BRLCAD_MANAGE_FILES(embedded_licenses ${DOC_DIR}/legal/embedded) CMAKEFILES(CMakeLists.txt) diff --git a/doc/legal/embedded/ParaView.txt b/doc/legal/embedded/ParaView.txt index ec22f444c7d..94e4c8fa012 100644 --- a/doc/legal/embedded/ParaView.txt +++ b/doc/legal/embedded/ParaView.txt @@ -37,6 +37,6 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -file:/src/libqtcad/QtConsole.cpp -file:/include/qtcad/QtConsole.h +file:/src/libqtcad/QgConsole.cpp +file:/include/qtcad/QgConsole.h diff --git a/doc/legal/embedded/QFlowLayout.txt b/doc/legal/embedded/QFlowLayout.txt deleted file mode 100644 index ea0c88dcb1a..00000000000 --- a/doc/legal/embedded/QFlowLayout.txt +++ /dev/null @@ -1,41 +0,0 @@ -https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/layouts/flowlayout - -Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -Contact: http://www.qt-project.org/legal - -This file is part of the examples of the Qt Toolkit. - -$QT_BEGIN_LICENSE:BSD$ -You may use this file under the terms of the BSD license as follows: - -"Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names - of its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." - -$QT_END_LICENSE$ - -file:/src/libqtcad/QFlowLayout.cpp -file:/include/qtcad/QFlowLayout.h - diff --git a/doc/legal/embedded/QgFlowLayout.txt b/doc/legal/embedded/QgFlowLayout.txt new file mode 100644 index 00000000000..e2f072d19ab --- /dev/null +++ b/doc/legal/embedded/QgFlowLayout.txt @@ -0,0 +1,41 @@ +https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/layouts/flowlayout + +Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +Contact: http://www.qt-project.org/legal + +This file is part of the examples of the Qt Toolkit. + +$QT_BEGIN_LICENSE:BSD$ +You may use this file under the terms of the BSD license as follows: + +"Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + +$QT_END_LICENSE$ + +file:/src/libqtcad/QgFlowLayout.cpp +file:/include/qtcad/QgFlowLayout.h + diff --git a/doc/legal/embedded/image-hash.txt b/doc/legal/embedded/image-hash.txt new file mode 100644 index 00000000000..50deb365ec4 --- /dev/null +++ b/doc/legal/embedded/image-hash.txt @@ -0,0 +1,25 @@ +MIT License + +Copyright (c) 2021 Samuel Bear Powell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +file:/src/libicv/PImgHash.cpp +file:/src/libicv/PImgHash.h + diff --git a/doc/legal/embedded/libtermlib.txt b/doc/legal/embedded/libtermlib.txt deleted file mode 100644 index e339f2febf2..00000000000 --- a/doc/legal/embedded/libtermlib.txt +++ /dev/null @@ -1,39 +0,0 @@ -This code contains changes by - Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - -The conditions and no-warranty notice below apply to these changes. - - -Copyright (c) 1980, 1993 - The Regents of the University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -file:/src/libtermio/termcap -file:/src/libtermio/termcap.c -file:/src/libtermio/termcap.h -file:/src/libtermio/tgoto.c -file:/src/libtermio/tputs.c - diff --git a/doc/legal/embedded/lod.txt b/doc/legal/embedded/lod.txt index 556ec0bd18f..21b43f3802a 100644 --- a/doc/legal/embedded/lod.txt +++ b/doc/legal/embedded/lod.txt @@ -20,5 +20,5 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -file:/src/libbg/lod.cpp +file:/src/libbv/lod.cpp diff --git a/doc/legal/embedded/picohash.txt b/doc/legal/embedded/picohash.txt new file mode 100644 index 00000000000..d5d68a4f62e --- /dev/null +++ b/doc/legal/embedded/picohash.txt @@ -0,0 +1,23 @@ +picohash from https://github.com/kazuho/picohash +Author: Kazuho Oku + +From README.md: + +The code is placed under public domain. It comes without any warranty, +to the extent permitted by applicable law. + +From picohash.h comment header: + +The code is placed under public domain by Kazuho Oku . + +The MD5 implementation is based on a public domain implementation written by + +Solar Designer in 2001, which is used by Dovecot. + +The SHA1 implementation is based on a public domain implementation written +by Wei Dai and other contributors for libcrypt, used also in liboauth. + +The SHA224/SHA256 implementation is based on a public domain implementation +by Sam Hocevar for LibTomCrypt. + +file:/src/gtools/gist/picohash.h diff --git a/doc/legal/embedded/qconsolelistener.txt b/doc/legal/embedded/qconsolelistener.txt index 08cca195799..0f0f99cc9d2 100644 --- a/doc/legal/embedded/qconsolelistener.txt +++ b/doc/legal/embedded/qconsolelistener.txt @@ -22,6 +22,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -file:/src/libqtcad/QtConsoleListener.cpp -file:/include/qtcad/QtConsoleListener.h +file:/src/libqtcad/QgConsoleListener.cpp +file:/include/qtcad/QgConsoleListener.h diff --git a/doc/legal/embedded/tcl.txt b/doc/legal/embedded/tcl.txt index 8bcf06e09ca..942236a2acc 100644 --- a/doc/legal/embedded/tcl.txt +++ b/doc/legal/embedded/tcl.txt @@ -40,6 +40,13 @@ permission to use and distribute the software in accordance with the terms specified in this license. file:/src/libbu/tcllist.c +file:/src/libdm/wgl/wintk/tkWinPort.h +file:/src/libdm/wgl/wintk/tkIntDecls.h +file:/src/libdm/wgl/wintk/tkWinInt.h +file:/src/libdm/wgl/wintk/tkInt.h +file:/src/libdm/wgl/wintk/tkWin.h +file:/src/libdm/wgl/wintk/tkIntPlatDecls.h +file:/src/libdm/wgl/wintk/tkPort.h tkImgFmtPPM.c -- diff --git a/doc/legal/other/CMakeLists.txt b/doc/legal/other/CMakeLists.txt index 67cde4f34b7..b878f697818 100644 --- a/doc/legal/other/CMakeLists.txt +++ b/doc/legal/other/CMakeLists.txt @@ -2,7 +2,6 @@ set(other_licenses Eigen.txt assetimport.txt openNURBS.txt - gct.txt gdal.txt itcl3.txt itk3.txt @@ -11,6 +10,7 @@ set(other_licenses libutahrle.txt linenoise.txt lmdb.txt + manifold.txt netpbm.txt openmesh.txt openNURBS.txt @@ -26,8 +26,7 @@ set(other_licenses tktable.txt zlib.txt ) - -ADD_DOC(other_licenses legal/other) +BRLCAD_MANAGE_FILES(other_licenses ${DOC_DIR}/legal/other) CMAKEFILES(CMakeLists.txt) diff --git a/doc/legal/other/gct.txt b/doc/legal/other/gct.txt deleted file mode 100644 index ea9a7fd822e..00000000000 --- a/doc/legal/other/gct.txt +++ /dev/null @@ -1,25 +0,0 @@ -NOTE: the BRL-CAD repository is the primary copy of this source code. - -Copyright (c) 2014 Alexis Naveros. All rights reserved. -Copyright (c) 2014 SURVICE Engineering. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - diff --git a/doc/legal/other/manifold.txt b/doc/legal/other/manifold.txt new file mode 100644 index 00000000000..6b49d2225d3 --- /dev/null +++ b/doc/legal/other/manifold.txt @@ -0,0 +1,518 @@ +Main license of Manifold is: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +================================================================================ +Clipper2 license: + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +================================================================================ +QuickHull implementation is released to the public domain per their README + + +================================================================================ +OpenGL Mathematics (GLM) +-------------------------------------------------------------------------------- +GLM is licensed under The Happy Bunny License or MIT License + +================================================================================ +The MIT License +-------------------------------------------------------------------------------- +Copyright (c) 2005 - G-Truc Creation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +================================================================================ +Thrust: + +Unless otherwise noted, Thrust's source code is released under the Apache +License, Version 2.0: + +================================================================================ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +================================================================================ + +Some portions of Thrust may be licensed under other compatible open-source +licenses. Any divergence from the Apache 2 license will be noted in the source +code where applicable. + +Portions under other terms include, but are not limited to: + +================================================================================ + +Various C++ utility classes in Thrust are based on the Boost Iterator, Tuple, +System, and Random Number libraries, which are provided under the Boost Software +License: + + Boost Software License - Version 1.0 - August 17th, 2003 + + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: + + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +================================================================================ + +Portions of the thrust::complex implementation are derived from FreeBSD with the +following terms: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice[1] unmodified, this list of conditions, and the following + disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[1] Individual copyright notices from the original authors are included in + the relevant source files. + +================================================================================ + diff --git a/doc/notes/ecosystem.dot b/doc/notes/ecosystem.dot index 53ce2741d04..24e99973e9f 100644 --- a/doc/notes/ecosystem.dot +++ b/doc/notes/ecosystem.dot @@ -111,9 +111,8 @@ digraph BRLCADDeps{ libfb [color = "green", style = bold, shape = box, label = "Framebuffer (libfb)"]; libged [color = "green", style = bold, shape = box, label = "Geometry Editing Library (libged)"]; libtclcad [color = "green", style = bold, shape = box, label = "Tcl CAD library (libtclcad)"]; - libtermio [color = "green", style = bold, shape = box, label = "Terminal IO library (libtermio)"]; - { rank = same; "BRL-CAD Libraries"; libbu; libpc; librt; libdm; libged; libtclcad; libtermio; } + { rank = same; "BRL-CAD Libraries"; libbu; libpc; librt; libdm; libged; libtclcad; } // BRL-CAD Application Categories geomedit [color = "green", style = bold, shape = box, label = "Geometry Editing"]; @@ -163,7 +162,6 @@ digraph BRLCADDeps{ geomedit -> libdm; geomedit -> libged; geomedit -> libtclcad; - geomedit -> libtermio; geomedit -> tkhtml; geomedit -> tkpng; geomedit -> tktable; diff --git a/doc/notes/tool_categories.txt b/doc/notes/tool_categories.txt index 6fc648bbaba..e669d56131b 100644 --- a/doc/notes/tool_categories.txt +++ b/doc/notes/tool_categories.txt @@ -2,7 +2,6 @@ Rendering Analysis Tools ======================== adrt_master adrt_slave -burst remrt reshoot rt @@ -49,7 +48,6 @@ obj-g off-g patch-g ply-g -proe-g step-g stl-g tankill-g @@ -173,7 +171,6 @@ fbclear fbcmap fbcmrot fbcolor -fbed fbfade fbframe fbfree @@ -195,7 +192,6 @@ pix-fb pixflip-fb plot3-fb polar-fb -pp-fb rle-fb show.sh spm-fb diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index b3fe7766fa0..eba7225e54c 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -34,7 +34,6 @@ set(public_hdrs gcv.h ged.h icv.h - libtermio.h nmg.h optical.h pc.h diff --git a/include/RTree.h b/include/RTree.h index 49db4b2e4ca..a6ca66fe48e 100644 --- a/include/RTree.h +++ b/include/RTree.h @@ -33,6 +33,7 @@ #include #include #include "vmath.h" +#include "bu/color.h" #include "bv/plot3.h" #include "bg/aabb_ray.h" @@ -442,6 +443,7 @@ class RTree size_t Intersects(Ray *a_ray, std::set *result); void plot(const char *fname); + void plot2d(const char *fname); }; // Because there is not stream support, this is a quick and dirty file I/O helper. @@ -1756,6 +1758,46 @@ void RTREE_QUAL::plot(const char *fname) fclose(plot_file); } +#define BB_PLOT2D(min, max) { \ + fastf_t pt[8][3]; \ + VSET(pt[0], max[X], min[Y], 0); \ + VSET(pt[1], max[X], max[Y], 0); \ + VSET(pt[2], max[X], max[Y], 0); \ + VSET(pt[3], max[X], min[Y], 0); \ + VSET(pt[4], min[X], min[Y], 0); \ + VSET(pt[5], min[X], max[Y], 0); \ + VSET(pt[6], min[X], max[Y], 0); \ + VSET(pt[7], min[X], min[Y], 0); \ + TREE_LEAF_FACE_3D(pt, 0, 1, 2, 3); \ + TREE_LEAF_FACE_3D(pt, 4, 0, 3, 7); \ + TREE_LEAF_FACE_3D(pt, 5, 4, 7, 6); \ + TREE_LEAF_FACE_3D(pt, 1, 5, 6, 2); \ +} + +RTREE_TEMPLATE +void RTREE_QUAL::plot2d(const char *fname) +{ + if (!m_root) return; + + if (kNumDimensions != 2) return; + + FILE* plot_file = fopen(fname, "w"); + struct bu_color c = BU_COLOR_INIT_ZERO; + bu_color_rand(&c, BU_COLOR_RANDOM_LIGHTENED); + pl_color_buc(plot_file, &c); + + RTREE_QUAL::Iterator tree_it; + this->GetFirst(tree_it); + while (!tree_it.IsNull()) { + double m_min[2]; + double m_max[2]; + tree_it.GetBounds(m_min, m_max); + BB_PLOT2D(m_min, m_max); + ++tree_it; + } + + fclose(plot_file); +} #undef RTREE_TEMPLATE diff --git a/include/bg/CMakeLists.txt b/include/bg/CMakeLists.txt index efdfb7b0913..c62c254a14b 100644 --- a/include/bg/CMakeLists.txt +++ b/include/bg/CMakeLists.txt @@ -3,7 +3,6 @@ set(bg_headers chull.h clip.h defines.h - lod.h lseg.h obr.h plane.h diff --git a/include/bg/lseg.h b/include/bg/lseg.h index a4b302e0a50..5e6e3f0ef17 100644 --- a/include/bg/lseg.h +++ b/include/bg/lseg.h @@ -32,7 +32,6 @@ #include "common.h" #include "vmath.h" -#include "bv.h" #include "bg/defines.h" __BEGIN_DECLS @@ -52,25 +51,6 @@ BG_EXPORT double bg_distsq_lseg3_lseg3(point_t *c1, point_t *c2, const point_t P0, const point_t P1, const point_t Q0, const point_t Q1); - -/* Logic for snapping points to their closes view lines. - * TODO - really should make this generic to any line set, not just the - * bv structures. */ - -/* Snap sample 2D point to lines active in the view */ -BG_EXPORT extern int bv_snap_lines_2d(struct bview *v, fastf_t *fx, fastf_t *fy); - -/* Snap sample 2D point to grid active in the view */ -BG_EXPORT extern int bv_snap_grid_2d(struct bview *v, fastf_t *fx, fastf_t *fy); - -/* Snap sample 3D point to lines active in the view */ -BG_EXPORT extern int bv_snap_lines_3d(point_t *out_pt, struct bview *v, point_t *p); - - -BG_EXPORT extern void bv_view_center_linesnap(struct bview *v); - - - __END_DECLS #endif /* BG_LSEG_H */ diff --git a/include/bg/polygon.h b/include/bg/polygon.h index 70a223d10db..9d008da7dd4 100644 --- a/include/bg/polygon.h +++ b/include/bg/polygon.h @@ -55,7 +55,7 @@ BG_EXPORT extern fastf_t bg_find_polygon_area( struct bg_polygon *gpoly, fastf_t sf, - matp_t model2view, + plane_t *vp, fastf_t size ); @@ -63,41 +63,44 @@ BG_EXPORT extern int bg_polygons_overlap( struct bg_polygon *polyA, struct bg_polygon *polyB, - matp_t model2view, + plane_t *vp, const struct bn_tol *tol, fastf_t iscale ); -/* model2view and view2model may be NULL, if the polygons are coplanar */ BG_EXPORT extern struct bg_polygon * bg_clip_polygon( bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, fastf_t sf, - matp_t model2view, - matp_t view2model + plane_t *vp ); -/* model2view and view2model may be NULL, if the polygons are coplanar */ BG_EXPORT extern struct bg_polygon * bg_clip_polygons( bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *clip, fastf_t sf, - matp_t model2view, - matp_t view2model + plane_t *vp ); -BG_EXPORT extern struct bg_polygon * -bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t line_spacing); - BG_EXPORT extern void bg_polygon_free(struct bg_polygon *gpp); BG_EXPORT extern void bg_polygons_free(struct bg_polygons *gpp); BG_EXPORT extern void bg_polygon_cpy(struct bg_polygon *dest, struct bg_polygon *src); +/** + * @brief + * Find the 2D axis aligned bounding box of a bg_polygon in view coordinates. + * + * NOTE: If the polygon's internal data is defined in the XY plane and no view + * projection is desired, pass MAT_IDN to model2view to get the raw data's + * bbox. + */ +BG_EXPORT extern void +bg_polygon_view_bbox(point2d_t *bmin, point2d_t *bmax, struct bg_polygon *p, matp_t model2view); /******************************** * Operations on 2D point types * @@ -123,7 +126,6 @@ BG_EXPORT extern void bg_polygon_cpy(struct bg_polygon *dest, struct bg_polygon */ BG_EXPORT extern int bg_polygon_direction(size_t npts, const point2d_t *pts, const int *pt_indices); - /** * @brief * test whether a point is inside a 2d polygon @@ -169,6 +171,9 @@ typedef enum { * If no holes are present, caller should pass NULL for holes_array and holes_npts, * and 0 for nholes, or use bg_polygon_triangulate instead. * + * This routine deliberately uses low level data types for both input and output + * to maximize the reusability of this logic. + * * @param[out] faces Set of faces in the triangulation, stored as integer indices to the pts. The first three indices are the vertices of the first face, the second three define the second face, and so forth. * @param[out] num_faces Number of faces created * @param[out] out_pts output points used by faces set. If an algorithm was selected that generates new points, this will be a new array. @@ -187,11 +192,12 @@ typedef enum { * @return 0 if triangulation is successful * @return 1 if triangulation is unsuccessful */ -BG_EXPORT extern int bg_nested_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, - const int *poly, const size_t poly_npts, - const int **holes_array, const size_t *holes_npts, const size_t nholes, - const int *steiner, const size_t steiner_npts, - const point2d_t *pts, const size_t npts, triangulation_t type); +BG_EXPORT extern int +bg_nested_poly_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, + const int *poly, const size_t poly_npts, + const int **holes_array, const size_t *holes_npts, const size_t nholes, + const int *steiner, const size_t steiner_npts, + const point2d_t *pts, const size_t npts, triangulation_t type); /** * @brief @@ -208,6 +214,9 @@ BG_EXPORT extern int bg_nested_polygon_triangulate(int **faces, int *num_faces, * logic - this is a convenience function to simplify calling the routine when * specification of hole polygons is not needed. * + * This routine deliberately uses low level data types for both input and output + * to maximize the reusability of this logic.* + * * @param[out] faces Set of faces in the triangulation, stored as integer indices to the pts. The first three indices are the vertices of the first face, the second three define the second face, and so forth. * @param[out] num_faces Number of faces created * @param[out] out_pts output points used by faces set, if an algorithm was selected that generates new points @@ -221,9 +230,28 @@ BG_EXPORT extern int bg_nested_polygon_triangulate(int **faces, int *num_faces, * @return 0 if triangulation is successful * @return 1 if triangulation is unsuccessful */ -BG_EXPORT extern int bg_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, - const int *steiner, const size_t steiner_npts, - const point2d_t *pts, const size_t npts, triangulation_t type); +BG_EXPORT extern int +bg_poly_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, + const int *steiner, const size_t steiner_npts, + const point2d_t *pts, const size_t npts, triangulation_t type); + +/** + * @brief + * Triangulate a bg_polygon. + * + * @param[out] faces Set of faces in the triangulation, stored as integer indices to the pts. The first three indices are the vertices of the first face, the second three define the second face, and so forth. + * @param[out] num_faces Number of faces created + * @param[out] out_pts output points used by faces set, if an algorithm was selected that generates new points + * @param[out] num_outpts number of output points, if an algorithm was selected that generates new points + * @param[in] p bg_polygon holding the polygon contours to be triangulated + * @param[in] type Triangulation type + * + * @return 0 if triangulation is successful + * @return 1 if triangulation is unsuccessful + */ +BG_EXPORT extern int +bg_polygon_triangulate(int **faces, int *num_faces, point_t **out_pts, int *num_outpts, + struct bg_polygon *p, triangulation_t type); /* Test function - do not use */ @@ -312,76 +340,6 @@ BG_EXPORT extern void bg_polygon_plot_2d(const char *filename, const point2d_t * BG_EXPORT extern void bg_polygon_plot(const char *filename, const point_t *pnts, int npnts, int r, int g, int b); BG_EXPORT extern void bg_tri_plot_2d(const char *filename, const int *faces, int num_faces, const point2d_t *pnts, int r, int g, int b); - -/* BV related polygon logic and types */ - -#define BV_POLYGON_GENERAL 0 -#define BV_POLYGON_CIRCLE 1 -#define BV_POLYGON_ELLIPSE 2 -#define BV_POLYGON_RECTANGLE 3 -#define BV_POLYGON_SQUARE 4 - -struct bv_polygon { - int type; - int fill_flag; /* set to shade the interior */ - vect2d_t fill_dir; - fastf_t fill_delta; - struct bu_color fill_color; - long curr_contour_i; - long curr_point_i; - point_t prev_point; - - /* We stash the view state on creation, so we know how to return - * to it for future 2D alterations */ - struct bview v; - - /* Actual polygon info */ - struct bg_polygon polygon; - - /* Arbitrary data */ - void *u_data; -}; - -// Given a polygon, create a scene object -BG_EXPORT extern struct bv_scene_obj *bv_create_polygon_obj(struct bview *v, struct bv_polygon *p); - -// Note - for these functions it is important that the bv -// gv_width and gv_height values are current! I.e.: -// -// v->gv_width = dm_get_width((struct dm *)v->dmp); -// v->gv_height = dm_get_height((struct dm *)v->dmp); - -// Creates a scene object with a default polygon -BG_EXPORT extern struct bv_scene_obj *bv_create_polygon(struct bview *v, int type, int x, int y); - -// Various update modes have similar logic - we pass in the flags to the update -// routine to enable/disable specific portions of the overall flow. -#define BV_POLYGON_UPDATE_DEFAULT 0 -#define BV_POLYGON_UPDATE_PROPS_ONLY 1 -#define BV_POLYGON_UPDATE_PT_SELECT 2 -#define BV_POLYGON_UPDATE_PT_MOVE 3 -#define BV_POLYGON_UPDATE_PT_APPEND 4 -BG_EXPORT extern int bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype); - -// Update just the scene obj vlist, without altering the source polygon -BG_EXPORT extern void bv_polygon_vlist(struct bv_scene_obj *s); - -// Find the closest polygon obj to a view's current x,y mouse points -BG_EXPORT extern struct bv_scene_obj *bv_select_polygon(struct bu_ptbl *objs, struct bview *v); - -BG_EXPORT extern int bv_move_polygon(struct bv_scene_obj *s); -BG_EXPORT extern struct bv_scene_obj *bg_dup_view_polygon(const char *nname, struct bv_scene_obj *s); - - -// For all polygon objects in the objs table, apply the specified boolean op -// using p and replace the original polygons in objs with the results (NOTE: p -// will not act on itself if it is in objs): -// -// u : objs[i] u p (unions p with objs[i]) -// - : objs[i] - p (removes p from objs[i]) -// + : objs[i] + p (intersects p with objs[i]) -BG_EXPORT extern int bv_polygon_csg(struct bu_ptbl *objs, struct bv_scene_obj *p, bg_clip_t op, int merge); - __END_DECLS #endif /* BG_POLYGON_H */ diff --git a/include/bg/polygon_types.h b/include/bg/polygon_types.h index a6b66fca5ed..482fbce6a3f 100644 --- a/include/bg/polygon_types.h +++ b/include/bg/polygon_types.h @@ -37,7 +37,7 @@ __BEGIN_DECLS /* The following data types are originally from bv - we keep them * separate here to maximize their ease of reuse */ -typedef enum { bg_Union, bg_Difference, bg_Intersection, bg_Xor } bg_clip_t; +typedef enum { bg_None, bg_Union, bg_Difference, bg_Intersection, bg_Xor } bg_clip_t; struct bg_poly_contour { size_t num_points; diff --git a/include/bg/trimesh.h b/include/bg/trimesh.h index d6eb3b72e9b..b92e0d16b04 100644 --- a/include/bg/trimesh.h +++ b/include/bg/trimesh.h @@ -84,8 +84,9 @@ BG_EXPORT extern int bg_trimesh_manifold_closed(int vcnt, int fcnt, fastf_t *v, BG_EXPORT extern int bg_trimesh_oriented(int vcnt, int fcnt, fastf_t *v, int *f); /** - * Check if a mesh is topologically solid. True if the mesh is closed, - * manifold, and oriented. + * Check if a mesh is topologically solid. Returns 1 if the mesh is NOT SOLID + * and 0 if the mesh is SOLID. A SOLID (0) outcome indicates the mesh satisfies + * all three criteria: Closed, Manifold, Oriented */ BG_EXPORT extern int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges); diff --git a/include/brep/edit.h b/include/brep/edit.h index a73e39bc7d7..30d700996fd 100644 --- a/include/brep/edit.h +++ b/include/brep/edit.h @@ -49,7 +49,32 @@ extern "C++" #include /** - * create an nurbs curve using a template. + * create a brep vertex + */ + BREP_EXPORT extern int + brep_vertex_create(ON_Brep *brep, ON_3dPoint point); + + /** + * remove a brep vertex + */ + BREP_EXPORT extern bool + brep_vertex_remove(ON_Brep *brep, int v_id); + + /** + * create a 2D parameter space geometric line + * return id of the curve2d + */ + BREP_EXPORT extern int + brep_curve2d_make_line(ON_Brep *brep, const ON_2dPoint &start, const ON_2dPoint &end); + + /** + * remove a curve2d from brep + */ + BREP_EXPORT extern bool + brep_curve2d_remove(ON_Brep *brep, int curve_id); + + /** + * create a nurbs curve using a template. * position can be specified if position != NULL * return id of the curve */ @@ -57,7 +82,7 @@ extern "C++" brep_curve_make(ON_Brep *brep, const ON_3dPoint &position); /** - * create an nurbs curve given detailed information + * create a nurbs curve given detailed information * return id of the curve */ BREP_EXPORT extern int @@ -72,6 +97,20 @@ extern "C++" BREP_EXPORT extern int brep_curve_interpCrv(ON_Brep *brep, std::vector points); + /** + * copy a curve from brep + * return id of the new curve + */ + BREP_EXPORT extern int + brep_curve_copy(ON_Brep *brep, int curve_id); + + /** + * remove a curve from brep + * @attention the index of m_C3 is changed after remove!!! + */ + BREP_EXPORT extern bool + brep_curve_remove(ON_Brep *brep, int curve_id); + /** * move curve along a vector. */ @@ -85,7 +124,7 @@ extern "C++" brep_curve_set_cv(ON_Brep *brep, int curve_id, int cv_id, const ON_4dPoint &point); /** - * Reverse parameterizatrion by negating all knots + * reverse parameterizatrion by negating all knots * and reversing the order of the control vertices. */ BREP_EXPORT extern bool @@ -104,21 +143,55 @@ extern "C++" brep_curve_trim(ON_Brep *brep, int curve_id, double t0, double t1); /** - * Join the end of curve_id_1 to the start of curve_id_2. + * split a curve at a parameter. Old curve will be deleted. + */ + BREP_EXPORT extern bool + brep_curve_split(ON_Brep *brep, int curve_id, double t); + + /** + * join the end of curve_id_1 to the start of curve_id_2. * return id of the new curve, delete the two old curves. - * Remark: the index of C3 is changed after join!!! + * @attention the index of m_C3 is changed after join!!! */ BREP_EXPORT extern int brep_curve_join(ON_Brep *brep, int curve_id_1, int curve_id_2); /** - * create an nurbs curve using a template + * create a nurbs curve using a template * position can be specified if argc == 3 * return id of the surface */ BREP_EXPORT extern int brep_surface_make(ON_Brep *brep, const ON_3dPoint &position); + /** + * extract a vertex from a surface + */ + BREP_EXPORT extern int + brep_surface_extract_vertex(ON_Brep *brep, int surface_id, double u, double v); + + /** + * extract a curve from a surface + */ + BREP_EXPORT extern int + brep_surface_extract_curve(ON_Brep *brep, int surface_id, int dir, double t); + + /** + * create a bicubic nurbs surface by interpolating a set of points + * return id of the surface + * method: Global cubic interpolation with C2 continuity + * reference: The NURBS Book (2nd Edition), chapter 9.2.5 + */ + BREP_EXPORT extern int + brep_surface_interpCrv(ON_Brep *brep, int cv_count_x, int cv_count_y, std::vector points); + + /** + * copy a surface from brep + * return id of the new surface + */ + BREP_EXPORT extern int + brep_surface_copy(ON_Brep *brep, int surface_id); + /** * move surface to a new position */ @@ -139,6 +212,12 @@ extern "C++" BREP_EXPORT extern bool brep_surface_trim(ON_Brep *brep, int surface_id, int dir, double t0, double t1); + /** + * split a surface at a parameter. Old surface will be deleted. + */ + BREP_EXPORT extern bool + brep_surface_split(ON_Brep *brep, int surface_id, int dir, double t); + /** * create a ruled surface. * The two curves must have the same NURBS form knots. @@ -147,6 +226,57 @@ extern "C++" */ BREP_EXPORT extern int brep_surface_create_ruled(ON_Brep *brep, int curve_id0, int curve_id1); + + /** + * create a surface by extruding a curve along another curve. + * return: if successful, id of the new surface; otherwise, -1. + */ + BREP_EXPORT extern int + brep_surface_tensor_product(ON_Brep *brep, int curve_id0, int curve_id1); + + /** + * create a surface by rotating a curve around an axis. + * return: if successful, id of the new surface; otherwise, -1. + */ + BREP_EXPORT extern int + brep_surface_revolution(ON_Brep *brep, int curve_id0, ON_3dPoint line_start, ON_3dPoint line_end, double angle = 2 * ON_PI); + + /** + * remove a surface from brep + * @attention the index of m_S is changed after remove!!! + */ + BREP_EXPORT extern bool + brep_surface_remove(ON_Brep *brep, int surface_id); + + /** + * create a brep edge + */ + BREP_EXPORT extern int + brep_edge_create(ON_Brep *brep, int from, int to, int curve); + + /** + * create a brep face + */ + BREP_EXPORT extern int + brep_face_create(ON_Brep *brep, int surface); + + /** + * reverse a brep face + */ + BREP_EXPORT extern bool + brep_face_reverse(ON_Brep *brep, int face); + + /** + * create a brep face loop + */ + BREP_EXPORT extern int + brep_loop_create(ON_Brep *brep, int face_id); + + /** + * create a trim of a loop + */ + BREP_EXPORT extern int + brep_trim_create(ON_Brep *brep, int loop_id, int edge_id, int orientation, int para_curve_id); } /* extern C++ */ #endif diff --git a/include/bu/CMakeLists.txt b/include/bu/CMakeLists.txt index caa100263d7..d7df70b38db 100644 --- a/include/bu/CMakeLists.txt +++ b/include/bu/CMakeLists.txt @@ -3,6 +3,7 @@ set(bu_headers assert.h avs.h bitv.h + cache.h cmd.h color.h cv.h diff --git a/include/bu/app.h b/include/bu/app.h index 165bf863497..6e744dd0823 100644 --- a/include/bu/app.h +++ b/include/bu/app.h @@ -171,6 +171,53 @@ BU_EXPORT extern const char *bu_whereis(const char *cmd); BU_EXPORT extern FILE *bu_temp_file(char *filepath, size_t len); +/** + * Generate a temporary file name using a prefix (if supplied), + * the current process ID, and the current thread's ID + * + * This function writes into buffer and returns a temporary file name + * that is unique to a process / thread pair. The caller can further + * distinguish the generated name using a specified filename prefix. + * When not supplied, the PACKAGE_NAME (BRL-CAD) is used as the prefix. + * + * Note that the filename parameter doubles as both a prefix specifier + * as well as a return buffer. + * + * @param filename prefixes the name, doubles as return buffer if len is set + * @param len total size of the available filename buffer + * + * @return + * name in the form of prefix_procID_threadID. This will be + * 'filename' or, when NULL, a read-only STATIC buffer will be returned + * that will be the caller's responsibility to bu_strdup() or + * otherwise save before a subsequent call. + * + * @code + * + * // e.g., BRL-CAD_123_456 + * const char *generic = bu_temp_file_name(NULL, 0); + * + * // e.g., BRL-CAD_123_456 -> saved to supplied buffer + * char generic[25] = {0}; + * bu_temp_file_name(generic, 25); + * + * // e.g., prefix_123_456 + * const char *prefix = bu_temp_file_name("prefix", 0); + * + * // e.g., prefix_123_456 -> saved to supplied buffer + * char prefix[25] = "prefix"; + * bu_temp_file_name(prefix, 25); + * + * // e.g., /path/to/temp/dir/BRL-CAD_123_456 -> combine with bu_dir for fullpath + * char tmpfil[MAXPATHLEN]; + * const char* tmp_filename = bu_temp_file_name(NULL, 0); + * bu_dir(tmpfil, MAXPATHLEN, BU_DIR_TEMP, tmp_filename, NULL); + * + * @endcode + */ +BU_EXPORT extern const char* bu_temp_file_name(char* filename, size_t len); + + /** * @brief Wrapper around fchmod. * diff --git a/include/bu/cache.h b/include/bu/cache.h new file mode 100644 index 00000000000..195ba490532 --- /dev/null +++ b/include/bu/cache.h @@ -0,0 +1,102 @@ +/* C A C H E . H + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file cache.h + * + * Routines for managing and accessing a key/value data store. + * + */ + +#ifndef BU_CACHE_H +#define BU_CACHE_H 1 + +#include "common.h" + +#include "bu/defines.h" + +__BEGIN_DECLS + +struct bu_cache_impl; + +struct bu_cache { + struct bu_cache_impl *i; +}; + +/** + * Opens the specified cache database from the BRL-CAD BU_DIR_CACHE folder. + * The cache_db string may contain a hierarchical path, but note that all + * paths will be interpreted as relative to the BU_DIR_CACHE location - no + * absolute paths can be specified. + * + * If the create flag is non-zero, bu_cache_open will create the specified + * cache_db if it does not already exist. + * + * returns the bu_cache structure on success, NULL on failure. + */ +BU_EXPORT extern struct bu_cache *bu_cache_open(const char *cache_db, int create); + +/** + * Closes the bu_cache and frees all associated memory. + */ +BU_EXPORT extern void bu_cache_close(struct bu_cache *c); + +/** + * Erase the specified cache from disk. Any open instances of the + * cache should be closed before calling this function. + */ +BU_EXPORT void bu_cache_erase(const char *cache_db); + +/** + * Retrieve data (read-only) from the cache using the specified key. User + * should call bu_cache_get_done once their use of data is complete. + * + * Returns the size of the retrieved data. + */ +BU_EXPORT size_t bu_cache_get(void **data, const char *key, struct bu_cache *c); + +/** + * Data retrieved using bu_cache_get is temporary - once the user is done + * either reading it or copying it, libbu needs to be told that the usage of + * the returned data is complete. */ +BU_EXPORT void bu_cache_get_done(const char *key, struct bu_cache *c); + +/** + * Assign data to the cache using the specified key + */ +BU_EXPORT size_t bu_cache_write(void **data, const char *key, struct bu_cache *c); + +/** + * Clear data associated with the specified key from the cache + */ +BU_EXPORT void bu_cache_clear(const char *key, struct bu_cache *c); + + +__END_DECLS + +#endif /* BU_CACHE_H */ + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/bu/color.h b/include/bu/color.h index 27220c5e92a..5eb1ac01b0d 100644 --- a/include/bu/color.h +++ b/include/bu/color.h @@ -70,6 +70,12 @@ typedef struct bu_color bu_color_t; */ #define BU_COLOR_INIT_ZERO {{0, 0, 0, 0}} +/* Initializers for commonly used colors */ +#define BU_COLOR_RED {{1, 0, 0, 0}} +#define BU_COLOR_GREEN {{0, 1, 0, 0}} +#define BU_COLOR_BLUE {{0, 0, 1, 0}} +#define BU_COLOR_YELLOW {{1, 1, 0, 0}} + /** * Copy a bu_color */ diff --git a/include/bu/parallel.h b/include/bu/parallel.h index b11957cd51a..95381bb20ae 100644 --- a/include/bu/parallel.h +++ b/include/bu/parallel.h @@ -67,6 +67,11 @@ __BEGIN_DECLS */ DEPRECATED BU_EXPORT extern int bu_is_parallel(void); +/** + * returns the thread ID of the calling thread + */ +BU_EXPORT extern int bu_thread_id(void); + /** * returns the CPU number of the current bu_parallel() invoked thread. */ diff --git a/include/bv.h b/include/bv.h index a1cf94b185d..2f8fa3a6fa5 100644 --- a/include/bv.h +++ b/include/bv.h @@ -42,6 +42,9 @@ #include "./bv/defines.h" #include "./bv/adc.h" +#include "./bv/lod.h" +#include "./bv/polygon.h" +#include "./bv/snap.h" #include "./bv/util.h" #include "./bv/vlist.h" #include "./bv/view_sets.h" diff --git a/include/bv/CMakeLists.txt b/include/bv/CMakeLists.txt index 111e1cbac17..297657489a9 100644 --- a/include/bv/CMakeLists.txt +++ b/include/bv/CMakeLists.txt @@ -3,7 +3,10 @@ set(bv_headers defines.h events.h faceplate.h + lod.h plot3.h + polygon.h + snap.h tcl_data.h tig.h util.h diff --git a/include/bv/defines.h b/include/bv/defines.h index 60c0850b8e0..eeb0b995e58 100644 --- a/include/bv/defines.h +++ b/include/bv/defines.h @@ -42,8 +42,8 @@ #include "common.h" #include "vmath.h" #include "bu/list.h" -#include "bu/vls.h" #include "bu/ptbl.h" +#include "bu/vls.h" /** @{ */ /** @file bv.h */ @@ -131,12 +131,13 @@ struct bv_axes { // for value setting struct bv_obj_settings { - int s_dmode; /**< @brief draw mode: 0 - wireframe + int s_dmode; /**< @brief draw mode: 0 - wireframe * 1 - shaded bots and polysolids only (booleans NOT evaluated) * 2 - shaded (booleans NOT evaluated) * 3 - shaded (booleans evaluated) * 4 - hidden line */ + int mixed_modes; /**< @brief when drawing, don't remove an objects view objects for other modes */ fastf_t transparency; /**< @brief holds a transparency value in the range [0.0, 1.0] - 1 is opaque */ int color_override; @@ -148,7 +149,7 @@ struct bv_obj_settings { int draw_solid_lines_only; /**< @brief do not use dashed lines for subtraction solids */ int draw_non_subtract_only; /**< @brief do not visualize subtraction solids */ }; -#define BV_OBJ_SETTINGS_INIT {0, 1.0, 0, {255, 0, 0}, 1, 0.0, 0.0, 0, 0} +#define BV_OBJ_SETTINGS_INIT {0, 0, 1.0, 0, {255, 0, 0}, 1, 0.0, 0.0, 0, 0} /* Note that it is possible for a view object to be view-only (not @@ -183,6 +184,7 @@ struct bview; #define BV_DB_OBJS 0x01 #define BV_VIEW_OBJS 0x02 #define BV_LOCAL_OBJS 0x04 +#define BV_CHILD_OBJS 0x08 struct bv_scene_obj_internal; @@ -194,9 +196,9 @@ struct bv_scene_obj { /* View object name and type id */ unsigned long long s_type_flags; - struct bu_vls s_name; /**< @brief object name (may not be unique, used for activities like path lookup) */ + struct bu_vls s_name; /**< @brief object name (should be unique if view objects are to be addressed by name) */ void *s_path; /**< @brief alternative (app specific) encoding of s_name */ - struct bu_vls s_uuid; /**< @brief object name (unique, may be less immediately clear to user) */ + void *dp; /**< @brief app obj data */ mat_t s_mat; /**< @brief mat to use for internal lookup and mesh LoD drawing */ /* Associated bv. Note that scene objects are not assigned uniquely to @@ -230,6 +232,7 @@ struct bv_scene_obj { int s_displayobj; /**< @brief Vector list contains vertices in display context flag */ point_t bmin; point_t bmax; + int have_bbox; /* Display properties */ char s_flag; /**< @brief UP = object visible, DOWN = obj invis */ @@ -251,6 +254,8 @@ struct bv_scene_obj { * settings. These values SHOULD NOT be directly manipulated by any user * facing commands (such as view obj). */ int adaptive_wireframe; + int csg_obj; + int mesh_obj; fastf_t view_scale; size_t bot_threshold; fastf_t curve_scale; @@ -392,6 +397,12 @@ struct bv_mesh_lod { void *i; }; +/* Flags to identify categories of objects to snap */ +#define BV_SNAP_SHARED 0x1 +#define BV_SNAP_LOCAL 0x2 +#define BV_SNAP_DB 0x4 +#define BV_SNAP_VIEW 0x8 +#define BV_SNAP_TCL 0x10 /* We encapsulate non-camera settings into a container mainly to allow for * easier re-use of the same settings between different views - if a common @@ -399,11 +410,13 @@ struct bv_mesh_lod { * us to just point to the common set from all views using it. */ struct bview_settings { struct bv_obj_settings obj_s; - int gv_snap_lines; - double gv_snap_tol_factor; - int gv_cleared; - int gv_zclip; - int gv_autoview; + int gv_snap_lines; + double gv_snap_tol_factor; + struct bu_ptbl gv_snap_objs; + int gv_snap_flags; + int gv_cleared; + int gv_zclip; + int gv_autoview; // Adaptive plotting related settings - these are used when the wireframe // generated by primitives is based on the view information. @@ -422,9 +435,8 @@ struct bview_settings { struct bv_axes gv_view_axes; struct bv_grid_state gv_grid; struct bv_other_state gv_center_dot; - struct bv_other_state gv_view_params; + struct bv_params_state gv_view_params; struct bv_other_state gv_view_scale; - int gv_fps; // Display Frames-Per-Second metric double gv_frametime; // Framebuffer visualization is possible if there is an attached dm and @@ -518,6 +530,8 @@ struct bview { fastf_t gv_prevMouseY; int gv_mouse_x; int gv_mouse_y; + point_t gv_prev_point; + point_t gv_point; char gv_key; unsigned long gv_mod_flags; fastf_t gv_minMouseDelta; @@ -560,29 +574,6 @@ struct bview { vect_t gv_lookat; double radius; - - /* - * gv_data_vZ is an internal parameter used by commands creating and - * manipulating data objects. Geometrically, it is a magnitude in the - * direction of the Z vector of the view plane. Functionally, what it - * allows the code to do is define a 2D plane embedded in in 3D space that - * is offset from but parallel to the view plane - in an orthogonal view - * this corresponds to objects drawn in that plane being "above" or "below" - * objects defined within the view plane itself. - * - * Visually, objects drawn in this fashion in orthogonal views will be - * indistinguishable regardless of their vZ offset - it is only when the - * view is rotated that the user will be able to see the "above" and - * "below" effect of creating view objects with differing vZ values. - * - * Users will generally not want to set gv_data_vZ directly, as it is a view - * space value and may not behave intuitively. Commands are defined to - * calculate vZ values based on model spaces inputs, and these should be - * used to generate the value supplied to gv_data_vZ. - */ - fastf_t gv_data_vZ; - - // libtclcad data struct bv_data_tclcad gv_tcl; diff --git a/include/bv/faceplate.h b/include/bv/faceplate.h index 5085b334e89..62688b42c6f 100644 --- a/include/bv/faceplate.h +++ b/include/bv/faceplate.h @@ -57,6 +57,7 @@ struct bv_adc_state { struct bv_grid_state { int rc; int draw; /* draw grid */ + int adaptive; /* adapt to view size */ int snap; /* snap to grid */ fastf_t anchor[3]; fastf_t res_h; /* grid resolution in h */ @@ -83,10 +84,25 @@ struct bv_interactive_rect_state { fastf_t aspect; /* Canvas aspect ratio */ }; + +struct bv_params_state { + int draw; /* Overall on/off toggle */ + int draw_size; /* Print view size */ + int draw_center; /* Print view X,Y,Z center point */ + int draw_az; /* Print view azimuth */ + int draw_el; /* Print view elevation */ + int draw_tw; /* Print view twist */ + int draw_fps; /* Print frame per second */ + int color[3]; /* Set params color */ + int font_size; /* Set params font size */ +}; + + struct bv_other_state { int gos_draw; int gos_line_color[3]; int gos_text_color[3]; + int gos_font_size; }; #endif /* DM_BV_FACEPLATE_H */ diff --git a/include/bg/lod.h b/include/bv/lod.h similarity index 75% rename from include/bg/lod.h rename to include/bv/lod.h index 9cf2142dc34..f95c76ce36b 100644 --- a/include/bg/lod.h +++ b/include/bv/lod.h @@ -20,7 +20,7 @@ /*----------------------------------------------------------------------*/ /* @file lod.h */ -/** @addtogroup bg_lod */ +/** @addtogroup bv_lod */ /** @{ */ /** @@ -28,13 +28,13 @@ * particularly for meshes. */ -#ifndef BG_LOD_H -#define BG_LOD_H +#ifndef BV_LOD_H +#define BV_LOD_H #include "common.h" #include "vmath.h" -#include "bv.h" -#include "bg/defines.h" +#include "bu/ptbl.h" +#include "bv/defines.h" __BEGIN_DECLS @@ -44,29 +44,30 @@ __BEGIN_DECLS * camera is looking. If the view width and height are not set or there is * some other problem, no volume is computed. This function is intended * primarily to be set as an updating callback for the bview structure. */ -BG_EXPORT extern void -bg_view_bounds(struct bview *v); +BV_EXPORT extern void +bv_view_bounds(struct bview *v); -/* Given a screen x,y coordinate, construct and return the set of all scene - * objects whose AABB intersect with the OBB created by the projection of that - * pixel through the scene. */ -BG_EXPORT int -bg_view_objs_select(struct bv_scene_obj ***set, struct bview *v, int x, int y); +/* Given a screen x,y coordinate, construct the set of all scene objects whose + * AABB intersect with the OBB created by the projection of that pixel through + * the scene. sset holds the struct bv_scene_obj pointers of the selected + * objects. */ +BV_EXPORT int +bv_view_objs_select(struct bu_ptbl *sset, struct bview *v, int x, int y); /* Given a screen x1,y1,x2,y2 rectangle, construct and return the set of all scene * objects whose AABB intersect with the OBB created by the projection of that * rectangle through the scene. */ -BG_EXPORT int -bg_view_objs_rect_select(struct bv_scene_obj ***set, struct bview *v, int x1, int y1, int x2, int y2); +BV_EXPORT int +bv_view_objs_rect_select(struct bu_ptbl *sset, struct bview *v, int x1, int y1, int x2, int y2); /* Storing and reading from a lot of small, individual files doesn't work very * well on some platforms. We provide a "context" to manage bookkeeping of data * across objects. The details are implementation internal - the application * will simply create a context with a file name and provide it to the various * LoD calls. */ -struct bg_mesh_lod_context_internal; -struct bg_mesh_lod_context { - struct bg_mesh_lod_context_internal *i; +struct bv_mesh_lod_context_internal; +struct bv_mesh_lod_context { + struct bv_mesh_lod_context_internal *i; }; /* Create an LoD context using "name". If data is already present associated @@ -77,21 +78,21 @@ struct bg_mesh_lod_context { * Note that "name" should be a full, unique path associated with the source * database. libbu will manage where the context data is cached. */ -BG_EXPORT struct bg_mesh_lod_context * -bg_mesh_lod_context_create(const char *name); +BV_EXPORT struct bv_mesh_lod_context * +bv_mesh_lod_context_create(const char *name); /* Free all memory associated with context c. Note that this call does NOT * remove the on-disk data. */ -BG_EXPORT void -bg_mesh_lod_context_destroy(struct bg_mesh_lod_context *c); +BV_EXPORT void +bv_mesh_lod_context_destroy(struct bv_mesh_lod_context *c); /* Remove cache data associated with key. If key == 0, remove ALL cache data * associated with all LoD objects in c. (i.e. a full LoD cache reset for that * .g database). If key == 0 AND c == NULL, clear all LoD cache data for all * .g databases associated with the current user's cache. */ -BG_EXPORT void -bg_mesh_lod_clear_cache(struct bg_mesh_lod_context *c, unsigned long long key); +BV_EXPORT void +bv_mesh_lod_clear_cache(struct bv_mesh_lod_context *c, unsigned long long key); /** * Given a set of points and faces, calculate a lookup key and determine if the @@ -104,14 +105,14 @@ bg_mesh_lod_clear_cache(struct bg_mesh_lod_context *c, unsigned long long key); * * If user_key != 0, it will be used instead of the mesh data hash as the db * key to be used for subsequent lookups. Typically calculated with - * bg_mesh_lod_custom_key from user supplied data, if the mesh data is not + * bv_mesh_lod_custom_key from user supplied data, if the mesh data is not * the desired source of the key. * - * Note: to clear pre-existing cached data, run bg_mesh_lod_clear_cache(); + * Note: to clear pre-existing cached data, run bv_mesh_lod_clear_cache(); * * @return the lookup key calculated from the data */ -BG_EXPORT unsigned long long -bg_mesh_lod_cache(struct bg_mesh_lod_context *c, const point_t *v, size_t vcnt, const vect_t *vn, int *f, size_t fcnt, unsigned long long user_key, fastf_t fratio); +BV_EXPORT unsigned long long +bv_mesh_lod_cache(struct bv_mesh_lod_context *c, const point_t *v, size_t vcnt, const vect_t *vn, int *f, size_t fcnt, unsigned long long user_key, fastf_t fratio); /** @@ -120,8 +121,8 @@ bg_mesh_lod_cache(struct bg_mesh_lod_context *c, const point_t *v, size_t vcnt, * on which to base a look-up key (for example, mesh data being used to represent * a non-mesh object. */ -BG_EXPORT unsigned long long -bg_mesh_lod_custom_key(void *data, size_t data_size); +BV_EXPORT unsigned long long +bv_mesh_lod_custom_key(void *data, size_t data_size); @@ -140,8 +141,8 @@ bg_mesh_lod_custom_key(void *data, size_t data_size); * a large model without having to hash the full mesh data of the model * to retrieve the data. */ -BG_EXPORT unsigned long long -bg_mesh_lod_key_get(struct bg_mesh_lod_context *c, const char *name); +BV_EXPORT unsigned long long +bv_mesh_lod_key_get(struct bv_mesh_lod_context *c, const char *name); /** * Given a name and a key, instruct the context to associate that name with @@ -149,34 +150,34 @@ bg_mesh_lod_key_get(struct bg_mesh_lod_context *c, const char *name); * * Returns 0 if successful, else error */ -BG_EXPORT int -bg_mesh_lod_key_put(struct bg_mesh_lod_context *c, const char *name, unsigned long long key); +BV_EXPORT int +bv_mesh_lod_key_put(struct bv_mesh_lod_context *c, const char *name, unsigned long long key); /** - * Set up the bg_mesh_lod container using cached LoD information associated + * Set up the bv_mesh_lod container using cached LoD information associated * with key. If no cached data has been prepared, a NULL container is - * returned - to prepare cached data, call bg_mesh_lod_cache with the original + * returned - to prepare cached data, call bv_mesh_lod_cache with the original * mesh input data. This call is intended to be usable in situations where * we don't want to pull the full mesh data set into memory, so we can't assume * the original data is present. * - * Note: bg_mesh_lod assumes a non-changing mesh - if the mesh is changed after + * Note: bv_mesh_lod assumes a non-changing mesh - if the mesh is changed after * it is created, the internal container does *NOT* automatically update. In * that case the old struct should be destroyed and a new one created. * - * A bg_mesh_lod return from this function will be initialized only to the + * A bv_mesh_lod return from this function will be initialized only to the * lowest level of data (i.e. the coarsest possible representation of the - * object.) To tailor the data, use the bg_mesh_lod_view function. For lower - * level control, the bg_mesh_lod_level function may be used to explicitly + * object.) To tailor the data, use the bv_mesh_lod_view function. For lower + * level control, the bv_mesh_lod_level function may be used to explicitly * manipulate the loaded LoD (usually used for debugging, but also useful if an * application wishes to visualize levels explicitly.) */ -BG_EXPORT struct bv_mesh_lod * -bg_mesh_lod_create(struct bg_mesh_lod_context *c, unsigned long long key); +BV_EXPORT struct bv_mesh_lod * +bv_mesh_lod_create(struct bv_mesh_lod_context *c, unsigned long long key); /* Clean up the lod container. */ -BG_EXPORT void -bg_mesh_lod_destroy(struct bv_mesh_lod *l); +BV_EXPORT void +bv_mesh_lod_destroy(struct bv_mesh_lod *l); /** * Given a scene object with mesh LoD data stored in s->draw_data, reduce @@ -185,8 +186,8 @@ bg_mesh_lod_destroy(struct bv_mesh_lod *l); * currently is OpenGL display lists - once generated, we can clear the * internally stored LoD data until the level changes. Note that there is a * re-loading performance penalty as a trade-off to the memory savings. */ -BG_EXPORT void -bg_mesh_lod_memshrink(struct bv_scene_obj *s); +BV_EXPORT void +bv_mesh_lod_memshrink(struct bv_scene_obj *s); /** * Given a scene object with mesh LoD data stored in s->draw_data and a bview, @@ -196,8 +197,8 @@ bg_mesh_lod_memshrink(struct bv_scene_obj *s); * * Returns the level selected. If v == NULL, return current level of l. If * there is an error or l == NULL, return -1; */ -BG_EXPORT int -bg_mesh_lod_view(struct bv_scene_obj *s, struct bview *v, int reset); +BV_EXPORT int +bv_mesh_lod_view(struct bv_scene_obj *s, struct bview *v, int reset); /** * Given a scene object with mesh LoD data stored in s->draw_data and a detail @@ -208,14 +209,14 @@ bg_mesh_lod_view(struct bv_scene_obj *s, struct bview *v, int reset); * * Returns the level selected. If level == -1, return current level of l. If * there is an error, return -1; */ -BG_EXPORT int -bg_mesh_lod_level(struct bv_scene_obj *s, int level, int reset); +BV_EXPORT int +bv_mesh_lod_level(struct bv_scene_obj *s, int level, int reset); /* Free a scene object's LoD data. Suitable as a s_free_callback function * for a bv_scene_obj. This function will also trigger any additional * "free" callback functions which might be defined for the LoD container. */ -BG_EXPORT void -bg_mesh_lod_free(struct bv_scene_obj *s); +BV_EXPORT void +bv_mesh_lod_free(struct bv_scene_obj *s); @@ -224,16 +225,16 @@ bg_mesh_lod_free(struct bv_scene_obj *s); * to the core LoD management logic with callbacks */ /* Set function callbacks for retrieving and freeing high levels of mesh detail */ -BG_EXPORT void -bg_mesh_lod_detail_setup_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *), void *cb_data); -BG_EXPORT void -bg_mesh_lod_detail_clear_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *)); -BG_EXPORT void -bg_mesh_lod_detail_free_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *)); +BV_EXPORT void +bv_mesh_lod_detail_setup_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *), void *cb_data); +BV_EXPORT void +bv_mesh_lod_detail_clear_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *)); +BV_EXPORT void +bv_mesh_lod_detail_free_clbk(struct bv_mesh_lod *lod, int (*clbk)(struct bv_mesh_lod *, void *)); __END_DECLS -#endif /* BG_LOD_H */ +#endif /* BV_LOD_H */ /** @} */ /* * Local Variables: diff --git a/include/bv/plot3.h b/include/bv/plot3.h index 046eff95573..4386f79c0c7 100644 --- a/include/bv/plot3.h +++ b/include/bv/plot3.h @@ -17,11 +17,55 @@ * License along with this file; see the file named COPYING for more * information. */ -/** @addtogroup bv_plot +/** @addtogroup plot3 + * + * @brief A public-domain UNIX plot library, for 2-D and 3-D plotting + * in 16-bit VAX signed integer spaces, or 64-bit IEEE floating point. + * + * These routines generate "UNIX plot" output (with the addition of + * 3-D commands). They behave almost exactly like the regular libplot + * routines, except: + * + * -# These all take a stdio file pointer, and can thus be used to + * create multiple plot files simultaneously. + * -# There are 3-D versions of most commands. + * -# There are IEEE floating point versions of the commands. + * -# The names have been changed. + * + * The 3-D extensions are those of Doug Gwyn, from his System V + * extensions. + * + * These are the ascii command letters allocated to various actions. + * Care has been taken to consistently match lowercase and uppercase + * letters. + * + * @code + 2d 3d 2df 3df + space s S w W + move m M o O + cont n N q Q + point p P x X + line l L v V + circle c i + arc a r + linmod f + label t + erase e + color C + flush F + + bd gh jk uyz + ABDEGHIJKRTUYZ + + @endcode * * The calling sequence is the same as the original Bell Labs routines, with * the exception of the pl_ prefix on the name. * + * NOTE: from libbv's perspective, plot3.h is a stand-alone header that does + * not use any other library functionality. To use this header without libbv, + * define PLOT3_IMPLEMENTATION before including the plot3.h header. + * * Of interest: the Plan 9 sources (recently MIT licensed) appear to be * related to the original code that would have formed the conceptual basis for * these routines: @@ -35,16 +79,26 @@ /** @{ */ /** @file plot3.h */ -#ifndef BV_PLOT3_H -#define BV_PLOT3_H +#ifndef PLOT3_H +#define PLOT3_H #include "common.h" #include "vmath.h" -#include "bu/defines.h" #include "bu/color.h" #include "bu/file.h" -#include "bv/defines.h" + +#ifndef PLOT3_EXPORT +# if defined(PLOT3_DLL_EXPORTS) && defined(PLOT3_DLL_IMPORTS) +# error "Only PLOT3_DLL_EXPORTS or PLOT3_DLL_IMPORTS can be defined, not both." +# elif defined(PLOT3_DLL_EXPORTS) +# define PLOT3_EXPORT COMPILER_DLLEXPORT +# elif defined(PLOT3_DLL_IMPORTS) +# define PLOT3_EXPORT COMPILER_DLLIMPORT +# else +# define PLOT3_EXPORT +# endif +#endif __BEGIN_DECLS @@ -56,44 +110,44 @@ __BEGIN_DECLS #define PL_OUTPUT_MODE_TEXT 1 -BV_EXPORT extern int pl_getOutputMode(void); -BV_EXPORT extern void pl_setOutputMode(int mode); -BV_EXPORT extern void pl_point(FILE *plotfp, +PLOT3_EXPORT extern int pl_getOutputMode(void); +PLOT3_EXPORT extern void pl_setOutputMode(int mode); +PLOT3_EXPORT extern void pl_point(FILE *plotfp, int x, int y); -BV_EXPORT extern void pl_line(FILE *plotfp, +PLOT3_EXPORT extern void pl_line(FILE *plotfp, int fx, int fy, int tx, int ty); -BV_EXPORT extern void pl_linmod(FILE *plotfp, +PLOT3_EXPORT extern void pl_linmod(FILE *plotfp, const char *s); -BV_EXPORT extern void pl_move(FILE *plotfp, +PLOT3_EXPORT extern void pl_move(FILE *plotfp, int x, int y); -BV_EXPORT extern void pl_cont(FILE *plotfp, +PLOT3_EXPORT extern void pl_cont(FILE *plotfp, int x, int y); -BV_EXPORT extern void pl_label(FILE *plotfp, +PLOT3_EXPORT extern void pl_label(FILE *plotfp, const char *s); -BV_EXPORT extern void pl_space(FILE *plotfp, +PLOT3_EXPORT extern void pl_space(FILE *plotfp, int x_1, int y_1, int x_2, int y_2); -BV_EXPORT extern void pl_erase(FILE *plotfp); -BV_EXPORT extern void pl_circle(FILE *plotfp, +PLOT3_EXPORT extern void pl_erase(FILE *plotfp); +PLOT3_EXPORT extern void pl_circle(FILE *plotfp, int x, int y, int r); -BV_EXPORT extern void pl_arc(FILE *plotfp, +PLOT3_EXPORT extern void pl_arc(FILE *plotfp, int xc, int yc, int x_1, int y_1, int x_2, int y_2); -BV_EXPORT extern void pl_box(FILE *plotfp, +PLOT3_EXPORT extern void pl_box(FILE *plotfp, int x_1, int y_1, int x_2, @@ -102,40 +156,40 @@ BV_EXPORT extern void pl_box(FILE *plotfp, /* * BRL extensions to the UNIX-plot file format. */ -BV_EXPORT extern void pl_color(FILE *plotfp, +PLOT3_EXPORT extern void pl_color(FILE *plotfp, int r, int g, int b); -BV_EXPORT extern void pl_color_buc(FILE *plotfp, +PLOT3_EXPORT extern void pl_color_buc(FILE *plotfp, struct bu_color *c); -BV_EXPORT extern void pl_flush(FILE *plotfp); -BV_EXPORT extern void pl_3space(FILE *plotfp, +PLOT3_EXPORT extern void pl_flush(FILE *plotfp); +PLOT3_EXPORT extern void pl_3space(FILE *plotfp, int x_1, int y_1, int z_1, int x_2, int y_2, int z_2); -BV_EXPORT extern void pl_3point(FILE *plotfp, +PLOT3_EXPORT extern void pl_3point(FILE *plotfp, int x, int y, int z); -BV_EXPORT extern void pl_3move(FILE *plotfp, +PLOT3_EXPORT extern void pl_3move(FILE *plotfp, int x, int y, int z); -BV_EXPORT extern void pl_3cont(FILE *plotfp, +PLOT3_EXPORT extern void pl_3cont(FILE *plotfp, int x, int y, int z); -BV_EXPORT extern void pl_3line(FILE *plotfp, +PLOT3_EXPORT extern void pl_3line(FILE *plotfp, int x_1, int y_1, int z_1, int x_2, int y_2, int z_2); -BV_EXPORT extern void pl_3box(FILE *plotfp, +PLOT3_EXPORT extern void pl_3box(FILE *plotfp, int x_1, int y_1, int z_1, @@ -144,37 +198,37 @@ BV_EXPORT extern void pl_3box(FILE *plotfp, int z_2); /* Double floating point versions */ -BV_EXPORT extern void pd_point(FILE *plotfp, +PLOT3_EXPORT extern void pd_point(FILE *plotfp, double x, double y); -BV_EXPORT extern void pd_line(FILE *plotfp, +PLOT3_EXPORT extern void pd_line(FILE *plotfp, double fx, double fy, double tx, double ty); -BV_EXPORT extern void pd_move(FILE *plotfp, +PLOT3_EXPORT extern void pd_move(FILE *plotfp, double x, double y); -BV_EXPORT extern void pd_cont(FILE *plotfp, +PLOT3_EXPORT extern void pd_cont(FILE *plotfp, double x, double y); -BV_EXPORT extern void pd_space(FILE *plotfp, +PLOT3_EXPORT extern void pd_space(FILE *plotfp, double x_1, double y_1, double x_2, double y_2); -BV_EXPORT extern void pd_circle(FILE *plotfp, +PLOT3_EXPORT extern void pd_circle(FILE *plotfp, double x, double y, double r); -BV_EXPORT extern void pd_arc(FILE *plotfp, +PLOT3_EXPORT extern void pd_arc(FILE *plotfp, double xc, double yc, double x_1, double y_1, double x_2, double y_2); -BV_EXPORT extern void pd_box(FILE *plotfp, +PLOT3_EXPORT extern void pd_box(FILE *plotfp, double x_1, double y_1, double x_2, @@ -182,66 +236,1020 @@ BV_EXPORT extern void pd_box(FILE *plotfp, /* Double 3-D both in vector and enumerated versions */ #ifdef VMATH_H -BV_EXPORT extern void pdv_3space(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3space(FILE *plotfp, const vect_t min, const vect_t max); -BV_EXPORT extern void pdv_3point(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3point(FILE *plotfp, const vect_t pt); -BV_EXPORT extern void pdv_3move(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3move(FILE *plotfp, const vect_t pt); -BV_EXPORT extern void pdv_3cont(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3cont(FILE *plotfp, const vect_t pt); -BV_EXPORT extern void pdv_3line(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3line(FILE *plotfp, const vect_t a, const vect_t b); -BV_EXPORT extern void pdv_3box(FILE *plotfp, +PLOT3_EXPORT extern void pdv_3box(FILE *plotfp, const vect_t a, const vect_t b); #endif /* VMATH_H */ -BV_EXPORT extern void pd_3space(FILE *plotfp, +PLOT3_EXPORT extern void pd_3space(FILE *plotfp, double x_1, double y_1, double z_1, double x_2, double y_2, double z_2); -BV_EXPORT extern void pd_3point(FILE *plotfp, +PLOT3_EXPORT extern void pd_3point(FILE *plotfp, double x, double y, double z); -BV_EXPORT extern void pd_3move(FILE *plotfp, +PLOT3_EXPORT extern void pd_3move(FILE *plotfp, double x, double y, double z); -BV_EXPORT extern void pd_3cont(FILE *plotfp, +PLOT3_EXPORT extern void pd_3cont(FILE *plotfp, double x, double y, double z); -BV_EXPORT extern void pd_3line(FILE *plotfp, +PLOT3_EXPORT extern void pd_3line(FILE *plotfp, double x_1, double y_1, double z_1, double x_2, double y_2, double z_2); -BV_EXPORT extern void pd_3box(FILE *plotfp, +PLOT3_EXPORT extern void pd_3box(FILE *plotfp, double x_1, double y_1, double z_1, double x_2, double y_2, double z_2); -BV_EXPORT extern void pdv_3ray(FILE *fp, +PLOT3_EXPORT extern void pdv_3ray(FILE *fp, const point_t pt, const vect_t dir, double t); -BV_EXPORT extern int plot3_invalid(FILE *fp, int mode); +PLOT3_EXPORT extern int plot3_invalid(FILE *fp, int mode); __END_DECLS -#endif /* BV_PLOT3_H */ +#if defined(PLOT3_IMPLEMENTATION) +#include +#include "bu/cv.h" + +static int pl_outputMode = PL_OUTPUT_MODE_BINARY; + +/* For the sake of efficiency, we trust putc() to write only one byte */ +#define putsi(a) putc(a, plotfp); putc((a>>8), plotfp) + +/* Making a common pd_3 to be used in pd_3cont and pd_3move */ +void +pd_3(register FILE *plotfp, double x, double y, double z, char c) +{ + size_t ret; + double in[3]; + unsigned char out[3*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = x; + in[1] = y; + in[2] = z; + bu_cv_htond(&out[1], (unsigned char *)in, 3); + + out[0] = c; + ret = fwrite(out, 1, 3*8+1, plotfp); + if (ret != 3*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "%c %g %g %g\n", c, x, y, z); + } +} + +/* Making a common pdv_3 to be used in pdv_3cont and pdv_3move */ +void +pdv_3(register FILE *plotfp, const fastf_t *pt, char c) +{ + size_t ret; + unsigned char out[3*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + bu_cv_htond(&out[1], (unsigned char *)pt, 3); + + out[0] = c; + ret = fwrite(out, 1, 3*8+1, plotfp); + if (ret != 3*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "%c %g %g %g\n", c, V3ARGS(pt)); + } +} + +/* Making a common pd to be used in pd_cont and pd_move */ +void +pd(register FILE *plotfp, double x, double y, char c) +{ + size_t ret; + double in[2]; + unsigned char out[2*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = x; + in[1] = y; + bu_cv_htond(&out[1], (unsigned char *)in, 2); + + out[0] = c; + ret = fwrite(out, 1, 2*8+1, plotfp); + if (ret != 2*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "%c %g %g\n", c, x, y); + } +} + +/* Making a common pl_3 to be used in pl_3cont and pl_3move */ +void +pl_3(register FILE *plotfp, int x, int y, int z, char c) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc( c, plotfp); + putsi(x); + putsi(y); + putsi(z); + } else { + fprintf(plotfp, "%c %d %d %d\n", c, x, y, z); + } +} + +/* + * These interfaces provide the standard UNIX-Plot functionality + */ + +int +pl_getOutputMode(void) { + return pl_outputMode; +} + +void +pl_setOutputMode(int mode) { + pl_outputMode = mode; +} + +/** + * @brief + * plot a point + */ +void +pl_point(register FILE *plotfp, int x, int y) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('p', plotfp); + putsi(x); + putsi(y); + } else { + fprintf(plotfp, "p %d %d\n", x, y); + } +} + +void +pl_line(register FILE *plotfp, int px1, int py1, int px2, int py2) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('l', plotfp); + putsi(px1); + putsi(py1); + putsi(px2); + putsi(py2); + } else { + fprintf(plotfp, "l %d %d %d %d\n", px1, py1, px2, py2); + } +} + +void +pl_linmod(register FILE *plotfp, const char *s) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('f', plotfp); + while (*s) + putc(*s++, plotfp); + putc('\n', plotfp); + } else { + fprintf(plotfp, "f %s\n", s); + } +} + +void +pl_move(register FILE *plotfp, int x, int y) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('m', plotfp); + putsi(x); + putsi(y); + } else { + fprintf(plotfp, "m %d %d\n", x, y); + } +} + +void +pl_cont(register FILE *plotfp, int x, int y) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('n', plotfp); + putsi(x); + putsi(y); + } else { + fprintf(plotfp, "n %d %d\n", x, y); + } +} + +void +pl_label(register FILE *plotfp, const char *s) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('t', plotfp); + while (*s) + putc(*s++, plotfp); + putc('\n', plotfp); + } else { + fprintf(plotfp, "t %s\n", s); + } +} + +void +pl_space(register FILE *plotfp, int px1, int py1, int px2, int py2) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('s', plotfp); + putsi(px1); + putsi(py1); + putsi(px2); + putsi(py2); + } else { + fprintf(plotfp, "s %d %d %d %d\n", px1, py1, px2, py2); + } +} + +void +pl_erase(register FILE *plotfp) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) + putc('e', plotfp); + else + fprintf(plotfp, "e\n"); +} + +void +pl_circle(register FILE *plotfp, int x, int y, int r) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('c', plotfp); + putsi(x); + putsi(y); + putsi(r); + } else { + fprintf(plotfp, "c %d %d %d\n", x, y, r); + } +} + +void +pl_arc(register FILE *plotfp, int xc, int yc, int px1, int py1, int px2, int py2) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('a', plotfp); + putsi(xc); + putsi(yc); + putsi(px1); + putsi(py1); + putsi(px2); + putsi(py2); + } else { + fprintf(plotfp, "a %d %d %d %d %d %d\n", xc, yc, px1, py1, px2, py2); + } +} + +void +pl_box(register FILE *plotfp, int px1, int py1, int px2, int py2) +{ + pl_move(plotfp, px1, py1); + pl_cont(plotfp, px1, py2); + pl_cont(plotfp, px2, py2); + pl_cont(plotfp, px2, py1); + pl_cont(plotfp, px1, py1); + pl_move(plotfp, px2, py2); +} + +/* + * Here lie the BRL 3-D extensions. + */ + +/* Warning: r, g, b are ints. The output is chars. */ +void +pl_color(register FILE *plotfp, int r, int g, int b) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('C', plotfp); + putc(r, plotfp); + putc(g, plotfp); + putc(b, plotfp); + } else { + fprintf(plotfp, "C %d %d %d\n", r, g, b); + } +} + +void +pl_color_buc(register FILE *plotfp, struct bu_color *c) +{ + int r = 0; + int g = 0; + int b = 0; + (void)bu_color_to_rgb_ints(c, &r, &g, &b); + pl_color(plotfp, r, g, b); +} + +void +pl_flush(register FILE *plotfp) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('F', plotfp); + } else { + fprintf(plotfp, "F\n"); + } + + fflush(plotfp); +} + +void +pl_3space(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('S', plotfp); + putsi(px1); + putsi(py1); + putsi(pz1); + putsi(px2); + putsi(py2); + putsi(pz2); + } else { + fprintf(plotfp, "S %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2); + } +} + +void +pl_3point(register FILE *plotfp, int x, int y, int z) +{ + pl_3(plotfp, x, y, z, 'P'); /* calling common function pl_3 */ +} + +void +pl_3move(register FILE *plotfp, int x, int y, int z) +{ + pl_3(plotfp, x, y, z, 'M'); /* calling common function pl_3 */ +} + +void +pl_3cont(register FILE *plotfp, int x, int y, int z) +{ + pl_3(plotfp, x, y, z, 'N'); /* calling common function pl_3 */ +} + +void +pl_3line(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) +{ + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + putc('L', plotfp); + putsi(px1); + putsi(py1); + putsi(pz1); + putsi(px2); + putsi(py2); + putsi(pz2); + } else { + fprintf(plotfp, "L %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2); + } +} + +void +pl_3box(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) +{ + pl_3move(plotfp, px1, py1, pz1); + /* first side */ + pl_3cont(plotfp, px1, py2, pz1); + pl_3cont(plotfp, px1, py2, pz2); + pl_3cont(plotfp, px1, py1, pz2); + pl_3cont(plotfp, px1, py1, pz1); + /* across */ + pl_3cont(plotfp, px2, py1, pz1); + /* second side */ + pl_3cont(plotfp, px2, py2, pz1); + pl_3cont(plotfp, px2, py2, pz2); + pl_3cont(plotfp, px2, py1, pz2); + pl_3cont(plotfp, px2, py1, pz1); + /* front edge */ + pl_3move(plotfp, px1, py2, pz1); + pl_3cont(plotfp, px2, py2, pz1); + /* bottom back */ + pl_3move(plotfp, px1, py1, pz2); + pl_3cont(plotfp, px2, py1, pz2); + /* top back */ + pl_3move(plotfp, px1, py2, pz2); + pl_3cont(plotfp, px2, py2, pz2); +} + +/* + * Double floating point versions + */ + +void +pd_point(register FILE *plotfp, double x, double y) +{ + pd( plotfp, x, y, 'x'); /* calling common function pd */ +} + +void +pd_line(register FILE *plotfp, double px1, double py1, double px2, double py2) +{ + size_t ret; + double in[4]; + unsigned char out[4*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = px1; + in[1] = py1; + in[2] = px2; + in[3] = py2; + bu_cv_htond(&out[1], (unsigned char *)in, 4); + + out[0] = 'v'; + ret = fwrite(out, 1, 4*8+1, plotfp); + if (ret != 4*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "v %g %g %g %g\n", px1, py1, px2, py2); + } +} + +/* Note: no pd_linmod(), just use pl_linmod() */ + +void +pd_move(register FILE *plotfp, double x, double y) +{ + pd( plotfp, x, y, 'o'); /* calling common function pd */ +} + +void +pd_cont(register FILE *plotfp, double x, double y) +{ + pd( plotfp, x, y, 'q'); /* calling common function pd */ +} + +void +pd_space(register FILE *plotfp, double px1, double py1, double px2, double py2) +{ + size_t ret; + double in[4]; + unsigned char out[4*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = px1; + in[1] = py1; + in[2] = px2; + in[3] = py2; + bu_cv_htond(&out[1], (unsigned char *)in, 4); + + out[0] = 'w'; + ret = fwrite(out, 1, 4*8+1, plotfp); + if (ret != 4*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "w %g %g %g %g\n", px1, py1, px2, py2); + } +} + +void +pd_circle(register FILE *plotfp, double x, double y, double r) +{ + size_t ret; + double in[3]; + unsigned char out[3*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = x; + in[1] = y; + in[2] = r; + bu_cv_htond(&out[1], (unsigned char *)in, 3); + + out[0] = 'i'; + ret = fwrite(out, 1, 3*8+1, plotfp); + if (ret != 3*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "i %g %g %g\n", x, y, r); + } +} + +void +pd_arc(register FILE *plotfp, double xc, double yc, double px1, double py1, double px2, double py2) +{ + size_t ret; + double in[6]; + unsigned char out[6*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = xc; + in[1] = yc; + in[2] = px1; + in[3] = py1; + in[4] = px2; + in[5] = py2; + bu_cv_htond(&out[1], (unsigned char *)in, 6); + + out[0] = 'r'; + ret = fwrite(out, 1, 6*8+1, plotfp); + if (ret != 6*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "r %g %g %g %g %g %g\n", xc, yc, px1, py1, px2, py2); + } +} + +void +pd_box(register FILE *plotfp, double px1, double py1, double px2, double py2) +{ + pd_move(plotfp, px1, py1); + pd_cont(plotfp, px1, py2); + pd_cont(plotfp, px2, py2); + pd_cont(plotfp, px2, py1); + pd_cont(plotfp, px1, py1); + pd_move(plotfp, px2, py2); +} + +/* Double 3-D, both in vector and enumerated versions */ +void +pdv_3space(register FILE *plotfp, const vect_t min, const vect_t max) +{ + size_t ret; + unsigned char out[6*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + bu_cv_htond(&out[1], (unsigned char *)min, 3); + bu_cv_htond(&out[3*8+1], (unsigned char *)max, 3); + + out[0] = 'W'; + ret = fwrite(out, 1, 6*8+1, plotfp); + if (ret != 6*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "W %g %g %g %g %g %g\n", V3ARGS(min), V3ARGS(max)); + } +} + +void +pd_3space(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) +{ + size_t ret; + double in[6]; + unsigned char out[6*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = px1; + in[1] = py1; + in[2] = pz1; + in[3] = px2; + in[4] = py2; + in[5] = pz2; + bu_cv_htond(&out[1], (unsigned char *)in, 6); + + out[0] = 'W'; + ret = fwrite(out, 1, 6*8+1, plotfp); + if (ret != 6*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "W %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2); + } +} + +void +pdv_3point(register FILE *plotfp, const point_t pt) +{ + pdv_3(plotfp, pt, 'X'); /* calling common function pdv_3 */ +} + +void +pd_3point(register FILE *plotfp, double x, double y, double z) +{ + pd_3(plotfp, x, y, z, 'X'); /* calling common function pd_3 */ +} + +void +pdv_3move(register FILE *plotfp, const point_t pt) +{ + pdv_3(plotfp, pt, 'O'); /* calling common function pdv_3 */ +} + +void +pd_3move(register FILE *plotfp, double x, double y, double z) +{ + pd_3(plotfp, x, y, z, 'O'); /* calling common function pd_3 */ +} + +void +pdv_3cont(register FILE *plotfp, const point_t pt) +{ + pdv_3(plotfp, pt, 'Q'); /* calling common function pdv_3 */ +} + +void +pd_3cont(register FILE *plotfp, double x, double y, double z) +{ + pd_3(plotfp, x, y, z, 'Q'); /* calling common function pd_3 */ +} + +void +pdv_3line(register FILE *plotfp, const vect_t a, const vect_t b) +{ + size_t ret; + unsigned char out[6*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + bu_cv_htond(&out[1], (unsigned char *)a, 3); + bu_cv_htond(&out[3*8+1], (unsigned char *)b, 3); + + out[0] = 'V'; + ret = fwrite(out, 1, 6*8+1, plotfp); + if (ret != 6*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "V %g %g %g %g %g %g\n", V3ARGS(a), V3ARGS(b)); + } +} + +void +pd_3line(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) +{ + size_t ret; + double in[6]; + unsigned char out[6*8+1]; + + if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { + in[0] = px1; + in[1] = py1; + in[2] = pz1; + in[3] = px2; + in[4] = py2; + in[5] = pz2; + bu_cv_htond(&out[1], (unsigned char *)in, 6); + + out[0] = 'V'; + ret = fwrite(out, 1, 6*8+1, plotfp); + if (ret != 6*8+1) { + perror("fwrite"); + } + } else { + fprintf(plotfp, "V %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2); + } +} + +void +pdv_3box(register FILE *plotfp, const vect_t a, const vect_t b) +{ + pd_3move(plotfp, a[X], a[Y], a[Z]); + /* first side */ + pd_3cont(plotfp, a[X], b[Y], a[Z]); + pd_3cont(plotfp, a[X], b[Y], b[Z]); + pd_3cont(plotfp, a[X], a[Y], b[Z]); + pd_3cont(plotfp, a[X], a[Y], a[Z]); + /* across */ + pd_3cont(plotfp, b[X], a[Y], a[Z]); + /* second side */ + pd_3cont(plotfp, b[X], b[Y], a[Z]); + pd_3cont(plotfp, b[X], b[Y], b[Z]); + pd_3cont(plotfp, b[X], a[Y], b[Z]); + pd_3cont(plotfp, b[X], a[Y], a[Z]); + /* front edge */ + pd_3move(plotfp, a[X], b[Y], a[Z]); + pd_3cont(plotfp, b[X], b[Y], a[Z]); + /* bottom back */ + pd_3move(plotfp, a[X], a[Y], b[Z]); + pd_3cont(plotfp, b[X], a[Y], b[Z]); + /* top back */ + pd_3move(plotfp, a[X], b[Y], b[Z]); + pd_3cont(plotfp, b[X], b[Y], b[Z]); +} + +void +pd_3box(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) +{ + pd_3move(plotfp, px1, py1, pz1); + /* first side */ + pd_3cont(plotfp, px1, py2, pz1); + pd_3cont(plotfp, px1, py2, pz2); + pd_3cont(plotfp, px1, py1, pz2); + pd_3cont(plotfp, px1, py1, pz1); + /* across */ + pd_3cont(plotfp, px2, py1, pz1); + /* second side */ + pd_3cont(plotfp, px2, py2, pz1); + pd_3cont(plotfp, px2, py2, pz2); + pd_3cont(plotfp, px2, py1, pz2); + pd_3cont(plotfp, px2, py1, pz1); + /* front edge */ + pd_3move(plotfp, px1, py2, pz1); + pd_3cont(plotfp, px2, py2, pz1); + /* bottom back */ + pd_3move(plotfp, px1, py1, pz2); + pd_3cont(plotfp, px2, py1, pz2); + /* top back */ + pd_3move(plotfp, px1, py2, pz2); + pd_3cont(plotfp, px2, py2, pz2); +} + +/** + * Draw a ray + */ +void +pdv_3ray(FILE *fp, const point_t pt, const vect_t dir, double t) +{ + point_t tip; + + VJOIN1(tip, pt, t, dir); + pdv_3move(fp, pt); + pdv_3cont(fp, tip); +} + + +/* + * Routines to validate a plot file + */ + +static int +read_short(FILE *fp, int cnt, int mode) +{ + if (mode == PL_OUTPUT_MODE_BINARY) { + for (int i = 0; i < cnt * 2; i++) { + if (getc(fp) == EOF) + return 1; + } + return 0; + } + if (mode == PL_OUTPUT_MODE_TEXT) { + int ret; + double val; + for (int i = 0; i < cnt; i++) { + ret = fscanf(fp, "%lf", &val); + if (ret != 1) + return 1; + } + return 0; + } + + return 1; +} + +static int +read_ieee(FILE *fp, int cnt, int mode) +{ + size_t ret; + if (mode == PL_OUTPUT_MODE_BINARY) { + for (int i = 0; i < cnt; i++) { + char inbuf[SIZEOF_NETWORK_DOUBLE]; + ret = fread(inbuf, SIZEOF_NETWORK_DOUBLE, 1, fp); + if (ret != 1) + return 1; + } + return 0; + } + if (mode == PL_OUTPUT_MODE_TEXT) { + double val; + for (int i = 0; i < cnt; i++) { + ret = (size_t)fscanf(fp, "%lf", &val); + if (ret != 1) + return 1; + } + return 0; + } + return 1; +} + +static int +read_tstring(FILE *fp, int mode) +{ + int ret; + if (mode == PL_OUTPUT_MODE_BINARY) { + int str_done = 0; + int cc; + while (!feof(fp) && !str_done) { + cc = getc(fp); + if (cc == '\n') + str_done = 1; + } + return 0; + } + if (mode == PL_OUTPUT_MODE_TEXT) { + char carg[256] = {0}; + ret = fscanf(fp, "%255s\n", &carg[0]); + if (ret != 1) + return 1; + return 0; + } + return 1; +} + +int +plot3_invalid(FILE *fp, int mode) +{ + + /* Only two valid modes */ + if (mode != PL_OUTPUT_MODE_BINARY && mode != PL_OUTPUT_MODE_TEXT) { + return 1; + } + + /* A non-readable file isn't a valid file */ + if (!fp) { + return 1; + } + + int i = 0; + int c; + unsigned int tchar = 0; + + while (!feof(fp) && (c=getc(fp)) != EOF) { + if (c < 'A' || c > 'z') { + return 1; + } + switch (c) { + case 'C': + // TCHAR, 3, "color" + if (mode == PL_OUTPUT_MODE_BINARY) { + for (i = 0; i < 3; i++) { + if (getc(fp) == EOF) + return 1; + } + } + if (mode == PL_OUTPUT_MODE_TEXT) { + i = fscanf(fp, "%u", &tchar); + if (i != 1) + return 1; + } + break; + case 'F': + // TNONE, 0, "flush" + break; + case 'L': + // TSHORT, 6, "3line" + if (read_short(fp, 6, mode)) + return 1; + break; + case 'M': + // TSHORT, 3, "3move" + if (read_short(fp, 3, mode)) + return 1; + break; + case 'N': + // TSHORT, 3, "3cont" + if (read_short(fp, 3, mode)) + return 1; + break; + case 'O': + // TIEEE, 3, "d_3move" + if (read_ieee(fp, 3, mode)) + return 1; + break; + case 'P': + // TSHORT, 3, "3point" + if (read_short(fp, 3, mode)) + return 1; + break; + case 'Q': + // TIEEE, 3, "d_3cont" + if (read_ieee(fp, 3, mode)) + return 1; + break; + case 'S': + // TSHORT, 6, "3space" + if (read_short(fp, 6, mode)) + return 1; + break; + case 'V': + // TIEEE, 6, "d_3line" + if (read_ieee(fp, 6, mode)) + return 1; + break; + case 'W': + // TIEEE, 6, "d_3space" + if (read_ieee(fp, 6, mode)) + return 1; + break; + case 'X': + // TIEEE, 3, "d_3point" + if (read_ieee(fp, 3, mode)) + return 1; + break; + case 'a': + // TSHORT, 6, "arc" + if (read_short(fp, 6, mode)) + return 1; + break; + case 'c': + // TSHORT, 3, "circle" + if (read_short(fp, 3, mode)) + return 1; + break; + case 'e': + // TNONE, 0, "erase" + break; + case 'f': + // TSTRING, 1, "linmod" + if (read_tstring(fp, mode)) + return 1; + break; + case 'i': + // TIEEE, 3, "d_circle" + if (read_ieee(fp, 3, mode)) + return 1; + break; + case 'l': + // TSHORT, 4, "line" + if (read_short(fp, 4, mode)) + return 1; + break; + case 'm': + // TSHORT, 2, "move" + if (read_short(fp, 2, mode)) + return 1; + break; + case 'n': + // TSHORT, 2, "cont" + if (read_short(fp, 2, mode)) + return 1; + break; + case 'o': + // TIEEE, 2, "d_move" + if (read_ieee(fp, 2, mode)) + return 1; + break; + case 'p': + // TSHORT, 2, "point" + if (read_short(fp, 2, mode)) + return 1; + break; + case 'q': + // TIEEE, 2, "d_cont" + if (read_ieee(fp, 2, mode)) + return 1; + break; + case 'r': + // TIEEE, 6, "d_arc" + if (read_ieee(fp, 6, mode)) + return 1; + break; + case 's': + // TSHORT, 4, "space" + if (read_short(fp, 4, mode)) + return 1; + break; + case 't': + // TSTRING, 1, "label" + if (read_tstring(fp, mode)) + return 1; + break; + case 'v': + // TIEEE, 4, "d_line" + if (read_ieee(fp, 4, mode)) + return 1; + break; + case 'w': + // TIEEE, 4, "d_space" + if (read_ieee(fp, 4, mode)) + return 1; + break; + case 'x': + // TIEEE, 2, "d_point" + if (read_ieee(fp, 2, mode)) + return 1; + break; + default: + return 1; + break; + }; + } + + return 0; +} + +#endif // PLOT3_IMPLEMENTATION + +#endif /* PLOT3_H */ /** @} */ /* diff --git a/include/bv/polygon.h b/include/bv/polygon.h new file mode 100644 index 00000000000..697210d0cd4 --- /dev/null +++ b/include/bv/polygon.h @@ -0,0 +1,141 @@ +/* P O L Y G O N . H + * BRL-CAD + * + * Copyright (c) 2004-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +/*----------------------------------------------------------------------*/ +/* @file polygon.h */ +/** @addtogroup bv_polygon */ +/** @{ */ + +/** + * @brief Functions for working with polygons + */ + +#ifndef BV_POLYGON_H +#define BV_POLYGON_H + +#include "common.h" +#include "vmath.h" +#include "bu/color.h" +#include "bv/defines.h" +#include "bg/polygon.h" +#include "bg/polygon_types.h" + +__BEGIN_DECLS + +/* View polygon logic and types */ + +#define BV_POLYGON_GENERAL 0 +#define BV_POLYGON_CIRCLE 1 +#define BV_POLYGON_ELLIPSE 2 +#define BV_POLYGON_RECTANGLE 3 +#define BV_POLYGON_SQUARE 4 + +struct bv_polygon { + int type; + int fill_flag; /* set to shade the interior */ + vect2d_t fill_dir; + fastf_t fill_delta; + struct bu_color fill_color; + long curr_contour_i; + long curr_point_i; + point_t origin_point; /* For non-general polygons */ + + /* We stash the view plane creation, so we know how to return + * to it for future 2D alterations */ + plane_t vp; + + /* Offset of polygon plane from the view plane. Allows for moving + * the polygon "towards" and "away from" the viewer. */ + fastf_t vZ; + + /* Actual polygon info */ + struct bg_polygon polygon; + + /* Arbitrary data */ + void *u_data; +}; + +// Given a polygon, create a scene object +BV_EXPORT extern struct bv_scene_obj *bv_create_polygon_obj(struct bview *v, int flags, struct bv_polygon *p); + +// Creates a scene object with a default polygon +BV_EXPORT extern struct bv_scene_obj *bv_create_polygon(struct bview *v, int flags, int type, point_t fp); + +// Various update modes have similar logic - we pass in the flags to the update +// routine to enable/disable specific portions of the overall flow. +#define BV_POLYGON_UPDATE_DEFAULT 0 +#define BV_POLYGON_UPDATE_PROPS_ONLY 1 +#define BV_POLYGON_UPDATE_PT_SELECT 2 +#define BV_POLYGON_UPDATE_PT_SELECT_CLEAR 3 +#define BV_POLYGON_UPDATE_PT_MOVE 4 +#define BV_POLYGON_UPDATE_PT_APPEND 5 +BV_EXPORT extern int bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype); + +// Update just the scene obj vlist, without altering the source polygon +BV_EXPORT extern void bv_polygon_vlist(struct bv_scene_obj *s); + +// Find the closest polygon obj to a point +BV_EXPORT extern struct bv_scene_obj *bv_select_polygon(struct bu_ptbl *objs, point_t cp); + +BV_EXPORT extern int bv_move_polygon(struct bv_scene_obj *s, point_t cp, point_t pp); +BV_EXPORT extern struct bv_scene_obj *bv_dup_view_polygon(const char *nname, struct bv_scene_obj *s); + +// Copy a bv polygon. Note that this also performs a +// view sync - if the user is copying the polygon into +// another view, they will have to update the output's +// bview to match their target view. +BV_EXPORT extern void bv_polygon_cpy(struct bv_polygon *dest , struct bv_polygon *src); + +// Calculate a suggested default fill delta based on the polygon structure. The +// idea is to try and strike a balance between line count and having enough fill +// lines to highlight interior holes. +BV_EXPORT extern int bv_polygon_calc_fdelta(struct bv_polygon *p); + +BG_EXPORT extern struct bg_polygon * +bv_polygon_fill_segments(struct bg_polygon *poly, plane_t *vp, vect2d_t line_slope, fastf_t line_spacing); + +// For all polygon bv_scene_objs in the objs table, apply the specified boolean +// op using p and replace the original polygon geometry in objs with the +// results (NOTE: p will not act on itself if it is in objs): +// +// u : objs[i] u p (unions p with objs[i]) +// - : objs[i] - p (removes p from objs[i]) +// + : objs[i] + p (intersects p with objs[i]) +// +// At a data structure level, what happens is the bv_polygon geometry stored in +// the bv_polygon stored as the data entry for a bv_scene_obj is replaced. The +// bv_scene_obj and bv_polygon pointers should remain valid, but the bv_polygon +// contained in bv_polygon is replaced - calling code should not rely on the +// bv_polygon pointer remaining the same after a boolean operation. +BV_EXPORT extern int bv_polygon_csg(struct bv_scene_obj *target, struct bv_scene_obj *stencil, bg_clip_t op); + +__END_DECLS + +#endif /* BV_POLYGON_H */ +/** @} */ +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/bv/snap.h b/include/bv/snap.h new file mode 100644 index 00000000000..6597d84a246 --- /dev/null +++ b/include/bv/snap.h @@ -0,0 +1,63 @@ +/* S N A P . H + * BRL-CAD + * + * Copyright (c) 1993-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup bv_snap + * + */ +/** @{ */ +/** @file bv/snap.h */ + +#ifndef BV_SNAP_H +#define BV_SNAP_H + +#include "common.h" +#include "vmath.h" +#include "bv/defines.h" + +__BEGIN_DECLS + +/* Logic for snapping points to their closes view lines. */ + +/* Snap sample 2D point to lines active in the view. If populated, + * v->gv_s->gv_snap_objs contains a subset of bv_scene_obj pointers indicating + * which view objects to consider for snapping. If nonzero, + * v->gv_s->gv_snap_flags also tells the routine which categories of objects to + * consider - objs objects will also be evaluated against the flags before + * being used. */ +BV_EXPORT extern int bv_snap_lines_2d(struct bview *v, fastf_t *fx, fastf_t *fy); + +BV_EXPORT extern void bv_view_center_linesnap(struct bview *v); + +BV_EXPORT extern int bv_snap_lines_3d(point_t *out_pt, struct bview *v, point_t *p); +BV_EXPORT extern int bv_snap_grid_2d(struct bview *v, fastf_t *fx, fastf_t *fy); + +__END_DECLS + +#endif /* BV_SNAP_H */ + +/** @} */ +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/bv/tcl_data.h b/include/bv/tcl_data.h index 10ae5ef95c6..11be8dd2e72 100644 --- a/include/bv/tcl_data.h +++ b/include/bv/tcl_data.h @@ -120,20 +120,41 @@ typedef struct { } bv_data_polygon_state; +/* A note about the vZ parameter... + * + * gv_data_vZ is an internal parameter used by commands creating and + * manipulating data objects. Geometrically, it is a magnitude in the + * direction of the Z vector of the view plane. Functionally, what it + * allows the code to do is define a 2D plane embedded in in 3D space that + * is offset from but parallel to the view plane - in an orthogonal view + * this corresponds to objects drawn in that plane being "above" or "below" + * objects defined within the view plane itself. + * + * Visually, objects drawn in this fashion in orthogonal views will be + * indistinguishable regardless of their vZ offset - it is only when the + * view is rotated that the user will be able to see the "above" and + * "below" effect of creating view objects with differing vZ values. + * + * Users will generally not want to set gv_data_vZ directly, as it is a view + * space value and may not behave intuitively. Commands are defined to + * calculate vZ values based on model spaces inputs, and these should be + * used to generate the value supplied to gv_data_vZ. + */ struct bv_data_tclcad { - int gv_polygon_mode; // libtclcad polygon modes - int gv_hide; // libtclcad setting for hiding view - unused? - struct bv_data_arrow_state gv_data_arrows; - struct bv_data_axes_state gv_data_axes; - struct bv_data_label_state gv_data_labels; - struct bv_data_line_state gv_data_lines; - bv_data_polygon_state gv_data_polygons; - struct bv_data_arrow_state gv_sdata_arrows; - struct bv_data_axes_state gv_sdata_axes; - struct bv_data_label_state gv_sdata_labels; - struct bv_data_line_state gv_sdata_lines; - bv_data_polygon_state gv_sdata_polygons; - struct bv_other_state gv_prim_labels; + int gv_polygon_mode; // libtclcad polygon modes + int gv_hide; // libtclcad setting for hiding view - unused? + fastf_t gv_data_vZ; + struct bv_data_arrow_state gv_data_arrows; + struct bv_data_axes_state gv_data_axes; + struct bv_data_label_state gv_data_labels; + struct bv_data_line_state gv_data_lines; + bv_data_polygon_state gv_data_polygons; + struct bv_data_arrow_state gv_sdata_arrows; + struct bv_data_axes_state gv_sdata_axes; + struct bv_data_label_state gv_sdata_labels; + struct bv_data_line_state gv_sdata_lines; + bv_data_polygon_state gv_sdata_polygons; + struct bv_other_state gv_prim_labels; }; #endif /* DM_BV_TCL_DATA_H */ diff --git a/include/bv/util.h b/include/bv/util.h index 72c1e809e27..85178e7aede 100644 --- a/include/bv/util.h +++ b/include/bv/util.h @@ -56,8 +56,10 @@ BV_EXPORT extern void bv_autoview(struct bview *v, fastf_t scale, int all_view_o /* Copy the size and camera info (deliberately not a full copy of all view state) */ BV_EXPORT extern void bv_sync(struct bview *dest, struct bview *src); -/* Copy settings (potentially) common to the view and scene objects */ -BV_EXPORT extern void bv_obj_settings_sync(struct bv_obj_settings *dest, struct bv_obj_settings *src); +/* Copy settings (potentially) common to the view and scene objects. + * Return 0 if no changes were made to dest. If dest did have one + * or more settings updated from src, return 1. */ +BV_EXPORT extern int bv_obj_settings_sync(struct bv_obj_settings *dest, struct bv_obj_settings *src); /* Sync values within the bv, perform callbacks if any are defined */ BV_EXPORT extern void bv_update(struct bview *gvp); @@ -109,6 +111,16 @@ BV_EXPORT extern int bv_adjust(struct bview *v, int dx, int dy, point_t keypoint * calculation is impossible), else 0. */ BV_EXPORT extern int bv_screen_to_view(struct bview *v, fastf_t *fx, fastf_t *fy, fastf_t x, fastf_t y); +/* Return -1 if width and/or height are unset (and hence a meaningful + * calculation is impossible), else 0. + * + * x and y will normally be integers, but the types are float to allow for + * the possibility of sub-pixel coordinate specifications. + */ +BV_EXPORT extern int bv_screen_pt(point_t *p, fastf_t x, fastf_t y, struct bview *v); + + + /* Compute the min, max, and center points of the scene object. * Return 1 if a bound was computed, else 0 */ BV_EXPORT extern int bv_scene_obj_bound(struct bv_scene_obj *s, struct bview *v); @@ -173,6 +185,14 @@ bv_find_child(struct bv_scene_obj *s, const char *vname); BV_EXPORT struct bv_scene_obj * bv_find_obj(struct bview *v, const char *vname); +/* Given a seed name, generate a name that does not collide with any existing + * object names in the top level. If the seed name does not collide, it is + * returned as the result - otherwise, a name based on the seed name will be + * generated. + */ +BV_EXPORT void +bv_uniq_obj_name(struct bu_vls *oname, const char *seed, struct bview *v); + /* For the specified object/view pairing, return the appropriate scene object * to use with that view. Usually this will return s, but if a Level of Detail * scheme or some other view-aware rendering of the object is active, that object @@ -180,10 +200,23 @@ bv_find_obj(struct bview *v, const char *vname); BV_EXPORT struct bv_scene_obj * bv_obj_for_view(struct bv_scene_obj *s, struct bview *v); -/* Stash a view-specific object vobj for view v on object s. If vobj is NULL, - * this will clear the object for that particular view. */ -BV_EXPORT void -bv_set_view_obj(struct bv_scene_obj *s, struct bview *v, struct bv_scene_obj *vobj); +/* Get a view-specific object vobj for view v on object s. */ +BV_EXPORT struct bv_scene_obj * +bv_obj_get_vo(struct bv_scene_obj *s, struct bview *v); + +/* Check for the presence of view-specific objects */ +BV_EXPORT int +bv_obj_have_vo(struct bv_scene_obj *s, struct bview *v); + +/* Clear view-specific objects */ +BV_EXPORT int +bv_clear_view_obj(struct bv_scene_obj *s, struct bview *v); + +/* Set the illumination state on the object and its children to ill_state. + * Returns 0 if no states were changed, and 1 if one or more states were + * updated. */ +BV_EXPORT int +bv_illum_obj(struct bv_scene_obj *s, char ill_state); /* For the given view, return a pointer to the bu_ptbl holding active scene * objects with the specified type. Note that view-specific db objects are not @@ -192,6 +225,24 @@ bv_set_view_obj(struct bv_scene_obj *s, struct bview *v, struct bv_scene_obj *vo BV_EXPORT struct bu_ptbl * bv_view_objs(struct bview *v, int type); +/* Given a view, construct the view plane */ +BV_EXPORT int +bv_view_plane(plane_t *p, struct bview *v); + + +/* Environment variable controlled logging. + * + * Set BV_LOG to numerical levels to get increasingly + * verbose reporting of drawing info */ +#define BV_ENABLE_ENV_LOGGING 1 +BV_EXPORT void +bv_log(int level, const char *fmt, ...) _BU_ATTR_PRINTF23; + + +/* Debugging function for printing contents of views */ +BV_EXPORT void +bv_view_print(const char *title, struct bview *v, int verbosity); + __END_DECLS /** @} */ diff --git a/include/bv/view_sets.h b/include/bv/view_sets.h index d893693d913..dead195f293 100644 --- a/include/bv/view_sets.h +++ b/include/bv/view_sets.h @@ -52,7 +52,8 @@ BV_EXPORT void bv_set_add_view(struct bview_set *s, struct bview *v); /** - * Remove view v from set s + * Remove view v from set s. If v == NULL, all views + * are removed from the set. */ BV_EXPORT void bv_set_rm_view(struct bview_set *s, struct bview *v); diff --git a/include/conf/MINOR b/include/conf/MINOR index 7facc89938b..e522732c77e 100644 --- a/include/conf/MINOR +++ b/include/conf/MINOR @@ -1 +1 @@ -36 +38 diff --git a/include/dm/view.h b/include/dm/view.h index b98798ab6c0..ac62ae2353e 100644 --- a/include/dm/view.h +++ b/include/dm/view.h @@ -56,7 +56,7 @@ struct dm_view_data { int refresh_on; }; -DM_EXPORT extern void dm_draw_faceplate(struct bview *v, double base2local, double local2base); +DM_EXPORT extern void dm_draw_faceplate(struct bview *v); /* As a temporary measure, require client codes to specifically ask to enable * the bits that require librt in the headers if they're not going to be @@ -69,10 +69,10 @@ DM_EXPORT extern void dm_draw_faceplate(struct bview *v, double base2local, doub * sort on a bv scene object... */ #include "rt/wdb.h" -DM_EXPORT extern void dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *d, double base2local, double local2base); +DM_EXPORT extern void dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *d); /* Stripped down form of dm_draw_viewobjs that does just what's needed for the new setup */ -DM_EXPORT extern void dm_draw_objs(struct bview *v, double base2local, double local2base, void (*dm_draw_custom)(struct bview *, double, double, void *), void *u_data); +DM_EXPORT extern void dm_draw_objs(struct bview *v, void (*dm_draw_custom)(struct bview *, void *), void *u_data); #endif /* DM_NO_RT */ __END_DECLS diff --git a/include/ged/CMakeLists.txt b/include/ged/CMakeLists.txt index 2f431ca5651..0648e3763f3 100644 --- a/include/ged/CMakeLists.txt +++ b/include/ged/CMakeLists.txt @@ -4,6 +4,7 @@ set(ged_headers analyze.h commands.h database.h + dbi.h debug.h defines.h framebuffer.h diff --git a/include/ged/commands.h b/include/ged/commands.h index d391d25a4c9..19bc09d31e5 100644 --- a/include/ged/commands.h +++ b/include/ged/commands.h @@ -901,6 +901,8 @@ DEPRECATED GED_EXPORT extern int ged_get_obj_bounds(struct ged *gedp, point_t rpp_min, point_t rpp_max); +GED_EXPORT void draw_scene(struct bv_scene_obj *s, struct bview *v); + /** @} */ diff --git a/include/ged/dbi.h b/include/ged/dbi.h new file mode 100644 index 00000000000..cdb861591db --- /dev/null +++ b/include/ged/dbi.h @@ -0,0 +1,449 @@ +/* D B I . H + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup ged_defines + * + * Experimental + * + * Geometry EDiting Library structures for reflecting the state of + * the database and views. + * + * These are used to provide a fast, explicit expression in memory of the + * database and view states, to allow applications to quickly display + * hierarchical information and manipulate view data. + * + * We want this to be visible to C++ APIs like libqtcad, so they can reflect + * the state of the .g hierarchy in their own structures without us or them + * having to make copies of the data. Pattern this on how we handle ON_Brep + */ +/** @{ */ +/** @file ged/defines.h */ + +#ifndef GED_DBI_H +#define GED_DBI_H + +#include "common.h" +#include "bu/vls.h" + +#ifdef __cplusplus +#include +#include +#include +#include +#include + +class GED_EXPORT DbiState; + +class GED_EXPORT BSelectState { + public: + BSelectState(DbiState *); + + bool select_path(const char *path, bool update); + bool select_hpath(std::vector &hpath); + + bool deselect_path(const char *path, bool update); + bool deselect_hpath(std::vector &hpath); + + void clear(); + + bool is_selected(unsigned long long); + bool is_active(unsigned long long); + bool is_active_parent(unsigned long long); + bool is_parent_obj(unsigned long long); + bool is_immediate_parent_obj(unsigned long long); + bool is_grand_parent_obj(unsigned long long); + + std::vector list_selected_paths(); + + void expand(); + void collapse(); + + void refresh(); + bool draw_sync(); + + unsigned long long state_hash(); + + std::unordered_map> selected; + std::unordered_set active_paths; // Solid paths to illuminate + std::unordered_set active_parents; // Paths above selection + // To support highlighting closed paths that have selected primitives + // below them, we need more information. This is different than + // highlighting only the paths related to the specific selected full + // path - in this situation, the application wants to know about all + // paths that are above the leaf *object* that is selected, in whatever + // portion of the database. Immediate parents are combs whose + // immediate child is the selected leaf; grand parents are higher level + // combs above immediate parents + std::unordered_set immediate_parents; + std::unordered_set grand_parents; + + void characterize(); + + private: + DbiState *dbis; + + void add_paths( + unsigned long long c_hash, + std::vector &path_hashes + ); + + void clear_paths( + unsigned long long c_hash, + std::vector &path_hashes + ); + + void expand_paths( + std::vector> &out_paths, + unsigned long long c_hash, + std::vector &path_hashes + ); + + void collapse_paths( + std::vector> &out_paths + ); + + void clear_paths(std::vector &path_hashes, unsigned long long c_hash); +}; + + +class GED_EXPORT BViewState { + public: + BViewState(DbiState *); + + + // Adds path to the BViewState container, but doesn't trigger a re-draw - that + // should be done once all paths to be added in a given draw cycle are added. + // The actual drawing (and mode specifications) are done with redraw and a + // supplied bv_obj_settings structure. + void add_path(const char *path); + void add_hpath(std::vector &path_hashes); + + // Erases paths from the view for the given mode. If mode < 0, all + // matching paths are erased. For modes that are un-evaluated, all + // paths that are subsets of the specified path are removed. For + // evaluated modes like 3 (bigE) that generate an evaluated visual + // specific to that path, only precise path matches are removed + void erase_path(int mode, int argc, const char **argv); + void erase_hpath(int mode, unsigned long long c_hash, std::vector &path_hashes, bool cache_collapse = true); + + // Return a sorted vector of strings encoding the drawn paths in the + // view. If mode == -1 list all paths, otherwise list those specific + // to the mode. If list_collapsed is true, return the minimal path set + // that captures what is drawn - otherwise, return the direct list of + // scene objects + std::vector list_drawn_paths(int mode, bool list_collapsed); + + // Get a count of the drawn paths + size_t count_drawn_paths(int mode, bool list_collapsed); + + // Report if a path hash is drawn - 0 == not drawn, 1 == fully drawn, 2 == partially drawn + int is_hdrawn(int mode, unsigned long long phash); + + // Clear all drawn objects (TODO - should allow mode specification here) + void clear(); + + // A View State refresh regenerates already drawn objects. + unsigned long long refresh(struct bview *v, int argc, const char **argv); + + // A View State redraw can impact multiple views with a shared state - most of + // the elements will be the same, but adaptive plotting will be view specific even + // with otherwise common objects - we must update accordingly. + unsigned long long redraw(struct bv_obj_settings *vs, std::unordered_set &views, int no_autoview); + + // Allow callers to calculate the drawing hash of a path + unsigned long long path_hash(std::vector &path, size_t max_len); + + // Debugging methods for printing out current states - the use of hashes + // means direct inspection of most data isn't informative, so we provide + // convenience methods that decode it to user-comprehensible info. + void print_view_state(struct bu_vls *o = NULL); + + private: + // Sets defining all drawn solid paths (including invalid paths). The + // s_keys holds the ordered individual keys of each drawn solid path - it + // is the latter that allows for the collapse operation to populate + // drawn_paths. s_map uses the same key as s_keys to map instances to + // actual scene objects. Because objects may be represented by more than + // one type of scene object (shaded, wireframe, evaluated, etc.) the mapping of + // key to scene object is not unique - we must also take scene object type + // into account. + std::unordered_map> s_map; + std::unordered_map> s_keys; + + // Called when the parent Db context is getting ready to update the data + // structures - we may need to redraw, so we save any necessary information + // ahead of the changes. Although this is a public function of the BViewState, + // it is practically speaking an implementation detail + void cache_collapsed(); + + DbiState *dbis; + + int check_status( + std::unordered_set *invalid_objects, + std::unordered_set *changed_paths, + unsigned long long path_hash, + std::vector &cpath, + bool leaf_expand + ); + + void walk_tree( + std::unordered_set &objs, + unsigned long long chash, + int curr_mode, + struct bview *v, + struct bv_obj_settings *vs, + matp_t m, + std::vector &path_hashes, + std::unordered_set &views, + unsigned long long *ret + ); + + void gather_paths( + std::unordered_set &objs, + unsigned long long c_hash, + int curr_mode, + struct bview *v, + struct bv_obj_settings *vs, + matp_t m, + matp_t lm, + std::vector &path_hashes, + std::unordered_set &views, + unsigned long long *ret + ); + + struct bv_scene_obj * scene_obj( + std::unordered_set &objs, + int curr_mode, + struct bv_obj_settings *vs, + matp_t m, + std::vector &path_hashes, + std::unordered_set &views, + struct bview *v + ); + + int leaf_check(unsigned long long chash, std::vector &path_hashes); + + // Paths supplied by commands to be incorporated into the drawn state by redraw method + std::vector> staged; + + // The collapsed drawn paths from the previous db state, organized + // by drawn mode + void depth_group_collapse( + std::vector> &collapsed, + std::unordered_set &d_paths, + std::unordered_set &p_d_paths, + std::map> &depth_groups + ); + std::unordered_map>> mode_collapsed; + std::vector> all_collapsed; + + // Set of hashes of all drawn paths and subpaths, constructed during the collapse + // operation from the set of drawn solid paths. This allows calling codes to + // spot check any path to see if it is active, without having to interrogate + // other data structures or walk down the tree. + std::unordered_map> drawn_paths; + std::unordered_set all_drawn_paths; + + // Set of partially drawn paths, constructed during the collapse operation. + // This holds the paths that should return 2 for is_hdrawn + std::unordered_map> partially_drawn_paths; + std::unordered_set all_partially_drawn_paths; + + friend class BSelectState; +}; + +#define GED_DBISTATE_DB_CHANGE 0x01 +#define GED_DBISTATE_VIEW_CHANGE 0x02 + +struct ged_draw_cache; + +class GED_EXPORT DbiState { + public: + DbiState(struct ged *); + ~DbiState(); + + unsigned long long update(); + + std::vector tops(bool show_cyclic); + + bool path_color(struct bu_color *c, std::vector &elements); + + bool path_is_subtraction(std::vector &elements); + db_op_t bool_op(unsigned long long, unsigned long long); + + bool get_matrix(matp_t m, unsigned long long p_key, unsigned long long i_key); + bool get_path_matrix(matp_t m, std::vector &elements); + + bool get_bbox(point_t *bbmin, point_t *bbmax, matp_t curr_mat, unsigned long long hash); + bool get_path_bbox(point_t *bbmin, point_t *bbmax, std::vector &elements); + + bool valid_hash(unsigned long long phash); + bool valid_hash_path(std::vector &phashes); + bool print_hash(struct bu_vls *opath, unsigned long long phash); + void print_path(struct bu_vls *opath, std::vector &path, size_t pmax = 0, int verbsose = 0); + + const char *pathstr(std::vector &path, size_t pmax = 0); + const char *hashstr(unsigned long long); + + std::vector digest_path(const char *path); + + unsigned long long path_hash(std::vector &path, size_t max_len); + + void clear_cache(struct directory *dp); + + BViewState *get_view_state(struct bview *); + + std::vector get_selected_states(const char *sname); + BSelectState * find_selected_state(const char *sname); + + void put_selected_state(const char *sname); + std::vector list_selection_sets(); + + // These maps are the ".g ground truth" of the comb structures - the set + // associated with each hash contains all the child hashes from the comb + // definition in the database for quick lookup, and the vector preserves + // the comb ordering for listing. + std::unordered_map> p_c; + // Note: to match MGED's 'l' printing you need to use a reverse_iterator + std::unordered_map> p_v; + + // Translate individual object hashes to their directory names. This map must + // be updated any time a database object changes to remain valid. + struct directory *get_hdp(unsigned long long); + std::unordered_map d_map; + + // For invalid comb entry strings, we can't point to a directory pointer. This + // map must also be updated after every db change - if a directory pointer hash + // maps to an entry in this map it needs to be removed, and newly invalid entries + // need to be added. + std::unordered_map invalid_entry_map; + + // This is a map of non-uniquely named child instances (i.e. instances that must be + // numbered) to the .g database name associated with those instances. Allows for + // one unique entry in p_c rather than requiring per-instance duplication + std::unordered_map i_map; + std::unordered_map i_str; + + // Matrices above comb instances are critical to geometry placement. For non-identity + // matrices, we store them locally so they may be accessed without having to unpack + // the comb from disk. + std::unordered_map>> matrices; + + // Similar to matrices, store non-union bool ops for instances + std::unordered_map> i_bool; + + + // Bounding boxes for each solid. To calculate the bbox for a comb, the + // children are walked combining the bboxes. The idea is to be able to + // retrieve solid bboxes and calculate comb bboxes without having to touch + // the disk beyond the initial per-solid calculations, which may be done + // once per load and/or dimensional change. + std::unordered_map> bboxes; + + + // We also have a number of standard attributes that can impact drawing, + // which are normally only accessible by loading in the attributes of + // the object. We stash them in maps to have the information available + // without having to interrogate the disk + std::unordered_map c_inherit; // color inheritance flag + std::unordered_map rgb; // color RGB value (r + (g << 8) + (b << 16)) + std::unordered_map region_id; // region_id + + + // Data to be used by callbacks + std::unordered_set added; + std::unordered_set changed; + std::unordered_set changed_hashes; + std::unordered_set removed; + std::unordered_map old_names; + + // The shared view is common to multiple views, so we always update it. + // For other associated views (if any), we track their drawn states + // separately, but they too need to update in response to database + // changes (as well as draw/erase commands). + BViewState *shared_vs = NULL; + std::unordered_map view_states; + + // We have a "default" selection state that is always available, + // and applications may define other named selection states. + BSelectState *default_selected; + std::unordered_map selected_sets; + + // Database Instance associated with this container + struct ged *gedp = NULL; + struct db_i *dbip = NULL; + + bool need_update_nref = true; + + // Debugging methods for printing out current states - the use of hashes + // means direct inspection of most data isn't informative, so we provide + // convenience methods that decode it to user-comprehensible info. + void print_dbi_state(struct bu_vls *o = NULL, bool report_view_states = false); + + private: + void gather_cyclic( + std::unordered_set &cyclic, + unsigned long long c_hash, + std::vector &path_hashes + ); + void print_leaves( + std::set &leaves, + unsigned long long c_hash, + std::vector &path_hashes + ); + + void populate_maps(struct directory *dp, unsigned long long phash, int reset); + unsigned long long update_dp(struct directory *dp, int reset); + unsigned int color_int(struct bu_color *); + int int_color(struct bu_color *c, unsigned int); + struct resource *res = NULL; + struct ged_draw_cache *dcache = NULL; + struct bu_vls hash_string = BU_VLS_INIT_ZERO; + struct bu_vls path_string = BU_VLS_INIT_ZERO; +}; + + +#else + +/* Placeholders to allow for compilation when we're included in a C file */ +typedef struct _dbi_state { + int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */ +} DbiState; +typedef struct _bview_state { + int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */ +} BViewState; +typedef struct _bselect_state { + int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */ +} BSelectState; + +#endif + +#endif /* GED_DBI_H */ + +/** @} */ + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/ged/defines.h b/include/ged/defines.h index c45c1962b6b..06295034172 100644 --- a/include/ged/defines.h +++ b/include/ged/defines.h @@ -36,10 +36,10 @@ #include "bv/defines.h" #include "rt/search.h" #include "bv/defines.h" +#include "bv/lod.h" #include "dm/fbserv.h" // for fbserv_obj #include "rt/wdb.h" // for struct rt_wdb -__BEGIN_DECLS #ifndef GED_EXPORT # if defined(GED_DLL_EXPORTS) && defined(GED_DLL_IMPORTS) @@ -184,8 +184,14 @@ struct ged_drawable { int gd_shaded_mode; /**< @brief 1 - draw bots shaded by default */ }; +/* Experimental work on a high-performance in-memory representation of + * database, view and selection states. We want this to be visible to C++ APIs + * like libqtcad, so they can reflect the state of the .g hierarchy in their + * own structures without us or them having to make copies of the data. + */ +#include "ged/dbi.h" - +__BEGIN_DECLS struct ged_cmd; @@ -195,6 +201,7 @@ struct ged_results; struct ged { struct bu_vls go_name; struct db_i *dbip; + DbiState *dbi_state; /*************************************************************/ /* Information pertaining to views and view objects . */ @@ -203,8 +210,15 @@ struct ged { struct bview *ged_gvp; /* The full set of views associated with this ged object */ struct bview_set ged_views; + /* Sometimes applications will supply GED views, and sometimes GED commands + * may create views. In the latter case, ged_close will also need to free + * the views. We define a container to hold those views that libged is + * managing, since ged_views views may belong to the application rather + * than GED. */ + struct bu_ptbl ged_free_views; + /* Drawing data associated with this .g file */ - struct bg_mesh_lod_context *ged_lod; + struct bv_mesh_lod_context *ged_lod; void *u_data; /**< @brief User data associated with this ged instance */ @@ -231,10 +245,8 @@ struct ged { char *ged_output_script; /**< @brief script for use by the outputHandler */ - /* Selection data */ - struct ged_selection_sets *ged_selection_sets; - struct ged_selection_set *ged_cset; - + /* Old selection data containers used by joint and brep*/ + struct bu_hash_tbl *ged_selections; /**< @brief object name -> struct rt_object_selections */ /* FIXME -- this ugly hack needs to die. the result string should * be stored before the call. @@ -267,6 +279,15 @@ struct ged { void (*ged_create_vlist_display_list_callback)(struct display_list *); /**< @brief function to call after all vlist created that loops through creating display list for each solid */ void (*ged_destroy_vlist_callback)(unsigned int, int); /**< @brief function to call after freeing a vlist */ + /* Functions related to database open/close - if the parent application + * needs to take any action upon database opening or closing, it should + * register these callbacks so GED's opendb/closedb commands trigger + * the correct logic. */ + void (*ged_pre_opendb_callback)(struct ged *, void *); + void (*ged_post_opendb_callback)(struct ged *, void *); + void (*ged_pre_closedb_callback)(struct ged *, void *); + void (*ged_post_closedb_callback)(struct ged *, void *); + void *ged_db_callback_udata; /* Functions assigned to ged_subprocess init_clbk and end_clbk * slots when the ged_subprocess is created. TODO - eventually diff --git a/include/ged/view/select.h b/include/ged/view/select.h index 74a4f257bd7..0616eca2281 100644 --- a/include/ged/view/select.h +++ b/include/ged/view/select.h @@ -29,73 +29,10 @@ #define GED_VIEW_SELECT_H #include "common.h" -#include "bv/defines.h" #include "ged/defines.h" __BEGIN_DECLS -struct ged_selection { - struct ged *gedp; - struct bu_vls path; - struct bu_ptbl sobjs; // struct bv_scene_obj pointers - struct rt_object_selections *r_os; -}; - -struct ged_selection_set_impl; -struct ged_selection_set { - struct ged *gedp; - struct bu_vls name; - struct ged_selection_set_impl *i; -}; - -struct ged_selection_sets_impl; -struct ged_selection_sets { - struct ged *gedp; - struct ged_selection_sets_impl *i; -}; - -// Routines to manage a set of selection sets -GED_EXPORT extern struct ged_selection_sets *ged_selection_sets_create(struct ged *gedp); -GED_EXPORT extern void ged_selection_sets_destroy(struct ged_selection_sets *s); - -// Routines for creating and destroying temporary sets (normally should be created within -// the context of a selection set - these are for temporary processing sets) -GED_EXPORT struct ged_selection_set *ged_selection_set_create(const char *s_name, struct ged *gedp); -GED_EXPORT void ged_selection_set_destroy(struct ged_selection_set *); - -// Routines to retrieve and remove individual selection sets -GED_EXPORT struct ged_selection_set *ged_selection_sets_get(struct ged_selection_sets *s, const char *s_path); -GED_EXPORT void ged_selection_sets_put(struct ged_selection_sets *s, const char *s_path); -GED_EXPORT int ged_selection_set_cpy(struct ged_selection_set *to, struct ged_selection_set *from); -GED_EXPORT size_t ged_selection_sets_lookup(struct bu_ptbl *sets, struct ged_selection_sets *s, const char *pattern); - -// Retrieve data. -GED_EXPORT int ged_selection_find(struct ged_selection_set *s, const char *s_name); -GED_EXPORT size_t ged_selection_lookup(struct bu_ptbl *matches, struct ged_selection_set *s, const char *s_path); -GED_EXPORT size_t ged_selection_lookup_fp(struct bu_ptbl *matches, struct ged_selection_set *s, struct db_full_path *fp); -GED_EXPORT int ged_selection_set_list(char ***keys, struct ged_selection_set *s); -GED_EXPORT void ged_selection_set_clear(struct ged_selection_set *s); - -// Manipulate data -GED_EXPORT struct ged_selection *ged_selection_insert(struct ged_selection_set *s, const char *s_path); -GED_EXPORT struct ged_selection *ged_selection_insert_fp(struct ged_selection_set *s, struct db_full_path *fp); -GED_EXPORT struct ged_selection *ged_selection_insert_obj(struct ged_selection_set *s, struct bv_scene_obj *o); -GED_EXPORT void ged_selection_remove(struct ged_selection_set *s, const char *s_path); -GED_EXPORT void ged_selection_remove_fp(struct ged_selection_set *s, struct db_full_path *fp); -GED_EXPORT void ged_selection_remove_obj(struct ged_selection_set *s, struct bv_scene_obj *o); -GED_EXPORT int ged_selection_set_expand(struct ged_selection_set *s_out, struct ged_selection_set *s); -GED_EXPORT int ged_selection_set_collapse(struct ged_selection_set *s_out, struct ged_selection_set *s); - -// Given a set, associate the DBOBJ scene objects with any matching selection objects. -GED_EXPORT void ged_selection_assign_objs(struct ged_selection_set *s); -GED_EXPORT void ged_selection_toggle_illum(struct ged_selection_set *s, char ill_state); - -// Given a set, return the hash of its contents -GED_EXPORT unsigned long long ged_selection_hash_set(struct ged_selection_set *s); - -// Given a set of sets, return the hash of all the set names and their contents -GED_EXPORT unsigned long long ged_selection_hash_sets(struct ged_selection_sets *ss); - /** * Returns a list of items within the previously defined rectangle. @@ -112,17 +49,15 @@ GED_EXPORT extern int ged_select(struct ged *gedp, int argc, const char *argv[]) * exist. */ GED_EXPORT struct rt_object_selections *ged_get_object_selections(struct ged *gedp, - const char *object_name); + const char *object_name); /** * Return ged selections of specified kind for specified object. * Created if it doesn't exist. */ GED_EXPORT struct rt_selection_set *ged_get_selection_set(struct ged *gedp, - const char *object_name, - const char *selection_name); - - + const char *object_name, + const char *selection_name); __END_DECLS diff --git a/include/ged/view/state.h b/include/ged/view/state.h index 093d9aa6bb9..53d8884e077 100644 --- a/include/ged/view/state.h +++ b/include/ged/view/state.h @@ -141,7 +141,7 @@ struct draw_update_data_t { struct db_full_path *fp; const struct bn_tol *tol; const struct bg_tess_tol *ttol; - struct bg_mesh_lod_context *mesh_c; + struct bv_mesh_lod_context *mesh_c; struct resource *res; }; diff --git a/include/icv/ops.h b/include/icv/ops.h index c54eceb859a..ba287746115 100644 --- a/include/icv/ops.h +++ b/include/icv/ops.h @@ -28,6 +28,8 @@ #include "common.h" #include /* for size_t */ +#include "vmath.h" +#include "bu/vls.h" #include "icv/defines.h" __BEGIN_DECLS @@ -190,6 +192,32 @@ ICV_EXPORT int icv_resize(icv_image_t *bif, ICV_RESIZE_METHOD method, size_t out */ ICV_EXPORT extern int icv_rot(size_t argc, const char *argv[]); +/** + * Compare two images and report pixel differences. Return code is 1 if there + * are any differences, else 0. For more detailed reporting, pass non-null + * integer pointers to the matching, off_by_1, and/or off_by_many parameters. + */ +ICV_EXPORT extern int icv_diff(int *matching, int *off_by_1, int *off_by_many, icv_image_t *img1, icv_image_t *img2); + +/** + * Generate a visual representation of the differences between two images. + * (At least for now, images must be the same size.) + * + * Returns NULL if there is an error. + */ +ICV_EXPORT extern icv_image_t *icv_diffimg(icv_image_t *img1, icv_image_t *img2); + +/** + * Compare two images using perceptual image hashing and report the Hamming + * distance between them. Useful for approximate image comparisons. + */ +ICV_EXPORT extern uint32_t icv_pdiff(icv_image_t *img1, icv_image_t *img2); + +/** + * Fit an image to suggested dimensions. + */ +ICV_EXPORT extern int icv_fit(icv_image_t *img, struct bu_vls *msg, size_t o_width_req, size_t o_height_req, fastf_t sf); + /** @} */ __END_DECLS diff --git a/include/libtermio.h b/include/libtermio.h deleted file mode 100644 index a1144412515..00000000000 --- a/include/libtermio.h +++ /dev/null @@ -1,106 +0,0 @@ -/* L I B T E R M I O . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @addtogroup libtermio - * - * @brief - * Externs for the BRL-CAD library LIBTERMIO - * - */ -/** @{ */ -/** @file libtermio.h */ - -#ifndef LIBTERMIO_H -#define LIBTERMIO_H - -#include "common.h" - -#if defined(HAVE_TERMIOS_H) -# undef SYSV -# undef BSD -# include -#else /* !defined(HAVE_TERMIOS_H) */ -# ifdef SYSV -# undef BSD -# include -# include -# endif /* SYSV */ -# ifdef BSD -# undef SYSV -# include -# endif /* BSD */ -#endif /* HAVE_TERMIOS_H */ - -#ifndef TERMIO_EXPORT -# if defined(TERMIO_DLL_EXPORTS) && defined(TERMIO_DLL_IMPORTS) -# error "Only TERMIO_DLL_EXPORTS or TERMIO_DLL_IMPORTS can be defined, not both." -# elif defined(TERMIO_DLL_EXPORTS) -# define TERMIO_EXPORT COMPILER_DLLEXPORT -# elif defined(TERMIO_DLL_IMPORTS) -# define TERMIO_EXPORT COMPILER_DLLIMPORT -# else -# define TERMIO_EXPORT -# endif -#endif - -__BEGIN_DECLS - -void clr_Cbreak(int fd); -TERMIO_EXPORT void set_Cbreak(int fd); -void clr_Raw(int fd); -TERMIO_EXPORT void set_Raw(int fd); -void set_Echo(int fd); -TERMIO_EXPORT void clr_Echo(int fd); -void set_Tabs(int fd); -void clr_Tabs(int fd); -void set_HUPCL(int fd); -void clr_CRNL(int fd); -unsigned short get_O_Speed(int fd); -TERMIO_EXPORT void save_Tty(int fd); -TERMIO_EXPORT void reset_Tty(int fd); -int save_Fil_Stat(int fd); -int reset_Fil_Stat(int fd); -int set_O_NDELAY(int fd); -void prnt_Tio( - char *msg, -#if defined(BSD) - struct sgttyb *tio_ptr -#elif defined(SYSV) - struct termio *tio_ptr -#elif defined(HAVE_TERMIOS_H) - struct termios *tio_ptr -#else - void *tio_ptr -#endif - ); - -__END_DECLS - -#endif /* LIBTERMIO_H */ - -/** @} */ -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/include/pkg.h b/include/pkg.h index 5530f584e0d..08435837ea0 100644 --- a/include/pkg.h +++ b/include/pkg.h @@ -85,8 +85,18 @@ struct pkg_header { #define PKG_STREAMLEN (32*1024) struct pkg_conn { int pkc_fd; /**< @brief TCP connection fd */ + + // TODO - these were added to support PKG_STDIO_MODE back in 5/2021 as an + // experiment to test whether we could use stdout/stderr piping on Windows + // to enable local pkg support without TCP/IP. That didn't work, so look at + // replacing/repurposing these to use with libuv, which supplies a cross + // platform uv_pipe_t. The places in the code checking for PKG_STDIO_MODE + // are a good start for where we will need logic to support a uv_pipe_t + // version, although the need for pipe names will most likely require + // further changes. int pkc_in_fd; /**< @brief input connection fd */ int pkc_out_fd; /**< @brief output connection fd */ + const struct pkg_switch *pkc_switch; /**< @brief Array of message handlers */ pkg_errlog pkc_errlog; /**< @brief Error message logger */ struct pkg_header pkc_hdr; /**< @brief hdr of cur msg */ diff --git a/include/qtcad/CMakeLists.txt b/include/qtcad/CMakeLists.txt index 28e5f7f4fcf..c4a6d24ae75 100644 --- a/include/qtcad/CMakeLists.txt +++ b/include/qtcad/CMakeLists.txt @@ -1,26 +1,30 @@ set(qtcad_headers - QAccordion.h - QColorRGB.h - QFlowLayout.h - QKeyVal.h - QToolPalette.h - QViewCtrl.h + QgAccordion.h + QgAppExecDialog.h + QgAttributesModel.h + QgColorRGB.h + QgConsole.h + QgConsoleListener.h QgDockWidget.h QgEdit.h + QgFlowLayout.h + QgGL.h + QgGeomImport.h + QgKeyVal.h + QgMeasureFilter.h QgModel.h + QgPolyFilter.h + QgQuadView.h + QgSW.h + QgSelectFilter.h + QgSignalFlags.h + QgToolPalette.h QgTreeSelectionModel.h QgTreeView.h QgUtil.h - QtAppExecDialog.h - QtCADQuad.h - QtCADView.h - QtConsole.h - QtConsoleListener.h - QtGL.h - QtSW.h - SignalFlags.h + QgView.h + QgViewCtrl.h defines.h - gInstance.h ) BRLCAD_MANAGE_FILES(qtcad_headers ${INCLUDE_DIR}/brlcad/qtcad) diff --git a/include/qtcad/QAccordion.h b/include/qtcad/QAccordion.h deleted file mode 100644 index 6a7330ec7ae..00000000000 --- a/include/qtcad/QAccordion.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Q A C C O R D I O N . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QAccordionWidget.h - * - * Show one of a stack of widgets - */ - -#ifndef QACCORDIANWIDGET_H -#define QACCORDIANWIDGET_H - -#include "common.h" - - -#include -#include -#include -#include -#include - -#include "qtcad/defines.h" - -class QTCAD_EXPORT QAccordionObject : public QWidget -{ - Q_OBJECT - - public: - QAccordionObject(QWidget *pparent = 0, QWidget *object = 0, QString header_title = QString("")); - ~QAccordionObject(); - QPushButton *toggle; - QScrollArea *objscrollarea; - - signals: - void select(QAccordionObject *); - - public slots: - void toggleVisibility(); - - private: - QVBoxLayout *objlayout; - QString title; -}; - -class QTCAD_EXPORT QAccordion : public QWidget -{ - Q_OBJECT - - public: - QAccordion(QWidget *pparent = 0); - ~QAccordion(); - void addObject(QAccordionObject *object); - - public slots: - void open(QAccordionObject *); - - private: - QSet objs; - QAccordionObject *selected = NULL; - QVBoxLayout *mlayout; -}; - -#endif /* QACCORDIANWIDGET_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/include/qtcad/QColorRGB.h b/include/qtcad/QColorRGB.h deleted file mode 100644 index 90bc9960df2..00000000000 --- a/include/qtcad/QColorRGB.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Q C O L O R R G B . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QColorRGB.h - * - * Set a color either via dialog or r/g/b text entry - */ - -#ifndef QCOLORRGB_H -#define QCOLORRGB_H - -#include "common.h" - -#include -#include -#include -#include -#include -#include - -#include "bu/color.h" -#include "bu/opt.h" -#include "qtcad/defines.h" - -class QTCAD_EXPORT QColorRGB: public QWidget -{ - Q_OBJECT - - public: - QColorRGB(QWidget *p = NULL, QString lstr = QString("Color:"), QColor dcolor = QColor(Qt::red)); - ~QColorRGB(); - - QLineEdit *rgbtext; - QPushButton *rgbcolor; - struct bu_color bc; - - signals: - void color_changed(); - - public slots: - void set_color_from_text(); - - private slots: - void set_color_from_button(); - - private: - QColorDialog *d; - QHBoxLayout *mlayout; - QColor qc; -}; - -#endif /* QACCORDIANWIDGET_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/include/qtcad/QFlowLayout.h b/include/qtcad/QFlowLayout.h deleted file mode 100644 index 6b555dc9dc7..00000000000 --- a/include/qtcad/QFlowLayout.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - ** Contact: http://www.qt-project.org/legal - ** - ** This file is part of the examples of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:BSD$ - ** You may use this file under the terms of the BSD license as follows: - ** - ** "Redistribution and use in source and binary forms, with or without - ** modification, are permitted provided that the following conditions are - ** met: - ** * Redistributions of source code must retain the above copyright - ** notice, this list of conditions and the following disclaimer. - ** * Redistributions in binary form must reproduce the above copyright - ** notice, this list of conditions and the following disclaimer in - ** the documentation and/or other materials provided with the - ** distribution. - ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names - ** of its contributors may be used to endorse or promote products derived - ** from this software without specific prior written permission. - ** - ** - ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#ifndef Q_FLOWLAYOUT_H -#define Q_FLOWLAYOUT_H - -#include "common.h" - -#include -#include -#include -#include "qtcad/defines.h" - -class QTCAD_EXPORT QFlowLayout : public QLayout -{ - public: - explicit QFlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); - explicit QFlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); - ~QFlowLayout(); - - void addItem(QLayoutItem *item); - int horizontalSpacing() const; - int verticalSpacing() const; - void setHorizontalSpacing(int); - void setVerticalSpacing(int); - Qt::Orientations expandingDirections() const; - bool hasHeightForWidth() const; - int heightForWidth(int) const; - int count() const; - QLayoutItem *itemAt(int index) const; - QSize minimumSize() const; - void setGeometry(const QRect &rect); - QSize sizeHint() const; - QLayoutItem *takeAt(int index); - - private: - int doLayout(const QRect &rect, bool testOnly) const; - int smartSpacing(QStyle::PixelMetric pm) const; - - QList itemList; - int m_hSpace; - int m_vSpace; -}; - -#endif // Q_FLOWLAYOUT_H - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/include/qtcad/QKeyVal.h b/include/qtcad/QKeyVal.h deleted file mode 100644 index 013f789e21d..00000000000 --- a/include/qtcad/QKeyVal.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Q K E Y V A L . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QKeyVal.h - * - */ - -#ifndef QKEYVAL_H -#define QKEYVAL_H - -#include "common.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "qtcad/defines.h" - -class QTCAD_EXPORT QKeyValNode - { - public: - QKeyValNode(QKeyValNode *aParent=0); - ~QKeyValNode(); - - QString name; - QString value; - int attr_type; - - QKeyValNode *parent; - QList children; -}; - -class QTCAD_EXPORT QKeyValModel : public QAbstractItemModel -{ - Q_OBJECT - - public: - QKeyValModel(QObject *p = NULL); - ~QKeyValModel(); - - QModelIndex index(int row, int column, const QModelIndex &parent) const; - QModelIndex parent(const QModelIndex &child) const; - int rowCount(const QModelIndex &child) const; - int columnCount(const QModelIndex &child) const; - - void setRootNode(QKeyValNode *root); - QKeyValNode* rootNode(); - - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); - - QKeyValNode *m_root; - QModelIndex NodeIndex(QKeyValNode *node) const; - QKeyValNode *IndexNode(const QModelIndex &index) const; - - QKeyValNode *add_pair(const char *name, const char *value, QKeyValNode *curr_node, int type); - - int NodeRow(QKeyValNode *node) const; -}; - -class QTCAD_EXPORT QKeyValDelegate : public QStyledItemDelegate -{ - Q_OBJECT - - public: - QKeyValDelegate(QWidget *pparent = 0) : QStyledItemDelegate(pparent) {} - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; -}; - -class QTCAD_EXPORT QKeyValView : public QTreeView -{ - Q_OBJECT - - public: - QKeyValView(QWidget *pparent, int decorate_tree = 0); - ~QKeyValView() {}; -}; - - -#endif /* QKEYVAL_H */ - - diff --git a/include/qtcad/QToolPalette.h b/include/qtcad/QToolPalette.h deleted file mode 100644 index dd425132602..00000000000 --- a/include/qtcad/QToolPalette.h +++ /dev/null @@ -1,219 +0,0 @@ -/* Q T O O L P A L E T T E . H - * BRL-CAD - * - * Copyright (c) 2020-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QToolPalette.h - * - * Signals/slots in Palettes and Elements - * - * In order to keep the scope of the various plugins local, we define - * a tiered system of signals and slots which are connected to by - * various aspects of this system: - * - * The QToolPalette widget is what is directly added to application - * widget hierarchies, and it is that widget's signals and slots which - * are connected to the top level view updating signal/slot system as - * articulated in SignalFlags.h. Individual elements (i.e.tools) are - * connected to QToolPalette, and the implementation specific "guts" - * of the various tools connect to their parent element. - * - */ - -#ifndef QTOOLPALETTE_H -#define QTOOLPALETTE_H - -#include "common.h" - -#include -#include -#include -#include -#include -#include -#include -#include "qtcad/defines.h" -#include "qtcad/QFlowLayout.h" -#include "qtcad/SignalFlags.h" - -class QTCAD_EXPORT QToolPaletteElement; - -class QTCAD_EXPORT QToolPaletteButton: public QPushButton -{ - Q_OBJECT - - public: - QToolPaletteButton(QWidget *bparent, QIcon *iicon = 0, QToolPaletteElement *eparent = 0); - ~QToolPaletteButton(){}; - - void setButtonElement(QIcon *iicon, QToolPaletteElement *n_element); - - public slots: - void select_element(); - - signals: - void element_selected(QToolPaletteElement *); - - private: - QToolPaletteElement *element; -}; - - -class QTCAD_EXPORT QToolPaletteElement: public QWidget -{ - Q_OBJECT - - public: - QToolPaletteElement(QIcon *iicon = 0, QWidget *control = 0); - ~QToolPaletteElement(); - - void setButton(QToolPaletteButton *n_button); - void setControls(QWidget *n_controls); - - signals: - // PUBLIC, for palette: - // Signal the application can listen to to see if the Element has - // changed anything in the view. Emitted by element_do_view_update slot, - // which is connected to internal widget signals in the controls. This - // provide a generic, public "signal interface" for widget internals. - void view_changed(unsigned long long); - - public slots: - // PUBLIC, for palette: - // These slots are intended to be connected to parent signals when the - // Element is added to a Palette. They will in turn emit the local - // signals below for internal Element use. These slots are used to - // hide any internal signal/slot implementation details from the - // application while still allowing changes at the app level to drive - // updates in the Element contents. - void do_view_update(unsigned long long); - - - void do_element_unhide(void *); - - signals: - // INTERNAL: - // These signals are emitted by the below slots. Subcomponents will - // connect to these in lieu of connecting directly to application - // signals, to decouple the implementation of the Element internals - // from the application. I.e. the application connects to the above - // slots, and internal connections listen for the emission of the below - // signals in lieu of the application signals. - // - // Note that these signals should NEVER be emitted directly by any of - // the Element subcomponents. Nor should they be connected to by - // application code. - void element_view_update(unsigned long long); - - void element_unhide(); - - public slots: - // INTERNAL: - void element_view_changed(unsigned long long); - - public: - QToolPaletteButton *button; - QWidget *controls; - int scroll_pos = 0; - - bool use_event_filter = false; - -}; - -class QTCAD_EXPORT QToolPalette: public QWidget -{ - Q_OBJECT - - public: - QToolPalette(QWidget *pparent = 0); - ~QToolPalette(); - void addElement(QToolPaletteElement *element); - void deleteElement(QToolPaletteElement *element); - void setIconWidth(int iwidth); - void setIconHeight(int iheight); - void setAlwaysSelected(int iheight); // If 0 can disable all tools, if 1 some tool is always selected - - void resizeEvent(QResizeEvent *pevent); - - QToolPaletteElement *selected; - QString selected_style = QString(""); - - QVBoxLayout *mlayout; - - signals: - - // PUBLIC, for parent application: - // Signal the application can listen to to see if any Element has - // changed anything in the view. - void view_changed(unsigned long long); - - - // INTERNAL, for elements: - // Emitted when an element is selected. - void palette_element_selected(QToolPaletteElement *); - - // INTERNAL, for elements: - // Emitted when the palette gets word of an app level view change. - // This is used so elements don't have to connect directly to the - // parent applications view changed signal (which they can't do without - // knowing about the parent applications top level class, or requiring - // the application to individually connect directly to each element.) - void palette_view_update(unsigned long long); - - public slots: - // PUBLIC, for parent application: - // Trigger any needed updates in any elements in response to an - // app level view change. - void do_view_update(unsigned long long); - - - // INTERNAL - // TODO - I think we're going to need an activateElement and drawElement - // distinction here for editing - we will want the current panel shown - // (and highlighted button, if we can figure out how to highlight without - // selecting) to reflect the most recent selection, and we'll probably - // want to highlight both the comb and appropriate solid button when when - // we're selecting instances in the tree, but we don't want to kick in - // the event filters and create the edit wireframes until one of the buttons - // is actually selected. - void palette_displayElement(QToolPaletteElement *); - void button_layout_resize(); - void palette_do_view_changed(unsigned long long); - - private: - int always_selected; - int icon_width; - int icon_height; - QSplitter *splitter; - QWidget *button_container; - QFlowLayout *button_layout; - QScrollArea *control_container; - QSet elements; -}; - -#endif //QTOOLPALETTE_H - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/include/qtcad/QViewCtrl.h b/include/qtcad/QViewCtrl.h deleted file mode 100644 index 573925cca6f..00000000000 --- a/include/qtcad/QViewCtrl.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Q V I E W C T R L . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QViewCtrl.h - * - * Array of buttons for toggling between various view control modes. - * Provides only the buttons and the signals - must be connected up - * to an actual view widget to impact a view - */ - -#ifndef QVIEWCTRL_H -#define QVIEWCTRL_H - -#include "common.h" - -#include -#include -#include "ged.h" -#include "qtcad/defines.h" - -// TODO - need a view image control widget for raytrace run, raytrace -// abort, overlay/underlay/off, and save scene image -// -// component picking, etc. will most likely need to be a tool - we need to -// be able to build up and manipulate selection sets, of which one is the -// active drawn set. Operations needed include clearing first hit drawn -// instances under the mouse click, adding and removing objects from -// selection sets, and creating an initial set with a rectangle selection - -class QTCAD_EXPORT QViewCtrl : public QToolBar -{ - Q_OBJECT - - public: - QViewCtrl(QWidget *p, struct ged *pgedp); - ~QViewCtrl(); - - struct ged *gedp = NULL; - int icon_size = 25; - - signals: - void view_changed(unsigned long long); - void lmouse_mode(int); - - public slots: - - void sca_mode(); - void rot_mode(); - void tra_mode(); - void center_mode(); - - void fbclear_cmd(); - - void fb_mode_cmd(); - - void do_view_update(unsigned long long); - - // Unlike the other commands, the raytrace button - // has to reflect a potentially long-running state - - // that of the child rt process Consequently the - // icon controls need to be independent of the command - // execution logic. - void raytrace_cmd(); - void raytrace_start(int); - void raytrace_done(int); - - public: - // Left mouse behavior controls (when not using a tool or editing) - QAction *sca; - QAction *rot; - QAction *tra; - QAction *center; - - // Raytrace/framebuffer controls - QAction *raytrace; - QAction *fb_mode; - QAction *fb_clear; - - private: - bool raytrace_running = false; - int pid = -1; -}; - - -#endif //QVIEWCTRL_H - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/qtcad/QgAccordion.h b/include/qtcad/QgAccordion.h new file mode 100644 index 00000000000..f78397b292b --- /dev/null +++ b/include/qtcad/QgAccordion.h @@ -0,0 +1,89 @@ +/* Q G A C C O R D I O N . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgAccordion.h + * + * Show one of a stack of widgets + */ + +#ifndef QGACCORDIANWIDGET_H +#define QGACCORDIANWIDGET_H + +#include "common.h" + + +#include +#include +#include +#include +#include + +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgAccordionObject : public QWidget +{ + Q_OBJECT + + public: + QgAccordionObject(QWidget *pparent = 0, QWidget *object = 0, QString header_title = QString("")); + ~QgAccordionObject(); + QPushButton *toggle; + QScrollArea *objscrollarea; + + signals: + void select(QgAccordionObject *); + + public slots: + void toggleVisibility(); + + private: + QVBoxLayout *objlayout; + QString title; +}; + +class QTCAD_EXPORT QgAccordion : public QWidget +{ + Q_OBJECT + + public: + QgAccordion(QWidget *pparent = 0); + ~QgAccordion(); + void addObject(QgAccordionObject *object); + + public slots: + void open(QgAccordionObject *); + + private: + QSet objs; + QgAccordionObject *selected = NULL; + QVBoxLayout *mlayout; +}; + +#endif /* QGACCORDIANWIDGET_H */ + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgAppExecDialog.h b/include/qtcad/QgAppExecDialog.h new file mode 100644 index 00000000000..095b9f3abad --- /dev/null +++ b/include/qtcad/QgAppExecDialog.h @@ -0,0 +1,75 @@ +/* Q G A P P E X E C D I A L O G . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file cadappexec.h + * + * Support for running console programs and viewing the output stream + * in a dialog window. + * + */ + +#ifndef QGAPPEXECDIALOG_H +#define QGAPPEXECDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qtcad/defines.h" +#include "qtcad/QgConsole.h" + +class QTCAD_EXPORT QgAppExecDialog : public QDialog +{ + Q_OBJECT + + public: + QgAppExecDialog(QWidget *pparent, QString executable, QStringList args, QString lfile = ""); + ~QgAppExecDialog() {} + + public slots: + void read_stdout(); + void read_stderr(); + void process_abort(); + void process_done(int, QProcess::ExitStatus); + + public: + QFile *logfile; + QgConsole *console; + QProcess *proc; + QDialogButtonBox *buttonBox; +}; + +#endif // QGAPPEXECDIALOG_H + +/* + * Local Variables: + * mode: C++ + * tab-width: 8 + * c-basic-offset: 4 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgAttributesModel.h b/include/qtcad/QgAttributesModel.h new file mode 100644 index 00000000000..04c5e921d9c --- /dev/null +++ b/include/qtcad/QgAttributesModel.h @@ -0,0 +1,81 @@ +/* Q G A T T R I B U T E S M O D E L . H + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgAttributesModel.h + * + * Model for reflecting a BRL-CAD object's attribute keys and values in a way + * suitable for use in a Qt view. + */ + +#ifndef QGATTRIBUTESMODEL_H +#define QGATTRIBUTESMODEL_H + +#ifndef Q_MOC_RUN +#include "bu/avs.h" +#include "bv.h" +#include "raytrace.h" +#include "ged.h" +#endif + +#include "qtcad/defines.h" +#include "qtcad/QgKeyVal.h" + +class QTCAD_EXPORT QgAttributesModel : public QgKeyValModel +{ + Q_OBJECT + + public: // "standard" custom tree model functions + explicit QgAttributesModel(QObject *parent = 0, struct db_i *dbip = DBI_NULL, struct directory *dp = RT_DIR_NULL, int show_std = 0, int show_user = 0); + ~QgAttributesModel(); + + bool hasChildren(const QModelIndex &parent) const; + int update(struct db_i *new_dbip, struct directory *dp); + + public slots: + // Used when a selection in the model has changed + void refresh(const QModelIndex &idx); + // Used when the values may have changed in the underlying .g + void db_change_refresh(); + // Used when the currently opened database changes + void do_dbi_update(struct db_i *dbip); + + protected: + bool canFetchMore(const QModelIndex &parent) const; + void fetchMore(const QModelIndex &parent); + + private: + void add_Children(const char *name, QgKeyValNode *curr_node); + struct db_i *current_dbip; + struct directory *current_dp; + struct bu_attribute_value_set *avs; + int std_visible; + int user_visible; +}; + +#endif /* QGATTRIBUTESMODEL */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgColorRGB.h b/include/qtcad/QgColorRGB.h new file mode 100644 index 00000000000..01254bc3d19 --- /dev/null +++ b/include/qtcad/QgColorRGB.h @@ -0,0 +1,79 @@ +/* Q G C O L O R R G B . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgColorRGB.h + * + * Set a color either via dialog or r/g/b text entry + */ + +#ifndef QGCOLORRGB_H +#define QGCOLORRGB_H + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +#include "bu/color.h" +#include "bu/opt.h" +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgColorRGB: public QWidget +{ + Q_OBJECT + + public: + QgColorRGB(QWidget *p = NULL, QString lstr = QString("Color:"), QColor dcolor = QColor(Qt::red)); + ~QgColorRGB(); + + QLineEdit *rgbtext; + QPushButton *rgbcolor; + struct bu_color bc; + + signals: + void color_changed(struct bu_color *); + + public slots: + void set_color_from_text(); + + private slots: + void set_color_from_button(); + + private: + QColorDialog *d; + QHBoxLayout *mlayout; + QColor qc; +}; + +#endif /* QACCORDIANWIDGET_H */ + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgConsole.h b/include/qtcad/QgConsole.h new file mode 100644 index 00000000000..a66c6d80b18 --- /dev/null +++ b/include/qtcad/QgConsole.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc. + All rights reserved. + * + * Sandia National Laboratories, New Mexico PO Box 5800 Albuquerque, NM 87185 + * + * Kitware Inc. + * 28 Corporate Drive + * Clifton Park, NY 12065 + * USA + * + * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license + * for use of this work by or on behalf of the U.S. Government. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Kitware nor the names of any contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * This widget is based off of ParaView's pqConsoleWidget + */ + +#ifndef QGCONSOLE_H +#define QGCONSOLE_H + +#include "common.h" + +#include +#include +#include +#include +#include + +#include "ged.h" +#include "qtcad/defines.h" +#include "qtcad/QgConsoleListener.h" + +class QTCAD_EXPORT QgConsoleWidgetCompleter : public QCompleter +{ +public: + /** + * Update the completion model given a string. The given string + * is the current console text between the cursor and the start of + * the line. + */ + virtual void updateCompletionModel(const QString& str) = 0; +}; + +/* Completion class specific to GED command line */ +class QTCAD_EXPORT GEDShellCompleter : public QgConsoleWidgetCompleter +{ +public: + GEDShellCompleter(QWidget *p, struct ged *ged_ptr); + void updateCompletionModel(const QString& console_txt) override; + struct ged *gedp = NULL; +}; + +/** + Qt widget that provides an interactive console - you can send text to the + console by calling printString() and receive user input by connecting to the + executeCommand() slot. + + Note: Qt's signals and slots mechanism helps to make a robust widget for + multithreaded inputs, since input strings to the console are coming in via + signals and written by slots. Users should not attempt to manipulate the + underlying QPlainTextEdit widget directly. +*/ +class QTCAD_EXPORT QgConsole : public QWidget +{ + Q_OBJECT + +public: + QgConsole(QWidget* Parent); + virtual ~QgConsole(); + + /// Returns the current font + QFont getFont(); + /// Sets current font + void setFont(const QFont &font); + + /// Set a completer for this console widget + void setCompleter(QgConsoleWidgetCompleter* completer); + + QPoint getCursorPosition(); + + // combine multiple history lines and replace them with the combination + bool consolidateHistory(size_t start, size_t end); + size_t historyCount(); + std::string historyAt(size_t ind); + + void listen(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d); + std::map, QConsoleListener *> listeners; + + // When inserting a completion, need a setting to control + // how we handle slashes + int split_slash = 0; + +signals: + /// Signal emitted whenever the user enters a command + void executeCommand(const QString& cmd); + + /// Signal that there is queued, unprinted buffer output + void queued_log(const QString& Text); + +public slots: + /// Writes the supplied text to the console + void printString(const QString& Text); + + /// Writes the supplied text to the console + void printStringBeforePrompt(const QString& Text); + + /// Clears a listener (called by the listener's finished() signal) + void detach(struct ged_subprocess *p, int t); + + /// Updates the current command. Unlike printString, this will affect the + /// current command being typed. + void printCommand(const QString& cmd); + + /// Clears the contents of the console + void clear(); + + /// Puts out an input accepting prompt. + /// It is recommended that one uses prompt instead of printString() to print + /// an input prompt since this call ensures that the prompt is shown on a new + /// line. + void prompt(const QString& text); + + /// Inserts the given completion string at the cursor. This will replace + /// the current word that the cursor is touching with the given text. + /// Determines the word using QTextCursor::StartOfWord, EndOfWord. + void insertCompletion(const QString& text); + +private: + QgConsole(const QgConsole&); + QgConsole& operator=(const QgConsole&); + + // Used by printStringBeforePrompt to queue up a timed repetition of printing + // to catch anything recently added but not subsequently printed successfully + // by an event based trigger. Avoids output getting "stuck" in the buffer + // waiting for an event. Noticed when rt instances are lingering but not + // closed and typing heavily on the command prompt - the last line or two of + // rt output sometimes weren't printed under those conditions until the + // window was closed. + void emit_queued() { + QString estring(""); + Q_EMIT queued_log(estring); + } + + QString prompt_str; + int prompt_start = 0; + int64_t log_timestamp = 0; + QString logbuf; + + void internalExecuteCommand(const QString& Command); + + class pqImplementation; + pqImplementation* const Implementation; + friend class pqImplementation; +}; + + +#endif // !QGCONSOLE_H + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QtConsoleListener.h b/include/qtcad/QgConsoleListener.h similarity index 100% rename from include/qtcad/QtConsoleListener.h rename to include/qtcad/QgConsoleListener.h diff --git a/include/qtcad/QgEdit.h b/include/qtcad/QgEdit.h index c494d409c51..7ad1cb7025a 100644 --- a/include/qtcad/QgEdit.h +++ b/include/qtcad/QgEdit.h @@ -83,9 +83,9 @@ class QTCAD_EXPORT QVectEdit: public QWidget * * Rot,Tra,Scale,Center,Add,(Clone?),Write,Revert */ // -// Related to QToolPalette and QToolPaletteButton, but we don't have panel +// Related to QgToolPalette and QgToolPaletteButton, but we don't have panel // elements for this application so it's probably a bit different. Not sure -// yet whether to try and generalize QToolPalette in some fashion or define +// yet whether to try and generalize QgToolPalette in some fashion or define // a simpler widget for this purpose. diff --git a/include/qtcad/QgFlowLayout.h b/include/qtcad/QgFlowLayout.h new file mode 100644 index 00000000000..f6ccd931e3a --- /dev/null +++ b/include/qtcad/QgFlowLayout.h @@ -0,0 +1,94 @@ +/**************************************************************************** + ** + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + ** Contact: http://www.qt-project.org/legal + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + ** of its contributors may be used to endorse or promote products derived + ** from this software without specific prior written permission. + ** + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef QgFLOWLAYOUTH +#define QgFLOWLAYOUTH + +#include "common.h" + +#include +#include +#include +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgFlowLayout : public QLayout +{ + public: + explicit QgFlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + explicit QgFlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); + ~QgFlowLayout(); + + void addItem(QLayoutItem *item); + int horizontalSpacing() const; + int verticalSpacing() const; + void setHorizontalSpacing(int); + void setVerticalSpacing(int); + Qt::Orientations expandingDirections() const; + bool hasHeightForWidth() const; + int heightForWidth(int) const; + int count() const; + QLayoutItem *itemAt(int index) const; + QSize minimumSize() const; + void setGeometry(const QRect &rect); + QSize sizeHint() const; + QLayoutItem *takeAt(int index); + + private: + int doLayout(const QRect &rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; + + QList itemList; + int m_hSpace; + int m_vSpace; +}; + +#endif // QgFLOWLAYOUTH + + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgGL.h b/include/qtcad/QgGL.h new file mode 100644 index 00000000000..dc045c52e14 --- /dev/null +++ b/include/qtcad/QgGL.h @@ -0,0 +1,125 @@ +/* Q G G L . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgGL.h + * + */ + +#ifndef QGGL_H +#define QGGL_H + +#include "common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "bu/ptbl.h" +#include "bv.h" +#define DM_WITH_RT +#include "dm.h" +} + +#include "qtcad/defines.h" + +// Use QOpenGLFunctions so we don't have to prefix all OpenGL calls with "f->" +class QTCAD_EXPORT QgGL : public QOpenGLWidget, protected QOpenGLFunctions +{ + Q_OBJECT + + public: + explicit QgGL(QWidget *parent = nullptr, struct fb *fbp = NULL); + ~QgGL(); + + void stash_hashes(); // Store current dmp and v hash values + bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) + + void aet(double a, double e, double t); + void save_image(); + + int current = 1; + struct bview *v = NULL; + struct dm *dmp = NULL; + struct fb *ifp = NULL; + struct bu_ptbl *dm_set = NULL; + + void (*draw_custom)(struct bview *, void *) = NULL; + void *draw_udata = NULL; + + void enableDefaultKeyBindings(); + void disableDefaultKeyBindings(); + + void enableDefaultMouseBindings(); + void disableDefaultMouseBindings(); + + signals: + void changed(); + void init_done(); + + public slots: + void need_update(); + void set_lmouse_move_default(int); + + protected: + void paintGL() override; + void resizeGL(int w, int h) override; + void resizeEvent(QResizeEvent *e) override; + + void keyPressEvent(QKeyEvent *k) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + + private: + unsigned long long prev_dhash = 0; + unsigned long long prev_vhash = 0; + + bool use_default_keybindings = true; + bool use_default_mousebindings = true; + int lmouse_mode = BV_SCALE; + + bool m_init = false; + int x_prev = -INT_MAX; + int y_prev = -INT_MAX; + double x_press_pos = -INT_MAX; + double y_press_pos = -INT_MAX; + + struct bview *local_v = NULL; +}; + +#endif /* QGGL_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgGeomImport.h b/include/qtcad/QgGeomImport.h new file mode 100644 index 00000000000..da62fe43635 --- /dev/null +++ b/include/qtcad/QgGeomImport.h @@ -0,0 +1,151 @@ +/* Q G G E O M I M P O R T . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file cadappexec.h + * + * Encapsulates a graphical process for getting a path to a .g file to + * open, wrapping patterns for graphical configuration and in-dialogue + * running of converter processes into a reusable package. + * + * The final result is a QString with the path to the .g file suitable for + * opening with libged's "open" command, or an empty string if no such .g file + * ends up being available. For 3dm, STEP, etc. files that path will be to the + * output of the converter, but if the original specified file is already a.g + * file this will function like a normal file open dialog from Qt. + */ + +#ifndef QGGEOMIMPORT_H +#define QGGEOMIMPORT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgGeomImport : public QObject +{ + Q_OBJECT + + public: + QgGeomImport(QWidget *pparent = NULL); + ~QgGeomImport(); + + QString gfile(const char *tfile = NULL); + + bool enable_conversion = true; + + struct bu_vls conv_msg = BU_VLS_INIT_ZERO; + + private: + int exec_console_app_in_window(QString command, QStringList options, QString lfile); + QString fileName; +}; + +// GUI dialogues for specific format conversion options + +class ASCImportDialog : public QDialog +{ + Q_OBJECT + + public: + ASCImportDialog(QString filename, QString g_path, QString l_path); + + QString command(); + QStringList options(); + QLineEdit *db_path; + QLineEdit *log_path; + + private: + + QString input_file; + QGroupBox *formGroupBox; + QDialogButtonBox *buttonBox; +}; + +class RhinoImportDialog : public QDialog +{ + Q_OBJECT + + public: + RhinoImportDialog(QString filename, QString g_path, QString l_path); + + QString command(); + QStringList options(); + QLineEdit *db_path; + QLineEdit *log_path; + + private: + + QString input_file; + + QLineEdit *scaling_factor; + QLineEdit *tolerance; + QLineEdit *verbosity; + QCheckBox *debug_printing; + QCheckBox *random_colors; + QCheckBox *uuid; + + + QGroupBox *formGroupBox; + QDialogButtonBox *buttonBox; +}; + +class STEPImportDialog : public QDialog +{ + Q_OBJECT + + public: + STEPImportDialog(QString filename, QString g_path, QString l_path); + + QString command(); + QStringList options(); + QLineEdit *db_path; + QLineEdit *log_path; + + private: + + QString input_file; + + QCheckBox *verbosity; + + QGroupBox *formGroupBox; + QDialogButtonBox *buttonBox; +}; + +#endif // QGGEOMIMPORT_H + +/* + * Local Variables: + * mode: C++ + * tab-width: 8 + * c-basic-offset: 4 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgKeyVal.h b/include/qtcad/QgKeyVal.h new file mode 100644 index 00000000000..e4692255f0a --- /dev/null +++ b/include/qtcad/QgKeyVal.h @@ -0,0 +1,106 @@ +/* Q G K E Y V A L . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgKeyVal.h + * + */ + +#ifndef QGKEYVAL_H +#define QGKEYVAL_H + +#include "common.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgKeyValNode + { + public: + QgKeyValNode(QgKeyValNode *aParent=0); + ~QgKeyValNode(); + + QString name; + QString value; + int attr_type; + + QgKeyValNode *parent; + QList children; +}; + +class QTCAD_EXPORT QgKeyValModel : public QAbstractItemModel +{ + Q_OBJECT + + public: + QgKeyValModel(QObject *p = NULL); + ~QgKeyValModel(); + + QModelIndex index(int row, int column, const QModelIndex &parent) const; + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &child) const; + int columnCount(const QModelIndex &child) const; + + void setRootNode(QgKeyValNode *root); + QgKeyValNode* rootNode(); + + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); + + QgKeyValNode *m_root; + QModelIndex NodeIndex(QgKeyValNode *node) const; + QgKeyValNode *IndexNode(const QModelIndex &index) const; + + QgKeyValNode *add_pair(const char *name, const char *value, QgKeyValNode *curr_node, int type); + + int NodeRow(QgKeyValNode *node) const; +}; + +class QTCAD_EXPORT QgKeyValDelegate : public QStyledItemDelegate +{ + Q_OBJECT + + public: + QgKeyValDelegate(QWidget *pparent = 0) : QStyledItemDelegate(pparent) {} + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +class QTCAD_EXPORT QgKeyValView : public QTreeView +{ + Q_OBJECT + + public: + QgKeyValView(QWidget *pparent, int decorate_tree = 0); + ~QgKeyValView() {}; +}; + + +#endif /* QGKEYVAL_H */ + + diff --git a/include/qtcad/QgMeasureFilter.h b/include/qtcad/QgMeasureFilter.h new file mode 100644 index 00000000000..2654ebd897d --- /dev/null +++ b/include/qtcad/QgMeasureFilter.h @@ -0,0 +1,143 @@ +/* Q G M E A S U R E F I L T E R . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgMeasureFilter.h + * + * Qt mouse filters for 2D and 3D dimensional measurement + * in a view. + */ + +#ifndef QGMEASUREFILTER_H +#define QGMEASUREFILTER_H + +#include "common.h" + +extern "C" { +#include "bu/color.h" +#include "bu/ptbl.h" +#include "bg/polygon.h" +#include "bv.h" +#include "raytrace.h" +} + +#include +#include +#include +#include +#include +#include "qtcad/defines.h" + +// Filters designed for specific editing modes +class QTCAD_EXPORT QgMeasureFilter : public QObject +{ + Q_OBJECT + + public: + // Primary mouse interaction. As it happens the 2D and 3D mouse event + // filtering is the same, so this is not a virtual function. See + // get_point for the 2D/3D specific logic. + bool eventFilter(QObject *, QEvent *); + + // Initialization common to the various polygon filter types + QMouseEvent *view_sync(QEvent *e); + + double length1(); + double length2(); + double angle(bool radians); + + // Current state of the measurement tool (clients may need to + // know which information to report) + // 0 == uninitialized + // 1 = length measurement in progress + // 2 = length measurement complete + // 3 = angle measurement in progress + // 4 = angle measurement complete + int mode = 0; + + // 2D and 3D point interrogation is different - hence this + // is a virtual method to be customized for 2D and 3D + virtual bool get_point() { return false; }; + point_t mpnt; + + // If the client code only wants a simple length measurement, + // without the follow-on behavior of a second angle measuring + // line, setting this variable to true will alter the mouse + // binding behavior accordingly. + bool length_only = false; + + signals: + void view_updated(int); + + public: + struct bview *v = NULL; + struct bv_scene_obj *s = NULL; + std::string oname = std::string("tool:measurement"); + + public slots: + void update_color(struct bu_color *); + + private: + point_t p1 = VINIT_ZERO; + point_t p2 = VINIT_ZERO; + point_t p3 = VINIT_ZERO; +}; + +class QTCAD_EXPORT QMeasure2DFilter : public QgMeasureFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + + private: + bool get_point(); +}; + + +class QTCAD_EXPORT QMeasure3DFilter : public QgMeasureFilter +{ + Q_OBJECT + + public: + QMeasure3DFilter(); + ~QMeasure3DFilter(); + bool eventFilter(QObject *, QEvent *e); + struct db_i *dbip = NULL; + + private: + bool get_point(); + + int prev_cnt = 0; + struct bu_ptbl scene_obj_set = BU_PTBL_INIT_ZERO; + struct application *ap = NULL; + struct rt_i *rtip = NULL; + struct resource *resp = NULL; +}; + +#endif /* QGMEASUREFILTER_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgModel.h b/include/qtcad/QgModel.h index dff7753db71..b9385239f9f 100644 --- a/include/qtcad/QgModel.h +++ b/include/qtcad/QgModel.h @@ -60,32 +60,7 @@ * D will impact BOTH Au[M1]BuCuD and Au[M2]BuCuD. This means that .g comb * instances cannot, by themselves, map directly to items in a Qt model. * - * Conversely, in a Qt .g model, if a Qt item which is going to express .g - * instance editing the mode must be prepared to cope with changes having non - * local side effects - i.e. any change to one item can potentially change an - * arbitrary number of additional items, based on what else in the .g database - * is referencing the object being changed. - * - * The approach taken to cope with these issues is to conceptually split the - * wrapping of .g comb instances into two parts - a gInstance that corresponds - * to one unique parent+bool_op+matrix+child instance in a .g combination tree, - * and a QgItem which corresponds to a globally unique instance of a gInstance. - * So, in the above example, CuD would be expressed as a gInstance, and the - * Au[M1]BuCuD QgItem would reference the CuD gInstance to connect the .g - * database information to the unique model hierarchy item. Likewise, the - * Au[M2]BuCuD QgItem would reference the same gInstance, despite being a - * different item in the model. - * - * gInstances are created to reflect the .g database state, and they are what - * is updated as a direct consequence of callbacks registered with the low - * level database I/O routines. QgItems must then be updated (or - * added/removed) in response to gInstance changes. The only QgItems that - * will be populated by default are the top level items - all others will be - * lazily created in response as the user specifies which combs to open in - * the view. (The latter is necessary for large databases, which may have - * very large and deep hierarchies.) - * - * Also investigate https://wiki.qt.io/Model_Test to see if it may be + * TODO - investigate https://wiki.qt.io/Model_Test to see if it may be * useful for this code. */ @@ -101,7 +76,6 @@ #include #include "qtcad/defines.h" -#include "qtcad/gInstance.h" #ifndef Q_MOC_RUN #include "raytrace.h" @@ -109,63 +83,52 @@ #endif // QgItems correspond to the actual Qt entries displayed in the view. If a -// comb is reused in multiple places in the tree a gInstance may be referenced -// by multiple QgItems, but each QgItem corresponds uniquely to a single string -// of directory pointers, ops, matrices and (if needed) icnt values from a -// series of gInstance structures generated by walking comb trees. A single -// QgItem being selected may activate multiple QgItems by virtue of those other -// QgItems using the same gInstance as the selected QgItem (this reflects the -// impact any changes will have on the database contents) but from the Qt -// perspective the unique selection item is the QgItem. If the QgItem is -// instructed to conduct an operation with implications at the gInstance level -// (modification of primitive parameters, for example) other QgItems with the -// same gInstance will have to be separately handled to reflect the same -// changes. +// comb is reused in multiple places in the tree the same comb child instance +// definition may be referenced by multiple QgItems, but each QgItem +// corresponds uniquely to a single string of directory pointers, ops, matrices +// and (if needed) icnt values from a series of instance structures generated +// by walking comb trees. A single QgItem being selected may activate multiple +// QgItems by virtue of those other QgItems using the same comb instance as the +// selected QgItem (this reflects the impact any changes will have on the +// database contents) but from the Qt perspective the unique selection item is +// the QgItem. If the QgItem is instructed to conduct an operation with +// implications at the instance level (modification of primitive parameters, +// for example) other QgItems with the same instance will have to be +// separately handled to reflect the same changes. // // A QgItem will store parents and children, but remember that both of those -// relationships are informed by the gInstance relationships rather than directly +// relationships are informed by the .g relationships rather than directly // representing them. A QgItem always has a unique parent, even if its -// gInstance is associated with multiple active QgItems elsewhere in the tree. +// instance is associated with multiple active QgItems elsewhere in the tree. // The children array is initially empty even though the comb it corresponds to // may have many children. It is only when the QgItem is opened that the -// gInstance is queried for its children and new QgItems based on the -// gInstance children are created. Because we don't want to collapse all -// opened/closed state in a subtree if we close a parent QgItem, the children -// QgItems remain populated through a close to persist that state. +// DbiState is queried for its children and new QgItems based on the children +// are created. Because we don't want to collapse all opened/closed state in a +// subtree if we close a parent QgItem, the children QgItems remain populated +// through a close to persist that state. class QTCAD_EXPORT QgModel; class QTCAD_EXPORT QgItem { public: - explicit QgItem(gInstance *ig, QgModel *ictx); + explicit QgItem(unsigned long long hash, QgModel *ictx); ~QgItem(); // Testing functions to simulate GUI activities void open(); void close(); - // Return a pointer to the gInstance associated with this QgItem, or - // NULL if no valid instance is found. - gInstance *instance(); - /* To a BRL-CAD developer's eyes this is rather abstract, but the * combination of the ihash and ctx points to the BRL-CAD specific data - * for this item via the ability to look up its related gInstance in - * the ctx map via the hash. The parent QgItem in turn provides the - * relationship which makes this entity distinct from all other - * gInstances present in the .g file. - * - * We do this rather than storing a gInstance pointer, because we will - * need to be able to determine if a given QgItem is valid at various - * points in the logic, and one of the validity tests is whether the - * gInstance it represents is still active in the model. Unlike a - * pointer, the ihash lookup will let us make a valid/invalid - * determination with a find lookup on the model's instance map. + * for this instance. */ unsigned long long ihash = 0; - QgModel *ctx = NULL; + QgModel *mdl = NULL; + QgItem *parentItem = NULL; + std::vector path_items(); + unsigned long long path_hash(); /* Flag to determine if this QgItem should be viewed as opened or closed - * in order to preserve subtree state, we don't want to obliterate the @@ -177,7 +140,7 @@ class QTCAD_EXPORT QgItem * storing a map in the view class or the selection proxy model * where we can set and store these flags - is a fair bit more * involved. Give we already have some separation between this logic - * and the gInstance logic which is the real wrapper around the .g + * and the instance logic which is the real wrapper around the .g * information, going with the simple approach for now. */ bool open_itm = false; @@ -195,23 +158,14 @@ class QTCAD_EXPORT QgItem std::unordered_map c_noderow; size_t c_count = 0; - // Return the full path to this particular item (equivalent to - // db_path_to_vls) - QString toString(); - struct db_full_path *fp(); - - // Cached data from the gInstance, so we can keep - // displaying while librt does work on the gInstances. + // Cached data from the instance, so we can keep + // displaying while librt does work on the instances. struct bu_vls name = BU_VLS_INIT_ZERO; db_op_t op = DB_OP_UNION; struct directory *dp = NULL; QImage icon; - - // Flag to determine whether the item is fully or partially drawn - int draw_state = 0; - - // Flag to determine whether the item is selected - int select_state = 0; + //int draw_state = 0; + //bool select_state = false; }; /* The primary expression in a Qt context of a .g database and its contents. @@ -227,10 +181,10 @@ class QTCAD_EXPORT QgItem * * Hierarchy items * - * One of the subtle points of a .g hierarchy representation is that a - * gInstance may be locally unique, but not globally unique. For - * example, if comb A has underneath it two different instances of comb - * B using different placement matrices, and B is defined using C: + * One of the subtle points of a .g hierarchy representation is that an + * instance may be locally unique, but not globally unique. For example, if + * comb A has underneath it two different instances of comb B using different + * placement matrices, and B is defined using C: * * A * u [M1] B @@ -240,19 +194,17 @@ class QTCAD_EXPORT QgItem * u C * u D * - * D has only one unique gInstance definition in this hierarchy - IDN - * matrix union of D into C - but that instance has TWO manifestations - * in the overall tree that are NOT the same model items by virtue of - * having different B parent instances further up in the hierarchy: - * Au[M1]B and Au[M2]B. + * D has only one unique instance definition in this hierarchy - IDN matrix + * union of D into C - but that instance has TWO manifestations in the overall + * tree that are NOT the same model items by virtue of having different B + * parent instances further up in the hierarchy: Au[M1]B and Au[M2]B. * - * To with this the primary model hierarchy is an items hierarchy which - * holds QgItems that encode a reference to a gInstance and the - * parent/child data specific to an individual place in the hierarchy. - * It is a QgItem, not a gInstance, which can correspond to a row in a - * Qt abstract model. Unlike gInstances, QgItems are created lazily in - * response to view requests, working from a seed set created from the - * top level objects in a database. + * To with this the primary model hierarchy is an items hierarchy which holds + * QgItems that encode a reference to an instance and the parent/child data + * specific to an individual place in the hierarchy. It is a QgItem, not an + * instance, which can correspond to a row in a Qt abstract model. QgItems are + * created lazily in response to view requests, working from a seed set created + * from the top level objects in a database. */ class QTCAD_EXPORT QgModel : public QAbstractItemModel { @@ -272,6 +224,13 @@ class QTCAD_EXPORT QgModel : public QAbstractItemModel // update the model, or upon startup. void g_update(struct db_i *n_dbip); + // This is a bit of a cheat in that an interaction mode isn't really + // part of the .g state, but we want the tree highlighting logic to + // reflect such a state and to have that logic reusable at the library + // level it needs to be available in a container readily accessible at + // that level. + int interaction_mode = 0; + // Qt Model interface // Get the root QgItem @@ -332,24 +291,10 @@ class QTCAD_EXPORT QgModel : public QAbstractItemModel * scene views are updated. */ std::unordered_set changed_dp; - // Build a map of gInstance hashes to instances for easy lookup. This - // is for gInstance reuse. In trees that heavily reuse combs avoiding - // the storing of duplicate gInstances will save memory. - std::unordered_map *instances = NULL; - // Convenience container holding all active QgItems std::unordered_set *items = NULL; - // The "seed" set for a tree view is the set of objects with no parents - // in the hierarchy. (What users of MGED think of as the "tops" set, - // as well as objects with cyclic subtrees - the latter would be - // invisible in the tree view if we do not list them as top level - // objects.) This set may change after each database edit, but there - // will always be at least one object in a valid .g hierarchy that has - // no parent. - std::unordered_map *tops_instances = NULL; - - // Sorted QgItem pointers corresponding to the tops_instances + // Sorted QgItem pointers corresponding to the tops instances std::vector tops_items; // Toggle for whether or not the model should be viewed using a tops @@ -368,6 +313,10 @@ class QTCAD_EXPORT QgModel : public QAbstractItemModel // do so, it may emit this signal void view_change(unsigned long long); + // Emit when some model action change will require a view to update + // its awareness of what is drawn + void view_changed(unsigned long long); + // Let the tree view know it has highlighting work to do it wouldn't // otherwise see void check_highlights(); @@ -376,15 +325,12 @@ class QTCAD_EXPORT QgModel : public QAbstractItemModel // needs to be done in the view after this happens...) void opened_item(QgItem *); - // Emit when some model action change will require a view to update - // its awareness of what is drawn - void view_changed(unsigned long long); public slots: int draw_action(); - int draw(QString &qpath); + int draw(const char *path); int erase_action(); - int erase(QString &qpath); + int erase(const char *path); void toggle_hierarchy(); void item_collapsed(const QModelIndex &index); void item_expanded(const QModelIndex &index); diff --git a/include/qtcad/QgPolyFilter.h b/include/qtcad/QgPolyFilter.h new file mode 100644 index 00000000000..a593da63540 --- /dev/null +++ b/include/qtcad/QgPolyFilter.h @@ -0,0 +1,136 @@ +/* Q G P O L Y F I L T E R . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgPolyFilter.h + * + * Qt mouse filters for polygon editing modes + */ + +#ifndef QGPOLYFILTER_H +#define QGPOLYFILTER_H + +#include "common.h" + +extern "C" { +#include "bu/ptbl.h" +#include "bg/polygon.h" +#include "bv.h" +} + +#include +#include +#include +#include +#include +#include "qtcad/defines.h" + +// Filters designed for specific editing modes +class QTCAD_EXPORT QgPolyFilter : public QObject +{ + Q_OBJECT + + public: + // Initialization common to the various polygon filter types + QMouseEvent *view_sync(QEvent *e); + + // We want to be able to swap derived QgPolyFilter classes in + // parent calling code - make eventFilter virtual to help + // simplify doing so. + virtual bool eventFilter(QObject *, QEvent *) { return false; }; + + signals: + void view_updated(int); + void finalized(bool); + + public: + bool close_polygon(); + + struct bview *v = NULL; + bg_clip_t op = bg_None; + struct bv_scene_obj *wp = NULL; + int ptype = BV_POLYGON_CIRCLE; + bool close_general_poly = true; // set to false if application wants to allow non-closed polygons + struct bu_color fill_color = BU_COLOR_BLUE; + struct bu_color edge_color = BU_COLOR_YELLOW; + bool fill_poly = false; + double fill_slope_x = 1.0; + double fill_slope_y = 1.0; + double fill_density = 10.0; + double vZ = 0.0; + std::string vname; +}; + +class QTCAD_EXPORT QPolyCreateFilter : public QgPolyFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + void finalize(bool); + + struct bu_ptbl bool_objs = BU_PTBL_INIT_ZERO; +}; + +class QTCAD_EXPORT QPolyUpdateFilter : public QgPolyFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + + struct bu_ptbl bool_objs = BU_PTBL_INIT_ZERO; +}; + +class QTCAD_EXPORT QPolySelectFilter : public QgPolyFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); +}; + +class QTCAD_EXPORT QPolyPointFilter : public QgPolyFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); +}; + +class QTCAD_EXPORT QPolyMoveFilter : public QgPolyFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + struct bu_ptbl move_objs = BU_PTBL_INIT_ZERO; +}; + + +#endif /* QGPOLYFILTER_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgQuadView.h b/include/qtcad/QgQuadView.h new file mode 100644 index 00000000000..d9de40d58e1 --- /dev/null +++ b/include/qtcad/QgQuadView.h @@ -0,0 +1,135 @@ +/* Q G Q U A D V I E W . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgQuadView.h + * + */ + +#ifndef QGQUADVIEW_H +#define QGQUADVIEW_H + +#include "common.h" + +#include + +extern "C" { +#include "bu/ptbl.h" +#include "bv.h" +#include "dm.h" +} + +#include "qtcad/defines.h" +#include "qtcad/QgView.h" + +// Abbreviations: +// +// ur == 0 == Upper Right Quadrant +// ul == 1 == Upper Left Quadrant +// ll == 2 == Lower Left Quadrant +// lr == 3 == Lower Right Quadrant + +#define UPPER_RIGHT_QUADRANT 0 +#define UPPER_LEFT_QUADRANT 1 +#define LOWER_LEFT_QUADRANT 2 +#define LOWER_RIGHT_QUADRANT 3 + +class QTCAD_EXPORT QgQuadView : public QWidget +{ + Q_OBJECT + + public: + explicit QgQuadView(QWidget *parent, struct ged *gedpRef, int type); + ~QgQuadView(); + + void stash_hashes(); // Store current dmp and v hash values + bool diff_hashes(); // Set dmp dirty flags if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) + + bool isValid(); + + void default_views(int); // Set the aet of the four quadrants to their standard defaults. If 0 is supplied the upper right quadrant isn't altered, if 1 is supplied all are adjusted. + QgView *get(int quadrant_num = UPPER_RIGHT_QUADRANT); + QgView *get(const QPoint &p); // Test is global point coordinates correspond to one of the quad view + QgView *get(QEvent *e); // Given a MouseButtonPress QEvent, see if the point identifies a view + QgView *curr_view(); // return the currently selected view + struct bview * view(int quadrant_id = UPPER_RIGHT_QUADRANT); + + void select(int quadrant_num); + void select(const char *id); // valid inputs: ur, ul, ll and lr + int get_selected(); // returns UPPER_RIGHT_QUADRANT, UPPER_LEFT_QUADRANT, LOWER_LEFT_QUADRANT, or LOWER_RIGHT_QUADRANT + + void changeToSingleFrame(); + void changeToQuadFrame(); + void changeToResizeableQuadFrame(); + + void enableDefaultKeyBindings(); + void disableDefaultKeyBindings(); + + void enableDefaultMouseBindings(); + void disableDefaultMouseBindings(); + + signals: + void changed(QgView *); + void selected(QgView *); + void init_done(); + + public slots: + void do_view_update(unsigned long long); + void do_view_changed(); + void do_init_done(); + void set_lmouse_move_default(int); + + private: + bool eventFilter(QObject*, QEvent*); + QgView *createView(unsigned int index); + QGridLayout *createLayout(); + + int graphicsType = QgView_SW; + // Holds up to 4 views in single view only the first view is constructed + // The other views are constructed if quad view mode is selected by the user + QgView *views[4] = {nullptr, nullptr, nullptr, nullptr}; + QgView *currentView; + // We need to hang on to this because we don't create the other quad views until the user switches mode + struct ged *gedp; + + // Hang on to these pointers so when we need to clean up memory we have them + QGridLayout *currentLayout = nullptr; + // Note that we use QWidget here rather than QSpacerItem in order to allow + // for color control to indicate active quadrants without having to resize + // the windows in response to a selection. + QWidget *spacerTop = nullptr; + QWidget *spacerBottom = nullptr; + QWidget *spacerLeft = nullptr; + QWidget *spacerRight = nullptr; + QWidget *spacerCenter = nullptr; + + // Flag for initializations of sub-widgets + bool init_done_flag = false; +}; + +#endif /* QGQUADVIEW_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgSW.h b/include/qtcad/QgSW.h new file mode 100644 index 00000000000..c4b5bb4856f --- /dev/null +++ b/include/qtcad/QgSW.h @@ -0,0 +1,129 @@ +/* Q G S W . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file qtcad/QgSW.h + * + * This defines a Qt widget for displaying the visualization results of the + * bundled libosmesa OpenGL software rasterizer, using the swrast libdm + * backend. + * + * Unlike the standard QgGL widget, this can display OpenGL rendered graphics + * even if the OpenGL stack on the host operating system is non-functional (it + * will be a great deal slower, but since it does not rely on any system + * capabilities to produce its images it should work in any environment where a + * basic Qt gui can load.) + */ + +#ifndef QGSW_H +#define QGSW_H + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "bu/ptbl.h" +#include "bv.h" +#define DM_WITH_RT +#include "dm.h" +} + +#include "qtcad/defines.h" + +class QTCAD_EXPORT QgSW : public QWidget +{ + Q_OBJECT + + public: + explicit QgSW(QWidget *parent = nullptr, struct fb *fbp = NULL); + ~QgSW(); + + void stash_hashes(); // Store current dmp and v hash values + bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) + + void save_image(); + + void aet(double a, double e, double t); + + int current = 1; + struct bview *v = NULL; + struct dm *dmp = NULL; + struct fb *ifp = NULL; + struct bu_ptbl *dm_set = NULL; + + void (*draw_custom)(struct bview *, void *) = NULL; + void *draw_udata = NULL; + + void enableDefaultKeyBindings(); + void disableDefaultKeyBindings(); + + void enableDefaultMouseBindings(); + void disableDefaultMouseBindings(); + + signals: + void changed(); + void init_done(); + + public slots: + void need_update(); + void set_lmouse_move_default(int); + + protected: + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + + void keyPressEvent(QKeyEvent *k) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + + private: + unsigned long long prev_dhash = 0; + unsigned long long prev_vhash = 0; + + bool use_default_keybindings = true; + bool use_default_mousebindings = true; + int lmouse_mode = BV_SCALE; + + bool m_init = false; + int x_prev = -INT_MAX; + int y_prev = -INT_MAX; + double x_press_pos = -INT_MAX; + double y_press_pos = -INT_MAX; + + struct bview *local_v = NULL; +}; + +#endif /* QGSW_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgSelectFilter.h b/include/qtcad/QgSelectFilter.h new file mode 100644 index 00000000000..9299e91e7b5 --- /dev/null +++ b/include/qtcad/QgSelectFilter.h @@ -0,0 +1,113 @@ +/* Q G S E L E C T F I L T E R . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgMeasureFilter.h + * + * Qt mouse filters for graphically selecting elements in a view. + */ + +#ifndef QGSELECTFILTER_H +#define QGSELECTFILTER_H + +#include "common.h" + +extern "C" { +#include "bu/color.h" +#include "bu/ptbl.h" +#include "bg/polygon.h" +#include "bv.h" +#include "raytrace.h" +} + +#include +#include +#include +#include +#include +#include "qtcad/defines.h" + +// Filters designed for specific editing modes +class QTCAD_EXPORT QgSelectFilter : public QObject +{ + Q_OBJECT + + public: + // Primary mouse interaction. This differs a bit for the + // various selection types, hence the virtual definition + // in the base class. + virtual bool eventFilter(QObject *, QEvent *) { return false; } + + // Recover info from view (common logic for all selection modes) + QMouseEvent *view_sync(QEvent *e); + + struct bu_ptbl selected_set = BU_PTBL_INIT_ZERO; + + struct bview *v = NULL; + + // Whenever we're doing selections, we may want either all the objects + // that match the selection criteria, or just the "closest" object. + // Default behavior is to return everything, but this flag allows the + // caller to request the more limited result as well. + bool first_only = false; + + signals: + void view_updated(int); +}; + +class QTCAD_EXPORT QgSelectPntFilter: public QgSelectFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); +}; + +class QTCAD_EXPORT QgSelectBoxFilter: public QgSelectFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + + private: + fastf_t px = -FLT_MAX; + fastf_t py = -FLT_MAX; +}; + +class QTCAD_EXPORT QgSelectRayFilter: public QgSelectFilter +{ + Q_OBJECT + + public: + bool eventFilter(QObject *, QEvent *e); + + struct db_i *dbip = NULL; +}; + +#endif /* QGSELECTFILTER_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgSignalFlags.h b/include/qtcad/QgSignalFlags.h new file mode 100644 index 00000000000..b105964c04d --- /dev/null +++ b/include/qtcad/QgSignalFlags.h @@ -0,0 +1,100 @@ +/* Q G S I G N A L F L A G S . H + * BRL-CAD + * + * Copyright (c) 2022-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgSignalFlags.h + * + * Qt uses a signals/slots mechanism to communicate when (for example) + * application UI elements need to update in response to data changes. + * However, it is very easy to set up a nest of complicated connections that + * can trigger feedback loops or just make the logic very difficult to debug. + * + * To keep things manageable, we define a couple of conventions for Qt widgets + * to use when defining "public facing" signals and slots that have + * implications beyond their own internal display logic: + * + * 1. An application will provide a view_update signal, which the application + * itself will connect to the slots of whatever view widgets need to execute + * the updates. Subcomponents shouldn't directly connect to other subcomponent + * view update signals - they should instead rely on the signal from the + * application. + * + * 2. The application will provide a do_view_changed slot, whose + * responsibility is to issue a view_update signal in response to signals of + * view changes from widgets. The application should connect the view_changed + * signal to from any widgets that potentially have an impact on the view to + * this slot. + * + * 3. The widgets will provide a view_changed signal, which is emitted by the + * widget when something happens that requires view updates to be triggered in + * other widgets. This signal is connected by the app to the app's + * do_view_changed slot + * + * 4. The widgets will provide a do_view_update slot, which is connected by + * the application to the app's view_update signal. The do_view_update slot + * does the work of updating the widget in response to the view_update signal. + * It should NEVER emit a view_changed signal either directly or indirectly + * (i.e. by calling other methods) to avoid setting up infinite loops. + * + * This results in some widget logic feeling a bit indirect - the "do the data + * setup" part of a widget must be separated from the "update my component + * graphical widgets to reflect the data" logic, and will only function + * "properly" when hooked up to a parent application that accepts its + * view_changed signal and turns around to call the widget's do_view_update + * slot. This is simply a reflection of the reality that many (most?) BRL-CAD + * Qt widgets must also be responsive not simply to their own graphical + * updates, but to GED command line induced data changes and/or model state + * changes induced by other widgets. Without this separation and connections, + * widgets will get "out of sync" with other parts of the interface. + * + * Because not all view updates have similar consequences (a removal of a + * database object from the drawn scene, for example, requires treeview updates + * to reflect drawn status changes. However, a rotation around the model + * changes only the view matrix, and requires updating only of the central + * display widget.) To reflect this, without requiring lots of separate signal + * connections, a flag is passed between the various view signals and slots. + * Widgets can set various values of the flags, and by checking those flags + * will know if a particular view update signal requires them to update their + * aspect of the user interface. (Some updates may be a bit resource intensive + * if they require full processing of a large geometry file's data, so we want + * to be able to exercise some discretion on what work we do when. + * + * We make these defines in this header file so all widgets and applications + * can share a common, mutually understood convention. + */ + +#include "common.h" + +#ifndef QGSIGNALFLAGS_H + +#define QG_VIEW_REFRESH 0x00000001 // Potential camera updates, no structural changes +#define QG_VIEW_DRAWN 0x00000002 // Used when what is drawn in the scene changes +#define QG_VIEW_SELECT 0x00000004 // Used when what is selected changes +#define QG_VIEW_MODE 0x00000008 // Used when mode-aware highlighting or drawing changes +#define QG_VIEW_DB 0x00000010 // Used when .g database content changes + +#endif // QGSIGNALFLAGS_H +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/qtcad/QgToolPalette.h b/include/qtcad/QgToolPalette.h new file mode 100644 index 00000000000..ba386eb62eb --- /dev/null +++ b/include/qtcad/QgToolPalette.h @@ -0,0 +1,219 @@ +/* Q G T O O L P A L E T T E . H + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgToolPalette.h + * + * Signals/slots in Palettes and Elements + * + * In order to keep the scope of the various plugins local, we define + * a tiered system of signals and slots which are connected to by + * various aspects of this system: + * + * The QgToolPalette widget is what is directly added to application + * widget hierarchies, and it is that widget's signals and slots which + * are connected to the top level view updating signal/slot system as + * articulated in QgSignalFlags.h. Individual elements (i.e.tools) are + * connected to QgToolPalette, and the implementation specific "guts" + * of the various tools connect to their parent element. + * + */ + +#ifndef QGTOOLPALETTE_H +#define QGTOOLPALETTE_H + +#include "common.h" + +#include +#include +#include +#include +#include +#include +#include +#include "qtcad/defines.h" +#include "qtcad/QgFlowLayout.h" +#include "qtcad/QgSignalFlags.h" + +class QTCAD_EXPORT QgToolPaletteElement; + +class QTCAD_EXPORT QgToolPaletteButton: public QPushButton +{ + Q_OBJECT + + public: + QgToolPaletteButton(QWidget *bparent, QIcon *iicon = 0, QgToolPaletteElement *eparent = 0); + ~QgToolPaletteButton(){}; + + void setButtonElement(QIcon *iicon, QgToolPaletteElement *n_element); + + public slots: + void select_element(); + + signals: + void element_selected(QgToolPaletteElement *); + + private: + QgToolPaletteElement *element; +}; + + +class QTCAD_EXPORT QgToolPaletteElement: public QWidget +{ + Q_OBJECT + + public: + QgToolPaletteElement(QIcon *iicon = 0, QWidget *control = 0); + ~QgToolPaletteElement(); + + void setButton(QgToolPaletteButton *n_button); + void setControls(QWidget *n_controls); + + signals: + // PUBLIC, for palette: + // Signal the application can listen to to see if the Element has + // changed anything in the view. Emitted by element_do_view_update slot, + // which is connected to internal widget signals in the controls. This + // provide a generic, public "signal interface" for widget internals. + void view_changed(unsigned long long); + + public slots: + // PUBLIC, for palette: + // These slots are intended to be connected to parent signals when the + // Element is added to a Palette. They will in turn emit the local + // signals below for internal Element use. These slots are used to + // hide any internal signal/slot implementation details from the + // application while still allowing changes at the app level to drive + // updates in the Element contents. + void do_view_update(unsigned long long); + + + void do_element_unhide(void *); + + signals: + // INTERNAL: + // These signals are emitted by the below slots. Subcomponents will + // connect to these in lieu of connecting directly to application + // signals, to decouple the implementation of the Element internals + // from the application. I.e. the application connects to the above + // slots, and internal connections listen for the emission of the below + // signals in lieu of the application signals. + // + // Note that these signals should NEVER be emitted directly by any of + // the Element subcomponents. Nor should they be connected to by + // application code. + void element_view_update(unsigned long long); + + void element_unhide(); + + public slots: + // INTERNAL: + void element_view_changed(unsigned long long); + + public: + QgToolPaletteButton *button; + QWidget *controls; + int scroll_pos = 0; + + bool use_event_filter = false; + +}; + +class QTCAD_EXPORT QgToolPalette: public QWidget +{ + Q_OBJECT + + public: + QgToolPalette(QWidget *pparent = 0); + ~QgToolPalette(); + void addElement(QgToolPaletteElement *element); + void deleteElement(QgToolPaletteElement *element); + void setIconWidth(int iwidth); + void setIconHeight(int iheight); + void setAlwaysSelected(int iheight); // If 0 can disable all tools, if 1 some tool is always selected + + void resizeEvent(QResizeEvent *pevent); + + QgToolPaletteElement *selected; + QString selected_style = QString(""); + + QVBoxLayout *mlayout; + + signals: + + // PUBLIC, for parent application: + // Signal the application can listen to to see if any Element has + // changed anything in the view. + void view_changed(unsigned long long); + + + // INTERNAL, for elements: + // Emitted when an element is selected. + void palette_element_selected(QgToolPaletteElement *); + + // INTERNAL, for elements: + // Emitted when the palette gets word of an app level view change. + // This is used so elements don't have to connect directly to the + // parent applications view changed signal (which they can't do without + // knowing about the parent applications top level class, or requiring + // the application to individually connect directly to each element.) + void palette_view_update(unsigned long long); + + public slots: + // PUBLIC, for parent application: + // Trigger any needed updates in any elements in response to an + // app level view change. + void do_view_update(unsigned long long); + + + // INTERNAL + // TODO - I think we're going to need an activateElement and drawElement + // distinction here for editing - we will want the current panel shown + // (and highlighted button, if we can figure out how to highlight without + // selecting) to reflect the most recent selection, and we'll probably + // want to highlight both the comb and appropriate solid button when when + // we're selecting instances in the tree, but we don't want to kick in + // the event filters and create the edit wireframes until one of the buttons + // is actually selected. + void palette_displayElement(QgToolPaletteElement *); + void button_layout_resize(); + void palette_do_view_changed(unsigned long long); + + private: + int always_selected; + int icon_width; + int icon_height; + QSplitter *splitter; + QWidget *button_container; + QgFlowLayout *button_layout; + QScrollArea *control_container; + QSet elements; +}; + +#endif //QGTOOLPALETTE_H + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/include/qtcad/QgTreeSelectionModel.h b/include/qtcad/QgTreeSelectionModel.h index fe419c080fe..f5e83513057 100644 --- a/include/qtcad/QgTreeSelectionModel.h +++ b/include/qtcad/QgTreeSelectionModel.h @@ -54,23 +54,8 @@ class QTCAD_EXPORT QgTreeSelectionModel : public QItemSelectionModel public slots: void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags flags) override; void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags) override; - void mode_change(int i); - void update_selected_node_relationships(const QModelIndex & index); - - // If we only need to check part of the tree (i.e. when opening a comb) - // we can supply a non-null start QgItem - void ged_selection_sync(QgItem *start, struct ged_selection_set *gs); - - // Sync GED drawn object information to QgItems, so the tree view can - // display the drawn state. If we only need to check part of the tree - // (i.e. when opening a comb) we can supply a non-null start QgItem - void ged_drawn_sync(QgItem *start, struct ged *gedp); public: - // There are a number of relationships which can be used for related - // node highlighting - this allows a client application to select one. - int interaction_mode = 0; - QgTreeView *treeview; }; diff --git a/include/qtcad/QgTreeView.h b/include/qtcad/QgTreeView.h index 8d922bee7a1..d74b539c031 100644 --- a/include/qtcad/QgTreeView.h +++ b/include/qtcad/QgTreeView.h @@ -62,8 +62,8 @@ class QTCAD_EXPORT QgTreeView : public QTreeView public slots: void tree_column_size(const QModelIndex &index); void context_menu(const QPoint &point); - void expand_path(QString path); - void expand_link(const QUrl &link); + //void expand_path(QString path); + //void expand_link(const QUrl &link); void redo_expansions(void *); void redo_highlights(); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; diff --git a/include/qtcad/QgView.h b/include/qtcad/QgView.h new file mode 100644 index 00000000000..f4a6a3e0cf2 --- /dev/null +++ b/include/qtcad/QgView.h @@ -0,0 +1,128 @@ +/* Q G V I E W . H + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgView.h + * + */ + +#ifndef QGVIEW_H +#define QGVIEW_H + +#include "common.h" + +extern "C" { +#include "bu/ptbl.h" +#include "bg/polygon.h" +#include "bv.h" +#include "dm.h" +} + +#include +#include +#include +#include +#include "qtcad/defines.h" +#include "qtcad/QgSW.h" +#ifdef BRLCAD_OPENGL +# include "qtcad/QgGL.h" +#endif + +#define QgView_AUTO 0 +#define QgView_SW 1 +#ifdef BRLCAD_OPENGL +# define QgView_GL 2 +#endif + +class QTCAD_EXPORT QgView : public QWidget +{ + Q_OBJECT + + public: + explicit QgView(QWidget *parent = nullptr, int type = 0, struct fb *fbp = NULL); + ~QgView(); + + int view_type(); + void set_current(int); + int current(); + + void stash_hashes(); // Store current dmp and v hash values + bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) + + void save_image(int quad = 0); + + bool isValid(); + + struct bview * view(); + struct dm * dmp(); + struct fb * ifp(); + + void set_view(struct bview *); + + void aet(double a, double e, double t); + + QObject *curr_event_filter = NULL; + void set_draw_custom(void (*draw_custom)(struct bview *, void *), void *draw_udata); + + // Wrappers around Qt's facility for adding eventFilter objects to + // widgets. This is how custom key binding modes are enabled and + // disabled in QgView windows. + void add_event_filter(QObject *); + + // If a filter object is supplied, remove just that filter. If NULL is + // passed in, remove all filters added using add_event_filter. Does + // not clear all event filters of any sort (i.e. internal filters used + // by Qt), just those managed using these methods. + void clear_event_filter(QObject *); + + void enableDefaultKeyBindings(); + void disableDefaultKeyBindings(); + + void enableDefaultMouseBindings(); + void disableDefaultMouseBindings(); + + signals: + void changed(QgView *); + void init_done(); + + public slots: + void need_update(unsigned long long); + void do_view_changed(); + void do_init_done(); + void set_lmouse_move_default(int); + + private: + QBoxLayout *l = NULL; + QgSW *canvas_sw = NULL; +#ifdef BRLCAD_OPENGL + QgGL *canvas_gl = NULL; +#endif + std::vector filters; +}; + +#endif /* QGVIEW_H */ + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QgViewCtrl.h b/include/qtcad/QgViewCtrl.h new file mode 100644 index 00000000000..79206c0177f --- /dev/null +++ b/include/qtcad/QgViewCtrl.h @@ -0,0 +1,110 @@ +/* Q G V I E W C T R L . H + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgViewCtrl.h + * + * Array of buttons for toggling between various view control modes. + * Provides only the buttons and the signals - must be connected up + * to an actual view widget to impact a view + */ + +#ifndef QGVIEWCTRL_H +#define QGVIEWCTRL_H + +#include "common.h" + +#include +#include +#include "ged.h" +#include "qtcad/defines.h" + +// TODO - add save scene image +// +// component picking, etc. will most likely need to be a tool - we need to +// be able to build up and manipulate selection sets, of which one is the +// active drawn set. Operations needed include clearing first hit drawn +// instances under the mouse click, adding and removing objects from +// selection sets, and creating an initial set with a rectangle selection + +class QTCAD_EXPORT QgViewCtrl : public QToolBar +{ + Q_OBJECT + + public: + QgViewCtrl(QWidget *p, struct ged *pgedp); + ~QgViewCtrl(); + + struct ged *gedp = NULL; + int icon_size = 25; + + signals: + void view_changed(unsigned long long); + void lmouse_mode(int); + + public slots: + + void sca_mode(); + void rot_mode(); + void tra_mode(); + void center_mode(); + + void fbclear_cmd(); + + void fb_mode_cmd(); + + void do_view_update(unsigned long long); + + // Unlike the other commands, the raytrace button + // has to reflect a potentially long-running state - + // that of the child rt process Consequently the + // icon controls need to be independent of the command + // execution logic. + void raytrace_cmd(); + void raytrace_start(int); + void raytrace_done(int); + + public: + // Left mouse behavior controls (when not using a tool or editing) + QAction *sca; + QAction *rot; + QAction *tra; + QAction *center; + + // Raytrace/framebuffer controls + QAction *raytrace; + QAction *fb_mode; + QAction *fb_clear; + + private: + bool raytrace_running = false; + int pid = -1; +}; + + +#endif //QGVIEWCTRL_H + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/include/qtcad/QtAppExecDialog.h b/include/qtcad/QtAppExecDialog.h deleted file mode 100644 index 3abafc0e265..00000000000 --- a/include/qtcad/QtAppExecDialog.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Q T A P P E X E C D I A L O G . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file cadappexec.h - * - * Support for running console programs and viewing the output stream - * in a dialog window. - * - */ - -#ifndef QTAPPEXECDIALOG_H -#define QTAPPEXECDIALOG_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qtcad/defines.h" -#include "qtcad/QtConsole.h" - -class QTCAD_EXPORT QtAppExecDialog : public QDialog -{ - Q_OBJECT - - public: - QtAppExecDialog(QWidget *pparent, QString executable, QStringList args, QString lfile = ""); - ~QtAppExecDialog() {} - - public slots: - void read_stdout(); - void read_stderr(); - void process_abort(); - void process_done(int, QProcess::ExitStatus); - - public: - QFile *logfile; - QtConsole *console; - QProcess *proc; - QDialogButtonBox *buttonBox; -}; - -#endif // QTAPPEXECDIALOG_H - -/* - * Local Variables: - * mode: C++ - * tab-width: 8 - * c-basic-offset: 4 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/include/qtcad/QtCADQuad.h b/include/qtcad/QtCADQuad.h deleted file mode 100644 index e29ec1eaa4b..00000000000 --- a/include/qtcad/QtCADQuad.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Q T G L Q U A D . H - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtGLQuad.h - * - */ - -#ifndef QTCADQUAD_H -#define QTCADQUAD_H - -#include "common.h" - -#include - -extern "C" { -#include "bu/ptbl.h" -#include "bv.h" -#include "dm.h" -} - -#include "qtcad/defines.h" -#include "qtcad/QtCADView.h" - -// Abbreviations: -// -// ur == 0 == Upper Right Quadrant -// ul == 1 == Upper Left Quadrant -// ll == 2 == Lower Left Quadrant -// lr == 3 == Lower Right Quadrant - -#define UPPER_RIGHT_QUADRANT 0 -#define UPPER_LEFT_QUADRANT 1 -#define LOWER_LEFT_QUADRANT 2 -#define LOWER_RIGHT_QUADRANT 3 - -class QTCAD_EXPORT QtCADQuad : public QWidget -{ - Q_OBJECT - - public: - explicit QtCADQuad(QWidget *parent, struct ged *gedpRef, int type); - ~QtCADQuad(); - - void stash_hashes(); // Store current dmp and v hash values - bool diff_hashes(); // Set dmp dirty flags if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) - - bool isValid(); - void fallback(); - - void default_views(); // Set the aet of the four quadrants to their standard defaults. - QtCADView *get(int quadrant_num = UPPER_RIGHT_QUADRANT); - struct bview * view(int quadrant_id = UPPER_RIGHT_QUADRANT); - - void select(int quadrant_num); - void select(const char *id); // valid inputs: ur, ul, ll and lr - int get_selected(); // returns UPPER_RIGHT_QUADRANT, UPPER_LEFT_QUADRANT, LOWER_LEFT_QUADRANT, or LOWER_RIGHT_QUADRANT - - void changeToSingleFrame(); - void changeToQuadFrame(); - void changeToResizeableQuadFrame(); - - void enableDefaultKeyBindings(); - void disableDefaultKeyBindings(); - - void enableDefaultMouseBindings(); - void disableDefaultMouseBindings(); - - signals: - void changed(QtCADView *); - void selected(QtCADView *); - void init_done(); - - public slots: - void do_view_update(unsigned long long); - void do_view_changed(); - void do_init_done(); - void set_lmouse_move_default(int); - - private: - bool eventFilter(QObject*, QEvent*); - QtCADView *createView(unsigned int index); - QGridLayout *createLayout(); - - int graphicsType = QtCADView_SW; - // Holds up to 4 views in single view only the first view is constructed - // The other views are constructed if quad view mode is selected by the user - QtCADView *views[4] = {nullptr, nullptr, nullptr, nullptr}; - QtCADView *currentView; - // We need to hang on to this because we don't create the other quad views until the user switches mode - struct ged *gedp; - - // Hang on to these pointers so when we need to clean up memory we have them - QGridLayout *currentLayout = nullptr; - QSpacerItem *spacerTop = nullptr; - QSpacerItem *spacerBottom = nullptr; - QSpacerItem *spacerLeft = nullptr; - QSpacerItem *spacerRight = nullptr; - QSpacerItem *spacerCenter = nullptr; - - // Flag for initializations of sub-widgets - bool init_done_flag = false; -}; - -#endif /* QTCADQUAD_H */ - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/qtcad/QtCADView.h b/include/qtcad/QtCADView.h deleted file mode 100644 index 57def6f98f3..00000000000 --- a/include/qtcad/QtCADView.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Q T C A D V I E W . H - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtCADView.h - * - */ - -#ifndef QTCADVIEW_H -#define QTCADVIEW_H - -#include "common.h" - -extern "C" { -#include "bu/ptbl.h" -#include "bv.h" -#include "dm.h" -} - -#include -#include -#include -#include "qtcad/defines.h" -#include "qtcad/QtSW.h" -#ifdef BRLCAD_OPENGL -# include "qtcad/QtGL.h" -#endif - -#define QtCADView_AUTO 0 -#define QtCADView_SW 1 -#ifdef BRLCAD_OPENGL -# define QtCADView_GL 2 -#endif - -class QTCAD_EXPORT QtCADView : public QWidget -{ - Q_OBJECT - - public: - explicit QtCADView(QWidget *parent = nullptr, int type = 0, struct fb *fbp = NULL); - ~QtCADView(); - - int view_type(); - void set_current(int); - int current(); - - void stash_hashes(); // Store current dmp and v hash values - bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) - - void save_image(int quad = 0); - - bool isValid(); - void fallback(); - - void select(int quad); - - struct bview * view(); - struct dm * dmp(); - struct fb * ifp(); - double base2local(); - double local2base(); - - void set_view(struct bview *, int quad = 1); - void set_dmp(struct dm *, int quad = 1); - void set_dm_current(struct dm **, int quad = 1); - void set_ifp(struct fb *, int quad = 1); - void set_base2local(double); - void set_local2base(double); - - void aet(double a, double e, double t); - - QObject *curr_event_filter = NULL; - void set_draw_custom(void (*draw_custom)(struct bview *, double, double, void *), void *draw_udata); - - void add_event_filter(QObject *); - void clear_event_filter(QObject *); - - void enableDefaultKeyBindings(); - void disableDefaultKeyBindings(); - - void enableDefaultMouseBindings(); - void disableDefaultMouseBindings(); - - signals: - void changed(); - void init_done(); - - public slots: - void need_update(unsigned long long); - void do_view_changed(); - void do_init_done(); - void set_lmouse_move_default(int); - - private: - QBoxLayout *l = NULL; - QtSW *canvas_sw = NULL; -#ifdef BRLCAD_OPENGL - QtGL *canvas_gl = NULL; -#endif -}; - -#endif /* QTCADVIEW_H */ - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/qtcad/QtConsole.h b/include/qtcad/QtConsole.h deleted file mode 100644 index 9da5e000470..00000000000 --- a/include/qtcad/QtConsole.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc. - All rights reserved. - * - * Sandia National Laboratories, New Mexico PO Box 5800 Albuquerque, NM 87185 - * - * Kitware Inc. - * 28 Corporate Drive - * Clifton Park, NY 12065 - * USA - * - * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license - * for use of this work by or on behalf of the U.S. Government. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Kitware nor the names of any contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - * This widget is based off of ParaView's pqConsoleWidget - */ - -#ifndef QTCAD_CONSOLE_H -#define QTCAD_CONSOLE_H - -#include "common.h" - -#include -#include -#include -#include -#include - -#include "ged.h" -#include "qtcad/defines.h" -#include "qtcad/QtConsoleListener.h" - -class QTCAD_EXPORT QtConsoleWidgetCompleter : public QCompleter -{ -public: - /** - * Update the completion model given a string. The given string - * is the current console text between the cursor and the start of - * the line. - */ - virtual void updateCompletionModel(const QString& str) = 0; -}; - -/* Completion class specific to GED command line */ -class QTCAD_EXPORT GEDShellCompleter : public QtConsoleWidgetCompleter -{ -public: - GEDShellCompleter(QWidget *p, struct ged *ged_ptr); - void updateCompletionModel(const QString& console_txt) override; - struct ged *gedp = NULL; -}; - -/** - Qt widget that provides an interactive console - you can send text to the - console by calling printString() and receive user input by connecting to the - executeCommand() slot. - - Note: Qt's signals and slots mechanism helps to make a robust widget for - multithreaded inputs, since input strings to the console are coming in via - signals and written by slots. Users should not attempt to manipulate the - underlying QPlainTextEdit widget directly. -*/ -class QTCAD_EXPORT QtConsole : public QWidget -{ - Q_OBJECT - -public: - QtConsole(QWidget* Parent); - virtual ~QtConsole(); - - /// Returns the current font - QFont getFont(); - /// Sets current font - void setFont(const QFont &font); - - /// Set a completer for this console widget - void setCompleter(QtConsoleWidgetCompleter* completer); - - QPoint getCursorPosition(); - - // combine multiple history lines and replace them with the combination - bool consolidateHistory(size_t start, size_t end); - size_t historyCount(); - std::string historyAt(size_t ind); - - void listen(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d); - std::map, QConsoleListener *> listeners; - - // When inserting a completion, need a setting to control - // how we handle slashes - int split_slash = 0; - -signals: - /// Signal emitted whenever the user enters a command - void executeCommand(const QString& cmd); - - /// Signal that there is queued, unprinted buffer output - void queued_log(const QString& Text); - -public slots: - /// Writes the supplied text to the console - void printString(const QString& Text); - - /// Writes the supplied text to the console - void printStringBeforePrompt(const QString& Text); - - /// Clears a listener (called by the listener's finished() signal) - void detach(struct ged_subprocess *p, int t); - - /// Updates the current command. Unlike printString, this will affect the - /// current command being typed. - void printCommand(const QString& cmd); - - /// Clears the contents of the console - void clear(); - - /// Puts out an input accepting prompt. - /// It is recommended that one uses prompt instead of printString() to print - /// an input prompt since this call ensures that the prompt is shown on a new - /// line. - void prompt(const QString& text); - - /// Inserts the given completion string at the cursor. This will replace - /// the current word that the cursor is touching with the given text. - /// Determines the word using QTextCursor::StartOfWord, EndOfWord. - void insertCompletion(const QString& text); - -private: - QtConsole(const QtConsole&); - QtConsole& operator=(const QtConsole&); - - // Used by printStringBeforePrompt to queue up a timed repetition of printing - // to catch anything recently added but not subsequently printed successfully - // by an event based trigger. Avoids output getting "stuck" in the buffer - // waiting for an event. Noticed when rt instances are lingering but not - // closed and typing heavily on the command prompt - the last line or two of - // rt output sometimes weren't printed under those conditions until the - // window was closed. - void emit_queued() { - QString estring(""); - Q_EMIT queued_log(estring); - } - - QString prompt_str; - int prompt_start = 0; - int64_t log_timestamp = 0; - QString logbuf; - - void internalExecuteCommand(const QString& Command); - - class pqImplementation; - pqImplementation* const Implementation; - friend class pqImplementation; -}; - - -#endif // !QTCAD_CONSOLE_H - diff --git a/include/qtcad/QtGL.h b/include/qtcad/QtGL.h deleted file mode 100644 index c2f9e360cc4..00000000000 --- a/include/qtcad/QtGL.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Q T G L . H - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file qtgl.h - * - */ - -#ifndef QTGL_H -#define QTGL_H - -#include "common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "bu/ptbl.h" -#include "bv.h" -#define DM_WITH_RT -#include "dm.h" -} - -#include "qtcad/defines.h" - -// Use QOpenGLFunctions so we don't have to prefix all OpenGL calls with "f->" -class QTCAD_EXPORT QtGL : public QOpenGLWidget, protected QOpenGLFunctions -{ - Q_OBJECT - - public: - explicit QtGL(QWidget *parent = nullptr, struct fb *fbp = NULL); - ~QtGL(); - - void stash_hashes(); // Store current dmp and v hash values - bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) - - void aet(double a, double e, double t); - void save_image(); - - int current = 1; - struct bview *v = NULL; - struct dm *dmp = NULL; - struct fb *ifp = NULL; - struct bu_ptbl *dm_set = NULL; - struct dm **dm_current = NULL; - - void (*draw_custom)(struct bview *, double, double, void *) = NULL; - void *draw_udata = NULL; - - void enableDefaultKeyBindings(); - void disableDefaultKeyBindings(); - - void enableDefaultMouseBindings(); - void disableDefaultMouseBindings(); - - signals: - void changed(); - void init_done(); - - public slots: - void need_update(); - void set_lmouse_move_default(int); - - protected: - void paintGL() override; - void resizeGL(int w, int h) override; - - void keyPressEvent(QKeyEvent *k) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - - private: - unsigned long long prev_dhash = 0; - unsigned long long prev_vhash = 0; - - bool use_default_keybindings = true; - bool use_default_mousebindings = true; - int lmouse_mode = BV_SCALE; - - bool m_init = false; - int x_prev = -INT_MAX; - int y_prev = -INT_MAX; - double x_press_pos = -INT_MAX; - double y_press_pos = -INT_MAX; -}; - -#endif /* QTGL_H */ - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/qtcad/QtSW.h b/include/qtcad/QtSW.h deleted file mode 100644 index c3042a9e42d..00000000000 --- a/include/qtcad/QtSW.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Q T S W . H - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file qtcad/QtSW.h - * - * This defines a Qt widget for displaying the visualization results of the - * bundled libosmesa OpenGL software rasterizer, using the swrast libdm - * backend. - * - * Unlike the standard QtGL widget, this can display OpenGL rendered graphics - * even if the OpenGL stack on the host operating system is non-functional (it - * will be a great deal slower, but since it does not rely on any system - * capabilities to produce its images it should work in any environment where a - * basic Qt gui can load.) - */ - -#ifndef QTCAD_QTSW_H -#define QTCAD_QTSW_H - -#include "common.h" - -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "bu/ptbl.h" -#include "bv.h" -#define DM_WITH_RT -#include "dm.h" -} - -#include "qtcad/defines.h" - -class QTCAD_EXPORT QtSW : public QWidget -{ - Q_OBJECT - - public: - explicit QtSW(QWidget *parent = nullptr, struct fb *fbp = NULL); - ~QtSW(); - - void stash_hashes(); // Store current dmp and v hash values - bool diff_hashes(); // Set dmp dirty flag if current hashes != stashed hashes. (Does not update stored hash values - use stash_hashes for that operation.) - - void save_image(); - - void aet(double a, double e, double t); - - int current = 1; - struct bview *v = NULL; - struct dm *dmp = NULL; - struct fb *ifp = NULL; - struct bu_ptbl *dm_set = NULL; - struct dm **dm_current = NULL; - - void (*draw_custom)(struct bview *, double, double, void *) = NULL; - void *draw_udata = NULL; - - void enableDefaultKeyBindings(); - void disableDefaultKeyBindings(); - - void enableDefaultMouseBindings(); - void disableDefaultMouseBindings(); - - signals: - void changed(); - void init_done(); - - public slots: - void need_update(); - void set_lmouse_move_default(int); - - protected: - void paintEvent(QPaintEvent *e) override; - void resizeEvent(QResizeEvent *e) override; - - void keyPressEvent(QKeyEvent *k) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - - private: - unsigned long long prev_dhash = 0; - unsigned long long prev_vhash = 0; - - bool use_default_keybindings = true; - bool use_default_mousebindings = true; - int lmouse_mode = BV_SCALE; - - bool m_init = false; - int x_prev = -INT_MAX; - int y_prev = -INT_MAX; - double x_press_pos = -INT_MAX; - double y_press_pos = -INT_MAX; -}; - -#endif /* QTCAD_QTSW_H */ - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/qtcad/SignalFlags.h b/include/qtcad/SignalFlags.h deleted file mode 100644 index 44b58b21fb7..00000000000 --- a/include/qtcad/SignalFlags.h +++ /dev/null @@ -1,100 +0,0 @@ -/* S I G N A L F L A G S . H - * BRL-CAD - * - * Copyright (c) 2022-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file SignalFlags.h - * - * Qt uses a signals/slots mechanism to communicate when (for example) - * application UI elements need to update in response to data changes. - * However, it is very easy to set up a nest of complicated connections that - * can trigger feedback loops or just make the logic very difficult to debug. - * - * To keep things manageable, we define a couple of conventions for Qt widgets - * to use when defining "public facing" signals and slots that have - * implications beyond their own internal display logic: - * - * 1. An application will provide a view_update signal, which the application - * itself will connect to the slots of whatever view widgets need to execute - * the updates. Subcomponents shouldn't directly connect to other subcomponent - * view update signals - they should instead rely on the signal from the - * application. - * - * 2. The application will provide a do_view_changed slot, whose - * responsibility is to issue a view_update signal in response to signals of - * view changes from widgets. The application should connect the view_changed - * signal to from any widgets that potentially have an impact on the view to - * this slot. - * - * 3. The widgets will provide a view_changed signal, which is emitted by the - * widget when something happens that requires view updates to be triggered in - * other widgets. This signal is connected by the app to the app's - * do_view_changed slot - * - * 4. The widgets will provide a do_view_update slot, which is connected by - * the application to the app's view_update signal. The do_view_update slot - * does the work of updating the widget in response to the view_update signal. - * It should NEVER emit a view_changed signal either directly or indirectly - * (i.e. by calling other methods) to avoid setting up infinite loops. - * - * This results in some widget logic feeling a bit indirect - the "do the data - * setup" part of a widget must be separated from the "update my component - * graphical widgets to reflect the data" logic, and will only function - * "properly" when hooked up to a parent application that accepts its - * view_changed signal and turns around to call the widget's do_view_update - * slot. This is simply a reflection of the reality that many (most?) BRL-CAD - * Qt widgets must also be responsive not simply to their own graphical - * updates, but to GED command line induced data changes and/or model state - * changes induced by other widgets. Without this separation and connections, - * widgets will get "out of sync" with other parts of the interface. - * - * Because not all view updates have similar consequences (a removal of a - * database object from the drawn scene, for example, requires treeview updates - * to reflect drawn status changes. However, a rotation around the model - * changes only the view matrix, and requires updating only of the central - * display widget.) To reflect this, without requiring lots of separate signal - * connections, a flag is passed between the various view signals and slots. - * Widgets can set various values of the flags, and by checking those flags - * will know if a particular view update signal requires them to update their - * aspect of the user interface. (Some updates may be a bit resource intensive - * if they require full processing of a large geometry file's data, so we want - * to be able to exercise some discretion on what work we do when. - * - * We make these defines in this header file so all widgets and applications - * can share a common, mutually understood convention. - */ - -#include "common.h" - -#ifndef SIGNAL_FLAGS_H - -#define QTCAD_VIEW_REFRESH 0x00000001 // Potential camera updates, no structural changes -#define QTCAD_VIEW_DRAWN 0x00000002 // Used when what is drawn in the scene changes -#define QTCAD_VIEW_SELECT 0x00000004 // Used when what is selected changes -#define QTCAD_VIEW_MODE 0x00000008 // Used when mode-aware highlighting or drawing changes -#define QTCAD_VIEW_DB 0x00000010 // Used when .g database content changes - -#endif // SIGNAL_FLAGS_H -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/include/qtcad/defines.h b/include/qtcad/defines.h index 85018dff3bc..994aba87da5 100644 --- a/include/qtcad/defines.h +++ b/include/qtcad/defines.h @@ -50,6 +50,42 @@ * it is found use this */ #define CADTREE_RECURSION_LIMIT 10000 +// Uncomment to allow the env command to enable printouts +// reporting on when libqtcad slots are being called +#include "bu/log.h" +#include "bu/str.h" +#define QTCAD_SUPPORT_ENV_SLOT_REPORTING 1 +#ifdef QTCAD_SUPPORT_ENV_SLOT_REPORTING +# define QTCAD_SLOT(slot_name, level) {\ + const char *qrsig = getenv("QTCAD_REPORT_SLOTS");\ + if (qrsig) {\ + int qlev = atoi(qrsig);\ + if (qlev == level) {\ + bu_log("%s\n", slot_name); \ + } \ + }\ +} +#else +# define QTCAD_SLOT(slot_name, level) +#endif + +// Uncomment to allow the env command to enable printouts +// reporting on when libqtcad events are being called +#define QTCAD_SUPPORT_ENV_EVENT_REPORTING 1 +#ifdef QTCAD_SUPPORT_ENV_EVENT_REPORTING +# define QTCAD_EVENT(event_name, level) {\ + const char *qrsig = getenv("QTCAD_REPORT_EVENTS");\ + if (qrsig) {\ + int qlev = atoi(qrsig);\ + if (qlev == level) {\ + bu_log("%s\n", event_name); \ + } \ + }\ +} +#else +# define QTCAD_EVENT(event_name, level) +#endif + #endif /* QTCAD_DEFINES_H */ /* diff --git a/include/qtcad/gInstance.h b/include/qtcad/gInstance.h deleted file mode 100644 index 4e2526cb2f0..00000000000 --- a/include/qtcad/gInstance.h +++ /dev/null @@ -1,115 +0,0 @@ -/* G I N S T A N C E . H - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file gInstance.h - * - * A gInstance corresponds - * to one unique parent+bool_op+matrix+child instance in a .g combination tree, - * - * gInstances are created to reflect the .g database state, and they are what - * is updated as a direct consequence of callbacks registered with the low - * level database I/O routines. - */ - -#ifndef GINSTANCE_H -#define GINSTANCE_H - -#include -#include -#include -#include - -#include "qtcad/defines.h" - -#ifndef Q_MOC_RUN -#include "raytrace.h" -#include "ged.h" -#endif - -class QTCAD_EXPORT gInstance -{ - public: - explicit gInstance(struct directory *idp, struct db_i *idbip); - ~gInstance(); - - // Debugging function for printing out data in container - std::string print(); - - // Report if the instance has children - bool has_children(); - - // Return hashes of child instances, if any - std::vector children(std::unordered_map *instances); - - // This is a flag that may be set or unset by parent applications. - // Used primarily to assist in visual identification of components - // in hierarchical structures. Not part of any hash calculations. - int active_flag = 0; - - // gInstance content based hash for quick lookup/comparison of two - // gInstances. - unsigned long long hash = 0; - - // dp of parent comb (NULL for tops objects) - struct directory *parent = NULL; - // dp of comb instance (NULL for instances with invalid object names) - struct directory *dp = NULL; - // dbip associated with this instance - struct db_i *dbip = NULL; - // instance name as string - std::string dp_name; - // instance boolean operation incorporating it into the comb tree (u/-/+) - db_op_t op = DB_OP_NULL; - // Matrix above comb instance in comb tree (default is IDN) - mat_t c_m; - - // Position in comb tree - intent is to be able to use this number in - // a GED command to look up an exact comb tree instance, i.e.: - // - // /comb1/comb2@3/comb3/comb4/obj.s@5 - // - // The idea would be that in each string there is an implicit @0 after - // each specifier, and IFF we need to distinguish others, we can add - // the explicit @ specifier - int icnt = 0; -}; - -// Given a dbip, construct or find the instances associated with it and add them -// to the containers. The instances maps may contain previous gInstances created -// by earlier passes, and if they are still valid they will be reused. Any gInstances -// that are no longer valid will be removed from the maps and deleted. -QTCAD_EXPORT extern void -sync_instances( - std::unordered_map *tops_instances, - std::unordered_map *instances, - struct db_i *dbip, - int flatten); - - -#endif //GINSTANCE_H - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/include/raytrace.h b/include/raytrace.h index 9f5f51240f6..384bc613fe4 100644 --- a/include/raytrace.h +++ b/include/raytrace.h @@ -178,6 +178,8 @@ __BEGIN_DECLS #include "./rt/binunif.h" +#include "./rt/conv.h" + #include "./rt/version.h" diff --git a/include/rt/CMakeLists.txt b/include/rt/CMakeLists.txt index 8356db948d6..dfb1a52d9c5 100644 --- a/include/rt/CMakeLists.txt +++ b/include/rt/CMakeLists.txt @@ -9,6 +9,7 @@ set(rt_headers calc.h cmd.h comb.h + conv.h db4.h db5.h db_attr.h diff --git a/include/rt/conv.h b/include/rt/conv.h new file mode 100644 index 00000000000..63872645b94 --- /dev/null +++ b/include/rt/conv.h @@ -0,0 +1,61 @@ +/* C O N V . H + * BRL-CAD + * + * Copyright (c) 1993-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file rt/conv.h */ + +#ifndef RT_CONV_H +#define RT_CONV_H + +#include "common.h" +#include "bu/list.h" +#include "bn/tol.h" +#include "rt/defines.h" +#include "rt/db_internal.h" +#include "rt/resource.h" +#include "nmg.h" + +__BEGIN_DECLS + +RT_EXPORT extern union tree *rt_booltree_leaf_tess(struct db_tree_state *tsp, + const struct db_full_path *pathp, + struct rt_db_internal *ip, + void *client_data); + +RT_EXPORT extern union tree *rt_booltree_evaluate(union tree *tp, + struct bu_list *vlfree, + const struct bn_tol *tol, + struct resource *resp, + int (*do_bool)(union tree *, union tree *, union tree *, int op, struct bu_list *, const struct bn_tol *, void *), + int verbose, + void *data + ); + +__END_DECLS + +#endif /* RT__CONV_H */ + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/include/rt/defines.h b/include/rt/defines.h index 449ec914ffe..676c3a60308 100644 --- a/include/rt/defines.h +++ b/include/rt/defines.h @@ -70,6 +70,12 @@ #include "bg/defines.h" +/* The most modern version of the .g database format. + * Code wanting to create the newest database format + * should use this define rather than hard coding the + * current latest format */ +#define BRLCAD_DB_FORMAT_LATEST 5 + /* * Values for Solid ID. */ diff --git a/include/rt/mater.h b/include/rt/mater.h index 4856e571815..f496f2e6318 100644 --- a/include/rt/mater.h +++ b/include/rt/mater.h @@ -48,8 +48,8 @@ struct mater_info { #define RT_MATER_INFO_INIT_IDN { {1.0, 0.0, 0.0} , -1.0, 0, 0, 0, NULL } struct mater { - short mt_low; /**< @brief bounds of region IDs, inclusive */ - short mt_high; + long mt_low; /**< @brief bounds of region IDs, inclusive */ + long mt_high; unsigned char mt_r; /**< @brief color */ unsigned char mt_g; unsigned char mt_b; diff --git a/include/rt/nmg_conv.h b/include/rt/nmg_conv.h index e527c8b9ab3..e56ad337912 100644 --- a/include/rt/nmg_conv.h +++ b/include/rt/nmg_conv.h @@ -166,10 +166,6 @@ RT_EXPORT extern struct rt_bot_internal *nmg_mdl_to_bot(struct model *m, struct bu_list *vlfree, const struct bn_tol *tol); struct db_tree_state; /* forward declaration */ -RT_EXPORT extern union tree *nmg_booltree_leaf_tess(struct db_tree_state *tsp, - const struct db_full_path *pathp, - struct rt_db_internal *ip, - void *client_data); RT_EXPORT extern union tree *nmg_booltree_leaf_tnurb(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, diff --git a/include/rt/op.h b/include/rt/op.h index 84cc54f1508..13473daa043 100644 --- a/include/rt/op.h +++ b/include/rt/op.h @@ -46,7 +46,7 @@ __BEGIN_DECLS #define OP_NOT MKOP(8) /**< @brief Unary: not L */ #define OP_GUARD MKOP(9) /**< @brief Unary: not L, or else! */ #define OP_XNOP MKOP(10) /**< @brief Unary: L, mark region */ -#define OP_NMG_TESS MKOP(11) /**< @brief Leaf: tr_stp -> nmgregion */ +#define OP_TESS MKOP(11) /**< @brief Leaf: tr_d -> evaluated tessellation result */ /* LIBWDB import/export interface to combinations */ #define OP_DB_LEAF MKOP(12) /**< @brief Leaf of combination, db fmt */ #define OP_FREE MKOP(13) /**< @brief Unary: L has free chain */ diff --git a/include/rt/primitives/brep.h b/include/rt/primitives/brep.h index 1b5937c2ae6..73dbabd20a5 100644 --- a/include/rt/primitives/brep.h +++ b/include/rt/primitives/brep.h @@ -40,7 +40,7 @@ RT_EXPORT extern int rt_brep_plot(struct bu_list *vhead, const struct bn_tol *tol, const struct bview *info); RT_EXPORT extern int rt_brep_plot_poly(struct bu_list *vhead, - const struct db_full_path *pathp, + const struct directory *dp, struct rt_db_internal *ip, const struct bg_tess_tol *ttol, const struct bn_tol *tol, diff --git a/include/rt/primitives/sketch.h b/include/rt/primitives/sketch.h index 6860f3cee99..c0a0e631cf6 100644 --- a/include/rt/primitives/sketch.h +++ b/include/rt/primitives/sketch.h @@ -63,7 +63,7 @@ RT_EXPORT extern int curve_to_tcl_list(struct bu_vls *vls, struct rt_curve *crv); RT_EXPORT extern struct bv_scene_obj * -db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *dp, struct bview *sv); +db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *dp, struct bview *sv, int flags); RT_EXPORT extern struct directory * db_scene_obj_to_sketch(struct db_i *dbip, const char *sname, struct bv_scene_obj *s); diff --git a/include/rt/tree.h b/include/rt/tree.h index 99b674a9d47..e317fcf43c6 100644 --- a/include/rt/tree.h +++ b/include/rt/tree.h @@ -166,11 +166,12 @@ union tree { struct region *tc_pad; /**< @brief unused */ struct combined_tree_state *tc_ctsp; } tr_c; - struct tree_nmgregion { + struct tree_tessellation { uint32_t magic; - int td_op; /**< @brief leaf, OP_NMG_TESS */ + int td_op; /**< @brief leaf, OP_TESS */ const char *td_name; /**< @brief If non-null, dynamic string describing heritage of this region */ struct nmgregion *td_r; /**< @brief ptr to NMG region */ + void *td_d; /**< @brief tessellation related data */ } tr_d; struct tree_db_leaf { uint32_t magic; diff --git a/include/tclcad.h b/include/tclcad.h index 8fb3f82560e..0bd73f7a9ec 100644 --- a/include/tclcad.h +++ b/include/tclcad.h @@ -34,15 +34,12 @@ #include "common.h" -__BEGIN_DECLS #include "tclcad/defines.h" #include "tclcad/draw.h" #include "tclcad/misc.h" #include "tclcad/setup.h" -__END_DECLS - #endif /* TCLCAD_H */ /** @} */ /* diff --git a/include/vmath.h b/include/vmath.h index c73c78cf673..d5fd9a1ce12 100644 --- a/include/vmath.h +++ b/include/vmath.h @@ -2053,20 +2053,6 @@ typedef enum vmath_matrix_component_ { (_lo1)[Y] >= (_lo2)[Y] && (_hi1)[Y] <= (_hi2)[Y] && \ (_lo1)[Z] >= (_lo2)[Z] && (_hi1)[Z] <= (_hi2)[Z]) -/** Convert an azimuth/elevation to a direction vector. */ -#define V3DIR_FROM_AZEL(_d, _a, _e) do { \ - fastf_t _c_e = cos(_e); \ - (_d)[X] = cos(_a) * _c_e; \ - (_d)[Y] = sin(_a) * _c_e; \ - (_d)[Z] = sin(_e); \ - } while (0) - -/** Convert a direction vector to azimuth/elevation (in radians). */ -#define AZEL_FROM_V3DIR(_a, _e, _d) do { \ - (_a) = ((NEAR_ZERO((_d)[X], SMALL_FASTF)) && (NEAR_ZERO((_d)[Y], SMALL_FASTF))) ? 0.0 : atan2(-((_d)[Y]), -((_d)[X])) * -RAD2DEG; \ - (_e) = atan2(-((_d)[Z]), sqrt((_d)[X]*(_d)[X] + (_d)[Y]*(_d)[Y])) * -RAD2DEG; \ - } while (0) - /** Swap two 3D vectors */ #define VSWAP(_a, _b) do { \ diff --git a/misc/CMake/BRLCAD_ExternalDeps.cmake b/misc/CMake/BRLCAD_ExternalDeps.cmake new file mode 100644 index 00000000000..a6bad371e8a --- /dev/null +++ b/misc/CMake/BRLCAD_ExternalDeps.cmake @@ -0,0 +1,1119 @@ +# B R L C A D _ E X T E R N A L D E P S . C M A K E +# BRL-CAD +# +# Copyright (c) 2023 United States Government as represented by +# the U.S. Army Research Laboratory. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# Logic to set up third party dependences (either system installed +# versions or prepared local versions to be bundled with BRL-CAD.) + +# When we need to have CMake treat includes as system paths to avoid warnings, +# we add those patterns to the SYS_INCLUDE_PATTERNS list +mark_as_advanced(SYS_INCLUDE_PATTERNS) + + +if (NOT EXISTS "${BRLCAD_EXT_INSTALL_DIR}") + message(WARNING "BRLCAD_EXT_INSTALL_DIR is set to ${BRLCAD_EXT_INSTALL_DIR} but that location does not exist. This will result in only system libraries being used for compilation, with no external dependencies being bundled into installers.") +endif (NOT EXISTS "${BRLCAD_EXT_INSTALL_DIR}") + +if (NOT EXISTS "${BRLCAD_EXT_NOINSTALL_DIR}") + message(WARNING "BRLCAD_EXT_NOINSTALL_DIR is set to ${BRLCAD_EXT_NOINSTALL_DIR} but that location does not exist. This means BRL-CAD's build will be dependent on system versions of build tools such as patchelf and astyle being present.") +endif (NOT EXISTS "${BRLCAD_EXT_NOINSTALL_DIR}") + +# If we got to ${BRLCAD_EXT_DIR}/install through a symlink, we need to expand it so +# we can spot the path that would have been used in ${BRLCAD_EXT_DIR}/install files +# +# TODO - once we can require CMake 3.21 minimum, add EXPAND_TILDE to +# the arguments list +file(REAL_PATH "${BRLCAD_EXT_INSTALL_DIR}" BRLCAD_EXT_DIR_REAL) + + +# See if we have plief available for rpath manipulation. If it is available, +# we will be using it to manage the RPATH settings for third party exe/lib +# files. If not, see if patchelf is available instead. +find_program(P_RPATH_EXECUTABLE NAMES plief HINTS ${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}) +if (NOT P_RPATH_EXECUTABLE) + find_program(P_RPATH_EXECUTABLE NAMES patchelf HINTS ${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}) +endif (NOT P_RPATH_EXECUTABLE) + +# Find the tool we use to scrub EXT paths from files +find_program(STRCLEAR_EXECUTABLE strclear HINTS ${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}) + + +# For repeat configure passes, we need to check any existing files copied +# against the ${BRLCAD_EXT_DIR}/install dir's contents, to detect if the latter has changed +# and we need to redo the process. +set(TP_INVENTORY "${CMAKE_BINARY_DIR}/CMakeFiles/thirdparty.txt") +set(TP_INVENTORY_BINARIES "${CMAKE_BINARY_DIR}/CMakeFiles/thirdparty_binaries.txt") + + +# These patterns are used to identify sets of files where we are assuming we +# don't need to do post-processing to correct file paths from the external +# install. +set(NOPROCESS_PATTERNS + ".*/encodings/.*" + ".*/include/.*" + ".*/man/.*" + ".*/msgs/.*" + ) + +# These patterns are to be excluded from ${BRLCAD_EXT_DIR}/install bundling - i.e., even if +# present in the specified ${BRLCAD_EXT_DIR}/install directory, BRL-CAD will not incorporate +# them. Generally speaking this is used to avoid files needed for external +# building but counterproductive in the BRL-CAD install. +set(EXCLUDED_PATTERNS + ${LIB_DIR}/itcl4.2.3/itclConfig.sh + ${LIB_DIR}/tclConfig.sh + ${LIB_DIR}/tdbc1.1.5/tdbcConfig.sh + ${LIB_DIR}/tkConfig.sh + ) + + +##################################################################### +# Utility functions for use when processing ${BRLCAD_EXT_DIR}/install files +##################################################################### + + +# In multiconfig we need to scrub excluded files out of multiple ${BRLCAD_EXT_DIR}/install +# copies, so wrap logic to do so into a function. +function(STRIP_EXCLUDED RDIR EXPATTERNS) + foreach (ep ${${EXPATTERNS}}) + file(GLOB_RECURSE MATCHING_FILES LIST_DIRECTORIES false RELATIVE "${RDIR}" "${RDIR}/${ep}") + foreach(rf ${MATCHING_FILES}) + file(REMOVE "${RDIR}/${rf}") + if (EXISTS ${RDIR}/${rf}) + message(FATAL_ERROR "Removing ${RDIR}/${rf} failed") + endif (EXISTS ${RDIR}/${rf}) + endforeach(rf ${MATCHING_FILES}) + endforeach (ep ${${EXPATTERNS}}) +endfunction(STRIP_EXCLUDED) + + + +# See if a file matches a pattern to skip its processing +# Sets the variable held in SVAR in the parent scope +function(SKIP_PROCESSING tf SVAR) + if (IS_SYMLINK ${tf}) + set(${SVAR} 1 PARENT_SCOPE) + return() + endif (IS_SYMLINK ${tf}) + foreach (skp ${NOPROCESS_PATTERNS}) + if ("${tf}" MATCHES "${skp}") + set(${SVAR} 1 PARENT_SCOPE) + return() + endif ("${tf}" MATCHES "${skp}") + endforeach (skp ${NOPROCESS_PATTERNS}) + set(${SVAR} 0 PARENT_SCOPE) +endfunction(SKIP_PROCESSING) + + +# Since the checking process can be long, we want some sort +# of feedback indicating we're progressing +function(BFILE_TYPE_MSG ALL_CNT ALL_PROCESSED BINARY_LIST) + list(LENGTH ${BINARY_LIST} BCNT) + if (BCNT) + math(EXPR skip_msg "${BCNT} % 100") + if (${skip_msg} EQUAL 0) + message("Found ${BCNT} shared object or executable files (characterized ${ALL_PROCESSED} of ${ALL_CNT} files.") + return() + endif (${skip_msg} EQUAL 0) + endif (BCNT) +endfunction(BFILE_TYPE_MSG) + +function(NFILE_TYPE_MSG ALL_CNT ALL_PROCESSED NOEXEC_LIST) + list(LENGTH ${NOEXEC_LIST} NCNT) + if (NCNT) + math(EXPR skip_msg "${NCNT} % 100") + if (${skip_msg} EQUAL 0) + message("Found ${NCNT} binary files (characterized ${ALL_PROCESSED} of ${ALL_CNT} files.") + return() + endif (${skip_msg} EQUAL 0) + endif (NCNT) +endfunction(NFILE_TYPE_MSG) + +function(TFILE_TYPE_MSG ALL_CNT ALL_PROCESSED TEXT_LIST) + list(LENGTH ${TEXT_LIST} TCNT) + if (TCNT) + math(EXPR skip_msg "${TCNT} % 500") + if (${skip_msg} EQUAL 0) + message("Found ${TCNT} text files (characterized ${ALL_PROCESSED} of ${ALL_CNT} files.") + return() + endif (${skip_msg} EQUAL 0) + endif (TCNT) +endfunction(TFILE_TYPE_MSG) + +# For processing purposes, there are three categories of ${BRLCAD_EXT_DIR}/install file: +# +# 1. exe or shared library files needing RPATH adjustment (which also need +# to be installed with executable permissions) +# 2. binary files which are NOT executable files (images, etc.) +# 3. text files +# +# If we don't want to hard-code information about specific files we expect +# to find in ${BRLCAD_EXT_DIR}/install, we need a way to detect "on the fly" what we are +# dealing with. +function(FILE_TYPE fname ALL_CNT BINARY_LIST TEXT_LIST NOEXEC_LIST) + if (IS_SYMLINK ${CMAKE_BINARY_DIR}/${fname}) + return() + endif (IS_SYMLINK ${CMAKE_BINARY_DIR}/${fname}) + + list(LENGTH ${BINARY_LIST} BCNT) + list(LENGTH ${TEXT_LIST} TCNT) + list(LENGTH ${NOEXEC_LIST} NCNT) + math(EXPR PCNT "${BCNT} + ${TCNT} + ${NCNT} + 1") + + foreach (skp ${NOPROCESS_PATTERNS}) + if ("${fname}" MATCHES "${skp}") + set(${TEXT_LIST} ${${TEXT_LIST}} ${fname} PARENT_SCOPE) + TFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${TEXT_LIST}) + return() + endif ("${fname}" MATCHES "${skp}") + endforeach (skp ${NOPROCESS_PATTERNS}) + execute_process(COMMAND ${STRCLEAR_EXECUTABLE} -B ${CMAKE_BINARY_DIR}/${fname} RESULT_VARIABLE TXT_FILE) + if ("${TXT_FILE}" GREATER 0) + set(${TEXT_LIST} ${${TEXT_LIST}} ${fname} PARENT_SCOPE) + TFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${TEXT_LIST}) + return() + endif ("${TXT_FILE}" GREATER 0) + + # Some kind of binary file, can we set an RPATH? + if (P_RPATH_EXECUTABLE) + execute_process(COMMAND ${P_RPATH_EXECUTABLE} ${CMAKE_BINARY_DIR}/${lf} RESULT_VARIABLE NOT_BIN_OBJ OUTPUT_VARIABLE NB_OUT ERROR_VARIABLE NB_ERR) + if (NOT_BIN_OBJ) + set(${NOEXEC_LIST} ${${NOEXEC_LIST}} ${fname} PARENT_SCOPE) + NFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${NOEXEC_LIST}) + return() + else (NOT_BIN_OBJ) + #message("File needing RPATH setting: ${fname}") + set(${BINARY_LIST} ${${BINARY_LIST}} ${fname} PARENT_SCOPE) + BFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${BINARY_LIST}) + return() + endif (NOT_BIN_OBJ) + endif(P_RPATH_EXECUTABLE) + if (APPLE) + execute_process(COMMAND otool -l ${CMAKE_BINARY_DIR}/${lf} RESULT_VARIABLE ORESULT OUTPUT_VARIABLE OTOOL_OUT ERROR_VARIABLE NB_ERR) + if ("${OTOOL_OUT}" MATCHES "Archive") + set(${NOEXEC_LIST} ${${NOEXEC_LIST}} ${fname} PARENT_SCOPE) + NFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${NOEXEC_LIST}) + return() + endif ("${OTOOL_OUT}" MATCHES "Archive") + if ("${OTOOL_OUT}" MATCHES "not an object") + set(${NOEXEC_LIST} ${${NOEXEC_LIST}} ${fname} PARENT_SCOPE) + NFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${NOEXEC_LIST}) + return() + endif ("${OTOOL_OUT}" MATCHES "not an object") + # Not one of the exceptions - binary + #message("File needing RPATH setting: ${fname}") + set(${BINARY_LIST} ${${BINARY_LIST}} ${fname} PARENT_SCOPE) + BFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${BINARY_LIST}) + return() + endif(APPLE) + + # If we haven't figured it out, treat as noexec binary + set(${NOEXEC_LIST} ${${NOEXEC_LIST}} ${fname} PARENT_SCOPE) + NFILE_TYPE_MSG(${ALL_CNT} ${PCNT} ${NOEXEC_LIST}) +endfunction(FILE_TYPE) + + + +# Copy everything in ${BRLCAD_EXT_DIR}/install into the build directory +function(INITIALIZE_TP_FILES) + # Rather than complicate matters trying to pick and choose what to move, just + # stage everything. Depending on what the dependencies write into their + # install directories we may have to be more selective about this in the + # future, but for now let's try simplicity - the less we can couple this + # logic to the specific contents of ${BRLCAD_EXT_DIR}/install, the better. + # + # Unfortuately, as implemented this is currently quite slow, but cmake's + # -E copy_directory command follows symlinks rather than duplicating them: + # https://cmake.org/cmake/help/latest/manual/cmake.1.html + if ("${BRLCAD_EXT_DIR}/install" STREQUAL "${BRLCAD_EXT_INSTALL_DIR}") + set(EXT_DIR_STR "${BRLCAD_EXT_INSTALL_DIR}") + else ("${BRLCAD_EXT_DIR}/install" STREQUAL "${BRLCAD_EXT_INSTALL_DIR}") + set(EXT_DIR_STR "${BRLCAD_EXT_INSTALL_DIR} (via symlink ${BRLCAD_EXT_DIR}/install)") + endif ("${BRLCAD_EXT_DIR}/install" STREQUAL "${BRLCAD_EXT_INSTALL_DIR}") + message("Staging third party files from ${EXT_DIR_STR} in build directory...") + file(GLOB SDIRS LIST_DIRECTORIES true RELATIVE "${BRLCAD_EXT_INSTALL_DIR}" "${BRLCAD_EXT_INSTALL_DIR}/*") + foreach(sd ${SDIRS}) + # Bundled up the sub-directory's contents so that the archive will expand with + # paths relative to the ${BRLCAD_EXT_DIR}/install root + message("Packing ${sd} subdirectory...") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_BINARY_DIR}/${sd}.tar "${BRLCAD_EXT_INSTALL_DIR}/${sd}" WORKING_DIRECTORY "${BRLCAD_EXT_INSTALL_DIR}") + message("Packing ${sd} subdirectory... done.") + + # Make sure the build directory has the target directory to write to + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${sd}) + + # Whether we're single or multi config, do a top level decompression to give + # the install targets a uniform source for all configurations. + message("Expanding ${sd}.tar in build directory...") + if ("${CMAKE_VERSION}" VERSION_LESS "3.24") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/${sd}.tar WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + else ("${CMAKE_VERSION}" VERSION_LESS "3.24") + # If we have it, use --touch instead of the (very slow) per file -E touch update + # https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-E_tar-touch + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/${sd}.tar --touch WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") + endif ("${CMAKE_VERSION}" VERSION_LESS "3.24") + message("Expanding ${sd}.tar in build directory... done.") + + # For multi-config, we'll also need to decompress once for each active configuration's build dir + # so the executables will work locally... + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${sd}) + message("Expanding ${sd}.tar in configuration: ${CFG_TYPE} build directory...") + if ("${CMAKE_VERSION}" VERSION_LESS "3.24") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/${sd}.tar WORKING_DIRECTORY "${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}") + else ("${CMAKE_VERSION}" VERSION_LESS "3.24") + # If we have it, use --touch instead of the (very slow) per file -E touch update + # https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-E_tar-touch + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/${sd}.tar --touch WORKING_DIRECTORY "${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}") + endif ("${CMAKE_VERSION}" VERSION_LESS "3.24") + message("Expanding ${sd}.tar in configuration: ${CFG_TYPE} build directory... done.") + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + + # Copying complete - remove the archive file + execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/${sd}.tar) + endforeach(sd ${SDIRS}) + + # The above copy is indiscriminate, so we follow behind it and strip out the + # files we don't wish to include + message("Removing files indicated by exclude patterns...") + STRIP_EXCLUDED("${CMAKE_BINARY_DIR}" EXCLUDED_PATTERNS) + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + STRIP_EXCLUDED("${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}" EXCLUDED_PATTERNS) + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + message("Removing files indicated by exclude patterns... done.") + + # In older CMake, unpacking the files didn't come with the option to update + # their timestamps - see https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-E_tar-touch + # If we want to be able to check if ${BRLCAD_EXT_DIR}/install has changed, we need to make + # sure the build dir copies are newer than the ${BRLCAD_EXT_DIR}/install copies for + # IS_NEWER_THAN testing. + if ("${CMAKE_VERSION}" VERSION_LESS "3.24") + message("Updating copied file timestamps...") + foreach(tf ${TP_FILES}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch_nocreate "${CMAKE_BINARY_DIR}/${tf}") + endforeach(tf ${TP_FILES}) + message("Updating copied file timestamps... done.") + endif ("${CMAKE_VERSION}" VERSION_LESS "3.24") + + message("Staging third party files from ${EXT_DIR_STR} in build directory... done.") + + # NOTE - we may need to find and redo symlinks, if we get any that are full + # paths - we expect .so and .so.* style symlinks on some platforms, and there + # may be others. If those paths are absolute in BRLCAD_EXT_INSTALL_DIR they will be + # wrong when copied into the BRL-CAD build - they will work on the build + # machine since full path links will resolve, but will fail when installed on + # another machine. A quick tests suggests we don't have any like that right + # now, but it's not clear we can count on that... +endfunction(INITIALIZE_TP_FILES) + + + +# If we have a pre-existing list of files, we need to determine the status of the +# current directories vs the list. Sets three lists at the parent scope: +# TP_NEW - files in ${BRLCAD_EXT_DIR}/install that are new since the previous list was generated +# TP_STALE - files in the old list that are no longer in ${BRLCAD_EXT_DIR}/install +# TP_CHANGED - files present in both lists but newer in ${BRLCAD_EXT_DIR}/install +# +# Note that TP_NEW will be empty if there is no previous state. The main logic +# uses a different variable - TP_INIT - to notify the appropriate processing steps +# that there are files to work on, since we don't want to do the copying step +# with configure_file when the initialize routines have already done the work. +function(TP_COMPARE_STATE TP_NEW_LIST TP_PREV_LIST) + + # See if any new files have appeared compared to the previous state + set(LTP_NEW "${${TP_NEW_LIST}}") + set(LTP_PREVIOUS "${${TP_PREV_LIST}}") + if (LTP_PREVIOUS) + list(REMOVE_ITEM LTP_NEW ${LTP_PREVIOUS}) + else (LTP_PREVIOUS) + # If everything is new, we're initializing + set(LTP_NEW) + endif (LTP_PREVIOUS) + + # See if any files previously copied into the build dir have been removed + set(LTP_STALE ${LTP_PREVIOUS}) + if (${TP_NEW_LIST}) + list(REMOVE_ITEM LTP_STALE ${${TP_NEW_LIST}}) + endif (${TP_NEW_LIST}) + + # We also need to see if any files are new based on timestamps. + set(LTP_CHANGED) + set(LTP_EXISTING ${${TP_NEW_LIST}}) + if (LTP_NEW) + list(REMOVE_ITEM LTP_EXISTING ${LTP_NEW}) + endif (LTP_NEW) + foreach (ef ${LTP_EXISTING}) + if (${BRLCAD_EXT_INSTALL_DIR}/${ef} IS_NEWER_THAN ${CMAKE_BINARY_DIR}/${ef}) + set(LTP_CHANGED ${LTP_CHANGED} ${ef}) + endif (${BRLCAD_EXT_INSTALL_DIR}/${ef} IS_NEWER_THAN ${CMAKE_BINARY_DIR}/${ef}) + endforeach (ef ${LTP_EXISTING}) + + set(TP_NEW "${LTP_NEW}" PARENT_SCOPE) + set(TP_STALE "${LTP_STALE}" PARENT_SCOPE) + set(TP_CHANGED "${LTP_CHANGED}" PARENT_SCOPE) + +endfunction(TP_COMPARE_STATE) + + + +# The relative RPATH is specific to the location and platform +function(find_relative_rpath fp rp) + # We don't want the filename to count, so offset our directory + # count down by 1 + set(dcnt -1) + set(fp_cpy ${fp}) + while (NOT "${fp_cpy}" STREQUAL "") + get_filename_component(pdir "${fp_cpy}" DIRECTORY) + set(fp_cpy ${pdir}) + math(EXPR dcnt "${dcnt} + 1") + endwhile (NOT "${fp_cpy}" STREQUAL "") + if (APPLE) + set(RELATIVE_RPATH "@executable_path") + else (APPLE) + set(RELATIVE_RPATH ":\\$ORIGIN") + endif (APPLE) + set(acnt 0) + while(acnt LESS dcnt) + set(RELATIVE_RPATH "${RELATIVE_RPATH}/..") + math(EXPR acnt "${acnt} + 1") + endwhile(acnt LESS dcnt) + set(RELATIVE_RPATH "${RELATIVE_RPATH}/${LIB_DIR}") + set(${rp} "${RELATIVE_RPATH}" PARENT_SCOPE) +endfunction(find_relative_rpath) + + + +# Apply the RPATH settings to be used in the build directory. This is a bit +# different from what is done for the final install - the goal here is not +# to produce relocatable files, but just have things work in place in the build +# locations. Parameterized to allow processing of both single and multiconfig +# builds. +function(RPATH_BUILD_DIR_PROCESS ROOT_DIR lf) + if (P_RPATH_EXECUTABLE) + execute_process(COMMAND ${P_RPATH_EXECUTABLE} --set-rpath "${ROOT_DIR}/${LIB_DIR}" ${lf} WORKING_DIRECTORY ${ROOT_DIR}) + elseif (APPLE) + execute_process(COMMAND install_name_tool -delete_rpath "${BRLCAD_EXT_DIR}/${BRLCAD_EXT_DIR}/install/${LIB_DIR}" ${lf} WORKING_DIRECTORY ${ROOT_DIR} OUTPUT_VARIABLE OOUT RESULT_VARIABLE ORESULT ERROR_VARIABLE OERROR) + execute_process(COMMAND install_name_tool -add_rpath "${ROOT_DIR}/${LIB_DIR}" ${lf} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + endif (P_RPATH_EXECUTABLE) + # RPATH updates are complete - now clear out any other stale paths in the file + execute_process(COMMAND ${STRCLEAR_EXECUTABLE} -v -b -c ${ROOT_DIR}/${lf} "${BRLCAD_EXT_DIR_REAL}/${LIB_DIR}" "${BRLCAD_EXT_DIR_REAL}/${BIN_DIR}" "${BRLCAD_EXT_DIR_REAL}/${INCLUDE_DIR}" "${BRLCAD_EXT_DIR_REAL}/") + # Modern Apple security features (particularly on ARM64) complicate our manipulation of these + # files in this fashion. For more info, see: + # https://developer.apple.com/documentation/security/updating_mac_software + # https://developer.apple.com/documentation/xcode/embedding-nonstandard-code-structures-in-a-bundle + # https://stackoverflow.com/questions/71744856/install-name-tool-errors-on-arm64 + if (APPLE) + execute_process(COMMAND codesign --force -s - ${lf} WORKING_DIRECTORY ${ROOT_DIR}) + endif (APPLE) +endfunction(RPATH_BUILD_DIR_PROCESS) + + + + +##################################################################### +# Start of processing for BRLCAD_EXT_INSTALL_DIR contents +# We need to keep the build directory copies of ${BRLCAD_EXT_DIR}/install files in +# sync with the BRLCAD_EXT_DIR originals, if they change. +##################################################################### + +# Ascertain the current state of ${BRLCAD_EXT_DIR}/install +file(GLOB_RECURSE TP_FILES LIST_DIRECTORIES false RELATIVE "${BRLCAD_EXT_INSTALL_DIR}" "${BRLCAD_EXT_INSTALL_DIR}/*") +# Filter out the files removed via STRIP_EXCLUDED +foreach(ep ${EXCLUDED_PATTERNS}) + list(FILTER TP_FILES EXCLUDE REGEX ${ep}) +endforeach(ep ${EXCLUDED_PATTERNS}) + + +# For the very first pass w bulk copy the contents of the +# BRLCAD_EXT_INSTALL_DIR tree into our own directory. For some of the +# external dependencies (like Tcl) library elements must be in sane relative +# locations to binaries being executed, and leaving them in +# BRLCAD_EXT_INSTALL_DIR won't work. On Windows, the dlls for all the +# dependencies will need to be located correctly relative to the bin build +# directory. +set(TP_INIT) +if (NOT EXISTS "${TP_INVENTORY}") + + INITIALIZE_TP_FILES() + + # Special variable for when we need to know about first time initialization + set(TP_INIT "${TP_FILES}") + + # With a clean copy, there aren't any previous files to check + set(TP_PREVIOUS) + +else (NOT EXISTS "${TP_INVENTORY}") + + # If we are repeating a configure process, we need to see what (if anything) + # has changed. Read in the previous list. + file(READ "${TP_INVENTORY}" TP_P) + string(REPLACE "\n" ";" TP_PREVIOUS "${TP_P}") + +endif (NOT EXISTS "${TP_INVENTORY}") + +# Write the current third party file list +string(REPLACE ";" "\n" TP_W "${TP_FILES}") +file(WRITE "${TP_INVENTORY}" "${TP_W}") + +# Make sure both lists are sorted +list(SORT TP_FILES) +list(SORT TP_PREVIOUS) + +# See what the delta looks like between the previous ${BRLCAD_EXT_DIR}/install state (if any) +# and the current +message("Comparing previous and current states...") +TP_COMPARE_STATE(TP_FILES TP_PREVIOUS) +message("Comparing previous and current states... done.") + +# If we do have changes in a repeat configure process, we're going to have to +# redo the find_package tests. However, we don't want to repeat them if we +# don't have to, so key the reset process on what we find. +set(RESET_TP FALSE) + +if (BRLCAD_TP_FULL_RESET) + + if (TP_NEW OR TP_CHANGED OR TP_STALE) + + # If the user has requested it, if anything has changed we do a full flush + # and re-copy of the ${BRLCAD_EXT_DIR}/install contents. This is useful if one is changing + # the ${BRLCAD_EXT_DIR}/install directory to a completely different directory rather than + # incrementally updating the same directory. In the former case, timestamps + # aren't a reliable indicator of what to update in the build tree. + # + # The tradeoff is a full re-initialization is usually slower, since it is + # doing more work. On platforms where configure is slow, this can be + # significant. Hence the user setting to control behavior. + + # Clear old files + foreach (ef ${TP_PREVIOUS}) + file(REMOVE ${CMAKE_BINARY_DIR}/${ef}) + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + file(REMOVE ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}) + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + endforeach (ef ${TP_PREVIOUS}) + + # Redo full copy + INTIIALIZE_TP_FILES() + + # Reset all the find_package results + set(RESET_DP TRUE) + + endif (TP_NEW OR TP_CHANGED OR TP_STALE) + +else (BRLCAD_TP_FULL_RESET) + + # Clear copies of anything found to be stale + if (TP_STALE) + message("Removing stale 3rd party files in build directory...") + foreach (ef ${TP_STALE}) + file(REMOVE ${CMAKE_BINARY_DIR}/${ef}) + message(" ${CMAKE_BINARY_DIR}/${ef}") + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + file(REMOVE ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}) + message(" ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}") + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + endforeach (ef ${TP_STALE}) + message("Removing stale 3rd party files in build directory... done.") + endif (TP_STALE) + + # Stage new files - we don't have the bulk tar mechanism going after the first + # configure pass, so we have to do the copies needed explicitly. TP_COMPARE_STATE + # shouldn't populate TP_NEW unless we have a previous state to compare to. + # + # configure_file follows symlinks rather than copying them, so we can't use + # that for this application and have to fall back on file(COPY): + # https://gitlab.kitware.com/cmake/cmake/-/issues/14609 + if (TP_NEW) + message("Staging new 3rd party files from ${BRLCAD_EXT_DIR}/install...") + foreach (ef ${TP_NEW}) + file(REMOVE ${CMAKE_BINARY_DIR}/${ef}) + get_filename_component(EF_DIR ${ef} DIRECTORY) + get_filename_component(EF_NAME ${ef} NAME) + file(COPY ${BRLCAD_EXT_INSTALL_DIR}/${ef} DESTINATION ${CMAKE_BINARY_DIR}/${EF_DIR}) + message(" ${CMAKE_BINARY_DIR}/${ef}") + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + file(REMOVE ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}) + file(COPY ${BRLCAD_EXT_INSTALL_DIR}/${ef} DESTINATION ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${EF_DIR}) + message(" ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}") + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + endforeach (ef ${TP_CHANGED}) + message("Staging new 3rd party files from ${BRLCAD_EXT_DIR}/install... done.") + endif (TP_NEW) + + # Stage changed files + if (TP_CHANGED) + message("Staging changed 3rd party files from ${BRLCAD_EXT_DIR}/install...") + foreach (ef ${TP_CHANGED}) + file(REMOVE ${CMAKE_BINARY_DIR}/${ef}) + get_filename_component(EF_DIR ${ef} DIRECTORY) + get_filename_component(EF_NAME ${ef} NAME) + file(COPY ${BRLCAD_EXT_INSTALL_DIR}/${ef} DESTINATION ${CMAKE_BINARY_DIR}/${EF_DIR}) + message(" ${CMAKE_BINARY_DIR}/${ef}") + if (CMAKE_CONFIGURATION_TYPES) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + file(REMOVE ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}) + file(COPY ${BRLCAD_EXT_INSTALL_DIR}/${ef} DESTINATION ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${EF_DIR}) + message(" ${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}/${ef}") + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (CMAKE_CONFIGURATION_TYPES) + endforeach (ef ${TP_CHANGED}) + message("Staging changed 3rd party files from ${BRLCAD_EXT_DIR}/install... done.") + endif (TP_CHANGED) + + # If the directory file lists differ, we have to reset find package + if (TP_NEW OR TP_STALE OR TP_CHANGED) + set(RESET_TP TRUE) + endif (TP_NEW OR TP_STALE OR TP_CHANGED) + +endif (BRLCAD_TP_FULL_RESET) + +# We'll either have TP_INIT (on the first pass) or (possibly) one or both of the +# others. Regardless, the processing from here on out is the same. +set(TP_PROCESS ${TP_CHANGED} ${TP_NEW} ${TP_INIT}) + +# We're only going to characterize new files, but even on repeat configures +# we need to know about ALL binary files, old and new, for defining the +# install rules. Read the cached list, if any, and scrub out any entries +# that are in one of the processing or clean-up lists +set(BINARY_FILES) +set(TEXT_FILES) +set(NOEXEC_FILES) +if (EXISTS ${TP_INVENTORY_BINARIES}) + file(READ "${TP_INVENTORY_BINARIES}" TP_B) + string(REPLACE "\n" ";" BINARY_FILES "${TP_B}") + if (TP_STALE) + list(REMOVE_ITEM BINARY_FILES ${TP_STALE}) + endif (TP_STALE) + if (TP_NEW) + list(REMOVE_ITEM BINARY_FILES ${TP_NEW}) + endif (TP_NEW) + if (TP_CHANGED) + list(REMOVE_ITEM BINARY_FILES ${TP_CHANGED}) + endif (TP_CHANGED) +endif (EXISTS ${TP_INVENTORY_BINARIES}) + +# Use various tools to sort out which files are exec/lib files, +# targeting only the files we've determined need processing (for +# an initialization this is everything, but for subsequent passes +# there is likely to be much less work to do.) +message("Characterizing new or changed bundled third party files...") +set(NBINARY_FILES) +set(NTEXT_FILES) +set(NNOEXEC_FILES) +list(LENGTH TP_PROCESS ALL_PCNT) +foreach(lf ${TP_PROCESS}) + FILE_TYPE("${lf}" ${ALL_PCNT} NBINARY_FILES NTEXT_FILES NNOEXEC_FILES) +endforeach(lf ${TP_PROCESS}) +message("Characterizing new or changed bundled third party files... done.") + +# Combine the previous lists and the new determinations, writing +# the final lists back out to files +set(ALL_BINARY_FILES ${BINARY_FILES} ${NBINARY_FILES}) +string(REPLACE ";" "\n" TP_B "${ALL_BINARY_FILES}") +file(WRITE "${TP_INVENTORY_BINARIES}" "${TP_B}") + +if (NBINARY_FILES) + message("Setting rpath on new 3rd party lib and exe files...") + if (NOT CMAKE_CONFIGURATION_TYPES) + # Set local RPATH so the files will work during build + foreach(lf ${NBINARY_FILES}) + RPATH_BUILD_DIR_PROCESS("${CMAKE_BINARY_DIR}" "${lf}") + endforeach(lf ${NBINARY_FILES}) + else (NOT CMAKE_CONFIGURATION_TYPES) + # For multi-config, we set the RPATHs for each active configuration's build dir + # so the executables will work locally. We don't need to set the top level copy + # being used for the install target since in multi-config those copies won't be + # used by build directory executables + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + foreach(lf ${NBINARY_FILES}) + RPATH_BUILD_DIR_PROCESS("${CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}}" "${lf}") + endforeach(lf ${NBINARY_FILES}) + endforeach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + endif (NOT CMAKE_CONFIGURATION_TYPES) + message("Setting rpath on new 3rd party lib and exe files... done.") +endif (NBINARY_FILES) + +if (NNOEXEC_FILES) + message("Scrubbing paths from new 3rd party data files...") + foreach(tf ${NNOEXEC_FILES}) + SKIP_PROCESSING(${tf} SKIP_FILE) + if (SKIP_FILE) + continue() + endif (SKIP_FILE) + + # Replace any stale paths in the files + #message("${STRCLEAR_EXECUTABLE} -v -b -c ${CMAKE_BINARY_DIR}/${tf} ${BRLCAD_EXT_DIR_REAL}") + execute_process(COMMAND ${STRCLEAR_EXECUTABLE} -v -b -c "${CMAKE_BINARY_DIR}/${tf}" "${BRLCAD_EXT_DIR_REAL}") + endforeach(tf ${NNOEXEC_FILES}) + message("Scrubbing paths from new 3rd party data files... done.") +endif (NNOEXEC_FILES) + +if (NTEXT_FILES) + message("Replacing paths in new 3rd party text files...") + foreach(tf ${NTEXT_FILES}) + SKIP_PROCESSING(${tf} SKIP_FILE) + if (SKIP_FILE) + continue() + endif (SKIP_FILE) + + execute_process(COMMAND ${STRCLEAR_EXECUTABLE} -v -r "${CMAKE_BINARY_DIR}/${tf}" "${BRLCAD_EXT_DIR_REAL}" "${CMAKE_INSTALL_PREFIX}") + endforeach(tf ${NTEXT_FILES}) + message("Replacing paths in new 3rd party text files... done.") +endif (NTEXT_FILES) + +# Everything until now has been setting the stage in the build directory. Now +# we set up the install rules. It is for these stages that we need complete +# knowledge of the third party files, since configure re-defines all of these +# rules on every pass. +foreach(tf ${TP_FILES}) + # Rather than doing the PROGRAMS install for all binary files, we target just + # those in the bin directory - those are the ones we would expect to want + # CMake's *_EXECUTE permissions during install. + get_filename_component(dir "${tf}" DIRECTORY) + if (NOT dir) + message("Error - unexpected toplevel ext file: ${tf} ") + continue() + endif (NOT dir) + # If we know it's a binary file, treat it accordingly + if ("${tf}" IN_LIST ALL_BINARY_FILES) + install(PROGRAMS "${CMAKE_BINARY_DIR}/${tf}" DESTINATION "${dir}") + continue() + endif ("${tf}" IN_LIST ALL_BINARY_FILES) + # BIN_DIR may contain scripts that aren't explicitly binary files - + # catch those based on path + if (${dir} MATCHES "${BIN_DIR}$") + install(PROGRAMS "${CMAKE_BINARY_DIR}/${tf}" DESTINATION "${dir}") + else (${dir} MATCHES "${BIN_DIR}$") + install(FILES "${CMAKE_BINARY_DIR}/${tf}" DESTINATION "${dir}") + endif (${dir} MATCHES "${BIN_DIR}$") +endforeach(tf ${TP_FILES}) + +# When installing, need to fix the RPATH on binary files again, similarly to +# what we did when staging in the build directory. Again we don't process +# symlinks since following them will just result in re-processing the same +# file's RPATH multiple times. This time, in contrast to the build directory +# setup, our goal is to define an RPATH that will allow the binary files to +# work when the install directory is relocated. +foreach(bf ${ALL_BINARY_FILES}) + if (IS_SYMLINK ${bf}) + continue() + endif (IS_SYMLINK ${bf}) + # Finalize the rpaths + set(REL_RPATH) + find_relative_rpath("${bf}" REL_RPATH) + if (P_RPATH_EXECUTABLE) + install(CODE "execute_process(COMMAND ${P_RPATH_EXECUTABLE} --set-rpath \"${CMAKE_INSTALL_PREFIX}/${LIB_DIR}${REL_RPATH}\" \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${bf}\")") + elseif (APPLE) + install(CODE "execute_process(COMMAND install_name_tool -delete_rpath \"${CMAKE_BINARY_DIR}/${LIB_DIR}\" \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${bf}\" OUTPUT_VARIABLE OOUT RESULT_VARIABLE ORESULT ERROR_VARIABLE OERROR)") + install(CODE "execute_process(COMMAND install_name_tool -add_rpath \"${REL_RPATH}\" \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${bf}\")") + endif (P_RPATH_EXECUTABLE) + # Overwrite any stale paths in the binary files with null chars, to make sure + # they're not interfering with the behavior of the final executables. This + # is a little fraught in that there's no guarantee these changes aren't going + # to break something, but given that reliance on invalid full paths was going + # to break something in any case eventually doing this will let us find out + # about it sooner. If the path is just a stale, unused leftover this should + # have no impact on functionality, and otherwise this offers a way to avoid + # "accidental success" where the program is using a build dir file to + # successfully run when we don't want it to see them. + install(CODE "execute_process(COMMAND ${STRCLEAR_EXECUTABLE} -v -b -c \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${bf}\" \"${CMAKE_BINARY_DIR}/${LIB_DIR}\")") + if (APPLE) + # As with the configure time processing, use codesign at install time to appease OSX: + # https://developer.apple.com/documentation/security/updating_mac_software + # https://developer.apple.com/documentation/xcode/embedding-nonstandard-code-structures-in-a-bundle + # https://stackoverflow.com/questions/71744856/install-name-tool-errors-on-arm64 + install(CODE "execute_process(COMMAND codesign --force -s - \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${bf}\")") + endif (APPLE) +endforeach(bf ${ALL_BINARY_FILES}) + +# Because ${BRLCAD_EXT_DIR}/install is handled at configure time (and indeed MUST be handled at +# configure time so find_package results will be correct) we make the CMake +# process depend on the ${BRLCAD_EXT_DIR}/install files +foreach (ef ${TP_FILES}) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${BRLCAD_EXT_INSTALL_DIR}/${ef}) +endforeach (ef ${TP_FILES}) + +# Add a extnoinstall touched file to also trigger CMake as above, to help +# ensure a reconfigure whenever the brlcad_externals repository is built. +# There should be a build-stamp file there that should be updated after each +# build run in brlcad_externals, regardless of what happens with other files. +file(GLOB_RECURSE TP_NOINST_FILES LIST_DIRECTORIES false RELATIVE "${BRLCAD_EXT_NOINSTALL_DIR}" "${BRLCAD_EXT_NOINSTALL_DIR}/*") +# For consistency, ignore files that would fall into the STRIP_EXCLUDED set +foreach(ep ${EXCLUDED_PATTERNS}) + list(FILTER TP_NOINST_FILES EXCLUDE REGEX ${ep}) +endforeach(ep ${EXCLUDED_PATTERNS}) +foreach (ef ${TP_NOINST_FILES}) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${BRLCAD_EXT_NOINSTALL_DIR}/${ef}) +endforeach (ef ${TP_NOINST_FILES}) + + +##################################################################### +# Now that the staging process is complete, it's time to run (or +# re-run) the find_package logic to let BRL-CAD know what to use. +# For the re-running case, if something changed with the files from +# the previous configure we need to reset the find_package variables. +# There isn't a standard way to do this, so we must sometimes have +# per-package logic for those projects using more complex variable +# sets. +# +# One advantage of this approach is that there is no longer order +# dependency between these find_package calls - because all 3rd +# party compilation is done by the time we reach this step, the +# results shouldn't vary. (TODO - right now these are ordered +# roughly by project complexity - should we switch to alphabetical +# by project name?) +##################################################################### + +# Not all packages will define all of these, but it shouldn't matter - an unset +# of an unused variable shouldn't be harmful +function(find_package_reset pname trigger_var) + if (NOT ${trigger_var}) + return() + endif (NOT ${trigger_var}) + unset(${pname}_DIR CACHE) + unset(${pname}_CONFIG CACHE) + unset(${pname}_DEFINITIONS CACHE) + unset(${pname}_FOUND CACHE) + unset(${pname}_INCLUDE_DIR CACHE) + unset(${pname}_INCLUDE_DIRS CACHE) + unset(${pname}_LIBRARIES CACHE) + unset(${pname}_LIBRARY CACHE) + unset(${pname}_LIBRARY_DEBUG CACHE) + unset(${pname}_LIBRARY_RELEASE CACHE) + unset(${pname}_VERSION_STRING CACHE) + unset(${pname}_PREFIX_STR CACHE) +endfunction(find_package_reset pname trigger_var) + +# zlib compression/decompression library +# https://zlib.net +# +# Note - our copy is modified from Vanilla upstream to support specifying a +# custom prefix - until a similar feature is available in upstream zlib, we +# need this to reliably avoid conflicts between bundled and system zlib. +find_package_reset(ZLIB RESET_TP) +unset(Z_PREFIX CACHE) +unset(Z_PREFIX_STR CACHE) +set(ZLIB_ROOT "${CMAKE_BINARY_DIR}") +find_package(ZLIB REQUIRED) +if ("${ZLIB_LIBRARIES}" MATCHES "${CMAKE_BINARY_DIR}/.*") + set(Z_PREFIX_STR "brl_" CACHE STRING "Using local zlib" FORCE) +endif ("${ZLIB_LIBRARIES}" MATCHES "${CMAKE_BINARY_DIR}/.*") + +# libregex regular expression matching +find_package_reset(REGEX RESET_TP) +set(REGEX_ROOT "${CMAKE_BINARY_DIR}") +find_package(REGEX REQUIRED) + +# netpbm library - support for pnm,ppm,pbm, etc. image files +# http://netpbm.sourceforge.net/ +# +# Note - we build a custom subset of this library for convenience, and (at the +# moment) mod it to remove a GPL string component, although there is some hope +# (2022) that the latter issue will be addressed upstream. Arguably in this +# form our netpbm copy isn't really a good fit for ext, but it is kept there +# because a) there is an active upstream and b) we are unlikely to need to +# modify these sources to our needs from a functional perspective. +find_package_reset(NETPBM RESET_TP) +set(NETPBM_ROOT "${CMAKE_BINARY_DIR}") +find_package(NETPBM) + +# libpng - Portable Network Graphics image file support +# http://www.libpng.org/pub/png/libpng.html +find_package_reset(PNG RESET_TP) +if (RESET_TP) + unset(PNG_PNG_INCLUDE_DIR CACHE) +endif (RESET_TP) +set(PNG_ROOT "${CMAKE_BINARY_DIR}") +find_package(PNG) + +# libutahrle - Utah RLE Image library +find_package_reset(UTAHRLE RESET_TP) +set(UTAHRLE_ROOT "${CMAKE_BINARY_DIR}") +find_package(UTAHRLE) + +# STEPcode - support for reading and writing STEP files +# https://github.com/stepcode/stepcode +# +# Note - We are heavily involved with the stepcode effort and in the past our +# stepcode copy has been extensively modified, but we are working to get our +# copy and a released upstream copy synced - in anticipation of that, stepcode +# lives in ext. +if (BRLCAD_ENABLE_STEP) + find_package_reset(STEPCODE RESET_TP) + if (RESET_TP) + unset(STEPCODE_CORE_LIBRARY CACHE) + unset(STEPCODE_DAI_DIR CACHE) + unset(STEPCODE_DAI_LIBRARY CACHE) + unset(STEPCODE_EDITOR_DIR CACHE) + unset(STEPCODE_EDITOR_LIBRARY CACHE) + unset(STEPCODE_EXPPP_DIR CACHE) + unset(STEPCODE_EXPPP_LIBRARY CACHE) + unset(STEPCODE_EXPRESS_DIR CACHE) + unset(STEPCODE_EXPRESS_LIBRARY CACHE) + unset(STEPCODE_INCLUDE_DIR CACHE) + unset(STEPCODE_STEPCORE_DIR CACHE) + unset(STEPCODE_UTILS_DIR CACHE) + unset(STEPCODE_UTILS_LIBRARY CACHE) + endif (RESET_TP) + set(STEPCODE_ROOT "${CMAKE_BINARY_DIR}") + find_package(STEPCODE) +endif (BRLCAD_ENABLE_STEP) + + +# Eigen - linear algebra library +find_package_reset(Eigen3 RESET_TP) +set(Eigen3_ROOT "${BRLCAD_EXT_NOINSTALL_DIR}/share/eigen3/cmake") +find_package(Eigen3 NO_MODULE) +set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} Eigen) +list(REMOVE_DUPLICATES SYS_INCLUDE_PATTERNS) +set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} Eigen CACHE STRING "Bundled system include dirs" FORCE) + + +# GDAL - translator library for raster and vector geospatial data formats +# https://gdal.org +if (BRLCAD_ENABLE_GDAL) + find_package_reset(GDAL RESET_TP) + set(GDAL_ROOT "${CMAKE_BINARY_DIR}") + find_package(GDAL) +endif (BRLCAD_ENABLE_GDAL) + +# Linenoise - line editing library +# https://github.com/msteveb/linenoise +find_package_reset(LINENOISE RESET_TP) +set(LINENOISE_ROOT "${CMAKE_BINARY_DIR}") +find_package(LINENOISE) + +# LMDB - Lightning Memory-Mapped Database +# https://github.com/LMDB/lmdb +find_package_reset(LMDB RESET_TP) +set(LMDB_ROOT "${CMAKE_BINARY_DIR}") +find_package(LMDB) + +# Open Asset Import Library - library for supporting I/O for a number of +# Geometry file formats +# https://github.com/assimp/assimp +if (BRLCAD_ENABLE_ASSETIMPORT) + find_package_reset(ASSETIMPORT RESET_TP) + set(ASSETIMPORT_ROOT "${CMAKE_BINARY_DIR}") + find_package(ASSETIMPORT) +endif (BRLCAD_ENABLE_ASSETIMPORT) + +# OpenMesh Library - library for representing and manipulating polygonal meshes +# https://www.graphics.rwth-aachen.de/software/openmesh/ +if (BRLCAD_ENABLE_OPENMESH) + find_package_reset(OPENMESH RESET_TP) + if (RESET_TP) + unset(OPENMESH_CORE_LIBRARY CACHE) + unset(OPENMESH_CORE_LIBRARY_DEBUG CACHE) + unset(OPENMESH_CORE_LIBRARY_RELEASE CACHE) + unset(OPENMESH_TOOLS_LIBRARY CACHE) + unset(OPENMESH_TOOLS_LIBRARY_DEBUG CACHE) + unset(OPENMESH_TOOLS_LIBRARY_RELEASE CACHE) + endif (RESET_TP) + set(OpenMesh_ROOT "${CMAKE_BINARY_DIR}") + find_package(OpenMesh) +endif (BRLCAD_ENABLE_OPENMESH) + + +# Manifold - Mesh library for boolean ops +# https://github.com/elalish/manifold +find_package_reset(MANIFOLD RESET_TP) +set(MANIFOLD_ROOT "${CMAKE_BINARY_DIR}") +find_package(MANIFOLD) + + +# openNURBS Non-Uniform Rational BSpline library +# https://github.com/mcneel/opennurbs +find_package_reset(OPENNURBS RESET_TP) +if (RESET_TP) + unset(OPENNURBS_X_INCLUDE_DIR CACHE) +endif (RESET_TP) +set(OPENNURBS_ROOT "${CMAKE_BINARY_DIR}") +find_package(OPENNURBS) +set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} openNURBS) +list(REMOVE_DUPLICATES SYS_INCLUDE_PATTERNS) +set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} openNURBS CACHE STRING "Bundled system include dirs" FORCE) + + +# OpenCV - Open Source Computer Vision Library +# http://opencv.org +find_package_reset(OpenCV RESET_TP) + +# First, see if we have a bundled version +set(OpenCV_DIR_TMP "${OpenCV_DIR}") +set(OpenCV_DIR "${CMAKE_BINARY_DIR}/${LIB_DIR}/cmake/opencv4") +set(OpenCV_ROOT ${CMAKE_BINARY_DIR}) +find_package(OpenCV COMPONENTS ${QtComponents}) +unset(OpenCV_ROOT) + +# If no bundled copy, see what the system has +if (NOT OpenCV_FOUND) + set(OpenCV_DIR "${OpenCV_DIR_TMP}") + find_package(OpenCV) +endif (NOT OpenCV_FOUND) + + +# OSMesa Off Screen Rendering library +# https://github.com/starseeker/osmesa +find_package_reset(OSMESA RESET_TP) +set(OSMESA_ROOT "${CMAKE_BINARY_DIR}") +find_package(OSMESA) + + +# Poly2Tri - constrained Delaunay triangulation +# https://github.com/jhasse/poly2tri +find_package_reset(POLY2TRI RESET_TP) +set(POLY2TRI_ROOT "${CMAKE_BINARY_DIR}") +find_package(POLY2TRI REQUIRED) + + +# TCL - scripting language. For Tcl/Tk builds we want +# static lib building on so we get the stub libraries. +if (BRLCAD_ENABLE_TK) + # For FindTCL.cmake + set(TCL_ENABLE_TK ON CACHE BOOL "enable tk") +endif (BRLCAD_ENABLE_TK) +mark_as_advanced(TCL_ENABLE_TK) + +find_package_reset(TCL RESET_TP) +find_package_reset(TK RESET_TP) +if (RESET_TP) + unset(TCL_INCLUDE_PATH CACHE) + unset(TCL_STUB_LIBRARY CACHE) + unset(TCL_TCLSH CACHE) + unset(TK_INCLUDE_PATH CACHE) + unset(TK_STUB_LIBRARY CACHE) + unset(TK_WISH CACHE) + unset(TK_X11_GRAPHICS CACHE) + unset(TTK_STUB_LIBRARY CACHE) +endif (RESET_TP) + +set(TCL_ROOT "${CMAKE_BINARY_DIR}") +find_package(TCL) +set(HAVE_TK 1) +set(ITK_VERSION "3.4") +set(IWIDGETS_VERSION "4.1.1") +CONFIG_H_APPEND(BRLCAD "#define ITK_VERSION \"${ITK_VERSION}\"\n") +CONFIG_H_APPEND(BRLCAD "#define IWIDGETS_VERSION \"${IWIDGETS_VERSION}\"\n") + +# A lot of code depends on knowing about Tk being active, +# so we set a flag in the configuration header to pass +# on that information. +CONFIG_H_APPEND(BRLCAD "#cmakedefine HAVE_TK\n") + + +# Qt - cross-platform user interface/application development toolkit +# https://download.qt.io/archive/qt +if (BRLCAD_ENABLE_QT) + + find_package_reset(Qt5 RESET_TP) + find_package_reset(Qt6 RESET_TP) + + set(QtComponents Core Widgets Gui Svg Network) + if (BRLCAD_ENABLE_OPENGL) + set(QtComponents ${QtComponents} OpenGL OpenGLWidgets) + endif (BRLCAD_ENABLE_OPENGL) + + if (RESET_TP) + foreach(qc ${QtComponents}) + unset(Qt6${qc}_DIR CACHE) + unset(Qt6${qc}_FOUND CACHE) + unset(Qt5${qc}_DIR CACHE) + unset(Qt5${qc}_FOUND CACHE) + endforeach(qc ${QtComponents}) + endif (RESET_TP) + + # First, see if we have a bundled version + set(Qt6_DIR_TMP "${Qt6_DIR}") + set(Qt6_DIR "${CMAKE_BINARY_DIR}/${LIB_DIR}/cmake/Qt6") + set(Qt6_ROOT ${CMAKE_BINARY_DIR}) + find_package(Qt6 COMPONENTS ${QtComponents}) + unset(Qt6_ROOT) + + if (NOT Qt6Widgets_FOUND) + set(Qt6_DIR "${Qt6_DIR_TMP}") + find_package(Qt6 COMPONENTS ${QtComponents}) + endif (NOT Qt6Widgets_FOUND) + if (NOT Qt6Widgets_FOUND) + # We didn't find 6, try 5. For non-standard install locations, you may + # need to set the following CMake variables: + # + # Qt5_DIR=/lib/cmake/Qt5 + # QT_QMAKE_EXECUTABLE=/bin/qmake + # AUTORCC_EXECUTABLE=/bin/rcc + list(REMOVE_ITEM QtComponents OpenGLWidgets) + find_package(Qt5 COMPONENTS ${QtComponents}) + endif (NOT Qt6Widgets_FOUND) + if (NOT Qt6Widgets_FOUND AND NOT Qt5Widgets_FOUND AND BRLCAD_ENABLE_QT) + message("Qt requested, but Qt installation not found - disabling") + set(BRLCAD_ENABLE_QT OFF) + endif (NOT Qt6Widgets_FOUND AND NOT Qt5Widgets_FOUND AND BRLCAD_ENABLE_QT) + if (Qt6Widgets_FOUND) + find_package(Qt6 COMPONENTS Test) + if (Qt6Test_FOUND) + CONFIG_H_APPEND(BRLCAD "#define USE_QTTEST 1\n") + endif (Qt6Test_FOUND) + endif (Qt6Widgets_FOUND) + mark_as_advanced(Qt6Widgets_DIR) + mark_as_advanced(Qt6Core_DIR) + mark_as_advanced(Qt6Gui_DIR) + mark_as_advanced(Qt5Widgets_DIR) + mark_as_advanced(Qt5Core_DIR) + mark_as_advanced(Qt5Gui_DIR) +endif (BRLCAD_ENABLE_QT) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/misc/CMake/BRLCAD_Summary.cmake b/misc/CMake/BRLCAD_Summary.cmake index 27d19b91125..c02cf66ae9a 100644 --- a/misc/CMake/BRLCAD_Summary.cmake +++ b/misc/CMake/BRLCAD_Summary.cmake @@ -235,21 +235,137 @@ function(BRLCAD_Summary) # Spacer between flags and compilation status lists message(" ") + + if (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") + ################################################### + # # + # Bundled External Libraries # + # # + ################################################### + # In current build logic, we're not building the external libs as part of our + # build anymore. We have to check the library variables to see if we're + # using the bundled versions. + # + # NOTE: these two lists must stay in sync - the var in the second list must + # correspond to the library labeled in the same position in the first list + set(BUNDLED_LABELS + "Asset Import Library" + "Eigen" + "Geospatial Data Abstraction Library" + "Lightning Memory-Mapped Database" + "Netpbm" + "OpenCV" + "OpenMesh" + "openNURBS" + "OSMesa" + "Portable Network Graphics" + "Qt" + "Regex Library" + "STEPcode" + "Tcl" + "Tk" + "UtahRLE" + "Zlib" + ) + + # Because we may have a Qt5 from the system as well as a Qt6, we need to + # flatten the two variables for reporting + set(QtCore_Dir) + if (Qt6Core_DIR) + set(QtCore_DIR ${Qt6Core_DIR}) + endif (Qt6Core_DIR) + if (Qt5Core_DIR) + set(QtCore_DIR ${Qt5Core_DIR}) + endif (Qt5Core_DIR) + + set(BUNDLED_VARS + ASSETIMPORT_LIBRARY + EIGEN3_INCLUDE_DIRS + GDAL_LIBRARY + LMDB_LIBRARY + NETPBM_LIBRARY + OpenCV_DIR + OPENMESH_LIBRARIES + OPENNURBS_LIBRARY + OSMESA_LIBRARY + PNG_LIBRARY_RELEASE + QtCore_DIR + REGEX_LIBRARY + STEPCODE_CORE_LIBRARY + TCL_LIBRARY + TK_LIBRARY + UTAHRLE_LIBRARY + ZLIB_LIBRARY + ) + + # Find the maximum label length + set(LABEL_LENGTH 0) + foreach(label ${BUNDLED_LABELS}) + string(LENGTH "${label}" CURRENT_LENGTH) + if(${CURRENT_LENGTH} GREATER ${LABEL_LENGTH}) + set(LABEL_LENGTH ${CURRENT_LENGTH}) + endif(${CURRENT_LENGTH} GREATER ${LABEL_LENGTH}) + endforeach(label ${BUNDLED_LABELS}) + + # Add necessary periods to each label to make a uniform + # label size + set(BUNDLED_LABELS_TMP) + foreach(label ${BUNDLED_LABELS}) + string(LENGTH "${label}" CURRENT_LENGTH) + while(${CURRENT_LENGTH} LESS ${LABEL_LENGTH}) + set(label "${label}.") + string(LENGTH "${label}" CURRENT_LENGTH) + endwhile(${CURRENT_LENGTH} LESS ${LABEL_LENGTH}) + set(label "${label}..:") + set(BUNDLED_LABELS_TMP ${BUNDLED_LABELS_TMP} ${label}) + endforeach(label ${BUNDLED_LABELS}) + set(BUNDLED_LABELS ${BUNDLED_LABELS_TMP}) + + # If we're referencing a local copy of the library, + # it's getting bundled. Otherwise we're using a + # system version + set(bindex 0) + foreach(blabel ${BUNDLED_LABELS}) + list(GET BUNDLED_VARS ${bindex} LVAR) + if (NOT ${LVAR}) + message("${blabel} NotFound") + math(EXPR bindex "${bindex} + 1") + continue() + endif (NOT ${LVAR}) + IS_SUBPATH("${CMAKE_BINARY_DIR}" "${${LVAR}}" LOCAL_TEST) + if (LOCAL_TEST) + message("${blabel} Bundled") + else (LOCAL_TEST) + # For header-only dependencies, we don't copy them into the build tree + # - check for the NOINSTALL directory + IS_SUBPATH("${BRLCAD_EXT_NOINSTALL_DIR}" "${${LVAR}}" EXT_TEST) + if (EXT_TEST) + message("${blabel} Bundled") + else (EXT_TEST) + message("${blabel} System") + endif (EXT_TEST) + endif (LOCAL_TEST) + math(EXPR bindex "${bindex} + 1") + endforeach(blabel ${BUNDLED_LABELS}) + endif (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") + ################################################### # # - # Set up primary report item lists and labels # + # Feature settings # # # ################################################### # Build options - set(BRLCAD_TCL_BUILD_LABEL "Compile Tcl ") - set(BRLCAD_TK_BUILD_LABEL "Compile Tk ") - set(BRLCAD_INCRTCL_BUILD_LABEL "Compile Itcl/Itk ") - set(BRLCAD_IWIDGETS_BUILD_LABEL "Compile Iwidgets ") - set(BRLCAD_PNG_BUILD_LABEL "Compile libpng ") - set(BRLCAD_REGEX_BUILD_LABEL "Compile libregex ") - set(BRLCAD_ZLIB_BUILD_LABEL "Compile zlib ") - set(BRLCAD_SC_BUILD_LABEL "Compile STEPcode") + if (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") + set(BRLCAD_TCL_BUILD_LABEL "Compile Tcl ") + set(BRLCAD_TK_BUILD_LABEL "Compile Tk ") + set(BRLCAD_INCRTCL_BUILD_LABEL "Compile Itcl/Itk ") + set(BRLCAD_IWIDGETS_BUILD_LABEL "Compile Iwidgets ") + set(BRLCAD_PNG_BUILD_LABEL "Compile libpng ") + set(BRLCAD_REGEX_BUILD_LABEL "Compile libregex ") + set(BRLCAD_ZLIB_BUILD_LABEL "Compile zlib ") + set(BRLCAD_SC_BUILD_LABEL "Compile STEPcode") + endif (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") set(BRLCAD_ENABLE_X11_LABEL "X11 support (optional) ") set(BRLCAD_ENABLE_OPENGL_LABEL "OpenGL support (optional) ") set(BRLCAD_ENABLE_QT_LABEL "Qt support (optional) ") @@ -270,8 +386,12 @@ function(BRLCAD_Summary) set(ENABLE_ALL_CXX_COMPILE_LABEL "Build all C and C++ files with a C++ compiler ") # Make sets to use for iteration over all report items - set(BUILD_REPORT_ITEMS - TCL TK INCRTCL IWIDGETS PNG REGEX ZLIB SC) + if (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") + set(BUILD_REPORT_ITEMS + TCL TK INCRTCL IWIDGETS PNG REGEX ZLIB SC) + else() + set(BUILD_REPORT_ITEMS) + endif (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") set(FEATURE_REPORT_ITEMS BRLCAD_ENABLE_OPENGL @@ -335,66 +455,62 @@ function(BRLCAD_Summary) set(${label} "${${label}}..:") endforeach(label ${ALL_LABELS}) - ################################################### - # # - # Third Party # - # # - ################################################### - # The actual build state (as opposed to the AUTO/BUNDLED/SYSTEM setting) - # of the third party libraries is not present in the global cache and - # must be explicitly pulled from src/other - macro(GET_BUILD_STATE ITEM) - endmacro(GET_BUILD_STATE) - - # List of components to be reported on. - set(THIRD_PARTY_COMPONENT_LIST ${BUILD_REPORT_ITEMS}) - # IncrTcl must be handled separately - list(REMOVE_ITEM THIRD_PARTY_COMPONENT_LIST "INCRTCL") - - # Set state messages for standard components - foreach(ITEM ${THIRD_PARTY_COMPONENT_LIST}) - get_directory_property(BRLCAD_${ITEM}_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_${ITEM}_BUILD) - get_directory_property(BRLCAD_${ITEM}_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_${ITEM}_NOTFOUND) - if("${BRLCAD_${ITEM}_BUILD}" STREQUAL "OFF" AND BRLCAD_${ITEM}_NOTFOUND) - set(BRLCAD_${ITEM}_BUILD "OFF!") - endif("${BRLCAD_${ITEM}_BUILD}" STREQUAL "OFF" AND BRLCAD_${ITEM}_NOTFOUND) - endforeach(ITEM ${THIRD_PARTY_COMPONENT_LIST}) - - # IncrTcl is both ITCL and ITK - handle the various possibilities here - get_directory_property(BRLCAD_ITCL_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_ITCL_BUILD) - get_directory_property(BRLCAD_ITK_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_ITK_BUILD) - get_directory_property(BRLCAD_ITCL_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_ITCL_NOTFOUND) - get_directory_property(BRLCAD_ITK_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_ITK_NOTFOUND) - if(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) - set(BRLCAD_INCRTCL_BUILD ON) - else(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) - if(BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) - set(BRLCAD_INCRTCL_BUILD "ON (Itcl only)") - endif(BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) - if(BRLCAD_ITK_BUILD AND NOT BRLCAD_ITCL_BUILD) - set(BRLCAD_INCRTCL_BUILD "ON (Itk only)") - endif(BRLCAD_ITK_BUILD AND NOT BRLCAD_ITCL_BUILD) - if(NOT BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) - if(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) - set(BRLCAD_INCRTCL_BUILD "OFF!") - else(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) - set(BRLCAD_INCRTCL_BUILD "OFF") - endif(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) - endif(NOT BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) - endif(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) - - foreach(item ${BUILD_REPORT_ITEMS}) - message("${BRLCAD_${item}_BUILD_LABEL} ${BRLCAD_${item}_BUILD}") - endforeach(item ${BUILD_REPORT_ITEMS}) + if (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") + ################################################### + # # + # Third Party # + # # + ################################################### + # The actual build state (as opposed to the AUTO/BUNDLED/SYSTEM setting) + # of the third party libraries is not present in the global cache and + # must be explicitly pulled from src/other + macro(GET_BUILD_STATE ITEM) + endmacro(GET_BUILD_STATE) + + # List of components to be reported on. + set(THIRD_PARTY_COMPONENT_LIST ${BUILD_REPORT_ITEMS}) + # IncrTcl must be handled separately + list(REMOVE_ITEM THIRD_PARTY_COMPONENT_LIST "INCRTCL") + + # Set state messages for standard components + foreach(ITEM ${THIRD_PARTY_COMPONENT_LIST}) + get_directory_property(BRLCAD_${ITEM}_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_${ITEM}_BUILD) + get_directory_property(BRLCAD_${ITEM}_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_${ITEM}_NOTFOUND) + if("${BRLCAD_${ITEM}_BUILD}" STREQUAL "OFF" AND BRLCAD_${ITEM}_NOTFOUND) + set(BRLCAD_${ITEM}_BUILD "OFF!") + endif("${BRLCAD_${ITEM}_BUILD}" STREQUAL "OFF" AND BRLCAD_${ITEM}_NOTFOUND) + endforeach(ITEM ${THIRD_PARTY_COMPONENT_LIST}) + + # IncrTcl is both ITCL and ITK - handle the various possibilities here + get_directory_property(BRLCAD_ITCL_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_ITCL_BUILD) + get_directory_property(BRLCAD_ITK_BUILD DIRECTORY src/other/ext DEFINITION BRLCAD_ITK_BUILD) + get_directory_property(BRLCAD_ITCL_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_ITCL_NOTFOUND) + get_directory_property(BRLCAD_ITK_NOTFOUND DIRECTORY src/other/ext DEFINITION BRLCAD_ITK_NOTFOUND) + if(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) + set(BRLCAD_INCRTCL_BUILD ON) + else(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) + if(BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) + set(BRLCAD_INCRTCL_BUILD "ON (Itcl only)") + endif(BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) + if(BRLCAD_ITK_BUILD AND NOT BRLCAD_ITCL_BUILD) + set(BRLCAD_INCRTCL_BUILD "ON (Itk only)") + endif(BRLCAD_ITK_BUILD AND NOT BRLCAD_ITCL_BUILD) + if(NOT BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) + if(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) + set(BRLCAD_INCRTCL_BUILD "OFF!") + else(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) + set(BRLCAD_INCRTCL_BUILD "OFF") + endif(BRLCAD_ITCL_NOTFOUND OR BRLCAD_ITK_NOTFOUND) + endif(NOT BRLCAD_ITCL_BUILD AND NOT BRLCAD_ITK_BUILD) + endif(BRLCAD_ITCL_BUILD AND BRLCAD_ITK_BUILD) + + foreach(item ${BUILD_REPORT_ITEMS}) + message("${BRLCAD_${item}_BUILD_LABEL} ${BRLCAD_${item}_BUILD}") + endforeach(item ${BUILD_REPORT_ITEMS}) + endif (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") message(" ") - ################################################### - # # - # Features # - # # - ################################################### - # Note when the word size is automatically set. if(${BRLCAD_WORD_SIZE} MATCHES "AUTO") set(BRLCAD_ARCH_BITSETTING "${CMAKE_WORD_SIZE} (Auto)") diff --git a/misc/CMake/BRLCAD_Targets.cmake b/misc/CMake/BRLCAD_Targets.cmake index ad91c3a4ea8..f82f44b68d9 100644 --- a/misc/CMake/BRLCAD_Targets.cmake +++ b/misc/CMake/BRLCAD_Targets.cmake @@ -57,6 +57,9 @@ function(SET_LANG_CXX SRC_FILES) endif(ENABLE_ALL_CXX_COMPILE) endfunction(SET_LANG_CXX SRC_FILES) +# See if we've got astyle +find_program(ASTYLE_EXECUTABLE astyle HINTS "${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}") + # BRL-CAD style checking with AStyle function(VALIDATE_STYLE targetname srcslist) @@ -382,6 +385,49 @@ function(BRLCAD_ADDLIB libname srcslist libslist) endfunction(BRLCAD_ADDLIB libname srcslist libslist) + +#----------------------------------------------------------------------------- +# We need a way to tell whether one path is a subpath of another path without +# relying on regular expressions, since file paths may have characters in them +# that will trigger regex matching behavior when we don't want it. (To test, +# for example, use a build directory name of build++) +# +# Sets ${result_var} to 1 if the candidate subpath is actually a subpath of +# the supplied "full" path, otherwise sets it to 0. +# +# The routine below does the check without using regex matching, in order to +# handle path names that contain characters that would be interpreted as active +# in a regex string. +if (NOT COMMAND IS_SUBPATH) + function(IS_SUBPATH candidate_subpath full_path result_var) + + # Just assume it isn't until we prove it is + set(${result_var} 0 PARENT_SCOPE) + + # get the CMake form of the path so we have something consistent to work on + file(TO_CMAKE_PATH "${full_path}" c_full_path) + file(TO_CMAKE_PATH "${candidate_subpath}" c_candidate_subpath) + + # check the string lengths - if the "subpath" is longer than the full path, + # there's not point in going further + string(LENGTH "${c_full_path}" FULL_LENGTH) + string(LENGTH "${c_candidate_subpath}" SUB_LENGTH) + if("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") + return() + endif("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") + + # OK, maybe it's a subpath - time to actually check + string(SUBSTRING "${c_full_path}" 0 ${SUB_LENGTH} c_full_subpath) + if(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") + return() + endif(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") + + # If we get here, it's a subpath + set(${result_var} 1 PARENT_SCOPE) + + endfunction(IS_SUBPATH) +endif (NOT COMMAND IS_SUBPATH) + #--------------------------------------------------------------------- # For situations when a local 3rd party library (say, zlib) has been # chosen in preference to a system version of that library, it is @@ -748,13 +794,17 @@ function(BRLCAD_ADDDATA datalist targetdir) endfunction(BRLCAD_ADDDATA) function(ADD_DOC doclist targetdir) - set(doc_target_dir ${DOC_DIR}/${targetdir}) - BRLCAD_MANAGE_FILES(${doclist} ${doc_target_dir}) + if (BRLCAD_INSTALL_DOCS) + set(doc_target_dir ${DOC_DIR}/${targetdir}) + BRLCAD_MANAGE_FILES(${doclist} ${doc_target_dir}) + endif (BRLCAD_INSTALL_DOCS) endfunction(ADD_DOC) function(ADD_MAN_PAGES num inmanlist) - set(man_target_dir ${MAN_DIR}/man${num}) - BRLCAD_MANAGE_FILES(${inmanlist} ${man_target_dir}) + if (BRLCAD_INSTALL_DOCS) + set(man_target_dir ${MAN_DIR}/man${num}) + BRLCAD_MANAGE_FILES(${inmanlist} ${man_target_dir}) + endif (BRLCAD_INSTALL_DOCS) endfunction(ADD_MAN_PAGES) diff --git a/misc/CMake/BRLCAD_User_Options.cmake b/misc/CMake/BRLCAD_User_Options.cmake index 6aa45f9ebb8..c43fae72f8c 100644 --- a/misc/CMake/BRLCAD_User_Options.cmake +++ b/misc/CMake/BRLCAD_User_Options.cmake @@ -214,24 +214,25 @@ mark_as_advanced(BRLCAD_ENABLE_STEP) # Enable features requiring Qt option(BRLCAD_ENABLE_QT "Enable features requiring Qt" OFF) mark_as_advanced(BRLCAD_ENABLE_QT) +if (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") if (BRLCAD_ENABLE_QT) # Note - to use Qt6, set Qt6_DIR to /lib/cmake/Qt6 and CMAKE_PREFIX_PATH # to if(Qt6_DIR) if(BRLCAD_ENABLE_OPENGL) - find_package(Qt6 COMPONENTS Core Widgets Gui OpenGL OpenGLWidgets Network REQUIRED) + find_package(Qt6 COMPONENTS Core Widgets Gui Svg OpenGL OpenGLWidgets Network REQUIRED) find_package(Qt6 COMPONENTS Test) else() - find_package(Qt6 COMPONENTS Core Widgets Gui Network REQUIRED) + find_package(Qt6 COMPONENTS Core Widgets Gui Svg Network REQUIRED) find_package(Qt6 COMPONENTS Test) endif(BRLCAD_ENABLE_OPENGL) else() if(BRLCAD_ENABLE_OPENGL) - find_package(Qt6 COMPONENTS Core Widgets Gui OpenGL OpenGLWidgets Network QUIET) + find_package(Qt6 COMPONENTS Core Widgets Gui Svg OpenGL OpenGLWidgets Network QUIET) find_package(Qt6 COMPONENTS Test) else() - find_package(Qt6 COMPONENTS Core Widgets Gui Network QUIET) + find_package(Qt6 COMPONENTS Core Widgets Gui Svg Network QUIET) find_package(Qt6 COMPONENTS Test) endif(BRLCAD_ENABLE_OPENGL) endif(Qt6_DIR) @@ -263,11 +264,9 @@ if (BRLCAD_ENABLE_QT) endif(NOT Qt6Widgets_FOUND AND BRLCAD_ENABLE_QT) - # There are a few source level incompatibilities between Qt6 and Qt5 - set - # configure flag so we know what we need to do. - if (Qt6Widgets_FOUND) - CONFIG_H_APPEND(BRLCAD "#define USE_QT6 1\n") - endif (Qt6Widgets_FOUND) + if (Qt6Test_FOUND) + CONFIG_H_APPEND(BRLCAD "#define USE_QTTEST 1\n") + endif (Qt6Test_FOUND) endif (BRLCAD_ENABLE_QT) mark_as_advanced(Qt6Widgets_DIR) @@ -276,6 +275,7 @@ mark_as_advanced(Qt6Gui_DIR) mark_as_advanced(Qt5Widgets_DIR) mark_as_advanced(Qt5Core_DIR) mark_as_advanced(Qt5Gui_DIR) +endif (EXISTS "${CMAKE_SOURCE_DIR}/src/other/ext") # Enable features requiring OpenSceneGraph option(BRLCAD_ENABLE_OSG "Enable features requiring OpenSceneGraph" OFF) @@ -516,6 +516,11 @@ if(APACHE_FOP) endif(NOT "${APACHE_FOP_VERSION}" STREQUAL "${APACHE_FOP_VERSION_REGEX}") endif(APACHE_FOP) +# Option controlling the installation of the non-Docbook based documentation +# Doesn't impact the installation of the licenses +option(BRLCAD_INSTALL_DOCS "Install core BRL-CAD documentation" ON) +mark_as_advanced(BRLCAD_INSTALL_DOCS) + # Toplevel variable that controls all DocBook based documentation. Key it off # of what target level is enabled. if(NOT BRLCAD_ENABLE_TARGETS OR "${BRLCAD_ENABLE_TARGETS}" GREATER 2) diff --git a/misc/CMake/BRLCAD_Util.cmake b/misc/CMake/BRLCAD_Util.cmake index 5d340133240..6219c0f60fa 100644 --- a/misc/CMake/BRLCAD_Util.cmake +++ b/misc/CMake/BRLCAD_Util.cmake @@ -37,6 +37,10 @@ # Need sophisticated option parsing include(CMakeParseArguments) +# CMAKEFILES and DISTCLEAN (and supporting routines) are defined +# in TrackFiles +include(TrackFiles) + #----------------------------------------------------------------------------- # Find the executable extension, if there is one. Really should be able to use # CMAKE_EXECUTABLE_SUFFIX for this, but we've hit a few cases over the years @@ -45,24 +49,6 @@ include(CMakeParseArguments) # with the platform exe extension, if there is one. get_filename_component(EXE_EXT "${CMAKE_COMMAND}" EXT) -#----------------------------------------------------------------------------- -# We want to support a "distclean" build target that will clear all -# CMake-generated files from a source directory in the case of an -# in-source-dir configuration. Not recommended, but we'll try to -# recover if it happens. -define_property(GLOBAL PROPERTY CMAKE_DISTCLEAN_TARGET_LIST BRIEF_DOCS "All CMake generated files" FULL_DOCS "List of all files generated by CMake") -function(distclean) - foreach(item ${ARGN}) - get_filename_component(item_dir ${item} DIRECTORY) - if ("${item_dir}" STREQUAL "") - set(item_path "${CMAKE_CURRENT_BINARY_DIR}/${item}") - else ("${item_dir}" STREQUAL "") - set(item_path "${item}") - endif ("${item_dir}" STREQUAL "") - set_property(GLOBAL APPEND PROPERTY CMAKE_DISTCLEAN_TARGET_LIST "${item_path}") - endforeach(item ${ARGN}) -endfunction(distclean) - #----------------------------------------------------------------------------- # Use a variation on Fraser's approach for capturing command line args from # http://stackoverflow.com/questions/10205986/how-to-capture-cmake-command-line-arguments @@ -128,46 +114,6 @@ function(BOX_PRINT input_string border_string) message("${SEPARATOR_STRING}") endfunction() -#----------------------------------------------------------------------------- -# We need a way to tell whether one path is a subpath of another path without -# relying on regular expressions, since file paths may have characters in them -# that will trigger regex matching behavior when we don't want it. (To test, -# for example, use a build directory name of build++) -# -# Sets ${result_var} to 1 if the candidate subpath is actually a subpath of -# the supplied "full" path, otherwise sets it to 0. -# -# The routine below does the check without using regex matching, in order to -# handle path names that contain characters that would be interpreted as active -# in a regex string. -function(IS_SUBPATH candidate_subpath full_path result_var) - - # Just assume it isn't until we prove it is - set(${result_var} 0 PARENT_SCOPE) - - # get the CMake form of the path so we have something consistent to work on - file(TO_CMAKE_PATH "${full_path}" c_full_path) - file(TO_CMAKE_PATH "${candidate_subpath}" c_candidate_subpath) - - # check the string lengths - if the "subpath" is longer than the full path, - # there's not point in going further - string(LENGTH "${c_full_path}" FULL_LENGTH) - string(LENGTH "${c_candidate_subpath}" SUB_LENGTH) - if("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") - return() - endif("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") - - # OK, maybe it's a subpath - time to actually check - string(SUBSTRING "${c_full_path}" 0 ${SUB_LENGTH} c_full_subpath) - if(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") - return() - endif(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") - - # If we get here, it's a subpath - set(${result_var} 1 PARENT_SCOPE) - -endfunction(IS_SUBPATH) - #----------------------------------------------------------------------------- # Plugins for libraries need a specific override of their output directories # to put them in the correct relative location @@ -196,113 +142,18 @@ function(PLUGIN_SETUP plugin_targets subdir) RUNTIME DESTINATION ${LIBEXEC_DIR}/${subdir} LIBRARY DESTINATION ${LIBEXEC_DIR}/${subdir} ARCHIVE DESTINATION ${LIBEXEC_DIR}/${subdir}) + # Set the RPATH target property + if (NOT APPLE) + set_property(TARGET ${target_name} PROPERTY INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}:$ORIGIN/../../${LIB_DIR}") + else (NOT APPLE) + # For OSX, set the INSTALL_NAME_DIR target property + set_property(TARGET ${target_name} PROPERTY INSTALL_RPATH "@executable_path/../../${LIB_DIR}") + set_property(TARGET ${target_name} PROPERTY INSTALL_NAME_DIR "@executable_path/../../${LIB_DIR}") + endif (NOT APPLE) endforeach (target_name${plugins}) endfunction(PLUGIN_SETUP) #----------------------------------------------------------------------------- -# Distcheck needs to know what files are "supposed" to be present in order to -# make sure the source tree is clean prior to building a distribution tarball, -# -# For this set of functions to work correctly, it is important that any call -# (via target definitions or via explicit calls to CMAKEFILES) supply relative -# paths for files present in the source tree. Generated files fed into -# compilation targets are not one of the things that should be in lists -# generated by this function, and the only way to reliably recognize them is to -# reject files specified using their full path. Such files must use their full -# path in the build logic in order for out-of-src-dir builds to function, so as -# long as no full paths are used for files actually IN the source tree this -# method is reliable. The filtering logic will try to catch improperly -# specified files, but if the build directory and the source directory are one -# and the same this will not be possible. - -define_property(GLOBAL PROPERTY CMAKE_IGNORE_FILES BRIEF_DOCS "distcheck ignore files" FULL_DOCS "List of files known to CMake") -define_property(GLOBAL PROPERTY CMAKE_IGNORE_DIRS BRIEF_DOCS "distcheck ignore dirs" FULL_DOCS "List of directories marked as fully known to CMake") - -# If the build directory is not the same as the source directory, we can -# enforce the convention that only generated files be specified with their full -# name. -function(CHECK_SOURCE_DIR_FULLPATH ITEM_PATH) - - # We can only do this if BINARY_DIR != SOURCE_DIR - if(NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") - return() - endif(NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") - - # If it's a full path in the binary dir, it's fine - IS_SUBPATH("${CMAKE_BINARY_DIR}" "${ITEM_PATH}" SUBPATH_TEST) - if(NOT "${SUBPATH_TEST}" STREQUAL "0") - return() - endif(NOT "${SUBPATH_TEST}" STREQUAL "0") - - # If it's a full path in the source dir, it's fatal - IS_SUBPATH("${CMAKE_SOURCE_DIR}" "${ITEM_PATH}" SUBPATH_TEST) - if("${SUBPATH_TEST}" STREQUAL "1") - message(FATAL_ERROR "${ITEM} is listed in \"${CMAKE_CURRENT_SOURCE_DIR}\" using its absolute path. Please specify the location of this file using a relative path.") - endif("${SUBPATH_TEST}" STREQUAL "1") - -endfunction(CHECK_SOURCE_DIR_FULLPATH ITEM_PATH) - -function(CMFILE ITEM) - - get_filename_component(ITEM_PATH "${ITEM}" PATH) - if(NOT "${ITEM_PATH}" STREQUAL "") - # The hard case - path specified, need some validation. - CHECK_SOURCE_DIR_FULLPATH("${ITEM_PATH}") - - # Ignore files specified using full paths, since they - # should be generated files and are not part of the - # source code repository. - get_filename_component(ITEM_ABS_PATH "${ITEM_PATH}" ABSOLUTE) - if("${ITEM_PATH}" STREQUAL "${ITEM_ABS_PATH}") - return() - endif("${ITEM_PATH}" STREQUAL "${ITEM_ABS_PATH}") - endif(NOT "${ITEM_PATH}" STREQUAL "") - - # Handle fatal cases - if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") - message(FATAL_ERROR "Trying to ignore directory: ${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") - endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") - if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") - message(FATAL_ERROR "Attempting to ignore non-existent file ${ITEM}, in directory \"${CMAKE_CURRENT_SOURCE_DIR}\"") - endif(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") - - # We're good - log it - get_filename_component(item_absolute "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}" ABSOLUTE) - set_property(GLOBAL APPEND PROPERTY CMAKE_IGNORE_FILES "${item_absolute}") - -endfunction(CMFILE ITEM) - -function(CMAKEFILES) - if(NOT BRLCAD_IS_SUBBUILD) - - # CMake flags to add_library/add_executable aren't going to be valid filenames - just - # yank them up front. - set(ITEMS ${ARGN}) - if (NOT ITEMS) - return() - endif (NOT ITEMS) - list(REMOVE_ITEM ITEMS SHARED STATIC OBJECT WIN32 UNKNOWN IMPORTED MODULE INTERFACE EXCLUDE_FROM_ALL) - list(FILTER ITEMS EXCLUDE REGEX "TARGET_OBJECTS") - - foreach(ITEM ${ITEMS}) - CMFILE("${ITEM}") - endforeach(ITEM ${ITEMS}) - - endif(NOT BRLCAD_IS_SUBBUILD) -endfunction(CMAKEFILES FILESLIST) - -# Routine to tell distcheck to ignore a series of items in a directory. -# Primarily useful when working with src/other dist lists. -function(CMAKEFILES_IN_DIR filestoignore targetdir) - if(NOT BRLCAD_IS_SUBBUILD) - set(CMAKE_IGNORE_LIST "") - foreach(filepath ${${filestoignore}}) - set(CMAKE_IGNORE_LIST ${CMAKE_IGNORE_LIST} "${targetdir}/${filepath}") - endforeach(filepath ${filestoignore}) - CMAKEFILES(${CMAKE_IGNORE_LIST}) - endif(NOT BRLCAD_IS_SUBBUILD) -endfunction(CMAKEFILES_IN_DIR) - # configure a header for substitution and installation given a header # template and an installation directory. function(BUILD_CFG_HDR chdr targetdir) @@ -570,61 +421,6 @@ int main(int argc, const char **argv) { endfunction(generate_dreport) -# Wrap the platform specific naming conventions we must manage to copy -# build output from 3rd party build systems. -function(set_lib_vars RVAR root vmaj vmin vpatch) - - # OpenBSD has its own naming conventions. Set a platform variable based on - # the OS name so we can test for it succinctly. - if ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") - set(OPENBSD ON) - endif ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") - - unset(${RVAR}_BASENAME) - unset(${RVAR}_STATICNAME) - unset(${RVAR}_SUFFIX) - unset(${RVAR}_SYMLINK1) - unset(${RVAR}_SYMLINK2) - - if (NOT "${vpatch}" STREQUAL "") - set(vpatch_suffix ".${vpatch}") - else() - set(vpatch_suffix "") - endif() - - if (MSVC) - set(${RVAR}_BASENAME ${root}) - set(${RVAR}_STATICNAME ${root}-static) - set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}) - elseif (APPLE) - set(${RVAR}_BASENAME lib${root}) - set(${RVAR}_STATICNAME lib${root}) - set(${RVAR}_SUFFIX .${vmaj}.${vmin}${vpatch_suffix}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}.${vmaj}${CMAKE_SHARED_LIBRARY_SUFFIX}) - elseif (OPENBSD) - set(${RVAR}_BASENAME lib${root}) - set(${RVAR}_STATICNAME lib${root}) - set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}.${vmin}) - else (MSVC) - set(${RVAR}_BASENAME lib${root}) - set(${RVAR}_STATICNAME lib${root}) - set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}.${vmin}${vpatch_suffix}) - set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}) - endif (MSVC) - - # Communicate the answers to the parent scope - these are the return values. - set(${RVAR}_BASENAME "${${RVAR}_BASENAME}" PARENT_SCOPE) - set(${RVAR}_STATICNAME "${${RVAR}_STATICNAME}" PARENT_SCOPE) - set(${RVAR}_SUFFIX "${${RVAR}_SUFFIX}" PARENT_SCOPE) - set(${RVAR}_SYMLINK_1 "${${RVAR}_SYMLINK_1}" PARENT_SCOPE) - set(${RVAR}_SYMLINK_2 "${${RVAR}_SYMLINK_2}" PARENT_SCOPE) - -endfunction(set_lib_vars RVAR root) - # Local Variables: # tab-width: 8 # mode: cmake diff --git a/misc/CMake/CMakeLists.txt b/misc/CMake/CMakeLists.txt index fce2d7937d1..606bda35ec4 100644 --- a/misc/CMake/CMakeLists.txt +++ b/misc/CMake/CMakeLists.txt @@ -5,6 +5,7 @@ set(cmake_ignore_files BRLCAD_CPackOptions.cmake.in BRLCAD_CheckFunctions.cmake BRLCAD_Environment_Setup.cmake + BRLCAD_ExternalDeps.cmake BRLCAD_Install_Prefix.cmake BRLCAD_Options.cmake BRLCAD_Regress_Util.cmake @@ -35,17 +36,23 @@ set(cmake_ignore_files FindGECODE.cmake FindIlmBase.cmake FindLEMON.cmake + FindLINENOISE.cmake + FindLMDB.cmake FindLibUV.cmake + FindMANIFOLD.cmake FindNETPBM.cmake FindNSIS.cmake FindOpenMesh.cmake FindOPENNURBS.cmake FindOSL.cmake + FindOSMESA.cmake FindOpenCL.cmake + FindOpenCV.cmake FindOpenGL.cmake FindOpenVDB.cmake FindPERPLEX.cmake FindPkgMacros.cmake + FindPNG.cmake FindPOLY2TRI.cmake FindPROJ4.cmake FindRE2C.cmake @@ -61,6 +68,7 @@ set(cmake_ignore_files FindWix.cmake FindXMLLINT.cmake FindXSLTPROC.cmake + FindZLIB.cmake NSIS.template.in NSIS_silent.template.in OpenVDBUtils.cmake @@ -68,6 +76,7 @@ set(cmake_ignore_files RPath_Setup.cmake ResetCache.cmake TCL_PKGINDEX.cmake + TrackFiles.cmake compat/README compat/README.compat compat/README.compat.c99 diff --git a/misc/CMake/DocBook.cmake b/misc/CMake/DocBook.cmake index 666a0945ec0..98088d98cce 100644 --- a/misc/CMake/DocBook.cmake +++ b/misc/CMake/DocBook.cmake @@ -36,21 +36,26 @@ # # In principle, DocBook conversion and validation can be accomplished # with multiple programs. BRL-CAD's CMake logic uses variables to -# hold the "active" tools for each conversion operation, but will -# set defaults if the user does not manually set them. +# hold the "active" tools for each conversion operation, but will set +# defaults if the user does not manually set them. # If a user wishes to use their own validation and/or conversion # tools, they can set the following variables to their executable # names and create .cmake.in files in misc/CMake. To work, # the cmake.in files will need to produce the same validity "stamp" # files and fatal errors as the default tools upon success or failure. -# For a worked example, see rnv.cmake.in - to test it, install rnv from -# http://sourceforge.net/projects/rnv/ and configure BRL-CAD as follows: +# For a worked example, see rnv.cmake.in - to test it, install rnv +# from http://sourceforge.net/projects/rnv/ and configure BRL-CAD as +# follows: # # cmake .. -DBRLCAD_EXTRADOCS_VALIDATE=ON -DVALIDATE_EXECUTABLE=rnv # # Note that rnv must be in the system path for this to work. +find_program(XSLTPROC_EXECUTABLE xsltproc HINTS ${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}) +mark_as_advanced(XSLTPROC_EXECUTABLE) +find_program(XMLLINT_EXECUTABLE xmllint HINTS ${BRLCAD_EXT_NOINSTALL_DIR}/${BIN_DIR}) +mark_as_advanced(XMLLINT_EXECUTABLE) # Handle default exec and sanity checking for XML validation if(BRLCAD_ENABLE_STRICT) @@ -88,9 +93,9 @@ else(CMAKE_CONFIGURATION_TYPES) set(bin_root "${CMAKE_BINARY_DIR}") endif(CMAKE_CONFIGURATION_TYPES) -# xsltproc is finicky about slashes in names - do some -# sanity scrubbing of the full root path string in -# preparation for generating DocBook scripts +# xsltproc is finicky about slashes in names - do some sanity +# scrubbing of the full root path string in preparation for generating +# DocBook scripts string(REGEX REPLACE "/+" "/" bin_root "${bin_root}") string(REGEX REPLACE "/$" "" bin_root "${bin_root}") @@ -132,11 +137,16 @@ set(MAN5_DIR "${DOC_DIR}/../man/") set(MANN_DIR "${DOC_DIR}/../man/") set(PDF_DIR "${DOC_DIR}/pdf/") -# The general pattern of the BRL-CAD build is to use CMAKE_CFG_INTDIR when -# multi-configuration builds complicate the location of binaries. In this -# case, however, we are using a generated script with a different mechanism -# for handling this situation, and we need to update the executable paths -# accordingly if they are configuration dependent. +# The general pattern of the BRL-CAD build is to use CMAKE_CFG_INTDIR +# when multi-configuration builds complicate the location of binaries. +# In this case, however, we are using a generated script with a +# different mechanism for handling this situation, and we need to +# update the executable paths accordingly if they are configuration +# dependent. +# +# TODO - is there some way generator expressions could be used to +# improve this? Maybe pass the build time location of these programs +# to the scripts as -D arguments? if(CMAKE_CONFIGURATION_TYPES) string(REPLACE "${CMAKE_CFG_INTDIR}" "\${BUILD_TYPE}" XMLLINT_EXEC "${XMLLINT_EXECUTABLE}") string(REPLACE "${CMAKE_CFG_INTDIR}" "\${BUILD_TYPE}" XSLTPROC_EXEC "${XSLTPROC_EXECUTABLE}") @@ -152,10 +162,24 @@ if (TARGET brlcad_css) add_dependencies(docbook brlcad_css) endif (TARGET brlcad_css) -macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) +# man1 or man3 man pages for which it is expected that there is no associated +# build target. +# +# NOTE: for now, remrt is listed because the target is disabled on Windows. +# If/when it works there, remove from this list +set(filtered_man + brlcad + brlcad-config + redblack + remrt + benchmark + dbclean + ) + +function(ADD_DOCBOOK fmts in_xml_files outdir deps_list) - # If we got the name of a list or an explicit list, - # translate into the form we need. + # If we got the name of a list or an explicit list, translate into + # the form we need. list(GET ${in_xml_files} 0 xml_files) if("${xml_files}" MATCHES "NOTFOUND") set(xml_files ${in_xml_files}) @@ -163,8 +187,8 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) set(xml_files ${${in_xml_files}}) endif("${xml_files}" MATCHES "NOTFOUND") - # Get a target name that is unique but at least has - # some information about what/where the target is. + # Get a target name that is unique but at least has some information + # about what/where the target is. get_filename_component(dname_root1 "${CMAKE_CURRENT_SOURCE_DIR}" NAME_WE) get_filename_component(dname_path1 "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(dname_root2 "${dname_path1}" NAME_WE) @@ -182,16 +206,43 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) if(BRLCAD_EXTRADOCS) set(all_outfiles) + set(errors 0) - # Each file gets its own script file and custom command, which handle all - # the outputs to be produced from that file. + # Each file gets its own script file and custom command, which + # handle all the outputs to be produced from that file. foreach(fname ${xml_files}) get_filename_component(fname_root "${fname}" NAME_WE) + + # Almost all of the man1 and man3 man pages should have build targets - + # check and handle accordingly + if ("${outdir}" MATCHES "man*") + if (NOT "${outdir}" STREQUAL "man5" AND NOT "${outdir}" STREQUAL "mann") + list(FIND filtered_man "${fname_root}" IS_FILTERED) + if ("${IS_FILTERED}" EQUAL "-1") + if (NOT TARGET "${fname_root}") + message("WARNING: ${outdir} man page ${fname_root} has no associated build target.") + # TODO - if we disable Tcl, we don't build some of the man page tools - we need + # to conditionalize the man page building the same way we do the targets for + # this to be a fatal error... + #math(EXPR errors "${errors} + 1") + endif (NOT TARGET "${fname_root}") + # TODO - until we can ensure uniformity across all platforms for + # definition of man1/man3 targets, we need to skip this check. + # Instead we just ignore anything in the filtered list completely. + #else ("${IS_FILTERED}" EQUAL "-1") + # if (TARGET "${fname_root}") + # message("WARNING: ${outdir} man page ${fname_root} is listed as not having a build target but one was found - remove from filtered list.") + # math(EXPR errors "${errors} + 1") + # endif (TARGET "${fname_root}") + endif ("${IS_FILTERED}" EQUAL "-1") + endif (NOT "${outdir}" STREQUAL "man5" AND NOT "${outdir}" STREQUAL "mann") + endif ("${outdir}" MATCHES "man*") + get_filename_component(filename "${fname}" ABSOLUTE) - # Find out which outputs we're actually going to produce, between - # what's currently enabled and what the command says the target - # *can* produce + # Find out which outputs we're actually going to produce, + # between what's currently enabled and what the command says the + # target *can* produce set(CURRENT_OUTPUT_FORMATS) foreach(fmt ${fmts}) list(FIND OUTPUT_FORMATS "${fmt}" IN_LIST) @@ -206,8 +257,9 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) list(FIND OUTPUT_FORMATS "${fmt}" IN_LIST) if(NOT "${IN_LIST}" STREQUAL "-1") set(${fmt}_OUTFILE_RAW "${bin_root}/${${fmt}_DIR}${outdir}/${fname_root}.${${fmt}_EXTENSION}") - # Use CMAKE_CFG_INTDIR for build system output list, but need - # BUILD_TYPE form of path for scripts and install commands. + # Use CMAKE_CFG_INTDIR for build system output list, but + # need BUILD_TYPE form of path for scripts and install + # commands. if(CMAKE_CONFIGURATION_TYPES) string(REPLACE "${CMAKE_CFG_INTDIR}" "\${BUILD_TYPE}" ${fmt}_OUTFILE "${${fmt}_OUTFILE_RAW}") else(CMAKE_CONFIGURATION_TYPES) @@ -218,19 +270,22 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) endif(NOT "${IN_LIST}" STREQUAL "-1") endforeach(fmt ${OUTPUT_FORMATS}) - # If we have more outputs than the default, they need to be handled here. + # If we have more outputs than the default, they need to be + # handled here. foreach(fmt ${fmts}) list(FIND OUTPUT_FORMATS "${fmt}" IN_LIST) if(NOT "${IN_LIST}" STREQUAL "-1") set(${fmt}_EXTRAS) get_property(EXTRA_OUTPUTS SOURCE ${fname} PROPERTY EXTRA_${fmt}_OUTPUTS) foreach(extra_out ${EXTRA_OUTPUTS}) - # Pass the file name to the script's extras list, in case the script - # has to manually place the file in the correct directory... + # Pass the file name to the script's extras list, in case + # the script has to manually place the file in the correct + # directory... set(${fmt}_EXTRAS ${${fmt}_EXTRAS} "${extra_out}") - # Use CMAKE_CFG_INTDIR for build system output list, but need - # BUILD_TYPE form of path for scripts and install commands. + # Use CMAKE_CFG_INTDIR for build system output list, but + # need BUILD_TYPE form of path for scripts and install + # commands. set(${fmt}_EXTRA_RAW "${bin_root}/${${fmt}_DIR}${outdir}/${extra_out}") if(CMAKE_CONFIGURATION_TYPES) string(REPLACE "${CMAKE_CFG_INTDIR}" "\${BUILD_TYPE}" ${fmt}_EXTRA "${${fmt}_EXTRA_RAW}") @@ -246,7 +301,7 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) set(all_outfiles ${all_outfiles} ${outputs}) - # As long as we're outputting *something*, we have a target to produce + # Long as we're outputting, we have a target to produce if(NOT "${outputs}" STREQUAL "") string(MD5 path_md5 "${CMAKE_CURRENT_SOURCE_DIR}/${fname}") configure_file(${BRLCAD_CMAKE_DIR}/docbook.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/dbp_${fname_root}-${path_md5}.cmake @ONLY) @@ -255,9 +310,11 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) OUTPUT ${outputs} COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/dbp_${fname_root}-${path_md5}.cmake DEPENDS ${fname} ${XMLLINT_EXECUTABLE_TARGET} ${XSLTPROC_EXECUTABLE_TARGET} ${DOCBOOK_RESOURCE_FILES} ${deps_list} - ) - # For now, we'll skip generating per-input-file build targets - that's not normally how - # the docbook targets are built. + ) + + # For now, we'll skip generating per-input-file build targets + # - that's not normally how the docbook targets are built. + #add_custom_target(docbook-${fname_root}-${path_md5} DEPENDS ${outputs}) #set_target_properties(docbook-${fname_root}-${path_md5} PROPERTIES FOLDER "DocBook") #if (TARGET brlcad_css) @@ -267,6 +324,10 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) endforeach(fname ${xml_files}) + if (errors GREATER "0") + message(FATAL_ERROR "Halting build due to previous DocBook error(s).") + endif (errors GREATER "0") + if(NOT "${all_outfiles}" STREQUAL "") add_custom_target(docbook-${target_root} ALL DEPENDS ${all_outfiles}) set_target_properties(docbook-${target_root} PROPERTIES FOLDER "DocBook") @@ -274,7 +335,7 @@ macro(ADD_DOCBOOK fmts in_xml_files outdir deps_list) endif(NOT "${all_outfiles}" STREQUAL "") endif(BRLCAD_EXTRADOCS) -endmacro(ADD_DOCBOOK) +endfunction(ADD_DOCBOOK) # Local Variables: # tab-width: 8 diff --git a/misc/CMake/FindASSETIMPORT.cmake b/misc/CMake/FindASSETIMPORT.cmake index 279cadd31cb..b0d2597a1d5 100644 --- a/misc/CMake/FindASSETIMPORT.cmake +++ b/misc/CMake/FindASSETIMPORT.cmake @@ -39,36 +39,31 @@ # #============================================================================= +set(_ASSETIMPORT_SEARCHES) -include (FindPackageHandleStandardArgs) +# Search ASSETIMPORT_ROOT first if it is set. +if(ASSETIMPORT_ROOT) + set(_ASSETIMPORT_SEARCH_ROOT PATHS ${ASSETIMPORT_ROOT} NO_DEFAULT_PATH) + list(APPEND _ASSETIMPORT_SEARCHES _ASSETIMPORT_SEARCH_ROOT) +endif() -find_path (ASSETIMPORT_INCLUDE_DIR - NAMES assimp/postprocess.h assimp/scene.h assimp/version.h assimp/config.h assimp/cimport.h - PATHS /usr/local/include - PATHS /usr/include/ - HINTS - ${ASSETIMPORT_ROOT} - PATH_SUFFIXES - include - ) +set(ASSETIMPORT_NAMES assimp assimpd) -find_library (ASSETIMPORT_LIBRARY - NAMES assimp - PATHS /usr/local/lib/ - PATHS /usr/lib64/ - PATHS /usr/lib/ - HINTS - ${ASSETIMPORT_ROOT} - PATH_SUFFIXES - bin - lib - lib64 - ) +# Try each search configuration. +foreach(search ${_ASSETIMPORT_SEARCHES}) + find_path(ASSETIMPORT_INCLUDE_DIR + NAMES assimp/postprocess.h assimp/scene.h assimp/version.h assimp/config.h assimp/cimport.h + ${${search}} PATH_SUFFIXES include) + find_library(ASSETIMPORT_LIBRARY + NAMES ${ASSETIMPORT_NAMES} + ${${search}} PATH_SUFFIXES lib lib64 bin) +endforeach() # Handle the QUIETLY and REQUIRED arguments and set assetimport_FOUND. -find_package_handle_standard_args (ASSETIMPORT DEFAULT_MSG - ASSETIMPORT_INCLUDE_DIR +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (ASSETIMPORT REQUIRED_VARS ASSETIMPORT_LIBRARY + ASSETIMPORT_INCLUDE_DIR ) # Set the output variables. diff --git a/misc/CMake/FindAppleseed.cmake b/misc/CMake/FindAppleseed.cmake index ebe8f319f8f..187744bd750 100644 --- a/misc/CMake/FindAppleseed.cmake +++ b/misc/CMake/FindAppleseed.cmake @@ -52,7 +52,7 @@ find_path (Appleseed_INCLUDE_DIR renderer/api/project.h ) find_library (Appleseed_LIBRARY - NAMES Appleseed + NAMES Appleseed appleseed HINTS ${Appleseed_ROOT} PATH_SUFFIXES diff --git a/misc/CMake/FindLEMON.cmake b/misc/CMake/FindLEMON.cmake index 59db72763cb..65455856eee 100644 --- a/misc/CMake/FindLEMON.cmake +++ b/misc/CMake/FindLEMON.cmake @@ -86,7 +86,7 @@ endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) # look for the template in bin dir - get_filename_component(lemon_path ${LEMON_EXECUTABLE} PATH) + get_filename_component(lemon_path ${LEMON_EXECUTABLE} DIRECTORY) if (lemon_path) if (EXISTS ${lemon_path}/lempar.c) set (LEMON_TEMPLATE "${lemon_path}/lempar.c") @@ -153,7 +153,7 @@ if(NOT COMMAND LEMON_TARGET) if ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c) else ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} PATH) + get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_SRC_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") @@ -164,7 +164,7 @@ if(NOT COMMAND LEMON_TARGET) if ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h) else ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} PATH) + get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_HDR_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") diff --git a/misc/CMake/FindLINENOISE.cmake b/misc/CMake/FindLINENOISE.cmake new file mode 100644 index 00000000000..33983b13eb4 --- /dev/null +++ b/misc/CMake/FindLINENOISE.cmake @@ -0,0 +1,76 @@ +#.rst: +# FindLINENOISE +# -------- +# +# Find the native LINENOISE includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``LINENOISE::LINENOISE``, if +# LINENOISE has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# LINENOISE_INCLUDE_DIRS - where to find linenoise.h, etc. +# LINENOISE_LIBRARIES - List of libraries when using linenoise. +# LINENOISE_FOUND - True if linenoise found. +# +# Hints +# ^^^^^ +# +# A user may set ``LINENOISE_ROOT`` to a linenoise installation root to tell this +# module where to look. + +#============================================================================= +# Copyright 2001-2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_LINENOISE_SEARCHES) + +# Search LINENOISE_ROOT first if it is set. +if(LINENOISE_ROOT) + set(_LINENOISE_SEARCH_ROOT PATHS ${LINENOISE_ROOT} NO_DEFAULT_PATH) + list(APPEND _LINENOISE_SEARCHES _LINENOISE_SEARCH_ROOT) +endif() + +set(LINENOISE_NAMES linenoise linenoised) + +# Try each search configuration. +foreach(search ${_LINENOISE_SEARCHES}) + find_path(LINENOISE_INCLUDE_DIR NAMES linenoise.h ${${search}} PATH_SUFFIXES include include/linenoise) + find_library(LINENOISE_LIBRARY NAMES ${LINENOISE_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() + +mark_as_advanced(LINENOISE_LIBRARY LINENOISE_INCLUDE_DIR) + +# handle the QUIETLY and REQUIRED arguments and set LINENOISE_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LINENOISE REQUIRED_VARS LINENOISE_LIBRARY LINENOISE_INCLUDE_DIR) + +if(LINENOISE_FOUND) + set(LINENOISE_INCLUDE_DIRS ${LINENOISE_INCLUDE_DIR}) + set(LINENOISE_LIBRARIES ${LINENOISE_LIBRARY}) + + if(NOT TARGET LINENOISE::LINENOISE) + add_library(LINENOISE::LINENOISE UNKNOWN IMPORTED) + set_target_properties(LINENOISE::LINENOISE PROPERTIES + IMPORTED_LOCATION "${LINENOISE_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LINENOISE_INCLUDE_DIRS}") + endif() +endif() diff --git a/misc/CMake/FindLMDB.cmake b/misc/CMake/FindLMDB.cmake new file mode 100644 index 00000000000..dd0a5955a5c --- /dev/null +++ b/misc/CMake/FindLMDB.cmake @@ -0,0 +1,76 @@ +#.rst: +# FindLMDB +# -------- +# +# Find the native LMDB includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``LMDB::LMDB``, if +# LMDB has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# LMDB_INCLUDE_DIRS - where to find lmdb.h, etc. +# LMDB_LIBRARIES - List of libraries when using lmdb. +# LMDB_FOUND - True if lmdb found. +# +# Hints +# ^^^^^ +# +# A user may set ``LMDB_ROOT`` to a lmdb installation root to tell this +# module where to look. + +#============================================================================= +# Copyright 2001-2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_LMDB_SEARCHES) + +# Search LMDB_ROOT first if it is set. +if(LMDB_ROOT) + set(_LMDB_SEARCH_ROOT PATHS ${LMDB_ROOT} NO_DEFAULT_PATH) + list(APPEND _LMDB_SEARCHES _LMDB_SEARCH_ROOT) +endif() + +set(LMDB_NAMES lmdb lmdbd) + +# Try each search configuration. +foreach(search ${_LMDB_SEARCHES}) + find_path(LMDB_INCLUDE_DIR NAMES lmdb.h ${${search}} PATH_SUFFIXES include include/lmdb) + find_library(LMDB_LIBRARY NAMES ${LMDB_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() + +mark_as_advanced(LMDB_LIBRARY LMDB_INCLUDE_DIR) + +# handle the QUIETLY and REQUIRED arguments and set LMDB_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LMDB REQUIRED_VARS LMDB_LIBRARY LMDB_INCLUDE_DIR) + +if(LMDB_FOUND) + set(LMDB_INCLUDE_DIRS ${LMDB_INCLUDE_DIR}) + set(LMDB_LIBRARIES ${LMDB_LIBRARY}) + + if(NOT TARGET LMDB::LMDB) + add_library(LMDB::LMDB UNKNOWN IMPORTED) + set_target_properties(LMDB::LMDB PROPERTIES + IMPORTED_LOCATION "${LMDB_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LMDB_INCLUDE_DIRS}") + endif() +endif() diff --git a/misc/CMake/FindMANIFOLD.cmake b/misc/CMake/FindMANIFOLD.cmake new file mode 100644 index 00000000000..2e7e37c94f9 --- /dev/null +++ b/misc/CMake/FindMANIFOLD.cmake @@ -0,0 +1,94 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindMANIFOLD +-------- + +Find the native MANIFOLD includes and library. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``MANIFOLD::MANIFOLD``, if +MANIFOLD has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +:: + + MANIFOLD_INCLUDE_DIRS - where to find manifold/manifold.h, etc. + MANIFOLD_LIBRARIES - List of libraries when using Manifold. + MANIFOLD_FOUND - True if Manifold found. + +Hints +^^^^^ + +A user may set ``MANIFOLD_ROOT`` to a Manifold installation root to tell this +module where to look. +#]=======================================================================] + +set(_MANIFOLD_SEARCHES) + +# Search MANIFOLD_ROOT first if it is set. +if(MANIFOLD_ROOT) + set(_MANIFOLD_SEARCH_ROOT PATHS ${MANIFOLD_ROOT} NO_DEFAULT_PATH) + list(APPEND _MANIFOLD_SEARCHES _MANIFOLD_SEARCH_ROOT) +endif() + +set(MANIFOLD_NAMES manifold) + +# Try each search configuration. +foreach(search ${_MANIFOLD_SEARCHES}) + find_path(MANIFOLD_INCLUDE_DIR NAMES manifold.h ${${search}} PATH_SUFFIXES include include/manifold) +endforeach() + +# Allow MANIFOLD_LIBRARY to be set manually, as the location of the Manifold library +if(NOT MANIFOLD_LIBRARY) + foreach(search ${_MANIFOLD_SEARCHES}) + find_library(MANIFOLD_LIBRARY NAMES ${MANIFOLD_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + endforeach() +endif() + +unset(MANIFOLD_NAMES) + +mark_as_advanced(MANIFOLD_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MANIFOLD REQUIRED_VARS MANIFOLD_LIBRARY MANIFOLD_INCLUDE_DIR) + +if(MANIFOLD_FOUND) + set(MANIFOLD_INCLUDE_DIRS ${MANIFOLD_INCLUDE_DIR}) + + if(NOT MANIFOLD_LIBRARIES) + set(MANIFOLD_LIBRARIES ${MANIFOLD_LIBRARY}) + endif() + + if(NOT TARGET MANIFOLD::MANIFOLD) + add_library(MANIFOLD::MANIFOLD UNKNOWN IMPORTED) + set_target_properties(MANIFOLD::MANIFOLD PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${MANIFOLD_INCLUDE_DIRS}") + + if(MANIFOLD_LIBRARY_RELEASE) + set_property(TARGET MANIFOLD::MANIFOLD APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(MANIFOLD::MANIFOLD PROPERTIES + IMPORTED_LOCATION_RELEASE "${MANIFOLD_LIBRARY_RELEASE}") + endif() + + if(MANIFOLD_LIBRARY_DEBUG) + set_property(TARGET MANIFOLD::MANIFOLD APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(MANIFOLD::MANIFOLD PROPERTIES + IMPORTED_LOCATION_DEBUG "${MANIFOLD_LIBRARY_DEBUG}") + endif() + + if(NOT MANIFOLD_LIBRARY_RELEASE AND NOT MANIFOLD_LIBRARY_DEBUG) + set_property(TARGET MANIFOLD::MANIFOLD APPEND PROPERTY + IMPORTED_LOCATION "${MANIFOLD_LIBRARY}") + endif() + endif() +endif() diff --git a/misc/CMake/FindOPENNURBS.cmake b/misc/CMake/FindOPENNURBS.cmake index f9f8c6a35b4..1624167fc87 100644 --- a/misc/CMake/FindOPENNURBS.cmake +++ b/misc/CMake/FindOPENNURBS.cmake @@ -52,6 +52,7 @@ set(OPENNURBS_NAMES openNURBS) # Try each search configuration. foreach(search ${_OPENNURBS_SEARCHES}) find_path(OPENNURBS_INCLUDE_DIR NAMES opennurbs.h ${${search}} PATH_SUFFIXES include include/openNURBS openNURBS) + find_path(OPENNURBS_X_INCLUDE_DIR NAMES opennurbs_x.h ${${search}} PATH_SUFFIXES include include/openNURBS openNURBS) endforeach() # Allow OPENNURBS_LIBRARY to be set manually, as the location of the openNURBS library @@ -66,7 +67,7 @@ unset(OPENNURBS_NAMES) mark_as_advanced(OPENNURBS_INCLUDE_DIR) include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENNURBS REQUIRED_VARS OPENNURBS_LIBRARY OPENNURBS_INCLUDE_DIR) +find_package_handle_standard_args(OPENNURBS REQUIRED_VARS OPENNURBS_LIBRARY OPENNURBS_INCLUDE_DIR OPENNURBS_X_INCLUDE_DIR) if(OPENNURBS_FOUND) set(OPENNURBS_INCLUDE_DIRS ${OPENNURBS_INCLUDE_DIR}) diff --git a/misc/CMake/FindOSMESA.cmake b/misc/CMake/FindOSMESA.cmake new file mode 100644 index 00000000000..6f0f89a37fe --- /dev/null +++ b/misc/CMake/FindOSMESA.cmake @@ -0,0 +1,94 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindOSMESA +-------- + +Find the native OSMESA includes and library. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``OSMESA::OSMESA``, if +OSMESA has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +:: + + OSMESA_INCLUDE_DIRS - where to find osmesa.h, etc. + OSMESA_LIBRARIES - List of libraries when using openNURBS. + OSMESA_FOUND - True if openNURBS found. + +Hints +^^^^^ + +A user may set ``OSMESA_ROOT`` to a openNURBS installation root to tell this +module where to look. +#]=======================================================================] + +set(_OSMESA_SEARCHES) + +# Search OSMESA_ROOT first if it is set. +if(OSMESA_ROOT) + set(_OSMESA_SEARCH_ROOT PATHS ${OSMESA_ROOT} NO_DEFAULT_PATH) + list(APPEND _OSMESA_SEARCHES _OSMESA_SEARCH_ROOT) +endif() + +set(OSMESA_NAMES osmesa OSMesa) + +# Try each search configuration. +foreach(search ${_OSMESA_SEARCHES}) + find_path(OSMESA_INCLUDE_DIR NAMES osmesa.h ${${search}} PATH_SUFFIXES include include/OSMesa OSMesa) +endforeach() + +# Allow OSMESA_LIBRARY to be set manually, as the location of the openNURBS library +if(NOT OSMESA_LIBRARY) + foreach(search ${_OSMESA_SEARCHES}) + find_library(OSMESA_LIBRARY NAMES ${OSMESA_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + endforeach() +endif() + +unset(OSMESA_NAMES) + +mark_as_advanced(OSMESA_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OSMESA REQUIRED_VARS OSMESA_LIBRARY OSMESA_INCLUDE_DIR) + +if(OSMESA_FOUND) + set(OSMESA_INCLUDE_DIRS ${OSMESA_INCLUDE_DIR}) + + if(NOT OSMESA_LIBRARIES) + set(OSMESA_LIBRARIES ${OSMESA_LIBRARY}) + endif() + + if(NOT TARGET OSMESA::OSMESA) + add_library(OSMESA::OSMESA UNKNOWN IMPORTED) + set_target_properties(OSMESA::OSMESA PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OSMESA_INCLUDE_DIRS}") + + if(OSMESA_LIBRARY_RELEASE) + set_property(TARGET OSMESA::OSMESA APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(OSMESA::OSMESA PROPERTIES + IMPORTED_LOCATION_RELEASE "${OSMESA_LIBRARY_RELEASE}") + endif() + + if(OSMESA_LIBRARY_DEBUG) + set_property(TARGET OSMESA::OSMESA APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(OSMESA::OSMESA PROPERTIES + IMPORTED_LOCATION_DEBUG "${OSMESA_LIBRARY_DEBUG}") + endif() + + if(NOT OSMESA_LIBRARY_RELEASE AND NOT OSMESA_LIBRARY_DEBUG) + set_property(TARGET OSMESA::OSMESA APPEND PROPERTY + IMPORTED_LOCATION "${OSMESA_LIBRARY}") + endif() + endif() +endif() diff --git a/misc/CMake/FindOpenCV.cmake b/misc/CMake/FindOpenCV.cmake new file mode 100644 index 00000000000..68d629da5a4 --- /dev/null +++ b/misc/CMake/FindOpenCV.cmake @@ -0,0 +1,160 @@ +########################################################### +# Find OpenCV Library +# See http://sourceforge.net/projects/opencvlibrary/ +#---------------------------------------------------------- +# +## 1: Setup: +# The following variables are optionally searched for defaults +# OpenCV_DIR: Base directory of OpenCv tree to use. +# +## 2: Variable +# The following are set after configuration is done: +# +# OpenCV_FOUND +# OpenCV_LIBS +# OpenCV_INCLUDE_DIR +# OpenCV_VERSION (OpenCV_VERSION_MAJOR, OpenCV_VERSION_MINOR, OpenCV_VERSION_PATCH) +# +# +# Deprecated variable are used to maintain backward compatibility with +# the script of Jan Woetzel (2006/09): www.mip.informatik.uni-kiel.de/~jw +# OpenCV_INCLUDE_DIRS +# OpenCV_LIBRARIES +# OpenCV_LINK_DIRECTORIES +# +## 3: Version +# +# 2010/04/07 Benoit Rat, Correct a bug when OpenCVConfig.cmake is not found. +# 2010/03/24 Benoit Rat, Add compatibility for when OpenCVConfig.cmake is not found. +# 2010/03/22 Benoit Rat, Creation of the script. +# +# +# tested with: +# - OpenCV 2.1: MinGW, MSVC2008 +# - OpenCV 2.0: MinGW, MSVC2008, GCC4 +# +# +## 4: Licence: +# +# LGPL 2.1 : GNU Lesser General Public License Usage +# Alternatively, this file may be used under the terms of the GNU Lesser + +# General Public License version 2.1 as published by the Free Software +# Foundation and appearing in the file LICENSE.LGPL included in the +# packaging of this file. Please review the following information to +# ensure the GNU Lesser General Public License version 2.1 requirements +# will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +# +#---------------------------------------------------------- + + +find_path(OpenCV_DIR "OpenCVConfig.cmake" /usr/share/OpenCV DOC "Root directory of OpenCV") + +##==================================================== +## Find OpenCV libraries +##---------------------------------------------------- +if(EXISTS "${OpenCV_DIR}") + + #When its possible to use the Config script use it. + if(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") + + ## Include the standard CMake script + include("${OpenCV_DIR}/OpenCVConfig.cmake") + + ## Search for a specific version + set(CVLIB_SUFFIX "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}") + + #Otherwise it try to guess it. + else(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") + + set(OPENCV_LIB_COMPONENTS cxcore cv ml highgui cvaux) + find_path(OpenCV_INCLUDE_DIR "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "") + if(EXISTS ${OpenCV_INCLUDE_DIR}) + include_directories(${OpenCV_INCLUDE_DIR}) + endif(EXISTS ${OpenCV_INCLUDE_DIR}) + + #Find OpenCV version by looking at cvver.h + file(STRINGS ${OpenCV_INCLUDE_DIR}/cvver.h OpenCV_VERSIONS_TMP REGEX "^#define CV_[A-Z]+_VERSION[ \t]+[0-9]+$") + string(REGEX REPLACE ".*#define CV_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_MAJOR ${OpenCV_VERSIONS_TMP}) + string(REGEX REPLACE ".*#define CV_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_MINOR ${OpenCV_VERSIONS_TMP}) + string(REGEX REPLACE ".*#define CV_SUBMINOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_PATCH ${OpenCV_VERSIONS_TMP}) + set(OpenCV_VERSION ${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH} CACHE STRING "" FORCE) + set(CVLIB_SUFFIX "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}") + + endif(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") + + + + + ## Initiate the variable before the loop + set(GLOBAL OpenCV_LIBS "") + set(OpenCV_FOUND_TMP true) + + ## Loop over each components + foreach(__CVLIB ${OPENCV_LIB_COMPONENTS}) + + find_library(OpenCV_${__CVLIB}_LIBRARY_DEBUG NAMES "${__CVLIB}${CVLIB_SUFFIX}d" "lib${__CVLIB}${CVLIB_SUFFIX}d" PATHS "${OpenCV_DIR}/lib" NO_DEFAULT_PATH) + find_library(OpenCV_${__CVLIB}_LIBRARY_RELEASE NAMES "${__CVLIB}${CVLIB_SUFFIX}" "lib${__CVLIB}${CVLIB_SUFFIX}" PATHS "${OpenCV_DIR}/lib" NO_DEFAULT_PATH) + + #Remove the cache value + set(OpenCV_${__CVLIB}_LIBRARY "" CACHE STRING "" FORCE) + + #both debug/release + if(OpenCV_${__CVLIB}_LIBRARY_DEBUG AND OpenCV_${__CVLIB}_LIBRARY_RELEASE) + set(OpenCV_${__CVLIB}_LIBRARY debug ${OpenCV_${__CVLIB}_LIBRARY_DEBUG} optimized ${OpenCV_${__CVLIB}_LIBRARY_RELEASE} CACHE STRING "" FORCE) + #only debug + elseif(OpenCV_${__CVLIB}_LIBRARY_DEBUG) + set(OpenCV_${__CVLIB}_LIBRARY ${OpenCV_${__CVLIB}_LIBRARY_DEBUG} CACHE STRING "" FORCE) + #only release + elseif(OpenCV_${__CVLIB}_LIBRARY_RELEASE) + set(OpenCV_${__CVLIB}_LIBRARY ${OpenCV_${__CVLIB}_LIBRARY_RELEASE} CACHE STRING "" FORCE) + #no library found + else() + set(OpenCV_FOUND_TMP false) + endif() + + #Add to the general list + if(OpenCV_${__CVLIB}_LIBRARY) + set(OpenCV_LIBS ${OpenCV_LIBS} ${OpenCV_${__CVLIB}_LIBRARY}) + endif(OpenCV_${__CVLIB}_LIBRARY) + + endforeach(__CVLIB) + + + set(OpenCV_FOUND ${OpenCV_FOUND_TMP} CACHE BOOL "" FORCE) + + +else(EXISTS "${OpenCV_DIR}") + set(ERR_MSG "Please specify OpenCV directory using OpenCV_DIR env. variable") +endif(EXISTS "${OpenCV_DIR}") +##==================================================== + + +##==================================================== +## Print message +##---------------------------------------------------- +if(NOT OpenCV_FOUND) + # make FIND_PACKAGE friendly + if(NOT OpenCV_FIND_QUIETLY) + if(OpenCV_FIND_REQUIRED) + message(FATAL_ERROR "OpenCV required but some headers or libs not found. ${ERR_MSG}") + else(OpenCV_FIND_REQUIRED) + message(STATUS "WARNING: OpenCV was not found. ${ERR_MSG}") + endif(OpenCV_FIND_REQUIRED) + endif(NOT OpenCV_FIND_QUIETLY) +endif(NOT OpenCV_FOUND) +##==================================================== + + +##==================================================== +## Backward compatibility +##---------------------------------------------------- +if(OpenCV_FOUND) + option(OpenCV_BACKWARD_COMPA "Add some variable to make this script compatible with the other version of FindOpenCV.cmake" false) + if(OpenCV_BACKWARD_COMPA) + find_path(OpenCV_INCLUDE_DIRS "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "Include directory") + find_path(OpenCV_INCLUDE_DIR "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "Include directory") + set(OpenCV_LIBRARIES "${OpenCV_LIBS}" CACHE STRING "" FORCE) + endif(OpenCV_BACKWARD_COMPA) +endif(OpenCV_FOUND) +##==================================================== diff --git a/misc/CMake/FindOpenMesh.cmake b/misc/CMake/FindOpenMesh.cmake index caf4784ee87..72b8f59e6ed 100644 --- a/misc/CMake/FindOpenMesh.cmake +++ b/misc/CMake/FindOpenMesh.cmake @@ -59,94 +59,41 @@ #=========================================================================== #if already found via finder or simulated finder in openmesh CMakeLists.txt, skip the search -IF (NOT OPENMESH_FOUND) - SET (SEARCH_PATHS - "${OPENMESH_ROOT}" - /usr/local/ - /usr/ - "${CMAKE_SOURCE_DIR}/OpenMesh/src/OpenMesh" - "${CMAKE_SOURCE_DIR}/libs_required/OpenMesh/src/OpenMesh" - "${CMAKE_SOURCE_DIR}/../OpenMesh/src/OpenMesh" - "C:/Program Files/OpenMesh 8.1" - "C:/Program Files/OpenMesh 8.0" - "C:/Program Files/OpenMesh 7.2" - "C:/Program Files/OpenMesh 7.1" - "C:/Program Files/OpenMesh 7.0" - "C:/Program Files/OpenMesh 6.3" - "C:/Program Files/OpenMesh 6.2" - "C:/Program Files/OpenMesh 6.1" - "C:/Program Files/OpenMesh 6.0" - "C:/Program Files/OpenMesh 5.2" - "C:/Program Files/OpenMesh 5.1" - "C:/Program Files/OpenMesh 5.0" - "C:/Program Files/OpenMesh 4.2" - "C:/Program Files/OpenMesh 4.1" - "C:/Program Files/OpenMesh 4.0" - "C:/Program Files/OpenMesh 3.4" - "C:/Program Files/OpenMesh 3.3" - "C:/Program Files/OpenMesh 3.2" - "C:/Program Files/OpenMesh 3.1" - "C:/Program Files/OpenMesh 3.0" - "C:/Program Files/OpenMesh 2.4.1" - "C:/Program Files/OpenMesh 2.4" - "C:/Program Files/OpenMesh 2.0/include" - "C:/libs/OpenMesh 8.1" - "C:/libs/OpenMesh 8.0" - "C:/libs/OpenMesh 7.1" - "C:/libs/OpenMesh 7.0" - "C:/libs/OpenMesh 6.3" - "C:/libs/OpenMesh 6.2" - "C:/libs/OpenMesh 6.1" - "C:/libs/OpenMesh 6.0" - "C:/libs/OpenMesh 5.2" - "C:/libs/OpenMesh 5.1" - "C:/libs/OpenMesh 5.0" - "C:/libs/OpenMesh 4.2" - "C:/libs/OpenMesh 4.1" - "C:/libs/OpenMesh 4.0" - "C:/libs/OpenMesh 3.4" - "C:/libs/OpenMesh 3.3" - "C:/libs/OpenMesh 3.2" - "C:/libs/OpenMesh 3.1" - "C:/libs/OpenMesh 3.0" - "C:/libs/OpenMesh 2.4.1" - "C:/libs/OpenMesh 2.4" - "${OPENMESH_LIBRARY_DIR}" - ) +if(NOT OPENMESH_FOUND) + set(SEARCH_PATHS + "${OpenMesh_ROOT}" + /usr/local/ + /usr/ + "${CMAKE_SOURCE_DIR}/OpenMesh/src/OpenMesh" + "${CMAKE_SOURCE_DIR}/libs_required/OpenMesh/src/OpenMesh" + "${CMAKE_SOURCE_DIR}/../OpenMesh/src/OpenMesh" + "C:/Program Files/OpenMesh 8.1" + "C:/libs/OpenMesh 8.1" + "C:/libs/OpenMesh 8.0" + "${OPENMESH_LIBRARY_DIR}" + ) - FIND_PATH (OPENMESH_INCLUDE_DIR OpenMesh/Core/Mesh/PolyMeshT.hh - PATHS ${SEARCH_PATHS} - PATH_SUFFIXES include) + foreach(sp ${SEARCH_PATHS}) + find_path(OPENMESH_INCLUDE_DIR NAMES OpenMesh/Core/Mesh/PolyMeshT.hh ${sp} PATH_SUFFIXES include) + find_library(OPENMESH_CORE_LIBRARY_RELEASE NAMES OpenMeshCore ${sp} PATH_SUFFIXES lib lib64) + find_library(OPENMESH_CORE_LIBRARY_DEBUG NAMES OpenMeshCored ${sp} PATH_SUFFIXES lib lib64) + find_library(OPENMESH_TOOLS_LIBRARY_RELEASE NAMES OpenMeshTools ${sp} PATH_SUFFIXES lib lib64) + find_library(OPENMESH_TOOLS_LIBRARY_DEBUG NAMES OpenMeshToolsd ${sp} PATH_SUFFIXES lib lib64) + endforeach(sp ${SEARCH_PATHS}) - FIND_LIBRARY(OPENMESH_CORE_LIBRARY_RELEASE NAMES OpenMeshCore - PATHS ${SEARCH_PATHS} - PATH_SUFFIXES lib lib64) + #select configuration depending on platform (optimized... on windows) + include(SelectLibraryConfigurations) + select_library_configurations(OPENMESH_TOOLS) + select_library_configurations(OPENMESH_CORE) - FIND_LIBRARY(OPENMESH_CORE_LIBRARY_DEBUG NAMES OpenMeshCored - PATHS ${SEARCH_PATHS} - PATH_SUFFIXES lib lib64) + set(OPENMESH_LIBRARIES ${OPENMESH_CORE_LIBRARY} ${OPENMESH_TOOLS_LIBRARY} CACHE STRING "OpenMesh Core and Tools libraries" FORCE) + set(OPENMESH_INCLUDE_DIRS ${OPENMESH_INCLUDE_DIR} CACHE STRING "OpenMesh include directory" FORCE) - FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_RELEASE NAMES OpenMeshTools - PATHS ${SEARCH_PATHS} - PATH_SUFFIXES lib lib64) + #checks, if OPENMESH was found and sets OPENMESH_FOUND if so + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(OpenMesh DEFAULT_MSG + OPENMESH_CORE_LIBRARY OPENMESH_TOOLS_LIBRARY OPENMESH_INCLUDE_DIR) - FIND_LIBRARY(OPENMESH_TOOLS_LIBRARY_DEBUG NAMES OpenMeshToolsd - PATHS ${SEARCH_PATHS} - PATH_SUFFIXES lib lib64) - -#select configuration depending on platform (optimized... on windows) - include(SelectLibraryConfigurations) - select_library_configurations( OPENMESH_TOOLS ) - select_library_configurations( OPENMESH_CORE ) - - set(OPENMESH_LIBRARIES ${OPENMESH_CORE_LIBRARY} ${OPENMESH_TOOLS_LIBRARY} CACHE STRING "OpenMesh Core and Tools libraries" FORCE) - set(OPENMESH_INCLUDE_DIRS ${OPENMESH_INCLUDE_DIR} CACHE STRING "OpenMesh include directory" FORCE) - -#checks, if OPENMESH was found and sets OPENMESH_FOUND if so - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(OpenMesh DEFAULT_MSG - OPENMESH_CORE_LIBRARY OPENMESH_TOOLS_LIBRARY OPENMESH_INCLUDE_DIR) - - - mark_as_advanced(OPENMESH_INCLUDE_DIR OPENMESH_CORE_LIBRARY_RELEASE OPENMESH_CORE_LIBRARY_DEBUG OPENMESH_TOOLS_LIBRARY_RELEASE OPENMESH_TOOLS_LIBRARY_DEBUG) + mark_as_advanced(OPENMESH_INCLUDE_DIR OPENMESH_CORE_LIBRARY_RELEASE OPENMESH_CORE_LIBRARY_DEBUG OPENMESH_TOOLS_LIBRARY_RELEASE OPENMESH_TOOLS_LIBRARY_DEBUG) endif() + diff --git a/misc/CMake/FindPERPLEX.cmake b/misc/CMake/FindPERPLEX.cmake index 789452217a6..ccbbeea7a89 100644 --- a/misc/CMake/FindPERPLEX.cmake +++ b/misc/CMake/FindPERPLEX.cmake @@ -74,7 +74,7 @@ endforeach() mark_as_advanced(PERPLEX_TEMPLATE) if(PERPLEX_EXECUTABLE AND NOT PERPLEX_TEMPLATE) - get_filename_component(perplex_path ${PERPLEX_EXECUTABLE} PATH) + get_filename_component(perplex_path ${PERPLEX_EXECUTABLE} DIRECTORY) if(perplex_path) set(PERPLEX_TEMPLATE "") if(EXISTS ${perplex_path}/../share/perplex/perplex_template.c) @@ -187,7 +187,7 @@ if(NOT COMMAND PERPLEX_TARGET) if ("${${PVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") set(${PVAR_PREFIX}_OUT_SRC_FILE ${${PVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c) else ("${${PVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${PVAR_PREFIX}_OUT_SRC_FILE} PATH) + get_filename_component(specified_out_dir ${${PVAR_PREFIX}_OUT_SRC_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_SRC_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") @@ -198,7 +198,7 @@ if(NOT COMMAND PERPLEX_TARGET) if ("${${PVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") set(${PVAR_PREFIX}_OUT_HDR_FILE ${${PVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h) else ("${${PVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${PVAR_PREFIX}_OUT_HDR_FILE} PATH) + get_filename_component(specified_out_dir ${${PVAR_PREFIX}_OUT_HDR_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_HDR_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") diff --git a/misc/CMake/FindPNG.cmake b/misc/CMake/FindPNG.cmake new file mode 100644 index 00000000000..7e3649c0c12 --- /dev/null +++ b/misc/CMake/FindPNG.cmake @@ -0,0 +1,161 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPNG +------- + +Find libpng, the official reference library for the PNG image format. + +Imported targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.5 + +This module defines the following :prop_tgt:`IMPORTED` target: + +``PNG::PNG`` + The libpng library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``PNG_INCLUDE_DIRS`` + where to find png.h, etc. +``PNG_LIBRARIES`` + the libraries to link against to use PNG. +``PNG_DEFINITIONS`` + You should add_definitions(${PNG_DEFINITIONS}) before compiling code + that includes png library files. +``PNG_FOUND`` + If false, do not try to use PNG. +``PNG_VERSION_STRING`` + the version of the PNG library found (since CMake 2.8.8) + +Obsolete variables +^^^^^^^^^^^^^^^^^^ + +The following variables may also be set, for backwards compatibility: + +``PNG_LIBRARY`` + where to find the PNG library. +``PNG_INCLUDE_DIR`` + where to find the PNG headers (same as PNG_INCLUDE_DIRS) + +Since PNG depends on the ZLib compression library, none of the above +will be defined unless ZLib can be found. +#]=======================================================================] + +if(PNG_FIND_QUIETLY) + set(_FIND_ZLIB_ARG QUIET) +endif() +find_package(ZLIB ${_FIND_ZLIB_ARG}) + +if(ZLIB_FOUND) + find_path(PNG_PNG_INCLUDE_DIR png.h PATH_SUFFIXES include/libpng) + mark_as_advanced(PNG_PNG_INCLUDE_DIR) + + list(APPEND PNG_NAMES png_brl libpng_brl png libpng) + unset(PNG_NAMES_DEBUG) + set(_PNG_VERSION_SUFFIXES 17 16 15 14 12) + if (PNG_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)(\\..*)?$") + set(_PNG_VERSION_SUFFIX_MIN "${CMAKE_MATCH_1}${CMAKE_MATCH_2}") + if (PNG_FIND_VERSION_EXACT) + set(_PNG_VERSION_SUFFIXES ${_PNG_VERSION_SUFFIX_MIN}) + else () + string(REGEX REPLACE + "${_PNG_VERSION_SUFFIX_MIN}.*" "${_PNG_VERSION_SUFFIX_MIN}" + _PNG_VERSION_SUFFIXES "${_PNG_VERSION_SUFFIXES}") + endif () + unset(_PNG_VERSION_SUFFIX_MIN) + endif () + foreach(v IN LISTS _PNG_VERSION_SUFFIXES) + list(APPEND PNG_NAMES png_brl${v} libpng_brl${v} png${v} libpng${v} libpng${v}_static) + list(APPEND PNG_NAMES_DEBUG png_brl${v}d libpng_brl${v}d png${v}d libpng${v}d libpng${v}_staticd) + endforeach() + unset(_PNG_VERSION_SUFFIXES) + # For compatibility with versions prior to this multi-config search, honor + # any PNG_LIBRARY that is already specified and skip the search. + if(NOT PNG_LIBRARY) + find_library(PNG_LIBRARY_RELEASE NAMES ${PNG_NAMES} NAMES_PER_DIR) + find_library(PNG_LIBRARY_DEBUG NAMES ${PNG_NAMES_DEBUG} NAMES_PER_DIR) + include(SelectLibraryConfigurations) + select_library_configurations(PNG) + mark_as_advanced(PNG_LIBRARY_RELEASE PNG_LIBRARY_DEBUG) + endif() + unset(PNG_NAMES) + unset(PNG_NAMES_DEBUG) + + # Set by select_library_configurations(), but we want the one from + # find_package_handle_standard_args() below. + unset(PNG_FOUND) + + if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR) + # png.h includes zlib.h. Sigh. + set(PNG_INCLUDE_DIRS ${PNG_PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) + set(PNG_INCLUDE_DIR ${PNG_INCLUDE_DIRS} ) # for backward compatibility + set(PNG_LIBRARIES ${PNG_LIBRARY} ${ZLIB_LIBRARY}) + if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND + ("${PNG_LIBRARY}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$")) + list(APPEND PNG_LIBRARIES m) + endif() + + if (CYGWIN) + if(BUILD_SHARED_LIBS) + # No need to define PNG_USE_DLL here, because it's default for Cygwin. + else() + set (PNG_DEFINITIONS -DPNG_STATIC) + set(_PNG_COMPILE_DEFINITIONS PNG_STATIC) + endif() + endif () + + if(NOT TARGET PNG::PNG) + add_library(PNG::PNG UNKNOWN IMPORTED) + set_target_properties(PNG::PNG PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "${_PNG_COMPILE_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES ZLIB::ZLIB) + if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND + ("${PNG_LIBRARY}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$")) + set_property(TARGET PNG::PNG APPEND PROPERTY + INTERFACE_LINK_LIBRARIES m) + endif() + + if(EXISTS "${PNG_LIBRARY}") + set_target_properties(PNG::PNG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${PNG_LIBRARY}") + endif() + if(EXISTS "${PNG_LIBRARY_RELEASE}") + set_property(TARGET PNG::PNG APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(PNG::PNG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${PNG_LIBRARY_RELEASE}") + endif() + if(EXISTS "${PNG_LIBRARY_DEBUG}") + set_property(TARGET PNG::PNG APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(PNG::PNG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${PNG_LIBRARY_DEBUG}") + endif() + endif() + + unset(_PNG_COMPILE_DEFINITIONS) + endif () + + if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h") + file(STRINGS "${PNG_PNG_INCLUDE_DIR}/png.h" png_version_str REGEX "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\".+\"") + + string(REGEX REPLACE "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\"([^\"]+)\".*" "\\1" PNG_VERSION_STRING "${png_version_str}") + unset(png_version_str) + endif () +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PNG + REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR + VERSION_VAR PNG_VERSION_STRING) diff --git a/misc/CMake/FindREGEX.cmake b/misc/CMake/FindREGEX.cmake index 0c757f2b461..2a644986365 100644 --- a/misc/CMake/FindREGEX.cmake +++ b/misc/CMake/FindREGEX.cmake @@ -1,75 +1,84 @@ -# F I N D R E G E X . C M A K E -# BRL-CAD +#.rst: +# FindREGEX +# -------- # -# Copyright (c) 2011-2023 United States Government as represented by -# the U.S. Army Research Laboratory. +# Find the native REGEX includes and library. # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ # -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. +# This module defines :prop_tgt:`IMPORTED` target ``REGEX::REGEX``, if +# REGEX has been found. # -# 2. Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. +# Result Variables +# ^^^^^^^^^^^^^^^^ # -# 3. The name of the author may not be used to endorse or promote -# products derived from this software without specific prior written -# permission. +# This module defines the following variables: # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# :: # -### -# - Find regex -# Find the native REGEX includes and library +# REGEX_INCLUDE_DIRS - where to find regex.h, etc. +# REGEX_LIBRARIES - List of libraries when using regex. +# REGEX_FOUND - True if regex found. # -# REGEX_INCLUDE_DIRS - where to find regex.h, etc. -# REGEX_LIBRARIES - List of libraries when using regex. -# REGEX_FOUND - True if regex found. # +# Hints +# ^^^^^ +# +# A user may set ``REGEX_ROOT`` to a regex installation root to tell this +# module where to look. + +#============================================================================= +# Copyright 2001-2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. #============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_REGEX_SEARCHES) + +# Search REGEX_ROOT first if it is set. +if(REGEX_ROOT) + set(_REGEX_SEARCH_ROOT PATHS ${REGEX_ROOT} NO_DEFAULT_PATH) + list(APPEND _REGEX_SEARCHES _REGEX_SEARCH_ROOT) +endif() + +# Normal search. +set(_REGEX_SEARCH_NORMAL + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Regex;InstallPath]" + "$ENV{PROGRAMFILES}/regex" + ) +list(APPEND _REGEX_SEARCHES _REGEX_SEARCH_NORMAL) -# Because at least one specific framework (Ruby) on OSX has been observed -# to include its own regex.h copy, check frameworks last - /usr/include -# is preferred to a package-specific copy for a generic regex search -set(CMAKE_FIND_FRAMEWORK LAST) -find_path(REGEX_INCLUDE_DIRS regex.h) +set(REGEX_NAMES regex_brl regex_brld regex regexd regexd1) -set(REGEX_NAMES c regex compat) -foreach(rname ${REGEX_NAMES}) - if(NOT REGEX_LIBRARY) - include(CheckLibraryExists) - check_library_exists(${rname} regcomp "" HAVE_REGEX_LIB) - if(HAVE_REGEX_LIB) - find_library(REGEX_LIBRARIES NAMES ${rname}) - endif(HAVE_REGEX_LIB) - endif(NOT REGEX_LIBRARY) -endforeach(rname ${REGEX_NAMES}) +# Try each search configuration. +foreach(search ${_REGEX_SEARCHES}) + find_path(REGEX_INCLUDE_DIR NAMES regex.h ${${search}} PATH_SUFFIXES include) + find_library(REGEX_LIBRARY NAMES ${REGEX_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() mark_as_advanced(REGEX_LIBRARY REGEX_INCLUDE_DIR) # handle the QUIETLY and REQUIRED arguments and set REGEX_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(REGEX DEFAULT_MSG REGEX_INCLUDE_DIRS REGEX_LIBRARIES) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(REGEX REQUIRED_VARS REGEX_LIBRARY REGEX_INCLUDE_DIR) +if(REGEX_FOUND) + set(REGEX_INCLUDE_DIRS ${REGEX_INCLUDE_DIR}) + set(REGEX_LIBRARIES ${REGEX_LIBRARY}) -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 + if(NOT TARGET REGEX::REGEX) + add_library(REGEX::REGEX UNKNOWN IMPORTED) + set_target_properties(REGEX::REGEX PROPERTIES + IMPORTED_LOCATION "${REGEX_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${REGEX_INCLUDE_DIRS}") + endif() +endif() diff --git a/misc/CMake/FindSTEPCODE.cmake b/misc/CMake/FindSTEPCODE.cmake index 38030ef0879..b2fc62bfab5 100644 --- a/misc/CMake/FindSTEPCODE.cmake +++ b/misc/CMake/FindSTEPCODE.cmake @@ -51,18 +51,16 @@ # latter needed beyond the stepcode build itself? Trim this # to the minimum actually needed...) set(STEPCODE_HDRS - base/sc_benchmark.h cldai/sdaiObject.h cleditor/STEPfile.h clstepcore/sdai.h clutils/gennodearray.h exppp/exppp.h express/express.h - sc_cf.h + config.h ) set(STEPCODE_LIBS - base express exppp stepcore @@ -85,22 +83,24 @@ endif() # Try each search configuration. foreach(search ${_STEPCODE_SEARCHES}) - find_path(STEPCODE_BASE_DIR NAMES sc_benchmark.h ${${search}} PATH_SUFFIXES include include/stepcode/base) find_path(STEPCODE_DAI_DIR NAMES sdaiObject.h ${${search}} PATH_SUFFIXES include include/stepcode/cldai) find_path(STEPCODE_EDITOR_DIR NAMES STEPfile.h ${${search}} PATH_SUFFIXES include include/stepcode/cleditor) find_path(STEPCODE_STEPCORE_DIR NAMES sdai.h ${${search}} PATH_SUFFIXES include include/stepcode/clstepcore) find_path(STEPCODE_UTILS_DIR NAMES gennodearray.h ${${search}} PATH_SUFFIXES include include/stepcode/clutils) find_path(STEPCODE_EXPPP_DIR NAMES exppp.h ${${search}} PATH_SUFFIXES include include/stepcode/exppp) find_path(STEPCODE_EXPRESS_DIR NAMES express.h ${${search}} PATH_SUFFIXES include include/stepcode/express) - find_path(STEPCODE_INCLUDE_DIR NAMES sc_cf.h ${${search}} PATH_SUFFIXES include include/stepcode) + find_path(STEPCODE_INCLUDE_DIR NAMES config.h ${${search}} PATH_SUFFIXES include include/stepcode) #TODO - should be an all-or-nothing for the set... endforeach() # Allow STEPCODE_LIBRARY to be set manually, as the location of the netpbm library foreach(search ${_STEPCODE_SEARCHES}) - find_library(STEPCODE_BASE_LIBRARY NAMES base NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) find_library(STEPCODE_EXPRESS_LIBRARY NAMES express NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) - find_library(STEPCODE_EXPPP_LIBRARY NAMES exppp NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + if (HAVE_WINDOWS_H) + find_library(STEPCODE_EXPPP_LIBRARY NAMES libexppp NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + else (HAVE_WINDOWS_H) + find_library(STEPCODE_EXPPP_LIBRARY NAMES exppp NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + endif (HAVE_WINDOWS_H) find_library(STEPCODE_CORE_LIBRARY NAMES stepcore NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) find_library(STEPCODE_EDITOR_LIBRARY NAMES stepeditor NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) find_library(STEPCODE_DAI_LIBRARY NAMES stepdai NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) @@ -117,7 +117,6 @@ endforeach() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(STEPCODE DEFAULT_MSG - STEPCODE_BASE_DIR STEPCODE_DAI_DIR STEPCODE_EDITOR_DIR STEPCODE_STEPCORE_DIR @@ -125,7 +124,6 @@ find_package_handle_standard_args(STEPCODE DEFAULT_MSG STEPCODE_EXPPP_DIR STEPCODE_EXPRESS_DIR STEPCODE_INCLUDE_DIR - STEPCODE_BASE_LIBRARY STEPCODE_EXPRESS_LIBRARY STEPCODE_EXPPP_LIBRARY STEPCODE_CORE_LIBRARY @@ -139,14 +137,12 @@ find_package_handle_standard_args(STEPCODE DEFAULT_MSG if (STEPCODE_FOUND) set(STEPCODE_INCLUDE_DIRS ${STEPCODE_INCLUDE_DIR} - ${STEPCODE_BASE_DIR} ${STEPCODE_STEPCORE_DIR} ${STEPCODE_EDITOR_DIR} ${STEPCODE_UTILS_DIR} ${STEPCODE_DAI_DIR} ) set(STEPCODE_LIBRARIES - ${STEPCODE_BASE_LIBRARY} ${STEPCODE_EXPRESS_LIBRARY} ${STEPCODE_EXPPP_LIBRARY} ${STEPCODE_CORE_LIBRARY} diff --git a/misc/CMake/FindZLIB.cmake b/misc/CMake/FindZLIB.cmake new file mode 100644 index 00000000000..e06dc8743c5 --- /dev/null +++ b/misc/CMake/FindZLIB.cmake @@ -0,0 +1,123 @@ +#.rst: +# FindZLIB +# -------- +# +# Find the native ZLIB includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``ZLIB::ZLIB``, if +# ZLIB has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. +# ZLIB_LIBRARIES - List of libraries when using zlib. +# ZLIB_FOUND - True if zlib found. +# +# :: +# +# ZLIB_VERSION_STRING - The version of zlib found (x.y.z) +# ZLIB_VERSION_MAJOR - The major version of zlib +# ZLIB_VERSION_MINOR - The minor version of zlib +# ZLIB_VERSION_PATCH - The patch version of zlib +# ZLIB_VERSION_TWEAK - The tweak version of zlib +# +# Backward Compatibility +# ^^^^^^^^^^^^^^^^^^^^^^ +# +# The following variable are provided for backward compatibility +# +# :: +# +# ZLIB_MAJOR_VERSION - The major version of zlib +# ZLIB_MINOR_VERSION - The minor version of zlib +# ZLIB_PATCH_VERSION - The patch version of zlib +# +# Hints +# ^^^^^ +# +# A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this +# module where to look. + +#============================================================================= +# Copyright 2001-2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_ZLIB_SEARCHES) + +# Search ZLIB_ROOT first if it is set. +if(ZLIB_ROOT) + set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH) + list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) +endif() + +# Normal search. +set(_ZLIB_SEARCH_NORMAL + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" + "$ENV{PROGRAMFILES}/zlib" + ) +list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) + +set(ZLIB_NAMES z_brl z zlib zdll zlib1 zlibd zlibd1) + +# Try each search configuration. +foreach(search ${_ZLIB_SEARCHES}) + find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include) + find_library(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() + +mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR) + +if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") + file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(ZLIB_VERSION_TWEAK "") + if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}") + endif() + + set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") + set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") + set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") +endif() + +# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) + +if(ZLIB_FOUND) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + + if(NOT TARGET ZLIB::ZLIB) + add_library(ZLIB::ZLIB UNKNOWN IMPORTED) + set_target_properties(ZLIB::ZLIB PROPERTIES + IMPORTED_LOCATION "${ZLIB_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") + endif() +endif() diff --git a/misc/CMake/TrackFiles.cmake b/misc/CMake/TrackFiles.cmake new file mode 100644 index 00000000000..7459bbc3659 --- /dev/null +++ b/misc/CMake/TrackFiles.cmake @@ -0,0 +1,246 @@ +# T R A C K F I L E S . C M A K E +# BRL-CAD +# +# Copyright (c) 2011-2023 United States Government as represented by +# the U.S. Army Research Laboratory. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +### +# +# Unlike most CMake based projects, BRL-CAD's current build system works like +# its AutoTools-based precursor and tracks all files present in the source +# tree. Additionally, it also defines a "distclean" target that is intended to +# "scrub" the tree down to either a vanilla source tree (when doing an +# in-src-dir build) or an empty directory (when doing the more traditional +# compile-in-build-directory process. (CMake's traditional 'clean' targets do +# not remove all outputs of any sort - custom command outputs and CMake's own +# files are left behind using those targets alone.) +# +# In order to support this process, we define functions that allow the build to +# identify both files that are part of the expected BRL-CAD build tree, and +# expected build outputs that need to be removed. Note that build outputs that +# the standard "clean" targets remove should not be listed - those are already +# handled by the standard CMake build process and the output names are +# frequently platform specific. The "distclean" function should only be used +# to identify files a "make clean" pass would leave behind. +# +# BRL-CAD's exec and lib build targets will handle listing non-generated source +# files specified for those targets as BRL-CAD files, so it is not necessary to +# use the raw "CMAKEFILES" function to list those inputs (unless such files +# may be turned on or off for compilation by feature flags - in that case, the +# files which may be disabled should also be listed in a "CMAKEFILES" list) +# +# For performance reasons, CMake global variables are used to build up the +# various file lists rather than writing them to disk each time an addition +# is made. Other build logic then retrieves the lists and writes them to +# disk to make them available for processing with build targets such as +# distclean and package_source + +#----------------------------------------------------------------------------- +# We need a way to tell whether one path is a subpath of another path without +# relying on regular expressions, since file paths may have characters in them +# that will trigger regex matching behavior when we don't want it. (To test, +# for example, use a build directory name of build++) +# +# Sets ${result_var} to 1 if the candidate subpath is actually a subpath of +# the supplied "full" path, otherwise sets it to 0. +# +# The routine below does the check without using regex matching, in order to +# handle path names that contain characters that would be interpreted as active +# in a regex string. +if (NOT COMMAND is_subpath) + function(is_subpath candidate_subpath full_path result_var) + + # Just assume it isn't until we prove it is + set(${result_var} 0 PARENT_SCOPE) + + # get the CMake form of the path so we have something consistent to work on + file(TO_CMAKE_PATH "${full_path}" c_full_path) + file(TO_CMAKE_PATH "${candidate_subpath}" c_candidate_subpath) + + # check the string lengths - if the "subpath" is longer than the full path, + # there's not point in going further + string(LENGTH "${c_full_path}" FULL_LENGTH) + string(LENGTH "${c_candidate_subpath}" SUB_LENGTH) + if("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") + return() + endif("${SUB_LENGTH}" GREATER "${FULL_LENGTH}") + + # OK, maybe it's a subpath - time to actually check + string(SUBSTRING "${c_full_path}" 0 ${SUB_LENGTH} c_full_subpath) + if(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") + return() + endif(NOT "${c_full_subpath}" STREQUAL "${c_candidate_subpath}") + + # If we get here, it's a subpath + set(${result_var} 1 PARENT_SCOPE) + + endfunction(is_subpath) +endif (NOT COMMAND is_subpath) + +#----------------------------------------------------------------------------- +# Distcheck needs to know what files are "supposed" to be present in order to +# make sure the source tree is clean prior to building a distribution tarball, +# +# For this set of functions to work correctly, it is important that any call +# (via target definitions or via explicit calls to CMAKEFILES) supply relative +# paths for files present in the source tree. Generated files fed into +# compilation targets are not one of the things that should be in lists +# generated by this function, and the only way to reliably recognize them is to +# reject files specified using their full path. Such files must use their full +# path in the build logic in order for out-of-src-dir builds to function, so as +# long as no full paths are used for files actually IN the source tree this +# method is reliable. The filtering logic will try to catch improperly +# specified files, but if the build directory and the source directory are one +# and the same this will not be possible. + +if (NOT COMMAND check_source_dir_fullpath) + define_property(GLOBAL PROPERTY CMAKE_IGNORE_FILES BRIEF_DOCS "distcheck ignore files" FULL_DOCS "List of files known to CMake") + define_property(GLOBAL PROPERTY CMAKE_IGNORE_DIRS BRIEF_DOCS "distcheck ignore dirs" FULL_DOCS "List of directories marked as fully known to CMake") + + # If the build directory is not the same as the source directory, we can + # enforce the convention that only generated files be specified with their full + # name. + function(check_source_dir_fullpath ITEM_PATH) + + # We can only do this if BINARY_DIR != SOURCE_DIR + if(NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + return() + endif(NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + + # If it's a full path in the binary dir, it's fine + is_subpath("${CMAKE_BINARY_DIR}" "${ITEM_PATH}" SUBPATH_TEST) + if(NOT "${SUBPATH_TEST}" STREQUAL "0") + return() + endif(NOT "${SUBPATH_TEST}" STREQUAL "0") + + # If it's a full path in the source dir, it's fatal + is_subpath("${CMAKE_SOURCE_DIR}" "${ITEM_PATH}" SUBPATH_TEST) + if("${SUBPATH_TEST}" STREQUAL "1") + message(FATAL_ERROR "${ITEM} is listed in \"${CMAKE_CURRENT_SOURCE_DIR}\" using its absolute path. Please specify the location of this file using a relative path.") + endif("${SUBPATH_TEST}" STREQUAL "1") + + endfunction(check_source_dir_fullpath ITEM_PATH) +endif (NOT COMMAND check_source_dir_fullpath) + +if (NOT COMMAND cmfile) + function(cmfile ITEM) + + get_filename_component(ITEM_PATH "${ITEM}" PATH) + if(NOT "${ITEM_PATH}" STREQUAL "") + # The hard case - path specified, need some validation. + CHECK_SOURCE_DIR_FULLPATH("${ITEM_PATH}") + + # Ignore files specified using full paths, since they + # should be generated files and are not part of the + # source code repository. + get_filename_component(ITEM_ABS_PATH "${ITEM_PATH}" ABSOLUTE) + if("${ITEM_PATH}" STREQUAL "${ITEM_ABS_PATH}") + return() + endif("${ITEM_PATH}" STREQUAL "${ITEM_ABS_PATH}") + endif(NOT "${ITEM_PATH}" STREQUAL "") + + # Handle fatal cases + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") + message(FATAL_ERROR "Trying to ignore directory: ${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") + endif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") + message(FATAL_ERROR "Attempting to ignore non-existent file ${ITEM}, in directory \"${CMAKE_CURRENT_SOURCE_DIR}\"") + endif(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}") + + # We're good - log it + get_filename_component(item_absolute "${CMAKE_CURRENT_SOURCE_DIR}/${ITEM}" ABSOLUTE) + set_property(GLOBAL APPEND PROPERTY CMAKE_IGNORE_FILES "${item_absolute}") + + endfunction(cmfile ITEM) +endif (NOT COMMAND cmfile) + +# This is the function most commonly used in calling code to specify files +# as part of the expected source tree. +if (NOT COMMAND cmakefiles) + function(CMAKEFILES) + + # CMake flags to add_library/add_executable aren't going to be valid filenames - just + # yank them up front. + set(ITEMS ${ARGN}) + if (NOT ITEMS) + return() + endif (NOT ITEMS) + list(REMOVE_ITEM ITEMS SHARED STATIC OBJECT WIN32 UNKNOWN IMPORTED MODULE INTERFACE EXCLUDE_FROM_ALL) + list(FILTER ITEMS EXCLUDE REGEX "TARGET_OBJECTS") + + foreach(ITEM ${ITEMS}) + cmfile("${ITEM}") + endforeach(ITEM ${ITEMS}) + + endfunction(CMAKEFILES FILESLIST) +endif (NOT COMMAND cmakefiles) + +# Routine to tell distcheck to ignore a series of items in a directory. +# Primarily useful when working with src/other dist lists. +if (NOT COMMAND cmakefiles_in_dir) + function(cmakefiles_in_dir filestoignore targetdir) + set(CMAKE_IGNORE_LIST "") + foreach(filepath ${${filestoignore}}) + set(CMAKE_IGNORE_LIST ${CMAKE_IGNORE_LIST} "${targetdir}/${filepath}") + endforeach(filepath ${filestoignore}) + cmakefiles(${CMAKE_IGNORE_LIST}) + endfunction(cmakefiles_in_dir) +endif (NOT COMMAND cmakefiles_in_dir) + +#----------------------------------------------------------------------------- +# The "distclean" build target will clear all CMake-generated files from a +# source directory in the case of an in-source-dir configuration, or will fully +# clear an out-of-source build directory. +# (NOTE: In the case of the ninja build tool, we can't FULLY clear the build +# directory since ninja itself requires that a .ninja_log file be present in +# the build directory while running... calling code shouldn't specify or fail +# on the presence of that file, as build targets won't be able to clear it.) +if (NOT COMMAND distclean) + define_property(GLOBAL PROPERTY CMAKE_DISTCLEAN_TARGET_LIST BRIEF_DOCS "Build output files to be cleared" FULL_DOCS "Additional files to remove if clearing ALL configure+build outputs") + function(distclean) + foreach(item ${ARGN}) + get_filename_component(item_dir ${item} DIRECTORY) + if ("${item_dir}" STREQUAL "") + set(item_path "${CMAKE_CURRENT_BINARY_DIR}/${item}") + else ("${item_dir}" STREQUAL "") + set(item_path "${item}") + endif ("${item_dir}" STREQUAL "") + set_property(GLOBAL APPEND PROPERTY CMAKE_DISTCLEAN_TARGET_LIST "${item_path}") + endforeach(item ${ARGN}) + endfunction(distclean) +endif (NOT COMMAND distclean) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/misc/auto-man-page/BIN_OPT_ARG_ANALYSIS.txt b/misc/auto-man-page/BIN_OPT_ARG_ANALYSIS.txt index 4043c320644..2d64f927ad3 100644 --- a/misc/auto-man-page/BIN_OPT_ARG_ANALYSIS.txt +++ b/misc/auto-man-page/BIN_OPT_ARG_ANALYSIS.txt @@ -648,14 +648,6 @@ Libraries: ----- end usage ----------------------------------- ***** end buildtimestart *********************************** -***** begin burst *********************************** - result : (window) - file(s): - error : 1:TIMEOUT ------ begin usage ----------------------------------- - ------ end usage ----------------------------------- -***** end burst *********************************** ***** begin bw-a *********************************** result : (usage) file(s): diff --git a/misc/debian/CMakeLists.txt b/misc/debian/CMakeLists.txt index 4f84607ea8e..559a07ea7d1 100644 --- a/misc/debian/CMakeLists.txt +++ b/misc/debian/CMakeLists.txt @@ -89,6 +89,7 @@ set(debian_ignore_files icons/96x96/mged.png icons/96x96/rtwizard.png mged.desktop + org.brlcad.BRL_CAD.metainfo.xml rtwizard.desktop rules source/format diff --git a/misc/debian/archer.desktop b/misc/debian/archer.desktop index 78e466fd58c..eb864b789d9 100644 --- a/misc/debian/archer.desktop +++ b/misc/debian/archer.desktop @@ -5,5 +5,5 @@ Comment=Archer - Constructive solid geometry (CSG) solid modeling computer-aided Exec=bash -c "cd /usr/brlcad/bin/ && /usr/brlcad/bin/archer %f" Icon=archer Type=Application -Categories=BRL-CAD; +Categories=Graphics;Science;Education;Engineering; MimeType=application/brlcad-v4;application/brlcad-v5; diff --git a/misc/debian/brlcad-db.desktop b/misc/debian/brlcad-db.desktop index f1b3d8afa5d..ebc3b71a4c0 100644 --- a/misc/debian/brlcad-db.desktop +++ b/misc/debian/brlcad-db.desktop @@ -5,4 +5,4 @@ Comment=BRL-CAD Database examples Exec=xdg-open /usr/brlcad/share/db Icon=brlcad-db Type=Application -Categories=BRL-CAD-doc; +Categories=Graphics;Science;Education;Engineering; diff --git a/misc/debian/brlcad-doc-mged.desktop b/misc/debian/brlcad-doc-mged.desktop index 324eb1957ab..d92b47e48f7 100644 --- a/misc/debian/brlcad-doc-mged.desktop +++ b/misc/debian/brlcad-doc-mged.desktop @@ -5,4 +5,4 @@ Comment=MGED geometry editor manual Exec=xdg-open /usr/brlcad/share/doc/html/manuals/mged/index.html Icon=brlcad-doc Type=Application -Categories=BRL-CAD-doc; +Categories=Graphics;Science;Education;Engineering; diff --git a/misc/debian/brlcad-doc.desktop b/misc/debian/brlcad-doc.desktop index b97e4a121e2..dabf567750b 100644 --- a/misc/debian/brlcad-doc.desktop +++ b/misc/debian/brlcad-doc.desktop @@ -5,4 +5,4 @@ Comment=BRL-CAD Articles, Books and Lessons Exec=xdg-open /usr/brlcad/share/doc/html/toc.html Icon=brlcad-doc Type=Application -Categories=BRL-CAD-doc; +Categories=Graphics;Science;Education;Engineering; diff --git a/misc/debian/changelog b/misc/debian/changelog index adf03ba7aeb..ee1e007b10c 100644 --- a/misc/debian/changelog +++ b/misc/debian/changelog @@ -1,3 +1,10 @@ +brlcad (7.38.0-0) unstable; urgency=low + + * update brlcad version + + -- Cliff Yapp Mon, 06 Nov 2023 10:20:04 UTC + + brlcad (7.36.0-0) unstable; urgency=low * update brlcad version diff --git a/misc/debian/org.brlcad.BRL_CAD.metainfo.xml b/misc/debian/org.brlcad.BRL_CAD.metainfo.xml new file mode 100644 index 00000000000..a2ab66214ed --- /dev/null +++ b/misc/debian/org.brlcad.BRL_CAD.metainfo.xml @@ -0,0 +1,60 @@ + + + org.brlcad.BRL_CAD + org.brlcad.BRL_CAD.desktop + BRL-CAD + Open source combinatorial solid modeling system + CC0-1.0 + LGPL-2.1-only + +

+ BRL-CAD is a powerful cross-platform open source combinatorial + solid modeling system that includes an interactive 3D solid geometry + editor, a network-distributed symmetric multiprocessing (SMP) + high-performance ray-tracer with support for rendering and geometric + analysis, image and signal-processing tools, a system performance + analysis benchmark suite, a flexible geometry scripting interface, + and a high-performance geometric representation and analysis library. +

+
+ + + https://brlcad.org/gallery/galleries/screenshots/Via_OpenBook_part_d.png + + + https://brlcad.org/gallery/galleries/screenshots/ronja_screenshot.png + + + https://brlcad.org/gallery/_data/i/galleries/screenshots/gnu_tux-xx.png + + + https://brlcad.org/gallery/galleries/screenshots/puget_mged.png + + + https://brlcad.org/gallery/galleries/screenshots/t62_mged.jpg + + + https://brlcad.org/gallery/galleries/screenshots/cassini-1.png + + + https://brlcad.org/gallery/galleries/screenshots/Archer_0_5prototype.png + + + https://brlcad.org/gallery/_data/i/galleries/screenshots/extractor-xx.png + + + https://brlcad.org/gallery/galleries/screenshots/cassini-glass-titan.png + + + https://brlcad.org/gallery/_data/i/galleries/screenshots/MGED-xx.jpg + + + https://brlcad.org/ + https://brlcad.org/wiki/Main_Page + https://github.com/BRL-CAD/brlcad/issues + + + + + +
diff --git a/misc/doxygen/CMakeLists.txt b/misc/doxygen/CMakeLists.txt index 25485a7f08c..38e0c581147 100644 --- a/misc/doxygen/CMakeLists.txt +++ b/misc/doxygen/CMakeLists.txt @@ -43,7 +43,6 @@ set(DOX_LIBS libdm libtclcad libpkg - libtermio ) foreach(libname ${DOX_LIBS}) @@ -84,13 +83,6 @@ INPUT += \"${CMAKE_SOURCE_DIR}/include/nmg.h\" ") endif("${libname}" STREQUAL "librt") - # libtermio header doesn't fit the template - if("${libname}" STREQUAL "libtermio") - set(INPUTS "${INPUTS} -INPUT += \"${CMAKE_SOURCE_DIR}/include/libtermio.h\" - ") - endif("${libname}" STREQUAL "libtermio") - if(DEFINED BRLCAD_DOXYGEN_ADD_SRCS) set(INPUTS "${INPUTS} INPUT += \"${CMAKE_SOURCE_DIR}/src/${libname}/\"") @@ -124,13 +116,6 @@ INPUT += \"${CMAKE_SOURCE_DIR}/include/nmg.h\" ") endif("${libname}" STREQUAL "librt") - # libtermio header doesn't fit the template - if("${libname}" STREQUAL "libtermio") - set(lib_inputs "${lib_inputs} -INPUT += \"${CMAKE_SOURCE_DIR}/include/libtermio.h\" - ") - endif("${libname}" STREQUAL "libtermio") - if(DEFINED BRLCAD_DOXYGEN_ADD_SRCS) set(lib_inputs "${lib_inputs} INPUT += \"${CMAKE_SOURCE_DIR}/src/${libname}/\"") @@ -192,7 +177,6 @@ set(doxygen_ignore_files libpkg.dox librt.dox libtclcad.dox - libtermio.dox libwdb.dox vmath.dox ) diff --git a/misc/doxygen/libtermio.dox b/misc/doxygen/libtermio.dox deleted file mode 100644 index 96bacccea01..00000000000 --- a/misc/doxygen/libtermio.dox +++ /dev/null @@ -1,2 +0,0 @@ -/** @defgroup libtermio libtermio (Terminal I/O) */ - diff --git a/misc/macosx/Resources/ReadMe.rtfd/TXT.rtf b/misc/macosx/Resources/ReadMe.rtfd/TXT.rtf index e5452d9306c..31ea626d352 100644 --- a/misc/macosx/Resources/ReadMe.rtfd/TXT.rtf +++ b/misc/macosx/Resources/ReadMe.rtfd/TXT.rtf @@ -11,7 +11,7 @@ \f0\i\b\fs72 \cf0 README \fs36 \ -\f1\i0\b0\fs28 This is BRL-CAD 7.36.0 for Mac OS X. Please send any bugs, comments, questions, or suggestions to the project website.\ +\f1\i0\b0\fs28 This is BRL-CAD 7.38.0 for Mac OS X. Please send any bugs, comments, questions, or suggestions to the project website.\ \fs22 \ diff --git a/misc/macosx/Resources/Welcome.rtfd/TXT.rtf b/misc/macosx/Resources/Welcome.rtfd/TXT.rtf index 9b0517281e8..d16b5ec1802 100644 --- a/misc/macosx/Resources/Welcome.rtfd/TXT.rtf +++ b/misc/macosx/Resources/Welcome.rtfd/TXT.rtf @@ -4,7 +4,7 @@ \margl1440\margr1440\vieww8020\viewh6280\viewkind0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural -\f0\fs22 \cf0 This installer will guide you through the installation of BRL-CAD 7.36.0 for Mac OS X and Darwin.\ +\f0\fs22 \cf0 This installer will guide you through the installation of BRL-CAD 7.38.0 for Mac OS X and Darwin.\ \ This distribution of BRL-CAD requires approximately 500 MB of available disk space and does not include source code.\ \ diff --git a/misc/tools/CMakeLists.txt b/misc/tools/CMakeLists.txt index c2af17bf8de..607cbbe8105 100644 --- a/misc/tools/CMakeLists.txt +++ b/misc/tools/CMakeLists.txt @@ -5,7 +5,9 @@ function(SetTargetFolder targetname folder) endfunction(SetTargetFolder) # Convenience bundling of external third party build tools -add_subdirectory(ext) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/ext) + add_subdirectory(ext) +endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/ext) # The following are build or utility tools written by BRL-CAD developers # specifically for use with our build and maintenance processes diff --git a/misc/tools/env2c/env2c.cpp b/misc/tools/env2c/env2c.cpp index cdc0151f096..27513d05a7a 100644 --- a/misc/tools/env2c/env2c.cpp +++ b/misc/tools/env2c/env2c.cpp @@ -69,10 +69,11 @@ process_file(env_outputs &env_t) env_outputs &env = const_cast(env_t); std::regex getenv_regex(".*getenv\\(\\\".*"); - std::regex evar_regex(".*getenv\\(\\\"([^\\\"]+)\\\"\\).*"); + std::regex evar_regex(".*getenv\\(\\\"([^\\\"]+)\\\"([^\\)]*)\\).*"); std::regex o_regex(".*[\\/]other[\\/].*"); std::regex sp_regex(".*[\\/]other[\\/]([A-Za-z0-9_-]+).*"); std::regex lp_regex(".*[\\/]lib([A-Za-z0-9_-]+)[\\/].*"); + std::regex inc_regex(".*[\\/]include[\\/].*"); std::regex ep_regex(".*[\\/]src[\\/]([A-Za-z0-9_-]+)[\\/].*"); std::regex bench_regex(".*[\\/](bench)[\\/].*"); std::regex bullet_regex(".*[\\/](bullet)[\\/].*"); @@ -132,6 +133,18 @@ process_file(env_outputs &env_t) } } + { + std::smatch inc_match; + if (std::regex_search(env.f, inc_match, inc_regex)) { + if (env.verbose) { + std::cout << "include" << inc_match[1] << ": " << envvar[1] << "\n"; + } + env.blib_vars.insert(std::make_pair(std::string(inc_match[1]), std::string(envvar[1]))); + env.c_vars[std::string(inc_match[1])].insert(std::string(envvar[1])); + continue; + } + } + { std::smatch ep_match; if (std::regex_search(env.f, ep_match, ep_regex)) { diff --git a/misc/tools/ext/CMakeLists.txt b/misc/tools/ext/CMakeLists.txt index c233b478e92..5f004076c64 100644 --- a/misc/tools/ext/CMakeLists.txt +++ b/misc/tools/ext/CMakeLists.txt @@ -151,10 +151,12 @@ SetTargetFolder(re2c "Compilation Utilities") SetTargetFolder(re2c_bootstrap "Compilation Utilities") include("${CMAKE_CURRENT_SOURCE_DIR}/perplex.dist") CMAKEFILES_IN_DIR(perplex_ignore_files perplex) -DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/perplex/config.h) -DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/perplex/bootstrap_parser/parser.yy) -DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/perplex/perplex_wd/parser.y) -DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/perplex/re2c_parser/parser.yy) +DISTCLEAN( + ${CMAKE_CURRENT_BINARY_DIR}/perplex/config.h + ${CMAKE_CURRENT_BINARY_DIR}/perplex/bootstrap_parser/parser.yy + ${CMAKE_CURRENT_BINARY_DIR}/perplex/perplex_wd/parser.y + ${CMAKE_CURRENT_BINARY_DIR}/perplex/re2c_parser/parser.yy + ) CMAKEFILES( CMakeLists.txt diff --git a/regress/CMakeLists.txt b/regress/CMakeLists.txt index 89b8c1bce01..315c85c1acc 100644 --- a/regress/CMakeLists.txt +++ b/regress/CMakeLists.txt @@ -22,9 +22,6 @@ add_subdirectory(asc) # Bag of Triangles Tests add_subdirectory(bots) -# Burst Regression Tests -add_subdirectory(burst) - # comgeom Conversion Tests add_subdirectory(comgeom) diff --git a/regress/burst/CMakeLists.txt b/regress/burst/CMakeLists.txt deleted file mode 100644 index f230f242e8a..00000000000 --- a/regress/burst/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -set(BURST_INPUT_FILES - ktank.b - ktank_air.ids - ktank_armor.ids - ktank_crit.ids - ktank_colors.ids - ) - -if (TARGET ktank.g) - BRLCAD_REGRESSION_TEST(regress-burst "burst;ktank.g" EXEC burst) - - set(BURST_CLEAN_FILES - ktank_burst.plot - ktank_burst.pix - ktank.burst - ktank.g - ktank_burst.shotlines - burst_ktank.log - regress-burst.log - ) - DISTCLEAN(${BURST_CLEAN_FILES}) - - # If we copied the input files, clear them out as well - if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - DISTCLEAN(${BURST_INPUT_FILES}) - endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") -endif (TARGET ktank.g) - -CMAKEFILES( - CMakeLists.txt - echo.b - regress-burst.cmake.in - ${BURST_INPUT_FILES} - ) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/regress/burst/echo.b b/regress/burst/echo.b deleted file mode 100644 index 1d7fa6e244c..00000000000 --- a/regress/burst/echo.b +++ /dev/null @@ -1,39 +0,0 @@ -attack-direction 35 25 -critical-comp-file ccf.file -deflect-spall-cone yes -dither-cells yes -enclose-target -enclose-portion 1 2 3 4 -#error-file error.file -grid-file grid.file -ground-plane yes 10 2 -2 3 -3 -burst-air-file ba.file -histogram-file histo.file -image-file image.file -input-2d-shot 10 20 -input-3d-shot 10 20 30 -max-barriers 3 -max-spall-rays 7 -plot-file plot.file -read-2d-shot-file 2dshot.file -read-3d-shot-file 3dshot.file -burst-armor-file armor.file -read-burst-file rburst.file -read-input-file input.file -report-overlaps yes -shotline-burst yes -shotline-file shotline.file -target-file target.file -target-objects obj1 obj2 obj3 -units inches -units feet -units millimeters -units centimeters -units meters -write-input-file inputs.file -burst-coordinates 20 30 40 -burst-distance 10.0 -burst-file burst.file -cell-size 11.0 -color-file color.file -cone-half-angle 45 diff --git a/regress/burst/ktank.b b/regress/burst/ktank.b deleted file mode 100644 index 0951cbaa8b6..00000000000 --- a/regress/burst/ktank.b +++ /dev/null @@ -1,47 +0,0 @@ -units inches -shotline-file ktank_burst.shotlines -#error-file ktank_burst.log -plot-file ktank_burst.plot -image-file ktank_burst.pix -burst-file ktank.burst -burst-air-file ktank_air.ids -burst-armor-file ktank_armor.ids -critical-comp-file ktank_crit.ids -color-file ktank_colors.ids -burst-distance 0 -cell-size 16 -attack-direction 0 0 -max-spall-rays 50 -cone-half-angle 45 -target-file ktank.g -target-objects tank -report-overlaps no -shotline-burst yes -#ground-plane yes 66 200 200 200 200 -execute - -# commands currently untested by this file: -# -# deflect-spall-cone -# dither-cells -# enclose-target -# enclose-portion -# error-file (not working in old burst code, IIRC) -# grid-file -# ground-plane -# help -# histogram-file -# input-2d-shot -# input-3d-shot -# max-barriers -# quit -# read-2d-shot-file -# read-3d-shot-file -# read-burst-file -# read-input-file -# report-overlaps -# shotline-file -# write-input-file -# burst-coordinates -# burst-distance -# diff --git a/regress/burst/ktank_air.ids b/regress/burst/ktank_air.ids deleted file mode 100644 index a59e5c5e237..00000000000 --- a/regress/burst/ktank_air.ids +++ /dev/null @@ -1,2 +0,0 @@ -2-3 -5 diff --git a/regress/burst/ktank_armor.ids b/regress/burst/ktank_armor.ids deleted file mode 100644 index af95d1a208d..00000000000 --- a/regress/burst/ktank_armor.ids +++ /dev/null @@ -1 +0,0 @@ -100-121 diff --git a/regress/burst/ktank_colors.ids b/regress/burst/ktank_colors.ids deleted file mode 100644 index dc0fbdd27d0..00000000000 --- a/regress/burst/ktank_colors.ids +++ /dev/null @@ -1 +0,0 @@ -100 120 0 252 0 diff --git a/regress/burst/ktank_crit.ids b/regress/burst/ktank_crit.ids deleted file mode 100644 index 07ba0174ce6..00000000000 --- a/regress/burst/ktank_crit.ids +++ /dev/null @@ -1,3 +0,0 @@ -618-839 -940-949 - diff --git a/regress/burst/regress-burst.cmake.in b/regress/burst/regress-burst.cmake.in deleted file mode 100644 index f9c2ed472c3..00000000000 --- a/regress/burst/regress-burst.cmake.in +++ /dev/null @@ -1,66 +0,0 @@ -set(CBDIR "@CMAKE_CURRENT_BINARY_DIR@") -set(CSDIR "@CMAKE_CURRENT_SOURCE_DIR@") -set(BURST_CF "@BURST_CLEAN_FILES@") -set(BURST_IF "@BURST_INPUT_FILES@") -set(BIN_DIR "@BIN_DIR@") -set(DDIR "@DATA_DIR@") -set(LOGFILE "${CBDIR}/regress-burst.log") - -file(WRITE "${LOGFILE}" "Starting burst run\n") - -# The executable locations aren't know at CMake configure time, so one of them -# is passed in via the EXEC variable at runtime. De-quote it and assign it to -# the appropriate variable. -string(REPLACE "\\" "" BURST "${EXEC}") -if (NOT EXISTS "${BURST}") - file(APPEND "${LOGFILE}" "burst not found at location \"${BURST}\" - aborting\n") - message(FATAL_ERROR "Unable to find burst, aborting.\nSee ${LOGFILE} for more details.") -endif (NOT EXISTS "${BURST}") - -# Clean up in case we've run before -foreach(BCF ${BURST_CF}) - execute_process(COMMAND "@CMAKE_COMMAND@" -E remove -f "${CBDIR}/${BCF}") -endforeach(BCF ${BURST_CF}) - -# Stage the input files, if we're not in the source directory -if (NOT "${CSDIR}" STREQUAL "${CBDIR}") - foreach(BIF ${BURST_IF}) - execute_process(COMMAND "@CMAKE_COMMAND@" -E copy "${CSDIR}/${BIF}" "${CBDIR}/${BIF}") - endforeach(BIF ${BURST_IF}) -endif (NOT "${CSDIR}" STREQUAL "${CBDIR}") - -# Find the root path from the executable, and from there the database path -get_filename_component(BDIR "${BURST}" DIRECTORY) -string(REGEX REPLACE "${BIN_DIR}$" "" RDIR "${BDIR}") -execute_process(COMMAND "@CMAKE_COMMAND@" -E copy "${RDIR}/${DDIR}/db/ktank.g" "${CBDIR}/ktank.g") - -file(APPEND "${LOGFILE}" "Running burst on ktank.g:\n${BURST} -b ${CBDIR}/ktank.b\n") - -execute_process( - COMMAND "${BURST}" -b "${CBDIR}/ktank.b" - RESULT_VARIABLE burst_result OUTPUT_VARIABLE burst_log ERROR_VARIABLE burst_log - WORKING_DIRECTORY ${CBDIR} - ) -file(APPEND "${LOGFILE}" "${burst_log}") -set(burst_log) -if(NOT EXISTS "${CBDIR}/ktank.burst" OR burst_result) - file(APPEND "${LOGFILE}" "Failure: ${burst_result}\n") - file(READ "${LOGFILE}" LOG) - message(FATAL_ERROR "${BURST} failed to process ktank.b, aborting.\nSee ${LOGFILE} for more details.\n${LOG}") -endif(NOT EXISTS "${CBDIR}/ktank.burst" OR burst_result) - -# If we copied the input files, clear them out as well -if(NOT "${CSDIR}" STREQUAL "${CBDIR}") - foreach(BIF ${BURST_INPUT_FILES}) - execute_process(COMMAND "@CMAKE_COMMAND@" -E remove -f "${CBDIR}/${BCF}") - endforeach(BIF ${BURST_INPUT_FILES}) -endif(NOT "${CSDIR}" STREQUAL "${CBDIR}") - - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 - diff --git a/regress/fuzz/CMakeLists.txt b/regress/fuzz/CMakeLists.txt index 764617ad1a5..7fd3ebd51ce 100644 --- a/regress/fuzz/CMakeLists.txt +++ b/regress/fuzz/CMakeLists.txt @@ -11,13 +11,25 @@ include(CheckCXXCompilerFlag) # anything with the results of computations check_cxx_compiler_flag(-Wno-unused-but-set-variable HAVE_NO_UNUSED_BUT_SET_VARIABLE) -# We may need the fuzzer option to be a library +# Check whether fuzzing support is available. +cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS -fsanitize=fuzzer) + # Unreliable: + # check_cxx_compiler_flag(-fsanitize=fuzzer HAVE_FSANITIZE_FUZZER) + set(CHECK_FUZZER_CODE "#include \nint main() { return 0; }") + check_cxx_source_compiles("${CHECK_FUZZER_CODE}" HAVE_FSANITIZE_FUZZER) +cmake_pop_check_state() + +if (HAVE_FSANITIZE_FUZZER) + message(STATUS "The '-fsanitize=fuzzer' flag is supported.") +else() + message(STATUS "The '-fsanitize=fuzzer' flag is not supported.") +endif() + +# Set up the fuzzer option like a library set(FUZZER_LIBRARY) -# Check whether fuzzing support is available. -set(CMAKE_REQUIRED_FLAGS -fsanitize=fuzzer) -check_cxx_compiler_flag(-fsanitize=fuzzer HAVE_FUZZER) -if (NOT HAVE_FUZZER) +if (NOT HAVE_FSANITIZE_FUZZER) set(LLVM_FUZZER_SRC " #include #include @@ -33,16 +45,16 @@ extern \\\"C\\\" int LLVMFuzzerTestOneInput(const uint8_t *, size_t) { if (HAVE_LLVMFUZZER) set(FUZZER_LIBRARY "-fsanitize=fuzzer") endif (HAVE_LLVMFUZZER) -endif (NOT HAVE_FUZZER) +endif (NOT HAVE_FSANITIZE_FUZZER) set(FUZZ_GED_SRCS fuzz_ged.cpp) set(FUZZ_SHOOTRAY_SRCS fuzz_shootray.cpp) -if (NOT HAVE_FUZZER AND NOT HAVE_LLVMFUZZER) +if (NOT HAVE_FSANITIZE_FUZZER AND NOT HAVE_LLVMFUZZER) # provide simple main() so they at least compile and run set(FUZZ_GED_SRCS ${FUZZ_GED_SRCS} fuzz_stub.cpp) set(FUZZ_SHOOTRAY_SRCS ${FUZZ_SHOOTRAY_SRCS} fuzz_stub.cpp) -endif (NOT HAVE_FUZZER AND NOT HAVE_LLVMFUZZER) +endif (NOT HAVE_FSANITIZE_FUZZER AND NOT HAVE_LLVMFUZZER) BRLCAD_ADDEXEC(fuzz_ged_test "${FUZZ_GED_SRCS}" "libbu;librt;libged;${FUZZER_LIBRARY}" TEST) BRLCAD_ADDEXEC(fuzz_shootray_test "${FUZZ_SHOOTRAY_SRCS}" "libbu;librt;libged;${FUZZER_LIBRARY}" TEST) @@ -52,15 +64,15 @@ BRLCAD_ADDEXEC(fuzz_shootray_test "${FUZZ_SHOOTRAY_SRCS}" "libbu;librt;libged;${ #BRLCAD_ADD_TEST(NAME fuzz_ged COMMAND fuzz_ged_test) #BRLCAD_ADD_TEST(NAME fuzz_shootray COMMAND fuzz_shootray_test) -if (HAVE_FUZZER OR HAVE_LLVMFUZZER) +if (HAVE_FSANITIZE_FUZZER OR HAVE_LLVMFUZZER) target_compile_options(fuzz_ged_test PRIVATE -fsanitize=fuzzer) target_compile_options(fuzz_shootray_test PRIVATE -fsanitize=fuzzer) -endif (HAVE_FUZZER OR HAVE_LLVMFUZZER) +endif (HAVE_FSANITIZE_FUZZER OR HAVE_LLVMFUZZER) -if (HAVE_FUZZER) +if (HAVE_FSANITIZE_FUZZER) target_link_options(fuzz_ged_test PRIVATE -fsanitize=fuzzer) target_link_options(fuzz_shootray_test PRIVATE -fsanitize=fuzzer) -endif (HAVE_FUZZER) +endif (HAVE_FSANITIZE_FUZZER) CMAKEFILES( CMakeLists.txt diff --git a/regress/repository/repocheck.cpp b/regress/repository/repocheck.cpp index 5ae156ade0c..3559a47dd7f 100644 --- a/regress/repository/repocheck.cpp +++ b/regress/repository/repocheck.cpp @@ -64,7 +64,7 @@ extern "C" char * bu_strnstr(const char *h, const char *n, size_t hlen); #define MAX_LINES_CHECK 500 -#define EXPECTED_PLATFORM_SYMBOLS 227 +#define EXPECTED_PLATFORM_SYMBOLS 217 class repo_info_t { public: @@ -878,6 +878,7 @@ main(int argc, const char *argv[]) "misc/repowork", "misc/tools", "pkg.h", + "src/libdm/wgl/wintk/", "src/libpkg", "src/other/", "~", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f5688b582fd..7fa86d9d1e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,49 @@ endif(MSVC) # globally consider anything in an 'ext' path a warning-free system header set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} ext CACHE STRING "Bundled system include dirs" FORCE) + + +# The BRL-CAD package provides a large number of tools and utilities. Not all +# applications require all of these components, so we need a mechanism to allow +# applications to specify subsets to build. However, we also don't want those +# specifications to be verbose - for example, if a client wants librt, what they +# will need is librt and its immediate dependencies. Rather than requiring the +# client to know and list all of those dependencies for building, we need to +# bake that knowledge into the build itself. +# +# Obviously, the build definitions for each library must have knowledge of the +# needed dependencies. However, that knowledge isn't available to us at this +# level since none of those subdirectories have been added. Nor is it +# necessarily trivial to programmatically extract that information from the +# CMakeLists.txt files - the formatting and content of them is not particularly +# constrained. +# +# To address this, we define the lists of the BRL-CAD dependencies used by various +# library targets here, up front. These lists are also used in the subdirectories +# when targets are defined, so they represent the canonical dependency definitions +# used to create the actual build targets. Defining them here, in turn, lets us +# also leverage this knowledge when activating or deactivating components in +# partial build scenarios. +set(libbu_deps) +set(libbn_deps libbu) +set(libbg_deps libbn libbu) +set(libbv_deps libbg libbn libbu) +set(libnmg_deps libbg libbv libbn libbu) +set(libbrep_deps libbg libbv libbn libbu) +set(librt_deps libbrep libnmg libbg libbv libbn libbu) +set(libwdb_deps librt libbrep libnmg libbg libbv libbn libbu) +set(libpkg_deps libbu) +set(libgcv_deps libwdb librt libnmg libbu) +set(libanalyze_deps librt libbu) +set(liboptical_deps librt libbn libbu) +set(libicv_deps libbn libbu) +set(libged_deps libicv libanalyze libwdb liboptical librt libbrep libnmg libbv libbg libbn libbu) +set(libdm_deps librt libicv libbv libbn libbg libbu libpkg) +set(libfft_deps) +set(libqtcad_deps libged libdm librt libbv libbu) +set(libtclcad_deps libged libdm libnmg libbg libbv libbn libbu) + + # We need to define a number of "components" to allow for easy building of # subsets of BRL-CAD. We will control this process with an advanced # variable named BRLCAD_ENABLE_TARGETS - if set to 0 (default) everything @@ -25,8 +68,8 @@ set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} ext CACHE STRING "Bundled syste set(level_1_dirs libbu libbn - libbv libbg + libbv libnmg libbrep librt @@ -49,7 +92,6 @@ set(level_2_dirs libpc libqtcad libtclcad - libtermio ) # Level 3 directories contain BRL-CAD's executables. Setting @@ -57,7 +99,6 @@ set(level_2_dirs set(level_3_dirs brlman - burst bwish conv fb @@ -155,6 +196,7 @@ endif(BRLCAD_ENABLE_BRLCAD_LIBRARY AND USE_OBJECT_LIBS) CMAKEFILES( CMakeLists.txt README + libtermio/libtermio.h ) # Add a convenience directory that is only added to the diff --git a/src/README b/src/README index 4271cd4751e..3d8ececdefa 100644 --- a/src/README +++ b/src/README @@ -19,7 +19,6 @@ adrt - Advanced Distributed Ray-Tracer, high-performance triangle ray-trace tool anim - animation tools archer - Archer, a geometry modeler implemented in Tcl brlman - a 'man' tool that knows where to look for BRL-CAD manual pages -burst - tool for simulation of burst effects bwish - BRL-CAD's version of 'tclsh' and 'wish' Tcl/Tk interpreters canon - tool to spool/queue image data to Canon printers via MDQS conv - codes for converting to/from BRL-CAD .g format and other TGM formats @@ -44,7 +43,6 @@ liboptical - an optics library for raster image ray-tracing libpkg - a network package transport library librt - the BRL-CAD ray-trace library libtclcad - a library for Tcl routines related to CAD -libtermio - a terminal I/O library libwdb - the write database library, for creating BRL-CAD geometry models mged - the Multi-device Geometry Editor, a CSG solid modeler nirt - Natalie's Interactive Ray-Tracer, an interactive ray-trace tool diff --git a/src/adrt/CMakeLists.txt b/src/adrt/CMakeLists.txt index 50397e9a747..3d9fec72bc3 100644 --- a/src/adrt/CMakeLists.txt +++ b/src/adrt/CMakeLists.txt @@ -7,10 +7,10 @@ set(ADRT_INCLUDE_DIRS list(REMOVE_DUPLICATES ADRT_INCLUDE_DIRS) BRLCAD_INCLUDE_DIRS(ADRT_INCLUDE_DIRS) -if(NOT "${Z_PREFIX_STR}" STREQUAL "") +IS_SUBPATH("${CMAKE_BINARY_DIR}" "${ZLIB_LIBRARY}" LOCAL_TEST) +if(LOCAL_TEST OR TARGET ZLIB_BLD) add_definitions(-DZ_PREFIX) - add_definitions(-DZ_PREFIX_STR=${Z_PREFIX_STR}) -endif(NOT "${Z_PREFIX_STR}" STREQUAL "") +endif(LOCAL_TEST OR TARGET ZLIB_BLD) set(LIBRENDER_SRCS load.c @@ -40,7 +40,7 @@ set(LIBRENDER_SRCS librender/texture_perlin.c librender/texture_stack.c ) -BRLCAD_ADDLIB(librender "${LIBRENDER_SRCS}" "libgcv") +BRLCAD_ADDLIB(librender "${LIBRENDER_SRCS}" "libgcv;${ZLIB_LIBRARIES}") set_target_properties(librender PROPERTIES VERSION 20.0.1 SOVERSION 20) add_dependencies(librender gcv_plugins) diff --git a/src/adrt/isst.c b/src/adrt/isst.c index 10e5b6c9bd9..6e79baaae59 100644 --- a/src/adrt/isst.c +++ b/src/adrt/isst.c @@ -160,7 +160,7 @@ isst_load_g(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, /* Set the initial az and el values in Tcl/Tk */ VSUB2(vec, isst->camera.pos, isst->camera.focus); VUNITIZE(vec); - AZEL_FROM_V3DIR(az, el, vec); + bn_ae_vec(&az, &el, vec); az = az * -DEG2RAD; el = el * -DEG2RAD; bu_vls_sprintf(&tclstr, "%f", az); @@ -462,10 +462,10 @@ aetolookat(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, Tcl_Obj VSUB2(vecdfoc, isst->camera.pos, isst->camera.focus); VUNITIZE(vecdfoc); - AZEL_FROM_V3DIR(az, el, vecdfoc); + bn_ae_vec(&az, &el, vecdfoc); az = az * -DEG2RAD + x; el = el * -DEG2RAD + y; - V3DIR_FROM_AZEL(vecdfoc, az, el); + bn_vec_ae(vecdfoc, az, el); VUNITIZE(vecdfoc); VSCALE(vecdfoc, vecdfoc, mag_vec); VADD2(isst->camera.focus, isst->camera.pos, vecdfoc); @@ -499,7 +499,7 @@ aerotate(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, Tcl_Obj *c VSUB2(vecdpos, isst->camera_focus_init, isst->camera.pos); VUNITIZE(vecdpos); - AZEL_FROM_V3DIR(az, el, vecdpos); + bn_ae_vec(&az, &el, vecdpos); az = az * -DEG2RAD - x; el = el * -DEG2RAD + y; @@ -509,13 +509,13 @@ aerotate(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, Tcl_Obj *c if (el>M_PI_2) el=M_PI_2 - 0.001; if (el<-M_PI_2) el=-M_PI_2 + 0.001; - V3DIR_FROM_AZEL(vecdpos, az, el); + bn_vec_ae(vecdfoc, az, el); VSCALE(vecdpos, vecdpos, mag_pos); VADD2(isst->camera.pos, isst->camera_focus_init, vecdpos); if (mag_focus > 0) { VSUB2(vecdfoc, isst->camera_focus_init, isst->camera.focus); VUNITIZE(vecdfoc); - AZEL_FROM_V3DIR(az, el, vecdfoc); + bn_ae_vec(&az, &el, vecdfoc); az = az * -DEG2RAD - x; el = el * -DEG2RAD + y; @@ -525,14 +525,14 @@ aerotate(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, Tcl_Obj *c if (el>M_PI_2) el=M_PI_2 - 0.001; if (el<-M_PI_2) el=-M_PI_2 + 0.001; - V3DIR_FROM_AZEL(vecdfoc, az, el); + bn_vec_ae(vecdfoc, az, el); VSCALE(vecdfoc, vecdfoc, mag_focus); VADD2(isst->camera.focus, isst->camera_focus_init, vecdfoc); } /* Update the tcl copies of the az/el vars */ VSUB2(vec, isst->camera.focus, isst->camera.pos); VUNITIZE(vec); - AZEL_FROM_V3DIR(az, el, vec); + bn_ae_vec(&az, &el, vec); bu_vls_sprintf(&tclstr, "%f", az); Tcl_SetVar(interp, "az", bu_vls_addr(&tclstr), 0); bu_vls_sprintf(&tclstr, "%f", el); diff --git a/src/adrt/load_g.c b/src/adrt/load_g.c index 157b1e19a3b..b85fe61ea15 100644 --- a/src/adrt/load_g.c +++ b/src/adrt/load_g.c @@ -308,7 +308,7 @@ load_g(struct tie_s *tie, const char *db, int argc, const char **argv, struct ad &tree_state, /* initial tree state */ nmg_to_adrt_regstart, /* region start function */ gcv_region_end, /* region end function */ - nmg_booltree_leaf_tess, /* leaf func */ + rt_booltree_leaf_tess, /* leaf func */ (void *)&gcvwriter); /* client data */ /* Release dynamic storage */ diff --git a/src/adrt/master/CMakeLists.txt b/src/adrt/master/CMakeLists.txt index ad4229e2543..ae081083630 100644 --- a/src/adrt/master/CMakeLists.txt +++ b/src/adrt/master/CMakeLists.txt @@ -6,7 +6,7 @@ set(ADRT_MASTER_SOURCES tienet_master.c ) -BRLCAD_ADDEXEC(adrt_master "${ADRT_MASTER_SOURCES}" librt) +BRLCAD_ADDEXEC(adrt_master "${ADRT_MASTER_SOURCES}" "librt;${ZLIB_LIBRARIES}") set(adrt_master_ignore_files CMakeLists.txt diff --git a/src/adrt/slave/CMakeLists.txt b/src/adrt/slave/CMakeLists.txt index 9359aeca735..56d4baf0703 100644 --- a/src/adrt/slave/CMakeLists.txt +++ b/src/adrt/slave/CMakeLists.txt @@ -4,7 +4,7 @@ set(ADRT_SLAVE_SOURCES tienet_slave.c ) -BRLCAD_ADDEXEC(adrt_slave "${ADRT_SLAVE_SOURCES}" "librt;librender") +BRLCAD_ADDEXEC(adrt_slave "${ADRT_SLAVE_SOURCES}" "librt;librender;${ZLIB_LIBRARIES}") set(adrt_slave_ignore_files CMakeLists.txt diff --git a/src/archer/CMakeLists.txt b/src/archer/CMakeLists.txt index 4f0a2fabea9..522ccf06f67 100644 --- a/src/archer/CMakeLists.txt +++ b/src/archer/CMakeLists.txt @@ -1,96 +1,103 @@ -set(ARCHER_INCLUDE_DIRS - ${BU_INCLUDE_DIRS} - ${TCLCAD_INCLUDE_DIRS} - ${TCL_INCLUDE_PATH} - ) -if (TK_INCLUDE_PATH) - set(ARCHER_INCLUDE_DIRS ${ARCHER_INCLUDE_DIRS} ${TK_INCLUDE_PATH}) -endif (TK_INCLUDE_PATH) -list(REMOVE_DUPLICATES ARCHER_INCLUDE_DIRS) -BRLCAD_INCLUDE_DIRS(ARCHER_INCLUDE_DIRS) - -BRLCAD_ADDDATA(archer_launch.tcl tclscripts/archer/init) - -# NOTE: Building "GUI" doesn't matter except on Windows, but on Windows archer -# currently works only in graphical mode - might as well behave "nicely" there. -# If/when we add MGED's ability to work in "classic" mode, Archer will have -# to be built as a non-GUI application (or we'll have to build two executables) -if(BRLCAD_ENABLE_TK) - set(archer_libs libtclcad libbu ${TCL_LIBRARY} ${IMM32_LIBRARY} ${COMCTL32_LIBRARY}) - set(archer_srcs archer.c) - if (HAVE_WINDOWS_H) - # To associate an icon with the application for Windows (needed - # for the WiX installer) we must use an rc file. - enable_language(RC) - set(archer_srcs ${archer_srcs} archer.rc) - endif (HAVE_WINDOWS_H) - BRLCAD_ADDEXEC(archer "${archer_srcs}" "${archer_libs}" GUI) - add_dependencies(archer rtwizard) - ADD_TARGET_DEPS(archer Tkhtml Tktable itcl_pkgIndex itk_pkgIndex dm_plugins) - - # Archer needs a lot of files to be copied into place to work - just have it - # depend on ALL the managed files, rather than trying to list specifics - add_dependencies(archer managed_files) - - foreach(item ${tclindex_target_list}) - add_dependencies(archer ${item}) - endforeach(item ${tclindex_target_list}) - - # stage targets - set(stgts tcl tk itcl itk iwidgets) - foreach(ST ${stgts}) - if (TARGET ${ST}_stage) - add_dependencies(archer ${ST}_stage) - endif (TARGET ${ST}_stage) - endforeach(ST ${stgts}) - - # Archer is one of the programs that gets a start menu entry - set_property(INSTALL "${BIN_DIR}/$" - PROPERTY CPACK_START_MENU_SHORTCUTS "Archer ${BRLCAD_VERSION}" - ) - set_property(INSTALL "${BIN_DIR}/$" - PROPERTY CPACK_DESKTOP_SHORTCUTS "Archer ${BRLCAD_VERSION}" +if (BRLCAD_ENABLE_TCL) + set(ARCHER_INCLUDE_DIRS + ${BU_INCLUDE_DIRS} + ${TCLCAD_INCLUDE_DIRS} + ${TCL_INCLUDE_PATH} ) + if (TK_INCLUDE_PATH) + set(ARCHER_INCLUDE_DIRS ${ARCHER_INCLUDE_DIRS} ${TK_INCLUDE_PATH}) + endif (TK_INCLUDE_PATH) + list(REMOVE_DUPLICATES ARCHER_INCLUDE_DIRS) + BRLCAD_INCLUDE_DIRS(ARCHER_INCLUDE_DIRS) + + BRLCAD_ADDDATA(archer_launch.tcl tclscripts/archer/init) + + # NOTE: Building "GUI" doesn't matter except on Windows, but on Windows archer + # currently works only in graphical mode - might as well behave "nicely" there. + # If/when we add MGED's ability to work in "classic" mode, Archer will have + # to be built as a non-GUI application (or we'll have to build two executables) + if(BRLCAD_ENABLE_TK) + set(archer_libs libtclcad libbu ${TCL_LIBRARY} ${IMM32_LIBRARY} ${COMCTL32_LIBRARY}) + set(archer_srcs archer.c) + if (HAVE_WINDOWS_H) + # To associate an icon with the application for Windows (needed + # for the WiX installer) we must use an rc file. + enable_language(RC) + set(archer_srcs ${archer_srcs} archer.rc) + endif (HAVE_WINDOWS_H) + BRLCAD_ADDEXEC(archer "${archer_srcs}" "${archer_libs}" GUI) + add_dependencies(archer rtwizard) + ADD_TARGET_DEPS(archer Tkhtml Tktable itcl_pkgIndex itk_pkgIndex dm_plugins) + + # Archer needs a lot of files to be copied into place to work - just have it + # depend on ALL the managed files, rather than trying to list specifics + add_dependencies(archer managed_files) + + foreach(item ${tclindex_target_list}) + add_dependencies(archer ${item}) + endforeach(item ${tclindex_target_list}) + + # stage targets + set(stgts tcl tk itcl itk iwidgets) + foreach(ST ${stgts}) + if (TARGET ${ST}_stage) + add_dependencies(archer ${ST}_stage) + endif (TARGET ${ST}_stage) + endforeach(ST ${stgts}) + + # Archer is one of the programs that gets a start menu entry + set_property(INSTALL "${BIN_DIR}/$" + PROPERTY CPACK_START_MENU_SHORTCUTS "Archer ${BRLCAD_VERSION}" + ) + set_property(INSTALL "${BIN_DIR}/$" + PROPERTY CPACK_DESKTOP_SHORTCUTS "Archer ${BRLCAD_VERSION}" + ) + + endif(BRLCAD_ENABLE_TK) +endif (BRLCAD_ENABLE_TCL) -endif(BRLCAD_ENABLE_TK) - +set(archer_txt + archer_ack.txt + ) +if (BRLCAD_ENABLE_TCL) + ADD_DOC(archer_txt ".") +endif (BRLCAD_ENABLE_TCL) # Archer plugins - -BRLCAD_ADDDATA(plugins/Core/README plugins/archer/Core) -BRLCAD_ADDDATA(plugins/Commands/README plugins/archer/Command) - set(archer_utility_FILES plugins/Utility/attrGroupsDisplayUtilityP.tcl plugins/Utility/botUtilityP.tcl plugins/Utility/lodUtilityP.tcl plugins/Utility/README ) -BRLCAD_ADDDATA(archer_utility_FILES plugins/archer/Utility) - -BRLCAD_ADDDATA(plugins/Utility/attrGroupsDisplayUtilityP/AttrGroupsDisplayUtilityP.tcl plugins/archer/Utility/attrGroupsDisplayUtilityP) -BRLCAD_ADDDATA(plugins/Utility/botUtilityP/BotUtilityP.tcl plugins/archer/Utility/botUtilityP) -BRLCAD_ADDDATA(plugins/Utility/lodUtilityP/LODUtilityP.tcl plugins/archer/Utility/lodUtilityP) - set(archer_wizard_FILES plugins/Wizards/humanwizard.tcl plugins/Wizards/tankwizard.tcl plugins/Wizards/tirewizard.tcl ) -BRLCAD_ADDDATA(archer_wizard_FILES plugins/archer/Wizards) -BRLCAD_ADDDATA(plugins/Wizards/humanwizard/HumanWizard.tcl plugins/archer/Wizards/humanwizard) -BRLCAD_ADDDATA(plugins/Wizards/tankwizard/TankWizard.tcl plugins/archer/Wizards/tankwizard) -BRLCAD_ADDDATA(plugins/Wizards/tankwizard/images/tank.png plugins/archer/Wizards/tankwizardIA/images) -BRLCAD_ADDDATA(plugins/Wizards/tirewizard/TireWizard.tcl plugins/archer/Wizards/tirewizard) - -set(archer_txt - archer_ack.txt - ) -ADD_DOC(archer_txt ".") +if (BRLCAD_ENABLE_TCL) + BRLCAD_ADDDATA(archer_utility_FILES plugins/archer/Utility) + BRLCAD_ADDDATA(archer_wizard_FILES plugins/archer/Wizards) + BRLCAD_ADDDATA(plugins/Commands/README plugins/archer/Command) + BRLCAD_ADDDATA(plugins/Core/README plugins/archer/Core) + BRLCAD_ADDDATA(plugins/Utility/attrGroupsDisplayUtilityP/AttrGroupsDisplayUtilityP.tcl plugins/archer/Utility/attrGroupsDisplayUtilityP) + BRLCAD_ADDDATA(plugins/Utility/botUtilityP/BotUtilityP.tcl plugins/archer/Utility/botUtilityP) + BRLCAD_ADDDATA(plugins/Utility/lodUtilityP/LODUtilityP.tcl plugins/archer/Utility/lodUtilityP) + BRLCAD_ADDDATA(plugins/Wizards/humanwizard/HumanWizard.tcl plugins/archer/Wizards/humanwizard) + BRLCAD_ADDDATA(plugins/Wizards/tankwizard/TankWizard.tcl plugins/archer/Wizards/tankwizard) + BRLCAD_ADDDATA(plugins/Wizards/tankwizard/images/tank.png plugins/archer/Wizards/tankwizardIA/images) + BRLCAD_ADDDATA(plugins/Wizards/tirewizard/TireWizard.tcl plugins/archer/Wizards/tirewizard) +endif (BRLCAD_ENABLE_TCL) set(archer_ignore_files CMakeLists.txt + ${archer_utility_FILES} + ${archer_wizard_FILES} + ${archer_txt} + archer_launch.tcl + archer.c + archer.rc TODO archer.c archer.rc diff --git a/src/archer/archer.c b/src/archer/archer.c index a6d122948a0..04606868a20 100644 --- a/src/archer/archer.c +++ b/src/archer/archer.c @@ -134,9 +134,9 @@ main(int argc, const char **argv) } Tcl_DeleteInterp(interp); -#endif /* HAVE_TK */ bu_free((void *)av, "argv cpy"); +#endif /* HAVE_TK */ return status; } diff --git a/src/art/CMakeLists.txt b/src/art/CMakeLists.txt index bda89f82014..40f81895c1b 100644 --- a/src/art/CMakeLists.txt +++ b/src/art/CMakeLists.txt @@ -10,6 +10,7 @@ set(art_ignore_files ) CMAKEFILES(${art_ignore_files}) +set(Appleseed_ROOT "${CMAKE_BINARY_DIR}") find_package(Appleseed) if(NOT Appleseed_FOUND) message("'art' appleseed ray tracing is DISABLED") @@ -17,6 +18,7 @@ if(NOT Appleseed_FOUND) endif(NOT Appleseed_FOUND) message("Found Appleseed: ${Appleseed_LIBRARIES}") +set(Boost_ROOT "${CMAKE_BINARY_DIR}") set(Boost_USE_STATIC_LIBS OFF) find_package(Boost COMPONENTS chrono date_time filesystem regex system thread wave) if(NOT Boost_FOUND) diff --git a/src/art/art.cpp b/src/art/art.cpp index 4c30736f8be..b5edbbee692 100644 --- a/src/art/art.cpp +++ b/src/art/art.cpp @@ -125,9 +125,9 @@ #include "foundation/math/scalar.h" #include "foundation/math/transform.h" #include "foundation/math/vector.h" -#include "foundation/utility/containers/dictionary.h" -#include "foundation/utility/log/consolelogtarget.h" -#include "foundation/utility/autoreleaseptr.h" +#include "foundation/containers/dictionary.h" +#include "foundation/log/consolelogtarget.h" +#include "foundation/memory/autoreleaseptr.h" #include "foundation/utility/searchpaths.h" // appleseed header for ITileCallback - needs to be organized somewhere @@ -228,15 +228,17 @@ color_hook(const struct bu_structparse *sp, const char *name, void *UNUSED(base) // holds application specific paramaters -extern "C" struct bu_structparse view_parse[] = { - {"%d", 1, "samples", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, - {"%d", 1, "s", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, - {"%f", 3, "background", 0, color_hook, NULL, NULL}, - {"%f", 3, "bg", 0, color_hook, NULL, NULL}, - {"%d", 1, "light_intensity", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, - {"%d", 1, "li", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, - {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL } -}; +extern "C" { + struct bu_structparse view_parse[] = { + {"%d", 1, "samples", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, + {"%d", 1, "s", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, + {"%f", 3, "background", 0, color_hook, NULL, NULL}, + {"%f", 3, "bg", 0, color_hook, NULL, NULL}, + {"%d", 1, "light_intensity", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, + {"%d", 1, "li", 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, + {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL } + }; +} /* Initializes module specific options @@ -864,12 +866,12 @@ build_project(const char* file, const char* UNUSED(objects)) asf::Transformd t; camera->transform_sequence().get_transform(0, time0, t); + /* const asf::Matrix& l2p = t.get_local_to_parent(); const asf::Matrix& p2l = t.get_parent_to_local(); mat_t ml2p, mp2l; MAT_COPY(ml2p, l2p); MAT_COPY(mp2l, p2l); - /* bn_mat_print("view2model AFTER: ", view2model); bn_mat_print("L2P TRANSFORM: ", ml2p); bn_mat_print("P2L TRANSFORM: ", mp2l); diff --git a/src/art/art.h b/src/art/art.h index 9ae9333f1ce..b49701af576 100644 --- a/src/art/art.h +++ b/src/art/art.h @@ -73,7 +73,7 @@ #include "renderer/api/object.h" /* appleseed.foundation headers */ -#include "foundation/utility/containers/dictionary.h" +#include "foundation/containers/dictionary.h" #if defined(__GNUC__) && !defined(__clang__) # pragma GCC diagnostic pop diff --git a/src/art/brlcadplugin.cpp b/src/art/brlcadplugin.cpp index cb4609ea17a..a5ead23a75f 100644 --- a/src/art/brlcadplugin.cpp +++ b/src/art/brlcadplugin.cpp @@ -78,11 +78,11 @@ #include "foundation/math/scalar.h" #include "foundation/math/vector.h" #include "foundation/utility/api/specializedapiarrays.h" -#include "foundation/utility/containers/dictionary.h" +#include "foundation/containers/dictionary.h" #include "foundation/utility/job/iabortswitch.h" -#include "foundation/utility/log/consolelogtarget.h" +#include "foundation/log/consolelogtarget.h" #include "foundation/utility/searchpaths.h" -#include "foundation/utility/string.h" +#include "foundation/string/string.h" /* appleseed.main headers */ @@ -170,9 +170,9 @@ brlcad_miss(struct application* UNUSED(ap)) /* constructor when called from appleseed */ BrlcadObject::BrlcadObject( - const char* name, + const char* bname, const asr::ParamArray& params) - : asr::ProceduralObject(name, params) + : asr::ProceduralObject(bname, params) { configure_raytrace_application(get_database().c_str(), get_object_count(), get_objects()); VSET(min, m_params.get_required("minX"), m_params.get_required("minY"), m_params.get_required("minZ")); @@ -186,10 +186,10 @@ BrlcadObject::BrlcadObject( /* constructor when called from art.cpp */ BrlcadObject:: BrlcadObject( - const char* name, + const char* bname, const asr::ParamArray& params, struct application* p_ap, struct resource* p_resources) - : asr::ProceduralObject(name, params) + : asr::ProceduralObject(bname, params) { // this->rtip = p_ap->a_rt_i; this->resources = p_resources; diff --git a/src/art/tile.h b/src/art/tile.h index dab84c3800b..111911dbb0a 100644 --- a/src/art/tile.h +++ b/src/art/tile.h @@ -20,21 +20,49 @@ #include "renderer/kernel/rendering/itilecallback.h" +class ArtTileCallback + :public renderer::ITileCallback +{ + public: + // + // Methods called by tile-based renderers. + // -class ArtTileCallback: public renderer::ITileCallback { + // This method is called before a frame is rendered. + void on_tiled_frame_begin(const renderer::Frame*) {;} -public: + // This method is called after a frame is rendered. + void on_tiled_frame_end(const renderer::Frame*) {;} - virtual void on_tile_end(const renderer::Frame* frame, const size_t tile_x, const size_t tile_y); + // This method is called before a tile is rendered. + void on_tile_begin( + const renderer::Frame*, //frame + const size_t, //tile_x + const size_t, //tile_y + const size_t, //thread_index + const size_t //thread_count + ) {;} - virtual void release() {}; - virtual void on_tiled_frame_begin(const renderer::Frame*) {}; - virtual void on_tiled_frame_end(const renderer::Frame*) {}; - virtual void on_tile_begin(const renderer::Frame*, const size_t, const size_t) {}; - virtual void on_progressive_frame_update(const renderer::Frame*) {}; -}; + // This method is called after a tile is rendered. + void on_tile_end( + const renderer::Frame*, //frame + const size_t, //tile_x + const size_t //tile_y + ); + + // This method is called after the frame has been updated. + void on_progressive_frame_update( + const renderer::Frame&, //frame + const double, //time + const std::uint64_t, //samples + const double, //samples_per_pixel + const std::uint64_t //samples_per_second + ) {;} + void release() {}; +}; + /* * Local Variables: * tab-width: 8 diff --git a/src/brlman/brlman.cpp b/src/brlman/brlman.cpp index ce6c08e49a4..f40b8b1080d 100644 --- a/src/brlman/brlman.cpp +++ b/src/brlman/brlman.cpp @@ -47,7 +47,7 @@ #include #include #include -#include "qtcad/QAccordion.h" +#include "qtcad/QgAccordion.h" #endif #include "bu/app.h" @@ -264,7 +264,7 @@ class ManViewer : public QDialog private: struct bu_vls mlang = BU_VLS_INIT_ZERO; - QAccordion *lists; + QgAccordion *lists; QTextBrowser *browser; QDialogButtonBox *buttons; }; @@ -333,34 +333,34 @@ ManViewer::ManViewer(QWidget *pparent, const char *man_name, char man_section, c connect(buttons, &QDialogButtonBox::accepted, this, &ManViewer::accept); QSplitter *s = new QSplitter(Qt::Horizontal, this); - lists = new QAccordion(); + lists = new QgAccordion(); s->addWidget(lists); l1 = new QListWidget(this); list_man_files(l1, bu_vls_cstr(&mlang), '1', 1); l1->setSizeAdjustPolicy(QListWidget::AdjustToContents); - QAccordionObject *a1 = new QAccordionObject(lists, l1, "Programs (man1)"); + QgAccordionObject *a1 = new QgAccordionObject(lists, l1, "Programs (man1)"); lists->addObject(a1); QObject::connect(l1, &QListWidget::currentItemChanged, this, &ManViewer::do_man1); l3 = new QListWidget(this); list_man_files(l3, bu_vls_cstr(&mlang), '3', 1); l3->setSizeAdjustPolicy(QListWidget::AdjustToContents); - QAccordionObject *a3 = new QAccordionObject(lists, l3, "Libraries (man3)"); + QgAccordionObject *a3 = new QgAccordionObject(lists, l3, "Libraries (man3)"); lists->addObject(a3); QObject::connect(l3, &QListWidget::currentItemChanged, this, &ManViewer::do_man3); l5 = new QListWidget(this); list_man_files(l5, bu_vls_cstr(&mlang), '5', 1); l5->setSizeAdjustPolicy(QListWidget::AdjustToContents); - QAccordionObject *a5 = new QAccordionObject(lists, l5, "Conventions (man5)"); + QgAccordionObject *a5 = new QgAccordionObject(lists, l5, "Conventions (man5)"); lists->addObject(a5); QObject::connect(l5, &QListWidget::currentItemChanged, this, &ManViewer::do_man5); ln = new QListWidget(this); list_man_files(ln, bu_vls_cstr(&mlang), 'n', 1); ln->setSizeAdjustPolicy(QListWidget::AdjustToContents); - QAccordionObject *an = new QAccordionObject(lists, ln, "GED (mann)"); + QgAccordionObject *an = new QgAccordionObject(lists, ln, "GED (mann)"); lists->addObject(an); QObject::connect(ln, &QListWidget::currentItemChanged, this, &ManViewer::do_mann); diff --git a/src/burst/CMakeLists.txt b/src/burst/CMakeLists.txt deleted file mode 100644 index f43132a5632..00000000000 --- a/src/burst/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -set(BURST_INCLUDE_DIRS - ${FB_INCLUDE_DIRS} - ${RT_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ) -list(REMOVE_DUPLICATES BURST_INCLUDE_DIRS) -include_directories(${BURST_INCLUDE_DIRS}) - -set(burst_old_SOURCES - Hm.c - HmGetc.c - HmGlob.c - Sc.c - burst.c - error.c - fb.c - glob.c - grid.c - gridrotate.c - idents.c - paint.c - plot.c - prnt.c - trie.c - ui.c - ) - - -BRLCAD_ADDEXEC(burst "${burst_old_SOURCES}" "librt;libdm;${M_LIBRARY}") -ADD_TARGET_DEPS(burst dm_plugins) - -# Burst coding style is very old, and tool is deprecated. Not worth -# updating it to satisfy the strict-prototypes flag -include(CheckCXXCompilerFlag) -check_cxx_compiler_flag(-Wno-strict-prototypes NO_STRICT_PROTO_COMPILER_FLAG) -if (NO_STRICT_PROTO_COMPILER_FLAG) - # If we have the Wno-strict-prototypes flag, use it - target_compile_options(burst PRIVATE "-Wno-strict-prototypes") -endif (NO_STRICT_PROTO_COMPILER_FLAG) - -set(burst_old_noinst_HEADERS - CMakeLists.txt - ascii.h - burst.h - extern.h - Mm.h - Sc.h - ) -CMAKEFILES(${burst_old_noinst_HEADERS}) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/src/burst/Hm.c b/src/burst/Hm.c deleted file mode 100644 index 3d75a872bac..00000000000 --- a/src/burst/Hm.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* H M . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/Hm.c - * - * This code is derived in part from menuhit(9.3) in AT&T 9th Edition - * UNIX, Version 1 Programmer's Manual. - */ - -#include "common.h" - -#include -#include -#include - -#include "bu/file.h" - -#include "./Sc.h" -#include "./Mm.h" -#include "./extern.h" - -#if defined(HAVE_FDOPEN) && !defined(HAVE_DECL_FDOPEN) -extern FILE *fdopen(int fd, const char *mode); -#endif - -#define ErLog brst_log - -#define HmDEBUG 0 - -#ifndef Max -# define Max(_a, _b) ((_a)<(_b)?(_b):(_a)) -# define Min(_a, _b) ((_a)>(_b)?(_b):(_a)) -#endif - -#define HmRingbell() (void) putchar('\07'), (void) fflush(stdout) - -/* Keys for manipulating menus. */ -#define Ctrl(c_) ((c_)&037) -#define M_DEBUG Ctrl('?') -#define M_DOWN 'd' -#define M_HELP 'h' -#define M_MYXMOUSE Ctrl('X') -#define M_NOSELECT 'q' -#define M_REDRAW Ctrl('L') -#define M_SELECT ' ' -#define M_UP 'u' - - -/* Alternate keys for conformance to standard conventions. */ -#define A_UP Ctrl('P') -#define A_DOWN Ctrl('N') -#define A_HELP '?' - -#define P_OFF (0) -#define P_ON (1) -#define P_FORCE (1<<1) - -#define PutMenuChar(_c, _co, _ro, _map, _bit) {\ - static int lro = -1, lco = -1;\ - if ((_map) & (_bit) || (_bit) == 0) {\ - if (lco++ != (_co)-1 || lro != (_ro)) {\ - (void) ScMvCursor(_co, _ro);\ - lco = _co;\ - }\ - (void) putchar((_c));\ - }\ - (_bit) <<= 1;\ - (_co)++;\ -} - - -static int HmDirty = 0; -static int HmPkgInit = 0; - -static HmWindow *windows = NULL; - -#define HmENTRY (itemp-win->menup->item) -#define HmHEIGHT Min(win->height, HmMaxVis) -typedef struct nmllist HmLList; -struct nmllist -{ - HmItem *itemp; - HmLList *next; -}; - - -/* - void HmBanner(char *pgmname, int borderchr) - - Print program name and row of border characters to delimit the top - of the scrolling region. -*/ -void -HmBanner(const char *pgmname, int borderchr) -{ - int column; - char *p; -#define HmBUFLEN 81 - static char HmPgmName[HmBUFLEN] = "No name"; - static int HmBorderChr = '_'; - if (pgmname != NULL) { - bu_strlcpy(HmPgmName, pgmname, sizeof(HmPgmName)); - HmBorderChr = borderchr; - } - (void) ScMvCursor(HmLftMenu, HmYBORDER); - for (column = 1; column <= 3; column++) - (void) putc(HmBorderChr, stdout); - for (p = HmPgmName; column <= ScCO && *p != '\0'; column++, p++) - (void) putc((int)(*p), stdout); - for (; column <= ScCO; column++) - (void) putc(HmBorderChr, stdout); - return; -} - - -/* - void HmPrntItem(HmItem *itemp) (DEBUG) - - Print contents of itemp. -*/ -static void -HmPrntItem(HmItem *itemp) -{ - (void) ErLog("\t\tHmPrntItem(0x%x)\n", itemp); - for (; itemp->text != (char *) NULL; itemp++) { - (void) ErLog("\t\t\ttext=\"%s\"\n", itemp->text); - (void) ErLog("\t\t\thelp=\"%s\"\n", itemp->help == (char *) NULL ? "(null)" : itemp->help); - (void) ErLog("\t\t\tnext=0x%x\n", itemp->next); - (void) ErLog("\t\t\tdfn=0x%x\n", itemp->dfn); - (void) ErLog("\t\t\tbfn=0x%x\n", itemp->bfn); - (void) ErLog("\t\t\thfn=0x%x\n", itemp->hfn); - (void) ErLog("\t\t\tdata=%d\n", itemp->data); - (void) ErLog("\t\t\t----\n"); - } - (void) ErLog("\t\t\ttext=0x%x\n", itemp->text); - return; -} - - -/* - void HmPrntMenu(menup) (DEBUG) - - Print "windows" stack. -*/ -static void -HmPrntMenu(HmMenu *menup) -{ - (void) ErLog("\tHmPrntMenu(0x%x)\n", menup); - (void) ErLog("\t\tgenerator=0x%x\n", menup->generator); - (void) ErLog("\t\tprevtop=%d\n", menup->prevtop); - (void) ErLog("\t\tprevhit=%d\n", menup->prevhit); - (void) ErLog("\t\tsticky=%s\n", menup->sticky ? "true" : "false"); - HmPrntItem(menup->item); - return; -} - - -/* - void HmPrntWindows(void) (DEBUG) - - Print "windows" stack. -*/ -static void -HmPrntWindows(void) -{ - HmWindow *win; - (void) ErLog("HmPrntWindows()\n"); - for (win = windows; win != (HmWindow *) NULL; win = win->next) { - (void) ErLog("\twin=0x%x\n", win); - (void) ErLog("\tmenup=0x%x\n", win->menup); - (void) ErLog("\tmenux=%d\n", win->menux); - (void) ErLog("\tmenuy=%d\n", win->menuy); - (void) ErLog("\twidth=%d\n", win->width); - (void) ErLog("\theight=%d\n", win->height); - (void) ErLog("\tdirty=0x%x\n", win->dirty); - (void) ErLog("\tnext=0x%x\n", win->next); - HmPrntMenu(win->menup); - } - return; -} - - -/* - void HmFreeItems(Hmitem *itemp) - - Free storage (allocated with malloc) for an array of HmItem's. -*/ -static void -HmFreeItems(HmItem *itemp) -{ - HmItem *citemp; - int count; - for (citemp = itemp, count = 1; - citemp->text != (char *) NULL; - citemp++, count++ - ) { - MmStrFree(citemp->text); - if (citemp->help != (char *) NULL) - MmStrFree(citemp->help); - } - MmVFree(count, HmItem, itemp); - return; -} - - -/* - void HmFreeLList(HmLList *listp) - - Free storage (allocated with malloc) for a linked-list of - HmItem's. -*/ -static void -HmFreeLList(HmLList *listp) -{ - HmLList *tp; - for (; listp != (HmLList *) NULL; listp = tp) { - MmFree(HmItem, listp->itemp); - tp = listp->next; - MmFree(HmLList, listp); - } - return; -} - - -/* - void HmPutItem(HmWindow *win, HmItem *itemp, int flag) - - Display menu entry itemp. - - Win is the menu control structure for itemp. - - Flag is a bit flag and the following bits are meaningful: - - P_FORCE means draw the entire entry regardless of the - value of the dirty bitmap. - P_ON means this entry is current so highlight it. -*/ -static void -HmPutItem(HmWindow *win, HmItem *itemp, int flag) -{ - size_t label_len = strlen(itemp->text); - static char buf[HmMAXLINE]; - char *p = buf; - int col = win->menux; - int row = win->menuy+ - (HmENTRY-win->menup->prevtop)+1; - size_t width = win->width; - int bitmap = flag & P_FORCE ? - ~0 : win->dirty[row-win->menuy]; - int bit = 1; - int writemask = 0; - if (bitmap == 0) - return; - if (itemp->text[0] & 0200) { - /* right-justified */ - size_t i; - label_len--; - for (i = 0; i < width - label_len; i++) - *p++ = itemp->text[0] & 0177; - for (i = 1; itemp->text[i] != '\0'; i++) - *p++ = itemp->text[i]; - } else /* left-justified */ - if (itemp->text[label_len-1] & 0200) { - size_t i; - label_len--; - for (i = 0; !(itemp->text[i] & 0200); i++) - *p++ = itemp->text[i]; - for (; i < width; i++) - *p++ = itemp->text[label_len] & 0177; - } else { - /* centered */ - size_t i, j; - for (i = 0; i < (width - label_len)/2; i++) - *p++ = ' '; - for (j = 0; itemp->text[j] != '\0'; j++) - *p++ = itemp->text[j]; - for (i += j; i < width; i++) - *p++ = ' '; - } - *p = '\0'; - - PutMenuChar('|', col, row, bitmap, bit); - if (flag & P_ON) - (void) ScSetStandout(); - else - (void) ScClrStandout(); - - /* Optimized printing of entry. */ - if (bitmap == ~0) { - (void) fputs(buf, stdout); - col += p-buf; - bit <<= p-buf; - } else { - int i; - for (i = 0; i < p-buf; i++) - writemask |= 1<<(i+1); - for (i = 0; i < p-buf; i++) { - if ((bitmap & writemask) == writemask) - break; - writemask &= ~bit; - PutMenuChar(buf[i], col, row, bitmap, bit); - } - if (i < p-buf) { - (void) ScMvCursor(col, row); - (void) fputs(&buf[i], stdout); - col += (p-buf) - i; - bit <<= (p-buf) - i; - } - } - - if (flag & P_ON) - (void) ScClrStandout(); - PutMenuChar('|', col, row, bitmap, bit); - return; -} - - -/* - void HmPutBorder(HmWindow *win, row, char mark) - - Draw the horizontal border for row of win->menup using mark - for the corner characters. -*/ -static void -HmPutBorder(HmWindow *win, int row, char mark) -{ - int i; - int col = win->menux; - int bitmap = win->dirty[row - win->menuy]; - static char buf[HmMAXLINE]; - char *p = buf; - if (bitmap == 0) - return; /* No dirty bits. */ - *p++ = mark; - for (i = 0; i < win->width; i++) - *p++ = '-'; - *p++ = mark; - *p = '\0'; - if (bitmap == ~0) { - /* All bits dirty. */ - (void) ScMvCursor(col, row); - (void) fputs(buf, stdout); - } else { - int bit = 1; - - for (i = 0; i < p - buf; i++) - PutMenuChar(buf[i], col, row, bitmap, bit); - } - return; -} - - -/* - void HmSetbit(HmWindow *win, int col, int row) - - Mark as dirty, the bit in win->dirty that corresponds to - col and row of the screen. -*/ -static void -HmSetbit(HmWindow *win, int col, int row) -{ - int bit = col - win->menux; -#if HmDEBUG && 0 - (void) ErLog("HmSetbit:menu{<%d, %d>, <%d, %d>}col=%d, row=%d\n", - win->menux, win->menux+win->width+1, - win->menuy, win->menuy+HmHEIGHT+1, - col, row - ); -#endif - win->dirty[row-win->menuy] |= bit == 0 ? 1 : 1 << bit; -#if HmDEBUG && 0 - (void) ErLog("\tdirty[%d]=0x%x\r\n", - row-win->menuy, win->dirty[row-win->menuy] - ); -#endif - return; -} - - -/* - void HmClrmap(HmWindow *win) - - Mark as clean, the entire dirty bitmap for win. -*/ -static void -HmClrmap(HmWindow *win) -{ - int row; - int height = HmHEIGHT; - for (row = 0; row <= height+1; row++) - win->dirty[row] = 0; - return; -} - - -/* - void HmSetmap(HmWindow *win) - - Mark as dirty the entire dirty bitmap for win. -*/ -static void -HmSetmap(HmWindow *win) -{ - int row; - int height = HmHEIGHT; - for (row = 0; row <= height+1; row++) - win->dirty[row] = ~0; /* 0xffff... */ - return; -} - - -/* - HmWindow *HmInWin(x, y, HmWindow *win) - - Return pointer to top window in stack, starting with win whose - boundaries contain the screen coordinate . If the point - is outside of all these windows, return 0. -*/ -static HmWindow * -HmInWin(int x, int y, HmWindow *win) -{ -#if HmDEBUG && 0 - if (win != (HmWindow *) NULL) - (void) ErLog("HmInWin:x=%d y=%d win{<%d, %d>, <%d, %d>}\r\n", - x, y, - win->menux, win->menux+win->width+1, - win->menuy, win->menuy+HmHEIGHT+1 - ); -#endif - for (; win != (HmWindow *) NULL; win = win->next) { - int height = HmHEIGHT; - if (! (x < win->menux || x > win->menux + win->width + 1 || - y < win->menuy || y > win->menuy + height + 1) - ) - return win; - } - return (HmWindow *) NULL; -} - - -/* - void HmDrawWin(HmWindow *win) - - Draw win->menup on screen. Actually, only characters flagged as - dirty are drawn. -*/ -static void -HmDrawWin(HmWindow *win) -{ - HmItem *itemp; - int height; - -#if HmDEBUG && 1 - (void) ErLog("HmDrawWin:win{<%d, %d>, <%d, %d>}\r\n", - win->menux, win->menux+win->width+1, - win->menuy, win->menuy+HmHEIGHT+1 - ); { - int i; - for (i = 0; i <= HmHEIGHT+1; i++) - (void) ErLog("\tdirty[%d]=0x%x\r\n", i, win->dirty[i]); - } -#endif - HmPutBorder(win, win->menuy, win->menup->prevtop > 0 ? '^' : '+'); - for (itemp = win->menup->item + win->menup->prevtop; - HmENTRY-win->menup->prevtop < HmMaxVis && itemp->text != (char *) NULL; - itemp++ - ) - HmPutItem(win, itemp, - HmENTRY == win->menup->prevhit ? P_ON : P_OFF - ); - height = HmHEIGHT; - HmPutBorder(win, win->menuy+height+1, HmENTRY < win->height ? 'v' : '+'); - HmClrmap(win); - (void) fflush(stdout); - return; -} - - -/* - void HmHelp(HmWindow *win, int entry) - - Display help message for item indexed by entry in win->menup - on line HmYCOMMO. This message will be erased when the user - strikes a key (or uses the mouse). -*/ -static void -HmHelp(HmWindow *win, int entry) -{ - (void) ScMvCursor(HmLftMenu, HmYCOMMO); - (void) ScClrEOL(); - (void) ScSetStandout(); - (void) printf("%s", win->menup->item[entry].help); - (void) ScClrStandout(); - (void) fflush(stdout); - return; -} - - -/* - void HmError(const char *str) - - Display str on line HmYCOMMO. -*/ -void -HmError(const char *str) -{ - (void) ScMvCursor(HmLftMenu, HmYCOMMO); - (void) ScClrEOL(); - (void) ScSetStandout(); - (void) fputs(str, stdout); - (void) ScClrStandout(); - (void) fflush(stdout); - return; -} - - -/* - void HmLiftWin(HmWindow *win) - - Remove win->menup from screen, marking any occluded portions - of other menus as dirty so that they will be redrawn by HmHit(). -*/ -static void -HmLiftWin(HmWindow *win) -{ - int row, col; - int lastcol = -1, lastrow = -1; - int endcol = win->menux + win->width + 2; - int endrow = win->menuy + - HmHEIGHT + HmHGTBORDER; -#if HmDEBUG && 1 - (void) ErLog("HmLiftWin:win{<%d, %d>, <%d, %d>}\r\n", - win->menux, win->menux+win->width+1, - win->menuy, win->menuy+HmHEIGHT+1 - ); -#endif - for (row = win->menuy; row < endrow; row++) { - for (col = win->menux; col < endcol; col++) { - HmWindow *olwin; - if ((olwin = HmInWin(col, row, win->next)) - != (HmWindow *) NULL - ) { - HmSetbit(olwin, col, row); - HmDirty = 1; - } else { - if (lastcol != col-1 || lastrow != row) - (void) ScMvCursor(col, row); - lastcol = col; lastrow = row; - (void) putchar(' '); - } - } - } - (void) fflush(stdout); - return; -} - - -/* - void HmPushWin(HmWindow *win) - - Add window to top of "windows" stack. -*/ -static void -HmPushWin(HmWindow *win) -{ - win->next = windows; - windows = win; - return; -} - - -/* - void HmPopWin(HmWindow *win) - - Delete window from top of "windows" stack. -*/ -static void -HmPopWin(HmWindow *win) -{ - windows = win->next; - return; -} - - -/* - void HmRefreshWin(HmWindow *win) - - Draw any dirty portions of all windows in stack starting at win. -*/ -static void -HmRefreshWin(HmWindow *win) -{ - if (win == (HmWindow *) NULL) { - HmDirty = 0; - return; - } - HmRefreshWin(win->next); - HmDrawWin(win); - return; -} -/* - void HmRedraw(void) - - Force a redraw of all active menus. -*/ -void -HmRedraw(void) -{ - HmWindow *win; - int reset = 0; - -#if HmDEBUG && 1 - HmPrntWindows(); -#endif - (void) ScClrText(); /* clear entire screen */ - - /* See if we changed the maximum items displayed parameter. */ - if (HmMaxVis != HmLastMaxVis) - reset = 1; - for (win = windows; win != (HmWindow *) NULL; win = win->next) { - if (reset) { - /* Correct window to reflect new maximum. */ - /* Reset scrolling state-info in each window. */ - if (win->menup->prevhit >= HmMaxVis) - win->menup->prevtop = win->menup->prevhit - - HmMaxVis + 1; - else - win->menup->prevtop = 0; - /* Must reallocate "dirty" bit map to fit new size. */ - MmVFree(Min(win->height, HmLastMaxVis)+HmHGTBORDER, - int, win->dirty); - if ((win->dirty = - MmVAllo((size_t)HmHEIGHT+HmHGTBORDER, int) - ) == NULL) { - return; - } - } - HmSetmap(win); /* force all bits on in "dirty" bitmap */ - } - HmLastMaxVis = HmMaxVis; - HmRefreshWin(windows); /* redisplay all windows */ - HmBanner((char *) NULL, 0); /* redraw banner */ - return; -} - - -/* - void HmTtySet(void) - - Set up terminal handler and MYX-menu options for menu interaction. -*/ -void -HmTtySet(void) -{ -} - -/* - void HmTtyReset(void) - - Reset terminal handler and MYX-menu options to user settings. -*/ -void -HmTtyReset(void) -{ -} - -/* - void HmInit(int x, int y, int maxvis) - - Initialize position of top-level menu. Specify maximum - number of menu items visible at once. Place these values - in global variables. Determine as best we can whether MYX - is available and place int result in HmMyxflag. Return - true for success and false for failure to open "/dev/tty". -*/ -int -HmInit(int UNUSED(x), int UNUSED(y), int UNUSED(maxvis)) -{ - return 0; -} - - -/* - void HmWidHgtMenu(HmWindow *win) - - Determine width and height of win->menup, and store in win. -*/ -static void -HmWidHgtMenu(HmWindow *win) -{ - HmItem *itemp; - - /* Determine width of menu, allowing for border. */ - for (itemp = win->menup->item; itemp->text != (char *) NULL; itemp++) { - int len = 0; - int i; - for (i = 0; itemp->text[i] != '\0'; i++) { - if (! (itemp->text[i] & 0200)) - len++; - } - win->width = Max(win->width, len); - } - win->height = HmENTRY; - return; -} - - -/* - int HmFitMenu(HmWindow *nwin, HmWindow *cwin) - - If nwin->menup will fit below cwin->menup on screen, store - position in nwin, and return 1. Otherwise, return 0. -*/ -static int -HmFitMenu(HmWindow *nwin, HmWindow *cwin) -{ - if (cwin == (HmWindow *) NULL) - return 0; - else - if (HmFitMenu(nwin, cwin->next)) - return 1; - else - /* Look for space underneath this menu. */ - if (cwin->menux + nwin->width + 1 <= ScCO - && (size_t)cwin->menuy + cwin->height + nwin->height + HmHGTBORDER - < (size_t)HmMaxVis + HmTopMenu - ) { - nwin->menux = cwin->menux; - nwin->menuy = cwin->menuy + cwin->height + HmHGTBORDER - 1; - return 1; - } else { - return 0; - } -} - - -/* - void HmPosMenu(HmWindow *win) - - Find best screen position for win->menup. -*/ -static void -HmPosMenu(HmWindow *win) -{ - /* Determine origin (top-left corner) of menu. */ - if (win->next != (HmWindow *) NULL) { - win->menux = win->next->menux + win->next->width + 1; - win->menuy = win->next->menuy; - if (win->menux + win->width + 2 > ScCO) { - if (! HmFitMenu(win, win->next)) { - /* No space, so overlap top-level menu. */ - win->menux = HmLftMenu; - win->menuy = HmTopMenu; - } - } - } else { - /* Top-level menu. */ - win->menux = HmLftMenu; - win->menuy = HmTopMenu; - } - return; -} - - -/* - void HmMyxMouse(int *x, int *y) - - Read and decode screen coordinates from MYX "editor ptr". - Implicit return in x and y. -*/ -static void -HmMyxMouse(int *x, int *y) -{ - int c; - - c = HmGetchar(); - switch (c) { - case Ctrl('A') : - *x = HmGetchar() - ' ' + 96; - break; - case Ctrl('B') : - *x = HmGetchar() - ' ' + 192; - break; - default : - *x = c - ' '; - break; - } - c = HmGetchar(); - switch (c) { - case Ctrl('A') : - *y = HmGetchar() - ' ' + 96; - break; - case Ctrl('B') : - *y = HmGetchar() - ' ' + 192; - break; - default : - *y = c - ' '; - break; - } - (*x)++; - (*y)++; - return; -} - - -/* - HmItem *HmHit(HmMenu *menup) - - Present menup to the user and return a pointer to the selected - item, or 0 if there was no selection made. For more details, - see "Hm.h". -*/ -HmItem * -HmHit(HmMenu *menup) -{ - HmItem *itemp; - HmItem *retitemp = NULL; - HmWindow *win; - int done = 0; - int dynamic = 0; - static int HmLevel = 0; - -#if HmDEBUG - ErLog("HmHit(0x%x)\n", menup); -#endif - if (HmPkgInit == 0) { - HmInit(HmLftMenu, HmTopMenu, HmMaxVis); - HmPkgInit = 1; - } - if (++HmLevel == 1) - HmTtySet(); - - /* If generator function is provided, dynamically allocate the - menu items. - */ - if ((dynamic = (menup->item == (HmItem *) NULL))) { - int i; - HmItem *gitemp; - HmLList llhead, **listp; - for (i = 0, listp = &llhead.next; - ; - i++, listp = &(*listp)->next - ) { - if ((*listp = MmAllo(HmLList)) == NULL - || ((*listp)->itemp = MmAllo(HmItem)) == NULL - ) { - goto clean_exit; - } - itemp = (*listp)->itemp; - if ((gitemp = (*menup->generator)(i)) == (HmItem *) NULL) { - itemp->text = (char *) NULL; - (*listp)->next = (HmLList *) NULL; - break; - } - if (gitemp->text != (char *) NULL) { - if ((itemp->text = MmStrDup(gitemp->text)) - == (char *) NULL - ) { - goto clean_exit; - } - } else - itemp->text = (char *) NULL; - if (gitemp->help != (char *) NULL) { - if ((itemp->help = MmStrDup(gitemp->help)) - == (char *) NULL - ) { - goto clean_exit; - } - } else - itemp->help = (char *) NULL; - itemp->next = gitemp->next; - itemp->dfn = gitemp->dfn; - itemp->bfn = gitemp->bfn; - itemp->hfn = gitemp->hfn; - itemp->data = gitemp->data; -#if HmDEBUG && 0 - HmPrntItem(itemp); -#endif - } -#if HmDEBUG && 0 - HmPrntLList(llhead.next); -#endif - /* Steal the field that the user isn't using temporarily to - emulate the static allocation of menu items. - */ - if (i > 0) { - int ii; - HmLList *lp; - if ((menup->item = MmVAllo((size_t)i+1, HmItem)) == NULL) { - goto clean_exit; - } - for (ii = 0, lp = llhead.next; - lp != (HmLList *) NULL; - ii++, lp = lp->next - ) - menup->item[ii] = *lp->itemp; - } - HmFreeLList(llhead.next); - if (i == 0) /* Zero items, so return NULL */ - goto clean_exit; - } - if ((win = MmAllo(HmWindow)) == NULL) { -#if HmDEBUG - ErLog("HmHit, BUG: memory pool possibly corrupted.\n"); -#endif - goto clean_exit; - } - win->menup = menup; - win->width = 0; - HmPushWin(win); - HmWidHgtMenu(win); - HmPosMenu(win); - - if (menup->prevhit < 0 || menup->prevhit >= win->height) - menup->prevhit = 0; - itemp = &menup->item[menup->prevhit]; - - if ((win->dirty = MmVAllo((size_t)HmHEIGHT+HmHGTBORDER, int)) == NULL) { - goto clean_exit; - } - if (HmDirty) - HmRefreshWin(windows); - HmSetmap(win); - HmDrawWin(win); - while (! done) { - int c; - if (HmDirty) - HmRefreshWin(windows); - (void) ScMvCursor(HmXPROMPT, HmYPROMPT); - (void) ScClrEOL(); - (void) ScMvCursor(win->menux+win->width+2, - win->menuy+(HmENTRY-win->menup->prevtop)+1); - (void) fflush(stdout); - c = HmGetchar(); - (void) ScMvCursor(HmLftMenu, HmYCOMMO); - (void) ScClrEOL(); - switch (c) { - case M_UP : - case A_UP : - if (HmENTRY == 0) - HmRingbell(); - else { - HmPutItem(win, itemp, P_OFF | P_FORCE); - itemp--; - menup->prevhit = HmENTRY; - if (HmENTRY < win->menup->prevtop) { - win->menup->prevtop -= - HmENTRY > HmMaxVis/2 ? - (short)HmMaxVis/2+1 : (short)HmENTRY+1; - HmSetmap(win); - HmDrawWin(win); - } else - HmPutItem(win, itemp, P_ON | P_FORCE); - } - break; - case M_DOWN : - case A_DOWN : - if ((size_t)HmENTRY >= (size_t)win->height-1) - HmRingbell(); - else { - HmPutItem(win, itemp, P_OFF | P_FORCE); - itemp++; - menup->prevhit = HmENTRY; - if (HmENTRY - win->menup->prevtop >= HmMaxVis) { - win->menup->prevtop += - win->height-HmENTRY > HmMaxVis/2 ? - HmMaxVis/2 : win->height-HmENTRY; - HmSetmap(win); - HmDrawWin(win); - } else - HmPutItem(win, itemp, P_ON | P_FORCE); - } - break; - case M_MYXMOUSE : { - static int mousex, mousey; - HmItem *lastitemp; - if (HmGetchar() != Ctrl('_') || HmGetchar() != '1') - goto m_badinput; - HmMyxMouse(&mousex, &mousey); - if (HmInWin(mousex, mousey, win) != win) { - /* Mouse cursor outside of menu. */ - HmRingbell(); - break; - } - if (mousey == win->menuy && win->menup->prevtop == 0) { - /* Top border of menu and can't scroll. */ - goto m_noselect; - } - if (mousey == win->menuy + HmHEIGHT + 1 - && win->height <= HmMaxVis + win->menup->prevtop - ) { - /* Bottom border of menu and can't scroll. */ - HmRingbell(); - break; - } - lastitemp = itemp; - itemp = win->menup->item + - win->menup->prevtop + - ((size_t)mousey - ((size_t)win->menuy + 1)); - if (itemp == lastitemp) - /* User hit item twice in a row, so select it. */ - goto m_select; - HmPutItem(win, lastitemp, P_OFF | P_FORCE); - menup->prevhit = HmENTRY; - if (HmENTRY - win->menup->prevtop >= HmMaxVis) { - win->menup->prevtop += - (short)(win->height-HmENTRY > HmMaxVis/2 ? - HmMaxVis/2 : win->height-HmENTRY); - HmSetmap(win); - HmDrawWin(win); - } else - if (HmENTRY < win->menup->prevtop) { - win->menup->prevtop -= - (short)(HmENTRY > HmMaxVis/2 ? - (size_t)HmMaxVis/2+1 : (size_t)(HmENTRY+1)); - HmSetmap(win); - HmDrawWin(win); - } else { - HmPutItem(win, itemp, P_ON | P_FORCE); - } - break; - } - case M_HELP : - case A_HELP : - HmHelp(win, HmENTRY); - break; - m_select : - case M_SELECT : - if (itemp->next != (HmMenu *) NULL) { - HmItem *subitemp; - if (itemp->dfn != (void (*)()) NULL) { - int level = HmLevel; - HmTtyReset(); - HmLevel = 0; - (*itemp->dfn)(itemp); - HmLevel = level; - HmTtySet(); - } - subitemp = HmHit(itemp->next); - if (itemp->bfn != (void (*)()) NULL) { - int level = HmLevel; - HmTtyReset(); - HmLevel = 0; - (*itemp->bfn)(itemp); - HmLevel = level; - HmTtySet(); - } - if (subitemp != (HmItem *) NULL) { - retitemp = subitemp; - done = ! menup->sticky; - } - } else { - retitemp = itemp; - if (itemp->hfn != (void (*)()) NULL) { - int level = HmLevel; - HmTtyReset(); - HmLevel = 0; - (*itemp->hfn)(itemp); - HmLevel = level; - HmTtySet(); - } - done = ! menup->sticky; - } - break; - m_noselect : - case M_NOSELECT : - done = 1; - break; - case M_REDRAW : - HmRedraw(); - break; - case M_DEBUG : - HmPrntWindows(); - break; - m_badinput : - default : - HmError("Type 'd' down, 'u' up, 'h' help, to select, 'q' no selection."); - break; - } - (void) fflush(stdout); - } - /* Free storage of dynamic menu. */ - if (dynamic) { - if (retitemp != (HmItem *) NULL) { - /* Must make copy of item we are returning. */ - static HmItem dynitem; - dynitem = *retitemp; - retitemp = &dynitem; - } - HmFreeItems(menup->item); - menup->item = 0; - } - - HmLiftWin(win); - HmPopWin(win); - MmVFree(HmHEIGHT+HmHGTBORDER, int, win->dirty); - MmFree(HmWindow, win); - clean_exit : - if (HmLevel-- == 1) - HmTtyReset(); - return retitemp; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/HmGetc.c b/src/burst/HmGetc.c deleted file mode 100644 index 8d17a8aadaf..00000000000 --- a/src/burst/HmGetc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* H M G E T C . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/HmGetc.c - * - */ - -#include "common.h" - -#include -#include - -#include "./burst.h" - -int -HmGetchar(void) -{ - int c; - - while ((c = getc(HmTtyFp)) == EOF) - ; - - return c; -} - - -int -HmUngetchar(int c) -{ - return ungetc(c, HmTtyFp); -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/HmGlob.c b/src/burst/HmGlob.c deleted file mode 100644 index 60637054588..00000000000 --- a/src/burst/HmGlob.c +++ /dev/null @@ -1,44 +0,0 @@ -/* H M G L O B . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/HmGlob.c - * - */ - -#include "common.h" - -#include - -FILE *HmTtyFp = NULL; /* read keyboard, not stdin */ -int HmLftMenu = 1; /* default top-level menu position */ -int HmTopMenu = 1; -int HmMaxVis = 10; /* default maximum menu items displayed */ -int HmLastMaxVis = 10; /* track changes in above parameter */ -int HmTtyFd; /* read keyboard, not stdin */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/Mm.h b/src/burst/Mm.h deleted file mode 100644 index dfada5034fd..00000000000 --- a/src/burst/Mm.h +++ /dev/null @@ -1,55 +0,0 @@ -/* M M . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/Mm.h - * - */ - -#ifndef BURST_MM_H -#define BURST_MM_H - -/* Emulate MUVES Mm package using malloc. */ - -#include "common.h" - -#include -#include - -#include "bu/malloc.h" -#include "bu/str.h" - -#define MmAllo(typ) (typ *) bu_malloc(sizeof(typ), CPP_FILELINE) -#define MmFree(typ, ptr) bu_free((char *) ptr, CPP_FILELINE) -#define MmVAllo(ct, typ) (typ *) bu_malloc((ct)*sizeof(typ), CPP_FILELINE) -#define MmVFree(ct, typ, ptr) bu_free((char *) ptr, CPP_FILELINE) -#define MmStrDup(str) bu_strdup(str) -#define MmStrFree(str) bu_free(str, CPP_FILELINE) - -#endif /* BURST_MM_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/Sc.c b/src/burst/Sc.c deleted file mode 100644 index 72438e706df..00000000000 --- a/src/burst/Sc.c +++ /dev/null @@ -1,260 +0,0 @@ -/* S C . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/Sc.c - * - */ - -#include "common.h" - -#include -#include -#include - -#ifdef HAVE_SYS__IOCTL_H -# include -#else -# ifdef HAVE_SYS_IOCTL_H -# include -# define _winsize winsize /* For compatibility with _ioctl.h. */ -# endif -#endif - -#include "bu/str.h" - -#include "./Sc.h" - - -static FILE *out_fp; /* Output stream. */ -static int fd_stdout = 1; - -/* This is a global buffer for the terminal capabilities entry. */ -char ScTermcap[ScTCAPSIZ]; - -/* This is a global buffer for the name of the terminal. */ -char ScTermname[ScTERMSIZ] = "UNKNOWN"; - -/* Individual terminal control strings (TCS). */ -char *ScBC, /* Backspace character. */ - *ScPC, /* Padding character. */ - *ScUP, /* Cursor up one line. */ - *ScCS, /* Change scrolling region. */ - *ScSO, /* Begin standout mode. */ - *ScSE, /* End standout mode. */ - *ScCE, /* Clear to end of line. */ - *ScCL, /* Clear display and home cursor. */ - *ScHO, /* Home cursor. */ - *ScCM, /* Screen-relative cursor motion. */ - *ScTI, /* Initialize terminal. */ - *ScAL, /* Insert line. */ - *ScDL, /* Delete line. */ - *ScSR, /* Scroll text down. */ - *ScSF; /* Scroll text up. */ - -/* Individual terminal parameters. */ -int ScLI, /* Number of lines on screen. */ - ScCO; /* Number of columns on screen. */ - - -/* - This function prevents the default "PutChr" from being pulled in - from the termcap library (-ltermlib). DO NOT change its name or - STDOUT will be assumed as the output stream for terminal control. - Some applications might want to open "/dev/tty" so that they can - use STDOUT for something else. -*/ -int -PutChr(int c) { - return putc((char)c, out_fp); -} - - -/* - ScInit() must be invoked before any other function in the Sc package. - Stream fp must be open for writing and all terminal control sequences - will be sent to fp, giving the application the option of using STDOUT - for other things. Besides setting the output stream, ScInit() does - the following: - - Initializes the terminal. Fills terminal name and capabilities - into external buffers. Gets terminal control strings into external - variables. Gets individual terminal parameters into external - variables. Returns "1" for success, "0" for failure and - prints appropriate diagnostics on STDERR if $TERM is not set or - there is a problem in retrieving the corresponding termcap entry. -*/ -int -ScInit(FILE *fp) { - char *term; /* Name of terminal from environment. */ - out_fp = fp; - fd_stdout = fileno(out_fp); - if ((term = getenv("TERM")) == NULL) { - (void) fprintf(stderr, "TERM not set or exported!\n"); - return 0; - } - bu_strlcpy(ScTermname, term, ScTERMSIZ); - - return 1; /* All is well. */ -} - - -/* - Clear from the cursor to the end of that line. -*/ -int -ScClrEOL(void) { - if (ScCE == NULL) - return 0; - return 1; -} - - -/* - Reset the scrolling region to the entire screen. -*/ -int -ScClrScrlReg(void) { - if (ScCS == NULL) - return 0; - return 1; -} - - -/* - End standout mode. -*/ -int -ScClrStandout(void) { - if (ScSE == NULL) - return 0; - return 1; -} - - -/* - Clear the screen and "home" the cursor. -*/ -int -ScClrText(void) { - if (ScCL == NULL) - return 0; - return 1; -} - - -/* - Insert a the line under the cursor. -*/ -int -ScInsertLn(void) { - if (ScAL == NULL) - return 0; - return 1; -} - - -/* - Delete the line under the cursor. -*/ -int -ScDeleteLn(void) { - if (ScDL == NULL) - return 0; - return 1; -} - - -/* - Scroll backward 1 line. -*/ -int -ScDnScroll(void) { - if (ScSR == NULL) - return 0; - return 1; -} - - -/* - Move the cursor to the top-left corner of the screen. -*/ -int -ScHmCursor(void) { - if (ScHO == NULL) - return 0; - return 1; -} - - -/* - Move the cursor to screen coordinates x, y (for column and row, - respectively). -*/ -int -ScMvCursor(int UNUSED(x), int UNUSED(y)) { - if (ScCM == NULL) - return 0; - return 1; -} - - -/* - Set the scrolling region to be from "top" line to "btm" line, - inclusive. -*/ -int -ScSetScrlReg(int UNUSED(top), int UNUSED(btm)) { - if (ScCS == NULL) - return 0; - return 1; -} - - -/* - Begin standout mode. -*/ -int -ScSetStandout(void) { - if (ScSO == NULL) - return 0; - return 1; -} - - -/* - Scroll text forward 1 line. -*/ -int -ScUpScroll(void) { - if (ScSF == NULL) - return 0; - return 1; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/Sc.h b/src/burst/Sc.h deleted file mode 100644 index a53fde4bbc9..00000000000 --- a/src/burst/Sc.h +++ /dev/null @@ -1,167 +0,0 @@ -/* S C . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/Sc.h - * - */ - -/** - -- MUVES "Sc" (Screen manager) package definitions -**/ - -#ifndef BURST_SC_H -#define BURST_SC_H -#include "./burst.h" - -/** - int ScInit(FILE *fp) - - ScInit() must be invoked before any other function in the Sc - package. Stream fp must be open for writing and all terminal - control sequences will be sent to fp, giving the application - the option of using STDOUT for other things. Besides setting - the output stream, ScInit() does the following: - - Initializes the terminal. - - Fills terminal name and capabilities into these externals: - - char ScTermname[ScTERMSIZ] (terminal name from $TERM) - char ScTermcap[ScTCAPSIZ] (terminal capabilities entry) - - Gets terminal control strings into external variables (here - are some that don't have individual functions to output them, - the ones that DO are below): - - char *ScBC (backspace character) - char *ScPC (padding character) - char *ScUP (move the cursor up one line) - char *ScTI (initialize the terminal) - - Gets individual terminal parameters into these externals: - - int ScLI (number of lines on screen) - int ScCO (number of columns on screen) - - Returns "1" for success, "0" for failure and prints - appropriate diagnostics on STDERR if $TERM is not set or - there is a problem in retrieving the corresponding termcap - entry. -**/ - extern int ScInit(FILE *fp); - -/** - -Below are functions paired with terminal control strings that -they output to the stream specified with ScInit(). It is not -recommended that the control strings be used directly, but it -may be useful in certain applications to check their value; -if ScInit() has not been invoked or the corresponding terminal -capability does not exist, its control string will be NULL, -AND the function will return "false". Otherwise, they will -return "true" (assuming that it worked). There is no way to -be sure of this. - -char *ScCE (clear from under the cursor to end of line) -int ScClrEOL(void) - -char *ScCS (change scrolling region) -int ScClrScrlReg(void) - -char *ScSE (end standout mode) -int ScClrStandout(void) - -char *ScCL (clear screen, and home cursor) -int ScClrText(void) - -char *ScAL (insert a line under the cursor) -int ScInsertLn(void) - -char *ScDL (delete the line under the cursor) -int ScDeleteLn(void) - -char *ScSR (scroll text backwards 1 line) -int ScDnScroll(void) - -char *ScHO (move cursor to top-left corner of screen) -int ScHmCursor(void) - -char *ScCM (move cursor to column and row ) -int ScMvCursor(x, y) - -char *ScCS (set scrolling region from top to btm incl.) -int ScSetScrlReg(top, btm) - -char *ScSO (begin standout mode) -int ScSetStandout(void) - -char *ScSF (scroll text forwards 1 line) -int ScUpScroll(void) - -**/ -extern char *ScBC; -extern char *ScPC; -extern char *ScUP; -extern char *ScCS; -extern char *ScSO; -extern char *ScSE; -extern char *ScCE; -extern char *ScCL; -extern char *ScHO; -extern char *ScCM; -extern char *ScTI; -extern char *ScDL; -extern char *ScSR; -extern char *ScSF; - -extern int ScLI; -extern int ScCO; - -extern int ScClrEOL(void); -extern int ScClrScrlReg(void); -extern int ScClrStandout(void); -extern int ScClrText(void); -extern int ScDeleteLn(void); -extern int ScDnScroll(void); -extern int ScHmCursor(void); -extern int ScInsertLn(void); -extern int ScMvCursor(int x, int y); -extern int ScSetScrlReg(int top, int btm); -extern int ScSetStandout(void); -extern int ScUpScroll(void); - -#define ScTCAPSIZ 1024 -#define ScTERMSIZ 80 - -extern char ScTermcap[]; -extern char ScTermname[]; - -#endif /* BURST_SC_H */ - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/ascii.h b/src/burst/ascii.h deleted file mode 100644 index b211f5a088b..00000000000 --- a/src/burst/ascii.h +++ /dev/null @@ -1,66 +0,0 @@ -/* A S C I I . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/ascii.h - * - */ - -#ifndef BURST_ASCII_H -#define BURST_ASCII_H - -#define NUL '\000' -#define SOH '\001' -#define STX '\002' -#define INTR '\003' -#define EOT '\004' -#define ACK '\006' -#define BEL '\007' -#define BS '\010' -#define HT '\011' -#define LF '\012' -#define FF '\014' -#define CRET '\015' -#define DLE '\020' -#define DC1 '\021' -#define DC2 '\022' -#define DC3 '\023' -#define DC4 '\024' -#define KILL '\025' -#define CAN '\030' -#define ESC '\033' -#define GS '\035' -#define RS '\036' -#define US '\037' -#define SP '\040' -#define DEL '\177' - -#define Ctrl(chr) ((int)chr&037) - -#endif /* BURST_ASCII_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/burst.c b/src/burst/burst.c deleted file mode 100644 index 12f01f1dba7..00000000000 --- a/src/burst/burst.c +++ /dev/null @@ -1,393 +0,0 @@ -/* B U R S T . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/burst.c - * - */ - -#include "common.h" - -#include -#include -#include - -#include "bu/app.h" -#include "bu/getopt.h" -#include "bu/file.h" -#include "bu/opt.h" -#include "bu/str.h" -#include "bu/exit.h" -#include "bu/log.h" -#include "bu/vls.h" - -#include "./burst.h" -#include "./extern.h" -#include "./ascii.h" - - -#define DEBUG_BURST 0 /* 1 enables debugging for this module */ - -/* - int getCommand(char *name, char *buf, int len, FILE *fp) - - Read next command line into buf and stuff the command name into name - from input stream fp. buf must be at least len bytes long. - - RETURN: 1 for success - - 0 for end of file -*/ -static int -getCommand(char *name, char *buf, int len, FILE *fp) -{ - assert(name != NULL); - assert(buf != NULL); - assert(fp != NULL); - while (bu_fgets(buf, len, fp) != NULL) { - if (buf[0] != CHAR_COMMENT) { - if (sscanf(buf, "%1330s", name) == 1) { - /* LNBUFSZ */ - buf[strlen(buf)-1] = NUL; /* clobber newline */ - return 1; - } else /* Skip over blank lines. */ - continue; - } else { - /* Generate comment command. */ - bu_strlcpy(name, CMD_COMMENT, LNBUFSZ); - return 1; - } - } - return 0; /* EOF */ -} - - -/* - void setupSigs(void) - - Initialize all signal handlers. -*/ - -static void -setupSigs(void) -{ - int i; - for (i = 0; i < NSIG; i++) - switch (i) { - case SIGINT : - if ((norml_sig = signal(i, SIG_IGN)) == SIG_IGN) - abort_sig = SIG_IGN; - else { - norml_sig = intr_sig; - abort_sig = abort_RT; - (void) signal(i, norml_sig); - } - break; -#ifdef SIGPIPE - case SIGPIPE : - (void) signal(i, SIG_IGN); - break; -#endif - default: - break; - } - return; -} - -/* - void readBatchInput(FILE *fp) - - Read and execute commands from input stream fp. -*/ -void -readBatchInput(FILE *fp) -{ - assert(fp != (FILE *) NULL); - batchmode = 1; - while (getCommand(cmdname, cmdbuf, LNBUFSZ, fp)) { - Func *cmdfunc; - if ((cmdfunc = getTrie(cmdname, LNBUFSZ, cmdtrie)) == NULL) { - size_t i; - size_t len = strlen(cmdname); - brst_log("ERROR -- command syntax:\n"); - brst_log("\t%s\n", cmdbuf); - brst_log("\t"); - for (i = 0; i < len; i++) - brst_log(" "); - brst_log("^\n"); - } else - if (BU_STR_EQUAL(cmdname, CMD_COMMENT)) { - /* special handling for comments */ - cmdptr = cmdbuf; - cmdbuf[strlen(cmdbuf)-1] = '\0'; /* clobber newline */ - (*cmdfunc)((HmItem *) 0); - } else { - /* Advance pointer past nul at end of - command name. */ - cmdptr = cmdbuf + strlen(cmdname) + 1; - (*cmdfunc)((HmItem *) 0); - } - } - batchmode = 0; - return; -} - -static const char usage[] = - "Usage: burst [-p|-P] [file]\n" - "\tThe -p/-P options specifies whether to plot points or lines." -; - -/* - int main(int argc, char *argv[]) -*/ -int -main(int argc, const char *argv[]) -{ - struct burst_state s; - const char *bfile = NULL; - int burst_opt; /* unused, for option compatibility */ - int plot_lines = 0; - int plot_points = 0; - int ret_ac; - - bu_setprogname(argv[0]); - - struct bu_opt_desc d[4]; - struct bu_vls pmsg = BU_VLS_INIT_ZERO; - - BU_OPT(d[0], "p", "", "", NULL, &plot_points, "Plot points"); - BU_OPT(d[1], "P", "", "", NULL, &plot_lines, "Plot lines"); - BU_OPT(d[2], "b", "", "", NULL, &burst_opt, "Batch mode"); - BU_OPT_NULL(d[3]); - - burst_state_init(&s); - - - /* Interactive mode is gone - until we strip all the leftovers out - * of the code, let it know we're not in tty mode */ - tty = 0; - - bu_setlinebuf(stderr); - - /* Skip first arg */ - argv++; argc--; - - /* no options imply a request for usage */ - if (argc < 1 || !argv || argv[0] == NULL) { - (void)fprintf(stderr, "%s\n", usage); - return EXIT_SUCCESS; - } - - /* Process options */ - ret_ac = bu_opt_parse(&pmsg, argc, argv, d); - if (ret_ac < 0) { - (void)fprintf(stderr, "%s\n", bu_vls_cstr(&pmsg)); - bu_vls_free(&pmsg); - (void)fprintf(stderr, "%s\n", usage); - return EXIT_FAILURE; - } - bu_vls_free(&pmsg); - - if (ret_ac) { - if (!bu_file_exists(argv[0], NULL)) { - (void)fprintf(stderr, "ERROR: Input file [%s] does not exist!\n", argv[0]); - (void)fprintf(stderr, "%s\n", usage); - return EXIT_FAILURE; - } else { - bfile = argv[0]; - } - } - - tmpfp = bu_temp_file(tmpfname, TIMER_LEN); - if (!tmpfp) { - bu_exit(EXIT_FAILURE, "ERROR: Unable to create temporary file.\n"); - return EXIT_FAILURE; - } - - setupSigs(); - - /* must be called before any output is produced */ - if (!initUi()) { - fclose(tmpfp); - return EXIT_FAILURE; - } - -#if DEBUG_BURST - prntTrie(cmdtrie, 0); -#endif - assert(airids.i_next == NULL); - assert(armorids.i_next == NULL); - assert(critids.i_next == NULL); - - if (bfile) { - FILE *fp = fopen(bfile, "rb"); - readBatchInput(fp); - fclose(fp); - } else { - readBatchInput(stdin); - } - - fclose(tmpfp); - return EXIT_SUCCESS; -} - - -/* - void exitCleanly(int code) - - Should be only exit from program after success of initUi(). -*/ -void -exitCleanly(int code) -{ - if (tty) - closeUi(); /* keep screen straight */ - (void) fclose(tmpfp); - if (!bu_file_delete(tmpfname)) - locPerror(tmpfname); - exit(code); -} - -void -burst_state_init(struct burst_state *s) -{ - //Colors colorids; - s->fbiop = NULL; - s->burstfp = NULL; - s->gridfp = NULL; - s->histfp = NULL; - s->outfp = NULL; - s->plotfp = NULL; - s->shotfp = NULL; - s->shotlnfp = NULL; - s->tmpfp = NULL; - s->mainhmenu = NULL; - //Ids airids; - //Ids armorids; - //Ids critids; - s->pixgrid = NULL; - VSET(s->pixaxis, 255, 0, 0); - VSET(s->pixbhit, 200, 255, 200); - VSET(s->pixbkgr, 150, 100, 255); - VSET(s->pixblack, 0, 0, 0); - VSET(s->pixcrit, 255, 200, 200); - VSET(s->pixghit, 255, 0, 255); - VSET(s->pixmiss, 200, 200, 200); - VSET(s->pixtarg, 255, 255, 255); - s->cmdtrie = NULL; - s->plotline = 0; - s->batchmode = 0; - s->cantwarhead = 0; - s->deflectcone = DFL_DEFLECT; - s->dithercells = DFL_DITHER; - s->fatalerror = 0; - s->groundburst = 0; - s->reportoverlaps = DFL_OVERLAPS; - s->reqburstair = 1; - s->shotburst = 0; - s->tty = 1; - s->userinterrupt = 0; - memset(s->airfile, 0, LNBUFSZ); - memset(s->armorfile, 0, LNBUFSZ); - memset(s->burstfile, 0, LNBUFSZ); - memset(s->cmdbuf, 0, LNBUFSZ); - memset(s->cmdname, 0, LNBUFSZ); - memset(s->colorfile, 0, LNBUFSZ); - memset(s->critfile, 0, LNBUFSZ); - memset(s->errfile, 0, LNBUFSZ); - memset(s->fbfile, 0, LNBUFSZ); - memset(s->gedfile, 0, LNBUFSZ); - memset(s->gridfile, 0, LNBUFSZ); - memset(s->histfile, 0, LNBUFSZ); - memset(s->objects, 0, LNBUFSZ); - memset(s->outfile, 0, LNBUFSZ); - memset(s->plotfile, 0, LNBUFSZ); - memset(s->scrbuf, 0, LNBUFSZ); - memset(s->scriptfile, 0, LNBUFSZ); - memset(s->shotfile, 0, LNBUFSZ); - memset(s->shotlnfile, 0, LNBUFSZ); - memset(s->title, 0, TITLE_LEN); - memset(s->timer, 0, TIMER_LEN); - memset(s->tmpfname, 0, TIMER_LEN); - s->cmdptr = NULL; - s->bdist = DFL_BDIST; - VSET(s->burstpoint, 0.0, 0.0, 0.0); - s->cellsz = DFL_CELLSIZE; - s->conehfangle = DFL_CONEANGLE; - VSET(s->fire, 0.0, 0.0, 0.0); - s->griddn = 0.0; - s->gridlf = 0.0; - s->gridrt = 0.0; - s->gridup = 0.0; - VSET(s->gridhor, 0.0, 0.0, 0.0); - VSET(s->gridsoff, 0.0, 0.0, 0.0); - VSET(s->gridver, 0.0, 0.0, 0.0); - s->grndbk = 0.0; - s->grndht = 0.0; - s->grndfr = 0.0; - s->grndlf = 0.0; - s->grndrt = 0.0; - VSET(s->modlcntr, 0.0, 0.0, 0.0); - s->modldn = 0.0; - s->modllf = 0.0; - s->modlrt = 0.0; - s->modlup = 0.0; - s->raysolidangle = 0.0; - s->standoff = 0.0; - s->unitconv = 1.0; - s->viewazim = DFL_AZIMUTH; - s->viewelev = DFL_ELEVATION; - s->pitch = 0.0; - s->yaw = 0.0; - VSET(s->xaxis, 1.0, 0.0, 0.0); - VSET(s->zaxis, 0.0, 0.0, 1.0); - VSET(s->negzaxis, 0.0, 0.0, -1.0); - co = 0; - devwid = 0; - devhgt = 0; - firemode = FM_DFLT; - gridsz = 512; - gridxfin = 0; - gridyfin = 0; - gridxorg = 0; - gridyorg = 0; - gridwidth = 0; - gridheight = 0; - li = 0; - nbarriers = DFL_BARRIERS; - noverlaps = 0; - nprocessors = 0; - nriplevels = DFL_RIPLEVELS; - s->nspallrays = DFL_NRAYS; - s->units = DFL_UNITS; - s->zoom = 1; - s->rtip = RTI_NULL; - s->norml_sig = NULL; /* active during interactive operation */ - s->abort_sig = NULL; /* active during ray tracing only */ -} - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/burst.h b/src/burst/burst.h deleted file mode 100644 index 7bc744cb616..00000000000 --- a/src/burst/burst.h +++ /dev/null @@ -1,666 +0,0 @@ -/* B U R S T . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/burst.h - * - */ - -#ifndef BURST_BURST_H -#define BURST_BURST_H - -#include "common.h" -#include -#include - -#include "vmath.h" -#include "dm.h" -#include "raytrace.h" - -/* NSIG not always defined in */ -#ifndef NSIG -# define NSIG 64 -#endif - - -/* menu configuration */ -#define MENU_LFT 1 -#define MENU_TOP 2 -#define MENU_MAXVISITEMS 10 - -/* prompt line configuration */ -#define PROMPT_X HmXPROMPT -#define PROMPT_Y HmYPROMPT - -/* banner (border) configuration */ -#define BORDER_CHR '_' -#define BORDER_Y (PROMPT_Y+1) - -/* grid offset printing window */ -#define GRID_X 55 /* where grid indices are printed */ -#define GRID_Y BORDER_Y - -/* scroll region configuration */ -#define SCROLL_TOP (BORDER_Y+1) -#define SCROLL_BTM (ScLI-1) /* bottom line causes scroll */ - -/* timer (cpu statistics) window configuration */ -#define TIMER_X 1 -#define TIMER_Y 1 - -/* buffer sizes */ -#define LNBUFSZ 256 /* buffer for one-line messages */ -#define MAXDEVWID 10000 /* maximum width of frame buffer */ - -#define CHAR_COMMENT '#' -#define CMD_COMMENT "comment" - -/* default parameters */ -#define DFL_AZIMUTH 0.0 -#define DFL_BARRIERS 100 -#define DFL_BDIST 0.0 -#define DFL_CELLSIZE 101.6 -#define DFL_CONEANGLE (45.0/RAD2DEG) -#define DFL_DEFLECT 0 -#define DFL_DITHER 0 -#define DFL_ELEVATION 0.0 -#define DFL_NRAYS 200 -#define DFL_OVERLAPS 1 -#define DFL_RIPLEVELS 1 -#define DFL_UNITS U_MILLIMETERS - -/* firing mode bit definitions */ -#define ASNBIT(w, b) (w = (b)) -#define SETBIT(w, b) (w |= (b)) -#define CLRBIT(w, b) (w &= ~(b)) -#define TSTBIT(w, b) ((w)&(b)) -#define FM_GRID 0 /* generate grid of shotlines */ -#define FM_DFLT FM_GRID -#define FM_PART (1) /* bit 0: ON = partial envelope, OFF = full */ -#define FM_SHOT (1<<1) /* bit 1: ON = discrete shots, OFF = gridding */ -#define FM_FILE (1<<2) /* bit 2: ON = file input, OFF = direct input */ -#define FM_3DIM (1<<3) /* bit 3: ON = 3-D coords., OFF = 2-D coords */ -#define FM_BURST (1<<4) /* bit 4: ON = discrete burst points, OFF = shots */ - -/* flags for notify() */ -#define NOTIFY_APPEND 1 -#define NOTIFY_DELETE 2 -#define NOTIFY_ERASE 4 - -#define NOTIFY_DELIM ':' - -#define PB_ASPECT_INIT '1' -#define PB_CELL_IDENT '2' -#define PB_RAY_INTERSECT '3' -#define PB_RAY_HEADER '4' -#define PB_REGION_HEADER '5' - -#define PS_ASPECT_INIT '1' -#define PS_CELL_IDENT '2' -#define PS_SHOT_INTERSECT '3' - -#define TITLE_LEN 72 -#define TIMER_LEN 72 - -#define U_INCHES 0 -#define U_FEET 1 -#define U_MILLIMETERS 2 -#define U_CENTIMETERS 3 -#define U_METERS 4 -#define U_BAD -1 - -#define UNITS_INCHES "inches" -#define UNITS_FEET "feet" -#define UNITS_MILLIMETERS "millimeters" -#define UNITS_CENTIMETERS "centimeters" -#define UNITS_METERS "meters" - -/* white space in input tokens */ -#define WHITESPACE " \t" - -/* colors for UNIX plot files */ -#define R_GRID 255 /* grid - yellow */ -#define G_GRID 255 -#define B_GRID 0 - -#define R_BURST 255 /* burst cone - red */ -#define G_BURST 0 -#define B_BURST 0 - -#define R_OUTAIR 100 /* outside air - light blue */ -#define G_OUTAIR 100 -#define B_OUTAIR 255 - -#define R_INAIR 100 /* inside air - light green */ -#define G_INAIR 255 -#define B_INAIR 100 - -#define R_COMP 0 /* component (default) - blue */ -#define G_COMP 0 -#define B_COMP 255 - -#define R_CRIT 255 /* critical component (default) - purple */ -#define G_CRIT 0 -#define B_CRIT 255 - -#define C_MAIN 0 -#define C_CRIT 1 - -#define COS_TOL 0.01 -#define LOS_TOL 0.1 -#define VEC_TOL 0.001 -#define OVERLAP_TOL 0.25 /* thinner overlaps not reported */ -#define EXIT_AIR 9 /* exit air is called 09 air */ -#define OUTSIDE_AIR 1 /* outside air is called 01 air */ - -#define Air(rp) ((rp)->reg_aircode > 0) -#define DiffAir(rp, sp) ((rp)->reg_aircode != (sp)->reg_aircode) -#define SameAir(rp, sp) ((rp)->reg_aircode == (sp)->reg_aircode) -#define SameCmp(rp, sp) ((rp)->reg_regionid == (sp)->reg_regionid) -#define OutsideAir(rp) ((rp)->reg_aircode == OUTSIDE_AIR) -#define InsideAir(rp) (Air(rp)&& !OutsideAir(rp)) - -#define Malloc_Bomb(_bytes_) \ - brst_log("\"%s\"(%d) : allocation of %d bytes failed.\n", \ - __FILE__, __LINE__, _bytes_) - -#define Swap_Doubles(a_, b_) \ - { fastf_t f_ = a_; \ - a_ = b_; \ - b_ = f_; \ - } -#define Toggle(f) (f) = !(f) - -typedef struct ids Ids; -struct ids -{ - short i_lower; - short i_upper; - Ids *i_next; -}; -#define IDS_NULL (Ids *) 0 - -typedef struct colors Colors; -struct colors -{ - short c_lower; - short c_upper; - unsigned char c_rgb[3]; - Colors *c_next; -}; -#define COLORS_NULL (Colors *) 0 - -typedef struct pt_queue Pt_Queue; -struct pt_queue -{ - struct partition *q_part; - Pt_Queue *q_next; -}; - - -#define PT_Q_NULL (Pt_Queue *) 0 - -/* - * MUVES "Hm" (hierarchical menu) package definitions - * - * This software and documentation is derived in part from the - * menuhit(9.3) manual pages (not source code) in AT&T 9th Edition - * UNIX, Version 1 Programmer's Manual. - * - * The Hm package provides a pop-up menu implementation which uses a - * terminal-independent screen management facility (Sc package) to - * simulate the necessary graphics using the ASCII character set. - * Only a few keyboard characters are required to control the menus, - * but when possible, as with DMD terminals running a MYX terminal - * emulator, the menus can be controlled with the mouse. - */ -/** - * Each menu is defined by the following structure: - * - * typedef struct { - * HmItem *item; - * HmItem *(*generator)(); - * short prevtop; - * short prevhit; - * int sticky; - * } - * HmMenu; - * - * A menu can be built as an array of HmItem's, pointed to by item, or - * with a generator function. If item is (HmItem *) 0, the generator - * field is assumed to be valid. The generator function is passed an - * integer parameter, and must return the pointer to an HmItem in a - * static area (the result is only needed until the next call). The - * n's are guaranteed to start at 0 and increase by 1 each invocation - * until generator returns (HmItem *) 0. Prevtop will contain the - * index of the menu item which appeared at the top of the menu the - * last time it was displayed. Prevhit will contain the index of the - * last item traversed (indices begin at 0). If sticky is true, the - * menu will hang around after an entry is selected so that another - * entry may be chosen and the menu must be exited explicitly with the - * appropriate key-stroke or equivalent mouse operation. Otherwise, - * the menu will exit after selection of an item (and any actions - * resulting from that selection such as submenus have finished). - * WARNING: if a menu is to be used more than once during recursive - * calls to HmHit, there needs to be distinct copies (allocated - * storage) since the item field is filled in by the generator - * function, and the prevtop and prevhit fields should be private to - * the current invocation of HmHit. - */ - -struct HmMenu; - -typedef struct -{ - char *text; /* menu item string */ - char *help; /* help string */ - struct HmMenu *next; /* sub-menu pointer or NULL */ - void (*dfn)(); - void (*bfn)(); - void (*hfn)(); - long data; -} -HmItem; - -/** - * Menu items are defined by the following structure: - * - * typedef struct { - * char *text; - * char *help; - * HmMenu *next; - * void (*dfn)(); - * void (*bfn)(); - * void (*hfn)(); - * long data; - * } - * HmItem; - * - * The text field will be displayed as the name of the item. - * Characters with the 0200 bit set are regarded as fill characters. - * For example, the string "\240X" will appear in the menu as a - * right-justified X (040 is the ASCII space character). Menu strings - * without fill characters are drawn centered in the menu. Whether - * generated statically or dynamically, the list of HmItem's must be - * terminated by a NULL text field. The help string will be displayed - * when the user presses the help key. If next is not equal to - * (HmMenu *) 0, it is assumed to point to a submenu, "dfn()" if - * non-zero is called just before the submenu is invoked, and "bfn()" - * likewise just afterwards. These functions are passed the current - * menu item. If the menu item is selected and next is 0, "hfn()" is - * called (if non-zero), also with the current menu item. The "data" - * field is reserved for the user to pass information between these - * functions and the calling routine. - */ -typedef struct HmMenu -{ - HmItem *item; /* List of menu items or 0. */ - HmItem *(*generator)(); /* If item == 0, generates items. */ - short prevtop; /* Top entry currently visible */ - short prevhit; /* Offset from top of last select */ - int sticky; /* If true, menu stays around after - SELECT, and until QUIT. */ -} -HmMenu; - -/* Structure used internally for screen management. These are stacked - dynamically with calls to HmHit() such that the head of the chain - is the current menu, and the end of the chain such that next is - 0, is the top-level menu. -*/ -typedef struct HmWin -{ - struct HmWin *next; /* Parent of this menu. */ - HmMenu *menup; /* Address of menu data structure. */ - int menux; /* Position on screen where top-left */ - int menuy; /* corner of menu will be displayed. */ - int width; /* Width of menu, not including border. */ - int height; /* Number of menu entries. */ - int *dirty; /* Dynamically allocated bitmap. ON bits - mean character needs a redraw. */ -} -HmWindow; - -/** - * int HmInit(int x, int y, int maxvis) - * - * HmInit() must be called before any other routines in the Hm package - * to initialize the screen position of the top-left corner of the - * top-level menu to x and y and to set the maximum number of menu - * entries which will be visible at one time to maxvis. If the number - * of entries in a menu exceeds maxvis, the menu will scroll to - * accommodate them. The values of x, y and maxvis are stored in - * these external variables: - * - * int HmLftMenu - * int HmTopMenu - * int HmMaxVis - * - * If this routine is not called, default parameters will be used. - * - * HmInit() also opens "/dev/tty" for input and stores its file - * descriptor in HmTtyFd and associated stream handle in HmTtyFp. - * - * int HmTtyFd - * FILE *HmTtyFp - * - * This routine returns true or false on success or failure to open - * "/dev/tty". - */ -extern int HmInit(int x, int y, int maxvis); -extern FILE *HmTtyFp; -extern int HmLftMenu; -extern int HmTopMenu; -extern int HmMaxVis; -extern int HmLastMaxVis; -extern int HmTtyFd; - -/** - * HmItem *HmHit(HmMenu *menup) - * - * HmHit() presents the user with a menu specified by HmMenu pointer - * menup and returns a pointer to the selected HmItem or 0 if nothing - * was selected. The menu is presented to the user with the item - * corresponding to prevhit (current item) highlighted. If a menu has - * not been accessed yet, prevhit will be set to the first item. The - * user may move the cursor to the item below the current one by - * pressing the 'd' key, or move up by pressing the 'u'. If the user - * presses 'h', the help message for the current item will be - * displayed until another key is struck. To select an item, the user - * presses the space bar. An actual selection has been made when the - * selected item does not have a submenu, otherwise, it may be termed - * a traversal of that item. Traversing an item does change the value - * of prevhit, but is not final as the submenu can be exited by the - * user pressing 'q', before selecting an item. In case the screen - * becomes disturbed (i.e. by the output of another process), holding - * down the CONTROL key and striking an 'l' will re-display all of the - * menus. - * - * Both the help and warning (non-fatal error) messages will be - * displayed in the one-line window at HmYCOMMO. For instance, if the - * user hits any keys other than the ones mentioned above, an error - * message will appear in this window. Also, a one-line window is - * reserved for application prompts at HmYPROMPT. The prompt window - * is cleared just prior to blocking on user input, and the message - * window is cleared when the user provides input (strikes a key). - * - * If a menu has more items than can be displayed at once, the corners - * of the menu will indicate this as follows: - * - * '+' means the adjacent displayed item is the actual first (or last - * if a bottom corner) item in the menu. - * - * 'v' means that the entry displayed in the previous line is not the - * last, and the menu can be scrolled upwards. - * - * '^' means that the entry displayed on the next line is not actually - * the first, and the menu can be scrolled downwards. - * - * Attempting to move the cursor below the bottom entry of the menu - * will cause the menu to scroll half a page or until the entries run - * out, which ever comes first. If there are no entries to scroll the - * terminal will beep. The analogous holds true for attempting to - * move upward past the top entry of the menu. If a DMD terminal with - * MYX running is used, a special cursor will appear, and the user may - * use the mouse rather than the keyboard as follows: Clicking button - * 1 of the mouse while the cursor is outside the "current menu", will - * cause the terminal to beep. If the cursor is on an item, that item - * will be made "current". If on the "current" item, that item will - * be selected. If on the top border of the current menu, that menu - * will scroll down if possible, and if not, that menu will exit. If - * on the bottom border, that menu will scroll upward if possible and - * beep if not. - */ - extern HmItem *HmHit(HmMenu *menup); - -/** - * void HmRedraw(void) - * - * HmRedraw() will force the entire set of active menus to be redrawn - * on the next call to HmHit(). This is useful when an application - * interferes with the portion of the screen used by the Hm package - * (from HmTopMenu to HmYCOMMO). -**/ -extern void HmRedraw(void); - -/** - * void HmError(const char *string) - * - * HmError() will display string on line HmYCOMMO. - */ -extern void HmError(const char *str); - -#define HmYCOMMO (HmTopMenu+HmMaxVis+HmHGTBORDER) -#define HmYPROMPT (HmYCOMMO+1) -#define HmXPROMPT 1 -#define HmYBORDER (HmYPROMPT+1) - -/** - * int HmGetchar(void) - * int HmUngetchar(int c) - * - * HmGetchar() and HmUngetchar() are used by the Hm package to read a - * character from the keyboard and to stuff one character back on the - * input stream. They may be both be supplied by the application if - * the default behavior is not desirable. HmGetchar() returns the - * next character on the standard input. This command will block - * until input is available. HmUngetchar() inserts the character c on - * the standard input. An EOF will be returned if this is not - * possible or c is equal to EOF. In general, this is guaranteed to - * work for one character assuming that something has already been - * read with HmGetchar() and the input stream is buffered. - */ -extern int HmGetchar(void); -extern int HmUngetchar(int c); - -/** - * void HmTtySet(void) - * void HmTtyReset(void) - * - * HmTtySet() and HmTtyReset() set/restore the terminal modes for the - * menus to work properly. These are mainly internal routines which - * are called from HmHit(), but are provided in case an escape from - * the program is provided by the application or job control is - * enabled in the underlying shell, in which case, these routines can - * be called from a menu function or signal handler. - */ -extern void HmTtySet(); -extern void HmTtyReset(); - - -#define HmMAXLINE 132 -#define HmHGTBORDER 2 - -#ifdef NULL_FUNC -# undef NULL_FUNC -#endif - -#define NULL_FUNC ((Func *) NULL) -#define TRIE_NULL ((Trie *) NULL) - -/* Datum for trie leaves. */ -typedef void Func(); - -/* Trie tree node. */ -typedef union trie Trie; -union trie { - struct { - /* Internal nodes: datum is current letter. */ - int t_char; /* Current letter. */ - Trie *t_altr; /* Alternate letter node link. */ - Trie *t_next; /* Next letter node link. */ - } - n; - struct { - /* Leaf nodes: datum is function ptr. */ - Func *t_func; /* Function pointer. */ - Trie *t_altr; /* Alternate letter node link. */ - Trie *t_next; /* Next letter node link. */ - } - l; -}; -#define NewTrie(p) if (((p) = (Trie *) malloc(sizeof(Trie))) == TRIE_NULL) {\ - Malloc_Bomb(sizeof(Trie));\ - return TRIE_NULL;\ -} -extern Trie *cmd_trie; - - -struct burst_state { - Colors colorids; /* ident range to color mappings for plots */ - struct fb *fbiop; /* frame buffer specific access from libfb */ - FILE *burstfp; /* input stream for burst point locations */ - FILE *gridfp; /* grid file output stream (2-d shots) */ - FILE *histfp; /* histogram output stream (statistics) */ - FILE *outfp; /* burst point library output stream */ - FILE *plotfp; /* 3-D UNIX plot stream (debugging) */ - FILE *shotfp; /* input stream for shot positions */ - FILE *shotlnfp; /* shotline file output stream */ - FILE *tmpfp; /* temporary file output stream for logging input */ - HmMenu *mainhmenu; /* */ - Ids airids; /* burst air idents */ - Ids armorids; /* burst armor idents */ - Ids critids; /* critical component idents */ - unsigned char *pixgrid; /* */ - unsigned char pixaxis[3]; /* grid axis */ - unsigned char pixbhit[3]; /* burst ray hit non-critical comps */ - unsigned char pixbkgr[3]; /* outside grid */ - unsigned char pixblack[3]; /* black */ - unsigned char pixcrit[3]; /* burst ray hit critical component */ - unsigned char pixghit[3]; /* ground burst */ - unsigned char pixmiss[3]; /* shot missed target */ - unsigned char pixtarg[3]; /* shot hit target */ - Trie *cmdtrie; /* */ - - int plotline; /* boolean for plot lines (otherwise plots points) */ - int batchmode; /* are we processing batch input now */ - int cantwarhead; /* pitch or yaw will be applied to warhead */ - int deflectcone; /* cone axis deflects towards normal */ - int dithercells; /* if true, randomize shot within cell */ - int fatalerror; /* must abort ray tracing */ - int groundburst; /* if true, burst on imaginary ground */ - int reportoverlaps; /* if true, overlaps are reported */ - int reqburstair; /* if true, burst air required for shotburst */ - int shotburst; /* if true, burst along shotline */ - int tty; /* if true, full screen display is used */ - int userinterrupt; /* has the ray trace been interrupted */ - - char airfile[LNBUFSZ]; /* input file name for burst air ids */ - char armorfile[LNBUFSZ]; /* input file name for burst armor ids */ - char burstfile[LNBUFSZ]; /* input file name for burst points */ - char cmdbuf[LNBUFSZ]; /* */ - char cmdname[LNBUFSZ]; /* */ - char colorfile[LNBUFSZ]; /* ident range-to-color file name */ - char critfile[LNBUFSZ]; /* input file for critical components */ - char errfile[LNBUFSZ]; /* errors/diagnostics log file name */ - char fbfile[LNBUFSZ]; /* frame buffer image file name */ - char gedfile[LNBUFSZ]; /* MGED data base file name */ - char gridfile[LNBUFSZ]; /* saved grid (2-d shots) file name */ - char histfile[LNBUFSZ]; /* histogram file name (statistics) */ - char objects[LNBUFSZ]; /* list of objects from MGED file */ - char outfile[LNBUFSZ]; /* burst point library output file name */ - char plotfile[LNBUFSZ]; /* 3-D UNIX plot file name (debugging) */ - char scrbuf[LNBUFSZ]; /* scratch buffer for temporary use */ - char scriptfile[LNBUFSZ]; /* shell script file name */ - char shotfile[LNBUFSZ]; /* input file of firing coordinates */ - char shotlnfile[LNBUFSZ]; /* shotline output file name */ - char title[TITLE_LEN]; /* title of MGED target description */ - char timer[TIMER_LEN]; /* CPU usage statistics */ - char tmpfname[TIMER_LEN]; /* temporary file for logging input */ - char *cmdptr; /* */ - - fastf_t bdist; /* fusing distance for warhead */ - fastf_t burstpoint[3]; /* explicit burst point coordinates */ - fastf_t cellsz; /* shotline separation */ - fastf_t conehfangle; /* spall cone half angle */ - fastf_t fire[3]; /* explicit firing coordinates (2-D or 3-D) */ - fastf_t griddn; /* distance in model coordinates from origin to bottom border of grid */ - fastf_t gridlf; /* distance to left border */ - fastf_t gridrt; /* distance to right border */ - fastf_t gridup; /* distance to top border */ - fastf_t gridhor[3]; /* horizontal grid direction cosines */ - fastf_t gridsoff[3]; /* origin of grid translated by stand-off */ - fastf_t gridver[3]; /* vertical grid direction cosines */ - fastf_t grndbk; /* distance to back border of ground plane (-X) */ - fastf_t grndht; /* distance of ground plane below target origin (-Z) */ - fastf_t grndfr; /* distance to front border of ground plane (+X) */ - fastf_t grndlf; /* distance to left border of ground plane (+Y) */ - fastf_t grndrt; /* distance to right border of ground plane (-Y) */ - fastf_t modlcntr[3]; /* centroid of target's bounding RPP */ - fastf_t modldn; /* distance in model coordinates from origin to bottom extent of projection of model in grid plane */ - fastf_t modllf; /* distance to left extent */ - fastf_t modlrt; /* distance to right extent */ - fastf_t modlup; /* distance to top extent */ - fastf_t raysolidangle; /* solid angle per spall sampling ray */ - fastf_t standoff; /* distance from model origin to grid */ - fastf_t unitconv; /* units conversion factor (mm to "units") */ - fastf_t viewazim; /* degrees from X-axis to firing position */ - fastf_t viewelev; /* degrees from XY-plane to firing position */ - - /* These are the angles and fusing distance used to specify the path of - the canted warhead in Bob Wilson's simulation. - */ - fastf_t pitch; /* elevation above path of main penetrator */ - fastf_t yaw; /* deviation right of path of main penetrator */ - - /* useful vectors */ - fastf_t xaxis[3]; - fastf_t zaxis[3]; - fastf_t negzaxis[3]; - - int co; /* columns of text displayable on video screen */ - int devwid; /* width in pixels of frame buffer window */ - int devhgt; /* height in pixels of frame buffer window */ - int firemode; /* mode of specifying shots */ - int gridsz; - int gridxfin; - int gridyfin; - int gridxorg; - int gridyorg; - int gridwidth; /* Grid width in cells. */ - int gridheight; /* Grid height in cells. */ - int li; /* lines of text displayable on video screen */ - int nbarriers; /* no. of barriers allowed to critical comp */ - int noverlaps; /* no. of overlaps encountered in this view */ - int nprocessors; /* no. of processors running concurrently */ - int nriplevels; /* no. of levels of ripping (0 = no ripping) */ - int nspallrays; /* no. of spall rays at each burst point */ - int units; /* target units (default is millimeters) */ - int zoom; /* magnification factor on frame buffer */ - - struct rt_i *rtip; /* model specific access from librt */ - - /* signal handlers */ - void (*norml_sig)(); /* active during interactive operation */ - void (*abort_sig)(); /* active during ray tracing only */ -}; - -void burst_state_init(struct burst_state *s); - -#endif /* BURST_BURST_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/error.c b/src/burst/error.c deleted file mode 100644 index 4746be878ae..00000000000 --- a/src/burst/error.c +++ /dev/null @@ -1,100 +0,0 @@ -/* E R R O R . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/error.c - * - * Ray Tracing library and Framebuffer library, error handling routines. - * - * Functions - - * brst_log Called to log RT library events. - * fb_log Called to log FB library events. - * - */ - -#include "common.h" - -#include -#include - -#include "./Sc.h" -#include "./extern.h" - -#include "bu/exit.h" -#include "bu/str.h" - -/* - * Log an RT library event - */ -void -brst_log(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (tty && (errfile[0] == '\0' || BU_STR_EQUAL(errfile, "/dev/tty"))) { - if (ScDL != NULL) { - (void) ScMvCursor(1, SCROLL_TOP); - (void) ScDeleteLn(); - (void) ScMvCursor(1, SCROLL_BTM); - (void) ScClrEOL(); - (void) vprintf(fmt, ap); - } else { - if (ScSetScrlReg(SCROLL_TOP, SCROLL_BTM+1)) { - char buf[LNBUFSZ]; - char *p; - (void) ScMvCursor(1, SCROLL_BTM+1); - (void) ScClrEOL(); - /* Work around for problem with vprintf(): it doesn't - cause the screen to scroll, don't know why. */ - (void) vsprintf(buf, fmt, ap); - /* Newline will cause double scroll. */ - p = buf+strlen(buf)-1; - if (*p == '\n') - *p = '\0'; /* clobber newline */ - (void) puts(buf); - (void) ScMvCursor(1, SCROLL_BTM+1); - (void) ScClrScrlReg(); - } else { - (void) fprintf(stderr, - "%s %s %s %s!\n", - "This terminal has no delete line", - "or scrolling region capability, ", - "please dump it somewhere and get", - "a real terminal" - ); - bu_exit(1, NULL); - } - } - (void) fflush(stdout); - } else { - (void) vfprintf(stderr, fmt, ap); - } - va_end(ap); -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/extern.h b/src/burst/extern.h deleted file mode 100644 index bd9f58adb27..00000000000 --- a/src/burst/extern.h +++ /dev/null @@ -1,243 +0,0 @@ -/* E X T E R N . H - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/extern.h - * - */ - -#ifndef BURST_EXTERN_H -#define BURST_EXTERN_H - -#include "common.h" - -#include -#include -#include - -#include "dm.h" - -#include "./burst.h" - -/* External functions from application. */ - -extern Func *getTrie(char *name, int buflen, Trie *triep); -extern Trie *addTrie(char *name, Trie **triepp); -extern void prntTrie(Trie *triep, int level); - -extern Colors *findColors(); -extern int chkEntryNorm(); -extern int chkExitNorm(); -extern int closFbDevice(); -extern int imageInit(); -extern int initUi(); -extern int openFbDevice(); -extern int findIdents(); -extern int readColors(); -extern int readIdents(); -extern int notify(); -extern void closeUi(); -extern void colorPartition(); -extern void exitCleanly(); -extern void freeIdents(); -extern void getRtHitNorm(); -extern void gridInit(); -extern void gridModel(); -extern void gridToFb(); -extern void locPerror(); -extern void logCmd(); -extern void paintCellFb(); -extern void paintGridFb(); -extern void paintSpallFb(); -extern void plotGrid(); -extern void plotInit(); -extern void plotPartition(); -extern void plotRayLine(); -extern void plotRayPoint(); -extern void prntAspectInit(); -extern void prntBurstHdr(); -extern void prntCellIdent(); -extern void prntDbgPartitions(); -extern void prntFiringCoords(); -extern void prntFusingComp(); -extern void prntGridOffsets(); -extern void prntIdents(); -extern void prntPhantom(); -extern void prntRayHeader(); -extern void prntRayIntersect(); -extern void prntTimer(); -extern void prompt(); -extern void readCmdFile(); -extern void warning(); -extern void clr_Tabs(); -extern void prntShieldComp(); -extern void qFree(); -extern void prntRegionHdr(); -extern int qAdd(); -extern void prntSeg(); -extern void gridRotate(); -extern void HmBanner(); -extern void spallInit(); -extern void readBatchInput(); -extern void set_Cbreak(); -extern void clr_Echo(); -extern void clr_Tabs(); -extern void reset_Tty(); -extern void save_Tty(); - -extern void (*norml_sig)(int); -extern void (*abort_sig)(int); -extern void abort_RT(int); -extern void intr_sig(int); - -/* proper prototype */ -extern void prntScr(const char *, ...); -extern void brst_log(const char *, ...); -extern int roundToInt(fastf_t f); - -extern Colors colorids; -extern struct fb *fbiop; -extern FILE *burstfp; -extern FILE *gridfp; -extern FILE *histfp; -extern FILE *outfp; -extern FILE *plotfp; -extern FILE *shotfp; -extern FILE *shotlnfp; -extern FILE *tmpfp; -extern HmMenu *mainhmenu; -extern Ids airids; -extern Ids armorids; -extern Ids critids; -extern unsigned char *pixgrid; -extern unsigned char pixaxis[3]; -extern unsigned char pixbkgr[3]; -extern unsigned char pixbhit[3]; -extern unsigned char pixblack[3]; -extern unsigned char pixcrit[3]; -extern unsigned char pixghit[3]; -extern unsigned char pixmiss[3]; -extern unsigned char pixtarg[3]; -extern Trie *cmdtrie; - -extern int plotline; -extern int batchmode; -extern int cantwarhead; -extern int deflectcone; -extern int dithercells; -extern int fatalerror; -extern int groundburst; -extern int reportoverlaps; -extern int reqburstair; -extern int shotburst; -extern int tty; -extern int userinterrupt; - -extern char airfile[]; -extern char armorfile[]; -extern char burstfile[]; -extern char cmdbuf[]; -extern char cmdname[]; -extern char colorfile[]; -extern char critfile[]; -extern char errfile[]; -extern char fbfile[]; -extern char gedfile[]; -extern char gridfile[]; -extern char histfile[]; -extern char objects[]; -extern char outfile[]; -extern char plotfile[]; -extern char scrbuf[]; -extern char scriptfile[]; -extern char shotfile[]; -extern char shotlnfile[]; -extern char title[]; -extern char timer[]; -extern char tmpfname[]; - -extern char *cmdptr; - -extern fastf_t bdist; -extern fastf_t burstpoint[]; -extern fastf_t cellsz; -extern fastf_t conehfangle; -extern fastf_t fire[]; -extern fastf_t griddn; -extern fastf_t gridlf; -extern fastf_t gridrt; -extern fastf_t gridup; -extern fastf_t gridhor[]; -extern fastf_t gridsoff[]; -extern fastf_t gridver[]; -extern fastf_t grndbk; -extern fastf_t grndht; -extern fastf_t grndfr; -extern fastf_t grndlf; -extern fastf_t grndrt; -extern fastf_t modlcntr[]; -extern fastf_t modldn; -extern fastf_t modllf; -extern fastf_t modlrt; -extern fastf_t modlup; -extern fastf_t pitch; -extern fastf_t raysolidangle; -extern fastf_t standoff; -extern fastf_t unitconv; -extern fastf_t viewazim; -extern fastf_t viewelev; -extern fastf_t viewsize; -extern fastf_t yaw; -extern fastf_t xaxis[]; -extern fastf_t zaxis[]; -extern fastf_t negzaxis[]; - -extern int co; -extern int devhgt; -extern int devwid; -extern int firemode; -extern int gridsz; -extern int gridxfin; -extern int gridyfin; -extern int gridxorg; -extern int gridyorg; -extern int gridheight; -extern int gridwidth; -extern int li; -extern int nbarriers; -extern int noverlaps; -extern int nprocessors; -extern int nriplevels; -extern int nspallrays; -extern int units; -extern int zoom; - -extern struct rt_i *rtip; - -#endif /* BURST_EXTERN_H */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/fb.c b/src/burst/fb.c deleted file mode 100644 index 2d7732ddde1..00000000000 --- a/src/burst/fb.c +++ /dev/null @@ -1,149 +0,0 @@ -/* F B . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/fb.c - * - */ - -#include "common.h" - -#include -#include -#include -#include - -#include "bu/str.h" -#include "dm.h" - -#include "./burst.h" -#include "./ascii.h" -#include "./extern.h" - - -int -imageInit() -{ - int needopen = 0; - static char lastfbfile[LNBUFSZ]={0}; /* last fbfile */ - devwid = 512; - devhgt = 512; - if (fbfile[0] == NUL) - return 1; - zoom = devwid / gridsz - 1; - while (zoom < 3 && devwid < MAXDEVWID) { - devwid *= 2; - devhgt *= 2; - zoom = devwid / gridsz; - } - if (zoom * gridsz == devwid) - zoom--; - V_MAX(zoom, 1); - - /* Determine whether it is necessary to open fbfile. */ - if (fbiop == FB_NULL || fb_getwidth(fbiop) != devwid) - needopen = 1; /* not currently open or size changed */ - else - if (lastfbfile[0] != NUL && !BU_STR_EQUAL(fbfile, lastfbfile)) - needopen = 1; /* name changed */ - bu_strlcpy(lastfbfile, fbfile, LNBUFSZ); - - if (needopen) { - if (! openFbDevice(fbfile)) - return 0; - paintGridFb(); - } else - if (!(firemode & FM_SHOT) || (firemode & FM_FILE)) - paintGridFb(); - return 1; -} - - -/* - Must be called after gridInit() so that gridsz is setup. -*/ -int -openFbDevice(char *fbdev) -{ - int ret = 1; - notify("Opening frame buffer", NOTIFY_APPEND); - if (zoom < 1) { - prntScr("Device is too small to display image."); - ret = 0; - goto safe_exit; - } - if (((fbiop != FB_NULL && fb_getwidth(fbiop) != devwid) - || pixgrid == NULL) - && (pixgrid = (unsigned char *) calloc(devwid*3, sizeof(unsigned char))) - == (unsigned char *) NULL) { - prntScr("Memory allocation of %d bytes failed.", - sizeof(unsigned char)*devwid); - ret = 0; - goto safe_exit; - } - (void) memset((char *) pixgrid, NUL, sizeof(unsigned char)*devwid*3); - if (fbiop != FB_NULL) { - if (! closFbDevice()) { - ret = 0; - goto safe_exit; - } - } - fbiop = fb_open(fbdev, devwid, devhgt); - if (fbiop == NULL) { - ret = 0; - goto safe_exit; - } else if (fb_clear(fbiop, pixblack) == -1 - || (notify("Zooming", NOTIFY_APPEND), - fb_zoom(fbiop, 1, 1) == -1) - || (notify("Windowing", NOTIFY_DELETE), - fb_window(fbiop, devwid/2, devhgt/2) == -1) - ) { - ret = 0; - goto safe_exit; - } - safe_exit : notify(NULL, NOTIFY_DELETE); - return ret; -} - - -int -closFbDevice() -{ - int ret; - notify("Closing frame buffer", NOTIFY_APPEND); - if (fb_close(fbiop) == -1) - ret = 0; - else { - ret = 1; - fbiop = FB_NULL; - } - notify(NULL, NOTIFY_DELETE); - return ret; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/glob.c b/src/burst/glob.c deleted file mode 100644 index 19501f97084..00000000000 --- a/src/burst/glob.c +++ /dev/null @@ -1,184 +0,0 @@ -/* G L O B . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/glob.c - * - */ - -#include "common.h" -#include -#include - -#include "vmath.h" -#include "dm.h" -#include "raytrace.h" - -#include "./burst.h" -#include "./extern.h" - - -Colors colorids; /* ident range to color mappings for plots */ -struct fb *fbiop = NULL;/* frame buffer specific access from libfb */ -FILE *burstfp = NULL; /* input stream for burst point locations */ -FILE *gridfp = NULL; /* grid file output stream (2-d shots) */ -FILE *histfp = NULL; /* histogram output stream (statistics) */ -FILE *outfp = NULL; /* burst point library output stream */ -FILE *plotfp = NULL; /* 3-D UNIX plot stream (debugging) */ -FILE *shotfp = NULL; /* input stream for shot positions */ -FILE *shotlnfp = NULL; /* shotline file output stream */ -FILE *tmpfp = NULL; /* temporary file output stream for logging input */ -HmMenu *mainhmenu; -Ids airids; /* burst air idents */ -Ids armorids; /* burst armor idents */ -Ids critids; /* critical component idents */ -unsigned char *pixgrid; -unsigned char pixaxis[3] = { 255, 0, 0 }; /* grid axis */ -unsigned char pixbhit[3] = { 200, 255, 200 }; /* burst ray hit non-critical comps */ -unsigned char pixbkgr[3] = { 150, 100, 255 }; /* outside grid */ -unsigned char pixblack[3] = { 0, 0, 0 }; /* black */ -unsigned char pixcrit[3] = { 255, 200, 200 }; /* burst ray hit critical component */ -unsigned char pixghit[3] = { 255, 0, 255 }; /* ground burst */ -unsigned char pixmiss[3] = { 200, 200, 200 }; /* shot missed target */ -unsigned char pixtarg[3] = { 255, 255, 255 }; /* shot hit target */ -Trie *cmdtrie = NULL; - -int plotline = 0; /* boolean for plot lines (otherwise plots points) */ -int batchmode = 0; /* are we processing batch input now */ -int cantwarhead = 0; /* pitch or yaw will be applied to warhead */ -int deflectcone = DFL_DEFLECT; /* cone axis deflects towards normal */ -int dithercells = DFL_DITHER; /* if true, randomize shot within cell */ -int fatalerror; /* must abort ray tracing */ -int groundburst = 0; /* if true, burst on imaginary ground */ -int reportoverlaps = DFL_OVERLAPS; -/* if true, overlaps are reported */ -int reqburstair = 1; /* if true, burst air required for shotburst */ -int shotburst = 0; /* if true, burst along shotline */ -int tty = 1; /* if true, full screen display is used */ -int userinterrupt; /* has the ray trace been interrupted */ - -char airfile[LNBUFSZ]={0}; /* input file name for burst air ids */ -char armorfile[LNBUFSZ]={0}; /* input file name for burst armor ids */ -char burstfile[LNBUFSZ]={0}; /* input file name for burst points */ -char cmdbuf[LNBUFSZ]={0}; -char cmdname[LNBUFSZ]={0}; -char colorfile[LNBUFSZ]={0}; /* ident range-to-color file name */ -char critfile[LNBUFSZ]={0}; /* input file for critical components */ -char errfile[LNBUFSZ]={0}; /* errors/diagnostics log file name */ -char fbfile[LNBUFSZ]={0}; /* frame buffer image file name */ -char gedfile[LNBUFSZ]={0}; /* MGED data base file name */ -char gridfile[LNBUFSZ]={0}; /* saved grid (2-d shots) file name */ -char histfile[LNBUFSZ]={0}; /* histogram file name (statistics) */ -char objects[LNBUFSZ]={0}; /* list of objects from MGED file */ -char outfile[LNBUFSZ]={0}; /* burst point library output file name */ -char plotfile[LNBUFSZ]={0}; /* 3-D UNIX plot file name (debugging) */ -char scrbuf[LNBUFSZ]={0}; /* scratch buffer for temporary use */ -char scriptfile[LNBUFSZ]={0}; /* shell script file name */ -char shotfile[LNBUFSZ]={0}; /* input file of firing coordinates */ -char shotlnfile[LNBUFSZ]={0}; /* shotline output file name */ -char title[TITLE_LEN]={0}; /* title of MGED target description */ -char timer[TIMER_LEN]={0}; /* CPU usage statistics */ -char tmpfname[TIMER_LEN]={0}; /* temporary file for logging input */ - -char *cmdptr; - -fastf_t bdist = DFL_BDIST; -/* fusing distance for warhead */ -fastf_t burstpoint[3]; /* explicit burst point coordinates */ -fastf_t cellsz = DFL_CELLSIZE; -/* shotline separation */ -fastf_t conehfangle = DFL_CONEANGLE; -/* spall cone half angle */ -fastf_t fire[3]; /* explicit firing coordinates (2-D or 3-D) */ -fastf_t griddn; /* distance in model coordinates from origin to - bottom border of grid */ -fastf_t gridlf; /* distance to left border */ -fastf_t gridrt; /* distance to right border */ -fastf_t gridup; /* distance to top border */ -fastf_t gridhor[3]; /* horizontal grid direction cosines */ -fastf_t gridsoff[3]; /* origin of grid translated by stand-off */ -fastf_t gridver[3]; /* vertical grid direction cosines */ -fastf_t grndbk = 0.0; /* distance to back border of ground plane (-X) */ -fastf_t grndht = 0.0; /* distance of ground plane below target origin (-Z) */ -fastf_t grndfr = 0.0; /* distance to front border of ground plane (+X) */ -fastf_t grndlf = 0.0; /* distance to left border of ground plane (+Y) */ -fastf_t grndrt = 0.0; /* distance to right border of ground plane (-Y) */ -fastf_t modlcntr[3]; /* centroid of target's bounding RPP */ -fastf_t modldn = 0.0; /* distance in model coordinates from origin to bottom - extent of projection of model in grid plane */ -fastf_t modllf = 0.0; /* distance to left extent */ -fastf_t modlrt = 0.0; /* distance to right extent */ -fastf_t modlup = 0.0; /* distance to top extent */ -fastf_t raysolidangle; /* solid angle per spall sampling ray */ -fastf_t standoff; /* distance from model origin to grid */ -fastf_t unitconv = 1.0; /* units conversion factor (mm to "units") */ -fastf_t viewazim = DFL_AZIMUTH; -/* degrees from X-axis to firing position */ -fastf_t viewelev = DFL_ELEVATION; -/* degrees from XY-plane to firing position */ - -/* These are the angles and fusing distance used to specify the path of - the canted warhead in Bob Wilson's simulation. -*/ -fastf_t pitch = 0.0; /* elevation above path of main penetrator */ -fastf_t yaw = 0.0; /* deviation right of path of main penetrator */ - -/* useful vectors */ -fastf_t xaxis[3] = { 1.0, 0.0, 0.0 }; -fastf_t zaxis[3] = { 0.0, 0.0, 1.0 }; -fastf_t negzaxis[3] = { 0.0, 0.0, -1.0 }; - -int co; /* columns of text displayable on video screen */ -int devwid; /* width in pixels of frame buffer window */ -int devhgt; /* height in pixels of frame buffer window */ -int firemode = FM_DFLT; /* mode of specifying shots */ -int gridsz = 512; -int gridxfin; -int gridyfin; -int gridxorg; -int gridyorg; -int gridwidth; /* Grid width in cells. */ -int gridheight; /* Grid height in cells. */ -int li; /* lines of text displayable on video screen */ -int nbarriers = DFL_BARRIERS; -/* no. of barriers allowed to critical comp */ -int noverlaps = 0; /* no. of overlaps encountered in this view */ -int nprocessors; /* no. of processors running concurrently */ -int nriplevels = DFL_RIPLEVELS; -/* no. of levels of ripping (0 = no ripping) */ -int nspallrays = DFL_NRAYS; -/* no. of spall rays at each burst point */ -int units = DFL_UNITS; /* target units (default is millimeters) */ -int zoom = 1; /* magnification factor on frame buffer */ - -struct rt_i *rtip = RTI_NULL; /* model specific access from librt */ - -/* signal handlers */ -void (*norml_sig)(int); /* active during interactive operation */ -void (*abort_sig)(int); /* active during ray tracing only */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/grid.c b/src/burst/grid.c deleted file mode 100644 index 2b7ae5b5198..00000000000 --- a/src/burst/grid.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* G R I D . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/grid.c - * - */ - -#include "common.h" - -#include -#include -#include -#include -#include - -#include "vmath.h" -#include "bn.h" -#include "raytrace.h" -#include "dm.h" -#include "bv/plot3.h" - -#include "./ascii.h" -#include "./extern.h" - -#define DEBUG_GRID 0 -#define DEBUG_SHOT 1 - -/* local communication with multitasking process */ -static int currshot; /* current shot index */ -static int lastshot; /* final shot index */ - -static fastf_t viewdir[3]; /* direction of attack */ -static fastf_t delta; /* angular delta ray of spall cone */ -static fastf_t comphi; /* angle between ring and cone axis */ -static fastf_t phiinc; /* angle between concentric rings */ - -static fastf_t cantdelta[3]; /* delta ray specified by yaw and pitch */ - -static struct application ag; /* global application structure (zeroed out) */ - -/* functions local to this module */ -static int doBursts(); -static int burstPoint(struct application *, fastf_t *, fastf_t *); -static int burstRay(); -static int gridShot(); -static int f_BurstHit(struct application *x, struct partition *, struct seg *); -static int f_BurstMiss(struct application *ap); -static int f_HushOverlap(struct application *ap, struct partition *, struct region *, struct region *, struct partition *); -static int f_Overlap(struct application *, struct partition *, struct region *, struct region *, struct partition *); -static int f_ShotHit(struct application *, struct partition *, struct seg *); -static int f_ShotMiss(struct application *); -static int getRayOrigin(struct application *); -static int readBurst(fastf_t *); -static int readShot(fastf_t *); -static void lgtModel(struct application *, struct partition *, struct hit *, struct xray *, fastf_t surfnorm[3]); -static void view_end(); -static void view_pix(struct application *); - -/* - void colorPartition(struct region *regp, int type) - - If user has asked for a UNIX plot write a color command to - the output stream plotfp which represents the region specified - by regp. -*/ -void -colorPartition(struct region *regp, int type) -{ - Colors *colorp; - if (plotfile[0] == NUL) - return; - assert(plotfp != NULL); - bu_semaphore_acquire(BU_SEM_SYSCALL); - switch (type) { - case C_CRIT : - if ((colorp = findColors(regp->reg_regionid, &colorids)) - == NULL) - pl_color(plotfp, R_CRIT, G_CRIT, B_CRIT); - else - pl_color(plotfp, - (int) colorp->c_rgb[0], - (int) colorp->c_rgb[1], - (int) colorp->c_rgb[2] - ); - break; - case C_MAIN : - if ((colorp = findColors(regp->reg_regionid, &colorids)) - == NULL) { - if (InsideAir(regp)) - pl_color(plotfp, - R_INAIR, G_INAIR, B_INAIR); - else - if (Air(regp)) - pl_color(plotfp, - R_OUTAIR, G_OUTAIR, B_OUTAIR); - else - pl_color(plotfp, R_COMP, G_COMP, B_COMP); - } else - pl_color(plotfp, - (int) colorp->c_rgb[0], - (int) colorp->c_rgb[1], - (int) colorp->c_rgb[2] - ); - break; - default : - brst_log("colorPartition: bad type %d.\n", type); - break; - } - bu_semaphore_release(BU_SEM_SYSCALL); - return; -} - - -/* - int doBursts(void) - - This routine gets called when explicit burst points are being - input. Crank through all burst points. Return code of 0 - would indicate a failure in the application routine given to - rt_shootray() or an error or EOF in getting the next set of - burst point coordinates. -*/ -static int -doBursts() -{ - int status = 1; - noverlaps = 0; - VMOVE(ag.a_ray.r_dir, viewdir); - - for (; ! userinterrupt; view_pix(&ag)) { - if (TSTBIT(firemode, FM_FILE) - && (!(status = readBurst(burstpoint)) || status == EOF) - ) - break; - ag.a_level = 0; /* initialize recursion level */ - plotGrid(burstpoint); - - prntBurstHdr(burstpoint, viewdir); - if (! burstPoint(&ag, zaxis, burstpoint)) { - /* fatal error in application routine */ - brst_log("Fatal error: raytracing aborted.\n"); - return 0; - } - if (! TSTBIT(firemode, FM_FILE)) { - view_pix(&ag); - break; - } - } - return status == EOF ? 1 : status; -} - - -/* - void enforceLOS(struct application *ap, - struct partition *pt_headp) - - Enforce the line-of-sight tolerance by deleting partitions that are - too thin. -*/ -static void -enforceLOS(struct application *ap, struct partition *pt_headp) -{ - struct partition *pp; - for (pp = pt_headp->pt_forw; pp != pt_headp;) { - struct partition *nextpp = pp->pt_forw; - if (pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist - <= LOS_TOL) { - DEQUEUE_PT(pp); - FREE_PT(pp, ap->a_resource); - } - pp = nextpp; - } - return; -} - - -/* - int f_BurstHit(struct application *ap, struct partition *pt_headp) - - This routine handles all output associated with burst ray intersections. - - RETURN CODES: -1 indicates a fatal error, and fatalerror will be - set to 1. A positive number is interpreted as the count of critical - component intersections. A value of 0 would indicate that zero - critical components were encountered. -*/ -static int -f_BurstHit(struct application *ap, struct partition *pt_headp, struct seg *UNUSED(segp)) -{ - Pt_Queue *qshield = PT_Q_NULL; - struct partition *cpp, *spp; - int nbar; - int ncrit = 0; -#ifdef VDEBUG - prntDbgPartitions(ap, pt_headp, "f_BurstHit: initial partitions"); -#endif - /* Find first barrier in front of the burst point. */ - for (spp = pt_headp->pt_forw; - spp != pt_headp - && spp->pt_outhit->hit_dist < 0.1; - spp = spp->pt_forw - ) - ; - for (cpp = spp, nbar = 0; - cpp != pt_headp && nbar <= nbarriers; - cpp = cpp->pt_forw - ) { - struct region *regp = cpp->pt_regionp; - struct xray *rayp = &ap->a_ray; - if (Air(regp)) - continue; /* Air doesn't matter here. */ - if (findIdents(regp->reg_regionid, &critids)) { - fastf_t entrynorm[3], exitnorm[3]; - if (ncrit == 0) - prntRayHeader(ap->a_ray.r_dir, viewdir, - ap->a_user); - /* Output queued non-critical components. */ - prntShieldComp(ap, pt_headp, qshield); - qFree(qshield); - qshield = PT_Q_NULL; /* queue empty */ - - /* Output critical component intersection; - prntRegionHdr fills in hit entry/exit normals. */ - prntRegionHdr(ap, pt_headp, cpp, entrynorm, exitnorm); - colorPartition(regp, C_CRIT); - plotPartition(cpp->pt_inhit, cpp->pt_outhit); - - if (fbfile[0] != NUL && ncrit == 0) - /* first hit on critical component */ - lgtModel(ap, cpp, cpp->pt_inhit, rayp, - entrynorm); - ncrit++; - } else - /* Queue up shielding components until we hit a critical one. */ - if (cpp->pt_forw != pt_headp) { - if (! qAdd(cpp, &qshield)) { - fatalerror = 1; - return -1; - } - nbar++; - } - } - qFree(qshield); - if (ncrit == 0) - return ap->a_miss(ap); - else - return ncrit; -} - - -/* - int f_HushOverlap(struct application *ap, struct partition *pp, - struct region *reg1, struct region *reg2, - struct partition *pheadp) - - Do not report diagnostics about individual overlaps, but keep count - of significant ones (at least as thick as OVERLAP_TOL). - - Returns - - 0 to eliminate partition with overlap entirely - 1 to retain partition in output list, claimed by reg1 - 2 to retain partition in output list, claimed by reg2 -*/ -/*ARGSUSED*/ -static int -f_HushOverlap(struct application *ap, struct partition *pp, struct region *reg1, struct region *reg2, struct partition *pheadp) -{ - fastf_t depth; - depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist; - if (depth >= OVERLAP_TOL) - noverlaps++; - - return rt_defoverlap(ap, pp, reg1, reg2, pheadp); -} - - -/* - int f_Overlap(struct application *ap, struct partition *pp, - struct region *reg1, struct region *reg2, - struct partition *pheadp) - - Do report diagnostics and keep count of individual overlaps - that are at least as thick as OVERLAP_TOL. - - Returns - - 0 to eliminate partition with overlap entirely - 1 to retain partition in output list, claimed by reg1 - 2 to retain partition in output list, claimed by reg2 -*/ -/*ARGSUSED*/ -static int -f_Overlap(struct application *ap, struct partition *pp, struct region *reg1, struct region *reg2, struct partition *pheadp) -{ - fastf_t depth; - point_t pt; - depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist; - if (depth >= OVERLAP_TOL) { - noverlaps++; - - VJOIN1(pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, - ap->a_ray.r_dir); - brst_log("OVERLAP:\n"); - brst_log("reg=%s isol=%s, \n", - reg1->reg_name, pp->pt_inseg->seg_stp->st_name - ); - brst_log("reg=%s osol=%s, \n", - reg2->reg_name, pp->pt_outseg->seg_stp->st_name - ); - brst_log("depth %.2fmm at (%g, %g, %g) x%d y%d lvl%d purpose=%s\n", - depth, - pt[X], pt[Y], pt[Z], - ap->a_x, ap->a_y, ap->a_level, ap->a_purpose - ); - } - - return rt_defoverlap(ap, pp, reg1, reg2, pheadp); -} - - -/* - int f_ShotHit(struct application *ap, struct partition *pt_headp) - - This routine is called when a shotline hits the model. All output - associated with the main penetrator path is printed here. If line- - of-sight bursting is requested, burst point gridding is spawned by - a call to burstPoint() which dispatches the burst ray task burstRay(), - a recursive call to the ray tracer. - - RETURN CODES: 0 would indicate a failure in an application routine - handed to rt_shootray() by burstRay(). Otherwise, 1 is returned. -*/ -static int -f_ShotHit(struct application *ap, struct partition *pt_headp, struct seg *UNUSED(segp)) -{ - struct partition *pp; - struct partition *bp = PT_NULL; - vect_t burstnorm = VINIT_ZERO; /* normal at burst point */ -#if DEBUG_GRID - brst_log("f_ShotHit\n"); - for (pp = pt_headp->pt_forw; pp != pt_headp; pp = pp->pt_forw) - brst_log("\tregion is '%s', \tid=%d\taircode=%d\n", - pp->pt_regionp->reg_name, - (int) pp->pt_regionp->reg_regionid, - (int) pp->pt_regionp->reg_aircode); -#endif - /* Output cell identification. */ - prntCellIdent(ap); - /* Color cell if making frame buffer image. */ - if (fbfile[0] != NUL) - paintCellFb(ap, pixtarg, zoom == 1 ? pixblack : pixbkgr); - - /* First delete thin partitions. */ - enforceLOS(ap, pt_headp); - - /* Output ray intersections. This code is extremely cryptic because - it is dealing with errors in the geometry, where there is - either adjacent airs of differing types, or voids (gaps) - in the description. In the case of adjacent airs, phantom - armor must be output. For voids, outside air is the default - (everyone knows that air rushes to fill a vacuum), so we - must pretend that it is there. Outside air is also called - 01 air because its aircode equals 1. Please tread carefully - on the code within this loop, it is filled with special - cases involving adjacency of partitions both real (explicit) - and imagined (implicit). - */ - for (pp = pt_headp->pt_forw; pp != pt_headp; pp = pp->pt_forw) { - int voidflag = 0; - struct partition *np = pp->pt_forw; - struct partition *cp; - struct region *regp = pp->pt_regionp; - struct region *nregp = pp->pt_forw->pt_regionp; - - /* Fill in entry and exit points into hit structures. */ - { - struct hit *ihitp = pp->pt_inhit; - struct hit *ohitp = pp->pt_outhit; - struct xray *rayp = &ap->a_ray; - VJOIN1(ihitp->hit_point, rayp->r_pt, ihitp->hit_dist, - rayp->r_dir); - VJOIN1(ohitp->hit_point, rayp->r_pt, ohitp->hit_dist, - rayp->r_dir); - colorPartition(regp, C_MAIN); - plotPartition(ihitp, ohitp); - } - - /* Check for voids. */ - if (np != pt_headp) { - fastf_t los = 0.0; - -#if DEBUG_GRID - brst_log("\tprocessing region '%s', \tid=%d\taircode=%d\n", - pp->pt_regionp->reg_name, - (int) pp->pt_regionp->reg_regionid, - (int) pp->pt_regionp->reg_aircode); - brst_log("\tcheck for voids\n"); -#endif - los = np->pt_inhit->hit_dist - - pp->pt_outhit->hit_dist; -#if DEBUG_GRID - brst_log("\tlos=%g tolerance=%g\n", - los, LOS_TOL); -#endif - voidflag = (los > LOS_TOL); - /* If the void occurs adjacent to explicit outside - air, extend the outside air to fill it. */ - if (OutsideAir(np->pt_regionp)) { -#if DEBUG_GRID - brst_log("\t\toutside air\n"); -#endif - if (voidflag) { - np->pt_inhit->hit_dist = - pp->pt_outhit->hit_dist; - voidflag = 0; - } - /* Keep going until we are past 01 air. */ - for (cp = np->pt_forw; - cp != pt_headp; - cp = cp->pt_forw) { - if (OutsideAir(cp->pt_regionp)) - /* Include outside air. */ - np->pt_outhit->hit_dist = - cp->pt_outhit->hit_dist; - else - if (cp->pt_inhit->hit_dist - - np->pt_outhit->hit_dist - > LOS_TOL) - /* Include void following - outside air. */ - np->pt_outhit->hit_dist = - cp->pt_inhit->hit_dist; - else - break; - } - } - } - /* Merge adjacent inside airs of same type. */ - if (np != pt_headp && InsideAir(np->pt_regionp)) { -#if DEBUG_GRID - brst_log("\tmerging inside airs\n"); -#endif - for (cp = np->pt_forw; - cp != pt_headp; - cp = cp->pt_forw) { - if (InsideAir(cp->pt_regionp) - && SameAir(np->pt_regionp, cp->pt_regionp) - && cp->pt_inhit->hit_dist - - np->pt_outhit->hit_dist - <= LOS_TOL) - np->pt_outhit->hit_dist = - cp->pt_outhit->hit_dist; - else - break; - } - } - - /* Check for possible phantom armor before internal air, - that is if it is the first thing hit. */ - if (pp->pt_back == pt_headp && InsideAir(regp)) { - /* If adjacent partitions are the same air, extend - the first on to include them. */ -#if DEBUG_GRID - brst_log("\tphantom armor before internal air\n"); -#endif - for (cp = np; cp != pt_headp; cp = cp->pt_forw) { - if (InsideAir(cp->pt_regionp) - && SameAir(regp, cp->pt_regionp) - && cp->pt_inhit->hit_dist - - pp->pt_outhit->hit_dist - <= LOS_TOL) - pp->pt_outhit->hit_dist = - cp->pt_outhit->hit_dist; - else - break; - - } - - prntPhantom(pp->pt_inhit, (int) regp->reg_aircode); - } else - if (! Air(regp)) { - /* If we have a component, output it. */ - fastf_t entrynorm[3]; /* normal at entry */ - fastf_t exitnorm[3]; /* normal at exit */ - /* Get entry normal. */ - getRtHitNorm(pp->pt_inhit, pp->pt_inseg->seg_stp, - &ap->a_ray, (int) pp->pt_inflip, entrynorm); - (void) chkEntryNorm(pp, &ap->a_ray, entrynorm, - "shotline entry normal"); - /* Get exit normal. */ - getRtHitNorm(pp->pt_outhit, pp->pt_outseg->seg_stp, - &ap->a_ray, (int) pp->pt_outflip, exitnorm); - (void) chkExitNorm(pp, &ap->a_ray, exitnorm, - "shotline exit normal"); - -#if DEBUG_GRID - brst_log("\twe have a component\n"); -#endif - /* In the case of fragmenting munitions, a hit on any - component will cause a burst point. */ - if (bp == PT_NULL && bdist > 0.0) { - bp = pp; /* exterior burst */ - VMOVE(burstnorm, exitnorm); - } - - /* If there is a void, output 01 air as space. */ - if (voidflag) { -#if DEBUG_GRID - brst_log("\t\tthere is a void, %s\n", - "so outputting 01 air"); -#endif - if (bp == PT_NULL && ! reqburstair - && findIdents(regp->reg_regionid, - &armorids)) { - /* Bursting on armor/void (ouch). */ - bp = pp; - VMOVE(burstnorm, exitnorm); - } - prntSeg(ap, pp, OUTSIDE_AIR, - entrynorm, exitnorm, pp == bp); - } else - /* If air explicitly follows, output space code. */ - if (np != pt_headp && Air(nregp)) { - /* Check for interior burst point. */ -#if DEBUG_GRID - brst_log("\t\texplicit air follows\n"); -#endif - if (bp == PT_NULL && bdist <= 0.0 - && findIdents(regp->reg_regionid, - &armorids) - && (! reqburstair - || findIdents(nregp->reg_aircode, - &airids)) - ) { - bp = pp; /* interior burst */ - VMOVE(burstnorm, exitnorm); - } - prntSeg(ap, pp, nregp->reg_aircode, - entrynorm, exitnorm, pp == bp); - } else - if (np == pt_headp) { - /* Last component gets 09 air. */ -#if DEBUG_GRID - brst_log("\t\tlast component\n"); -#endif - prntSeg(ap, pp, EXIT_AIR, - entrynorm, exitnorm, pp == bp); - } else - /* No air follows component. */ - if (SameCmp(regp, nregp)) { -#if DEBUG_GRID - brst_log("\t\tmerging adjacent components\n"); -#endif - /* Merge adjacent components with same - idents. */ - *np->pt_inhit = *pp->pt_inhit; - np->pt_inseg = pp->pt_inseg; - np->pt_inflip = pp->pt_inflip; - continue; - } else { -#if DEBUG_GRID - brst_log("\t\tdifferent component follows\n"); -#endif - prntSeg(ap, pp, 0, - entrynorm, exitnorm, pp == bp); - /* component follows */ - } - } - /* Check for adjacency of differing airs, implicit or - explicit and output phantom armor as needed. */ - if (InsideAir(regp)) { -#if DEBUG_GRID - brst_log("\tcheck for adjacency of differing airs; inside air\n"); -#endif - /* Inside air followed by implicit outside air. */ - if (voidflag) - prntPhantom(pp->pt_outhit, OUTSIDE_AIR); - } - /* Check next partition for adjacency problems. */ - if (np != pt_headp) { -#if DEBUG_GRID - brst_log("\tcheck next partition for adjacency\n"); -#endif - /* See if inside air follows impl. outside air. */ - if (voidflag && InsideAir(nregp)) { -#if DEBUG_GRID - brst_log("\t\tinside air follows impl. outside air\n"); -#endif - prntPhantom(np->pt_inhit, nregp->reg_aircode); - } else - /* See if differing airs are adjacent. */ - if (! voidflag - && Air(regp) - && Air(nregp) - && DiffAir(nregp, regp) - ) { -#if DEBUG_GRID - brst_log("\t\tdiffering airs are adjacent\n"); -#endif - prntPhantom(np->pt_inhit, (int) nregp->reg_aircode); - } - } - /* Output phantom armor if internal air is last hit. */ - if (np == pt_headp && InsideAir(regp)) { -#if DEBUG_GRID - brst_log("\tinternal air last hit\n"); -#endif - prntPhantom(pp->pt_outhit, EXIT_AIR); - } - } - if (nriplevels == 0) - return 1; - - if (bp != PT_NULL) { - fastf_t burstpt[3]; - /* This is a burst point, calculate coordinates. */ - if (bdist > 0.0) { - /* Exterior burst point (i.e. case-fragmenting - munition with contact-fuzed set-back device): - location is bdist prior to entry point. */ - VJOIN1(burstpt, bp->pt_inhit->hit_point, -bdist, - ap->a_ray.r_dir); - } else - if (bdist < 0.0) { - /* Interior burst point (i.e. case-fragment - munition with delayed fuzing): location is - the magnitude of bdist beyond the exit - point. */ - VJOIN1(burstpt, bp->pt_outhit->hit_point, -bdist, - ap->a_ray.r_dir); - } else /* Interior burst point: no fuzing offset. */ - VMOVE(burstpt, bp->pt_outhit->hit_point); - - /* Only generate burst rays if nspallrays is greater than - zero. */ - if (nspallrays < 1) - return 1; - - return burstPoint(ap, burstnorm, burstpt); - } - return 1; -} - - -/* - void getRtHitNorm(struct hit *hitp, struct soltab *stp, - struct xray *rayp, int flipped, fastf_t normvec[3]) - - Fill normal and hit point into hit struct and if the flipped - flag is set, reverse the normal. Return a private copy of the - flipped normal in normvec. NOTE: the normal placed in the hit - struct should not be modified (i.e. reversed) by the application - because it can be instanced by other solids. -*/ -void -getRtHitNorm(struct hit *hitp, struct soltab *stp, struct xray *UNUSED(rayp), int flipped, fastf_t normvec[3]) -{ - RT_HIT_NORMAL(normvec, hitp, stp, rayp, flipped); -} - - -int -chkEntryNorm(struct partition *pp, struct xray *rayp, fastf_t normvec[3], char *purpose) -{ - fastf_t f; - static int flipct = 0; - static int totalct = 0; - struct soltab *stp = pp->pt_inseg->seg_stp; - int ret = 1; - totalct++; - /* Dot product of ray direction with normal *should* be negative. */ - f = VDOT(rayp->r_dir, normvec); - if (ZERO(f)) { -#ifdef DEBUG - brst_log("chkEntryNorm: near 90 degree obliquity.\n"); - brst_log("\tPnt %g, %g, %g\n\tDir %g, %g, %g\n\tNorm %g, %g, %g.\n", - rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z], - rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z], - normvec[X], normvec[Y], normvec[Z]); -#endif - ret = 0; - } - if (f > 0.0) { - flipct++; - brst_log("Fixed flipped entry normal:\n"); - brst_log("\tregion \"%s\" solid \"%s\" type %d \"%s\".\n", - pp->pt_regionp->reg_name, stp->st_name, - stp->st_id, purpose); -#ifdef DEBUG - brst_log("\tPnt %g, %g, %g\n\tDir %g, %g, %g\n\tNorm %g, %g, %g.\n", - rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z], - rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z], - normvec[X], normvec[Y], normvec[Z]); - brst_log("\tDist %g Hit Pnt %g, %g, %g\n", - pp->pt_inhit->hit_dist, - pp->pt_inhit->hit_point[X], - pp->pt_inhit->hit_point[Y], - pp->pt_inhit->hit_point[Z]); - brst_log("\t%d of %d normals flipped.\n", flipct, totalct); -#endif - VSCALE(normvec, normvec, -1.0); - ret = 0; - } - return ret; -} - - -int -chkExitNorm(struct partition *pp, struct xray *rayp, fastf_t normvec[3], char *purpose) -{ - fastf_t f; - static int flipct = 0; - static int totalct = 0; - struct soltab *stp = pp->pt_outseg->seg_stp; - int ret = 1; - totalct++; - /* Dot product of ray direction with normal *should* be positive. */ - f = VDOT(rayp->r_dir, normvec); - if (ZERO(f)) { -#ifdef DEBUG - brst_log("chkExitNorm: near 90 degree obliquity.\n"); - brst_log("\tPnt %g, %g, %g\n\tDir %g, %g, %g\n\tNorm %g, %g, %g.\n", - rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z], - rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z], - normvec[X], normvec[Y], normvec[Z]); -#endif - ret = 0; - } - if (f < 0.0) { - flipct++; - brst_log("Fixed flipped exit normal:\n"); - brst_log("\tregion \"%s\" solid \"%s\" type %d \"%s\".\n", - pp->pt_regionp->reg_name, stp->st_name, - stp->st_id, purpose); -#ifdef DEBUG - brst_log("\tPnt %g, %g, %g\n\tDir %g, %g, %g\n\tNorm %g, %g, %g.\n", - rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z], - rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z], - normvec[X], normvec[Y], normvec[Z]); - brst_log("\tDist %g Hit Pnt %g, %g, %g\n", - pp->pt_outhit->hit_dist, - pp->pt_outhit->hit_point[X], - pp->pt_outhit->hit_point[Y], - pp->pt_outhit->hit_point[Z]); - brst_log("\t%d of %d normals flipped.\n", flipct, totalct); -#endif - VSCALE(normvec, normvec, -1.0); - ret = 0; - } - return ret; -} - - -/* - int f_ShotMiss(struct application *ap) - - Shot missed the model; if ground bursting is enabled, intersect with - ground plane, else just arrange for appropriate background color for - debugging. -*/ -static int -f_ShotMiss(struct application *ap) -{ - if (groundburst) { - fastf_t dist; - fastf_t hitpoint[3]; - /* first find intersection of shot with ground plane */ - if (ap->a_ray.r_dir[Z] >= 0.0) - /* Shot direction is upward, can't hit the ground - from underneath. */ - goto missed_ground; - if (ap->a_ray.r_pt[Z] <= -grndht) - /* Must be above ground to hit it from above. */ - goto missed_ground; - /* ground plane is grndht distance below the target origin */ - hitpoint[Z] = -grndht; - /* distance along ray from ray origin to ground plane */ - dist = (hitpoint[Z] - ap->a_ray.r_pt[Z]) / ap->a_ray.r_dir[Z]; - /* solve for X and Y intersection coordinates */ - hitpoint[X] = ap->a_ray.r_pt[X] + ap->a_ray.r_dir[X]*dist; - hitpoint[Y] = ap->a_ray.r_pt[Y] + ap->a_ray.r_dir[Y]*dist; - /* check for limits of ground plane */ - if (hitpoint[X] <= grndfr && hitpoint[X] >= -grndbk - && hitpoint[Y] <= grndlf && hitpoint[Y] >= -grndrt - ) { - /* We have a hit. */ - if (fbfile[0] != NUL) - paintCellFb(ap, pixghit, - zoom == 1 ? pixblack : pixbkgr); - if (bdist > 0.0) { - /* simulate standoff fuzing */ - VJOIN1(hitpoint, hitpoint, -bdist, - ap->a_ray.r_dir); - } else - if (bdist < 0.0) { - /* interior burst not implemented in ground */ - brst_log("User error: %s %s.\n", - "negative burst distance can not be", - "specified with ground plane bursting" - ); - fatalerror = 1; - return -1; - } - /* else bdist == 0.0, no adjustment necessary */ - /* only burst if nspallrays greater than zero */ - if (nspallrays > 0) { - prntBurstHdr(hitpoint, viewdir); - return burstPoint(ap, zaxis, hitpoint); - } else - return 1; - } - } -missed_ground : - if (fbfile[0] != NUL) - paintCellFb(ap, pixmiss, zoom == 1 ? pixblack : pixbkgr); - VSETALL(ap->a_color, 0.0); /* All misses black. */ - return 0; -} - - -/* - int f_BurstMiss(struct application *ap) - - Burst ray missed the model, so do nothing. -*/ -static int -f_BurstMiss(struct application *ap) -{ - VSETALL(ap->a_color, 0.0); /* All misses black. */ - return 0; -} - - -/* - int getRayOrigin(struct application *ap) - - This routine fills in the ray origin ap->a_ray.r_pt by folding - together firing mode and dithering options. By-products of this - routine include the grid offsets which are stored in ap->a_uvec, - 2-digit random numbers (when opted) which are stored in ap->a_user, - and grid indices are stored in ap->a_x and ap->a_y. Return - codes are: 0 for failure to read new firing coordinates, or - 1 for success. -*/ -static int -getRayOrigin(struct application *ap) -{ - fastf_t *vec = ap->a_uvec; - fastf_t gridyinc[3], gridxinc[3]; - fastf_t scalecx, scalecy; - if (TSTBIT(firemode, FM_SHOT)) { - if (TSTBIT(firemode, FM_FILE)) { - switch (readShot(vec)) { - case EOF : return EOF; - case 1 : break; - case 0 : return 0; - } - } else /* Single shot specified. */ - VMOVE(vec, fire); - if (TSTBIT(firemode, FM_3DIM)) { - fastf_t hitpoint[3]; - /* Project 3-d hit-point back into grid space. */ - VMOVE(hitpoint, vec); - vec[X] = VDOT(gridhor, hitpoint); - vec[Y] = VDOT(gridver, hitpoint); - } - ap->a_x = vec[X] / cellsz; - ap->a_y = vec[Y] / cellsz; - scalecx = vec[X]; - scalecy = vec[Y]; - } else { - fastf_t xoffset = 0.0; - fastf_t yoffset = 0.0; - ap->a_x = currshot % gridwidth + gridxorg; - ap->a_y = currshot / gridwidth + gridyorg; - if (dithercells) { - /* 2-digit random number, 1's place gives X - offset, 10's place gives Y offset. - */ - ap->a_user = lrint(bn_randmt() * 100.0) % 100; - xoffset = (ap->a_user%10)*0.1 - 0.5; - yoffset = (ap->a_user/10)*0.1 - 0.5; - } - /* Compute magnitude of grid offsets. */ - scalecx = (fastf_t) ap->a_x + xoffset; - scalecy = (fastf_t) ap->a_y + yoffset; - vec[X] = scalecx *= cellsz; - vec[Y] = scalecy *= cellsz; - } - /* Compute cell horizontal and vertical vectors relative to - grid origin. */ - VSCALE(gridxinc, gridhor, scalecx); - VSCALE(gridyinc, gridver, scalecy); - VADD2(ap->a_ray.r_pt, gridsoff, gridyinc); - VADD2(ap->a_ray.r_pt, ap->a_ray.r_pt, gridxinc); - return 1; -} - - -/* - Construct a direction vector out of azimuth and elevation angles - in radians, allocating storage for it and returning its address. -*/ -static void -consVector(fastf_t *vec, fastf_t azim, fastf_t elev) -{ - /* Store cosine of the elevation to save calculating twice. */ - fastf_t cosE; - cosE = cos(elev); - vec[0] = cos(azim) * cosE; - vec[1] = sin(azim) * cosE; - vec[2] = sin(elev); - return; -} - - -/* - void gridInit(void) - - Grid initialization routine; must be done once per view. -*/ -void -gridInit() -{ - notify("Initializing grid", NOTIFY_APPEND); - rt_prep_timer(); - -#if DEBUG_SHOT - if (TSTBIT(firemode, FM_BURST)) - brst_log("gridInit: reading burst points.\n"); - else { - if (TSTBIT(firemode, FM_SHOT)) - brst_log("gridInit: shooting discrete shots.\n"); - else - brst_log("gridInit: shooting %s.\n", - TSTBIT(firemode, FM_PART) ? - "partial envelope" : "full envelope"); - } - if (TSTBIT(firemode, FM_BURST) || TSTBIT(firemode, FM_SHOT)) { - brst_log("gridInit: reading %s coordinates from %s.\n", - TSTBIT(firemode, FM_3DIM) ? "3-d" : "2-d", - TSTBIT(firemode, FM_FILE) ? "file" : "command stream"); - - } else - if (TSTBIT(firemode, FM_FILE) || TSTBIT(firemode, FM_3DIM)) - brst_log("BUG: insane combination of fire mode bits:0x%x\n", - firemode); - if (TSTBIT(firemode, FM_BURST) || shotburst) - nriplevels = 1; - else - nriplevels = 0; - if (!shotburst && groundburst) { - (void) snprintf(scrbuf, LNBUFSZ, - "Ground bursting directive ignored: %s.\n", - "only relevant if bursting along shotline"); - warning(scrbuf); - brst_log(scrbuf); - } -#endif - /* compute grid unit vectors */ - gridRotate(viewazim, viewelev, 0.0, gridhor, gridver); - - if (!NEAR_ZERO(yaw, VDIVIDE_TOL) || !NEAR_ZERO(pitch, VDIVIDE_TOL)) { - fastf_t negsinyaw = -sin(yaw); - fastf_t sinpitch = sin(pitch); - fastf_t xdeltavec[3], ydeltavec[3]; -#if DEBUG_SHOT - brst_log("gridInit: canting warhead\n"); -#endif - cantwarhead = 1; - VSCALE(xdeltavec, gridhor, negsinyaw); - VSCALE(ydeltavec, gridver, sinpitch); - VADD2(cantdelta, xdeltavec, ydeltavec); - } - - /* unit vector from origin of model toward eye */ - consVector(viewdir, viewazim, viewelev); - - /* reposition file pointers if necessary */ - if (TSTBIT(firemode, FM_SHOT) && TSTBIT(firemode, FM_FILE)) - rewind(shotfp); - else - if (TSTBIT(firemode, FM_BURST) && TSTBIT(firemode, FM_FILE)) - rewind(burstfp); - - /* Compute distances from grid origin (model origin) to each - border of grid, and grid indices at borders of grid. - */ - if (! TSTBIT(firemode, FM_PART)) { - fastf_t modelmin[3]; - fastf_t modelmax[3]; - if (groundburst) { - /* extend grid to include ground platform */ - modelmax[X] = FMAX(rtip->mdl_max[X], grndfr); - modelmin[X] = FMIN(rtip->mdl_min[X], -grndbk); - modelmax[Y] = FMAX(rtip->mdl_max[Y], grndlf); - modelmin[Y] = FMIN(rtip->mdl_min[Y], -grndrt); - modelmax[Z] = rtip->mdl_max[Z]; - modelmin[Z] = FMIN(rtip->mdl_min[Z], -grndht); - } else { - /* size grid by model RPP */ - VMOVE(modelmin, rtip->mdl_min); - VMOVE(modelmax, rtip->mdl_max); - } - /* Calculate extent of grid. */ - gridrt = FMAX(gridhor[X] * modelmax[X], - gridhor[X] * modelmin[X] - ) + - FMAX(gridhor[Y] * modelmax[Y], - gridhor[Y] * modelmin[Y] - ) + - FMAX(gridhor[Z] * modelmax[Z], - gridhor[Z] * modelmin[Z] - ); - gridlf = FMIN(gridhor[X] * modelmax[X], - gridhor[X] * modelmin[X] - ) + - FMIN(gridhor[Y] * modelmax[Y], - gridhor[Y] * modelmin[Y] - ) + - FMIN(gridhor[Z] * modelmax[Z], - gridhor[Z] * modelmin[Z] - ); - gridup = FMAX(gridver[X] * modelmax[X], - gridver[X] * modelmin[X] - ) + - FMAX(gridver[Y] * modelmax[Y], - gridver[Y] * modelmin[Y] - ) + - FMAX(gridver[Z] * modelmax[Z], - gridver[Z] * modelmin[Z] - ); - griddn = FMIN(gridver[X] * modelmax[X], - gridver[X] * modelmin[X] - ) + - FMIN(gridver[Y] * modelmax[Y], - gridver[Y] * modelmin[Y] - ) + - FMIN(gridver[Z] * modelmax[Z], - gridver[Z] * modelmin[Z] - ); - /* Calculate extent of model in plane of grid. */ - if (groundburst) { - modlrt = FMAX(gridhor[X] * rtip->mdl_max[X], - gridhor[X] * rtip->mdl_min[X] - ) + - FMAX(gridhor[Y] * rtip->mdl_max[Y], - gridhor[Y] * rtip->mdl_min[Y] - ) + - FMAX(gridhor[Z] * rtip->mdl_max[Z], - gridhor[Z] * rtip->mdl_min[Z] - ); - modllf = FMIN(gridhor[X] * rtip->mdl_max[X], - gridhor[X] * rtip->mdl_min[X] - ) + - FMIN(gridhor[Y] * rtip->mdl_max[Y], - gridhor[Y] * rtip->mdl_min[Y] - ) + - FMIN(gridhor[Z] * rtip->mdl_max[Z], - gridhor[Z] * rtip->mdl_min[Z] - ); - modlup = FMAX(gridver[X] * rtip->mdl_max[X], - gridver[X] * rtip->mdl_min[X] - ) + - FMAX(gridver[Y] * rtip->mdl_max[Y], - gridver[Y] * rtip->mdl_min[Y] - ) + - FMAX(gridver[Z] * rtip->mdl_max[Z], - gridver[Z] * rtip->mdl_min[Z] - ); - modldn = FMIN(gridver[X] * rtip->mdl_max[X], - gridver[X] * rtip->mdl_min[X] - ) + - FMIN(gridver[Y] * rtip->mdl_max[Y], - gridver[Y] * rtip->mdl_min[Y] - ) + - FMIN(gridver[Z] * rtip->mdl_max[Z], - gridver[Z] * rtip->mdl_min[Z] - ); - } else { - modlrt = gridrt; - modllf = gridlf; - modlup = gridup; - modldn = griddn; - } - } - gridxorg = gridlf / cellsz; - gridxfin = gridrt / cellsz; - gridyorg = griddn / cellsz; - gridyfin = gridup / cellsz; - - /* allow for randomization of cells */ - if (dithercells) { - gridxorg--; - gridxfin++; - gridyorg--; - gridyfin++; - } -#if DEBUG_SHOT - brst_log("gridInit: xorg, xfin, yorg, yfin=%d, %d, %d, %d\n", - gridxorg, gridxfin, gridyorg, gridyfin); - brst_log("gridInit: left, right, down, up=%g, %g, %g, %g\n", - gridlf, gridrt, griddn, gridup); -#endif - - /* compute stand-off distance */ - standoff = FMAX(viewdir[X] * rtip->mdl_max[X], - viewdir[X] * rtip->mdl_min[X] - ) + - FMAX(viewdir[Y] * rtip->mdl_max[Y], - viewdir[Y] * rtip->mdl_min[Y] - ) + - FMAX(viewdir[Z] * rtip->mdl_max[Z], - viewdir[Z] * rtip->mdl_min[Z] - ); - - /* determine largest grid dimension for frame buffer display */ - gridwidth = gridxfin - gridxorg + 1; - gridheight = gridyfin - gridyorg + 1; - gridsz = FMAX(gridwidth, gridheight); - - /* vector to grid origin from model origin */ - VSCALE(gridsoff, viewdir, standoff); - - /* direction of grid rays */ - VSCALE(viewdir, viewdir, -1.0); - - prntTimer("grid"); - notify(NULL, NOTIFY_DELETE); - return; -} - - -/* - void gridModel(void) - - This routine dispatches the top-level ray tracing task. -*/ -void -gridModel() -{ - ag.a_onehit = 0; - ag.a_overlap = reportoverlaps ? f_Overlap : f_HushOverlap; - ag.a_logoverlap = rt_silent_logoverlap; - ag.a_rt_i = rtip; - if (! TSTBIT(firemode, FM_BURST)) { - /* set up for shotlines */ - ag.a_hit = f_ShotHit; - ag.a_miss = f_ShotMiss; - } - - plotInit(); /* initialize plot file if appropriate */ - - if (! imageInit()) { - /* initialize frame buffer if appropriate */ - warning("Error: problem opening frame buffer."); - return; - } - /* output initial line for this aspect */ - prntAspectInit(); - - fatalerror = 0; - userinterrupt = 0; /* set by interrupt handler */ - - rt_prep_timer(); - notify("Raytracing", NOTIFY_ERASE); - - if (TSTBIT(firemode, FM_BURST)) { - if (! doBursts()) - return; - else - goto endvu; - } - - /* get starting and ending shot number */ - currshot = 0; - lastshot = gridwidth * gridheight - 1; - - /* SERIAL case -- one CPU does all the work */ - if (! gridShot()) - return; -endvu: view_end(); - return; -} - - -/* - int gridShot(void) - - This routine is the grid-level raytracing task; suitable for a - multi-tasking process. Return code of 0 would indicate a - failure in the application routine given to rt_shootray() or an - error or EOF in getting the next set of firing coordinates. -*/ -static int -gridShot() -{ - int status = 1; - struct application a; - a = ag; - a.a_resource = RESOURCE_NULL; - - assert(a.a_hit == ag.a_hit); - assert(a.a_miss == ag.a_miss); - assert(a.a_overlap == ag.a_overlap); - assert(a.a_rt_i == ag.a_rt_i); - assert(a.a_onehit == ag.a_onehit); - a.a_user = 0; - a.a_purpose = "shotline"; - prntGridOffsets(gridxorg, gridyorg); - noverlaps = 0; - for (; ! userinterrupt; view_pix(&a)) { - if (! TSTBIT(firemode, FM_SHOT) && currshot > lastshot) - break; - if (! (status = getRayOrigin(&a)) || status == EOF) - break; - currshot++; - prntFiringCoords(a.a_uvec); - VMOVE(a.a_ray.r_dir, viewdir); - a.a_level = 0; /* initialize recursion level */ - plotGrid(a.a_ray.r_pt); - if (rt_shootray(&a) == -1 && fatalerror) { - /* fatal error in application routine */ - brst_log("Fatal error: raytracing aborted.\n"); - return 0; - } - if (! TSTBIT(firemode, FM_FILE) && TSTBIT(firemode, FM_SHOT)) { - view_pix(&a); - break; - } - } - return status == EOF ? 1 : status; -} - - -/* - void lgtModel(struct application *ap, struct partition *pp, - struct hit *hitp, struct xray *rayp, - fastf_t surfnorm[3]) - - This routine is a simple lighting model which places RGB coefficients - (0 to 1) in ap->a_color based on the cosine of the angle between - the surface normal and viewing direction and the color associated with - the component. Also, the distance to the surface is placed in - ap->a_cumlen so that the impact location can be projected into grid - space. -*/ -static void -lgtModel(struct application *ap, struct partition *pp, struct hit *hitp, struct xray *UNUSED(rayp), fastf_t surfnorm[3]) -{ - Colors *colorp; - fastf_t intensity = -VDOT(viewdir, surfnorm); - if (intensity < 0.0) - intensity = -intensity; - - if ((colorp = - findColors(pp->pt_regionp->reg_regionid, &colorids)) - != COLORS_NULL - ) { - ap->a_color[RED] = (fastf_t)colorp->c_rgb[RED]/255.0; - ap->a_color[GRN] = (fastf_t)colorp->c_rgb[GRN]/255.0; - ap->a_color[BLU] = (fastf_t)colorp->c_rgb[BLU]/255.0; - } else - ap->a_color[RED] = - ap->a_color[GRN] = - ap->a_color[BLU] = 1.0; - VSCALE(ap->a_color, ap->a_color, intensity); - ap->a_cumlen = hitp->hit_dist; -} - - -/* - int readBurst(fastf_t *vec) - - This routine reads the next set of burst point coordinates from the - input stream burstfp. Returns 1 for success, 0 for a format - error and EOF for normal end-of-file. If 0 is returned, - fatalerror will be set to 1. -*/ -static int -readBurst(fastf_t *vec) -{ - int items; - double scan[3]; - - assert(burstfp != (FILE *) NULL); - /* read 3D firing coordinates from input stream */ - items = fscanf(burstfp, "%lf %lf %lf", &scan[0], &scan[1], &scan[2]); - VMOVE(vec, scan); /* double to fastf_t */ - if (items != 3) { - if (items != EOF) { - brst_log("Fatal error: %d burst coordinates read.\n", - items); - fatalerror = 1; - return 0; - } else { - return EOF; - } - } else { - vec[X] /= unitconv; - vec[Y] /= unitconv; - vec[Z] /= unitconv; - } - return 1; -} - - -/* - int readShot(fastf_t *vec) - - This routine reads the next set of firing coordinates from the - input stream shotfp, using the format selected by the firemode - bitflag. Returns 1 for success, 0 for a format error and EOF - for normal end-of-file. If 0 is returned, fatalerror will be - set to 1. -*/ -static int -readShot(fastf_t *vec) -{ - double scan[3] = VINIT_ZERO; - - assert(shotfp != (FILE *) NULL); - - if (! TSTBIT(firemode, FM_3DIM)) { - /* absence of 3D flag means 2D */ - int items; - - /* read 2D firing coordinates from input stream */ - items = fscanf(shotfp, "%lf %lf", &scan[0], &scan[1]); - VMOVE(vec, scan); - if (items != 2) { - if (items != EOF) { - brst_log("Fatal error: only %d firing coordinates read.\n", items); - fatalerror = 1; - return 0; - } else { - return EOF; - } - } else { - vec[X] /= unitconv; - vec[Y] /= unitconv; - } - } else - if (TSTBIT(firemode, FM_3DIM)) { - /* 3D coordinates */ - int items; - - /* read 3D firing coordinates from input stream */ - items = fscanf(shotfp, "%lf %lf %lf", &scan[0], &scan[1], &scan[2]); - VMOVE(vec, scan); /* double to fastf_t */ - if (items != 3) { - if (items != EOF) { - brst_log("Fatal error: %d firing coordinates read.\n", items); - fatalerror = 1; - return 0; - } else { - return EOF; - } - } else { - vec[X] /= unitconv; - vec[Y] /= unitconv; - vec[Z] /= unitconv; - } - } else { - brst_log("BUG: readShot called with bad firemode.\n"); - return 0; - } - return 1; -} - - -/* - int roundToInt(fastf_t f) - - RETURN CODES: the nearest integer to f. -*/ -int roundToInt(fastf_t f) -{ - int a; - a = f; - if (f - a >= 0.5) - return a + 1; - else - return a; -} - - -/* - void spallInit(void) - - Burst grid initialization routine; should be called once per view. - Does some one-time computation for current bursting parameters; the - following globals are filled in: - - delta -- the target ray delta angle - phiinc -- the actual angle between concentric rings - raysolidangle -- the average solid angle per spall ray - - Determines actual number of sampling rays yielded by the even- - distribution algorithm from the number requested. -*/ -void -spallInit() -{ - fastf_t theta; /* solid angle of spall sampling cone */ - fastf_t phi; /* angle between ray and cone axis */ - fastf_t philast; /* guard against floating point error */ - int spallct = 0; /* actual no. of sampling rays */ - int n; - if (nspallrays < 1) { - delta = 0.0; - phiinc = 0.0; - raysolidangle = 0.0; - brst_log("%d sampling rays\n", spallct); - return; - } - - /* Compute sampling cone of rays which are equally spaced. */ - theta = M_2PI * (1.0 - cos(conehfangle)); /* solid angle */ - delta = sqrt(theta/nspallrays); /* angular ray delta */ - n = conehfangle / delta; - phiinc = conehfangle / n; - philast = conehfangle + VUNITIZE_TOL; - /* Crank through spall cone generation once to count actual number - generated. - */ - for (phi = 0.0; phi <= philast; phi += phiinc) { - fastf_t sinphi = sin(phi); - fastf_t gammaval, gammainc, gammalast; - int m; - sinphi = fabs(sinphi); - m = (M_2PI * sinphi)/delta + 1; - gammainc = M_2PI / m; - gammalast = M_2PI-gammainc + VUNITIZE_TOL; - for (gammaval = 0.0; gammaval <= gammalast; gammaval += gammainc) - spallct++; - } - raysolidangle = theta / spallct; - brst_log("Solid angle of sampling cone = %g\n", theta); - brst_log("Solid angle per sampling ray = %g\n", raysolidangle); - brst_log("%d sampling rays\n", spallct); - return; -} - - -/* To facilitate one-time per burst point initialization of the spall - ray application structure while leaving burstRay() with the - capability of being used as a multitasking process, a_burst must - be accessible by both the burstPoint() and burstRay() routines, but - can be local to this module. */ -static struct application a_burst; /* prototype spall ray */ - -/* - * This routine dispatches the burst point ray tracing task burstRay(). - * RETURN CODES: 0 for fatal ray tracing error, 1 otherwise. - * - * bpt is burst point coordinates. - */ -static int -burstPoint(struct application *ap, fastf_t *normal, fastf_t *bpt) -{ - a_burst = *ap; - a_burst.a_miss = f_BurstMiss; - a_burst.a_hit = f_BurstHit; - a_burst.a_level++; - a_burst.a_user = 0; /* ray number */ - a_burst.a_purpose = "spall ray"; - assert(a_burst.a_overlap == ap->a_overlap); - - /* If pitch or yaw is specified, cant the main penetrator - axis. */ - if (cantwarhead) { - VADD2(a_burst.a_ray.r_dir, a_burst.a_ray.r_dir, cantdelta); - VUNITIZE(a_burst.a_ray.r_dir); - } - /* If a deflected cone is specified (the default) the spall cone - axis is half way between the main penetrator axis and exit - normal of the spalling component. - */ - if (deflectcone) { - VADD2(a_burst.a_ray.r_dir, a_burst.a_ray.r_dir, normal); - VUNITIZE(a_burst.a_ray.r_dir); - } - VMOVE(a_burst.a_ray.r_pt, bpt); - - comphi = 0.0; /* Initialize global for concurrent access. */ - - /* SERIAL case -- one CPU does all the work. */ - return burstRay(); -} - - -static void -spallVec(fastf_t *dvec, fastf_t *s_rdir, fastf_t phi, fastf_t gammaval) -{ - fastf_t cosphi = cos(phi); - fastf_t singamma = sin(gammaval); - fastf_t cosgamma = cos(gammaval); - fastf_t csgaphi, ssgaphi; - fastf_t sinphi = sin(phi); - fastf_t cosdphi[3]; - fastf_t fvec[3]; - fastf_t evec[3]; - - if (VNEAR_EQUAL(dvec, zaxis, VEC_TOL) - || VNEAR_EQUAL(dvec, negzaxis, VEC_TOL) - ) { - VMOVE(evec, xaxis); - } else { - VCROSS(evec, dvec, zaxis); - } - VCROSS(fvec, evec, dvec); - VSCALE(cosdphi, dvec, cosphi); - ssgaphi = singamma * sinphi; - csgaphi = cosgamma * sinphi; - VJOIN2(s_rdir, cosdphi, ssgaphi, evec, csgaphi, fvec); - VUNITIZE(s_rdir); - return; -} - - -static int -burstRay() -{ - /* Need local copy of all but readonly variables for concurrent - threads of execution. */ - struct application a_spall; - fastf_t phi; - int hitcrit = 0; - a_spall = a_burst; - a_spall.a_resource = RESOURCE_NULL; - for (; ! userinterrupt;) { - fastf_t sinphi; - fastf_t gammaval, gammainc, gammalast; - int done; - int m; - bu_semaphore_acquire(RT_SEM_WORKER); - phi = comphi; - comphi += phiinc; - done = phi > conehfangle; - bu_semaphore_release(RT_SEM_WORKER); - if (done) - break; - sinphi = sin(phi); - sinphi = fabs(sinphi); - m = (M_2PI * sinphi)/delta + 1; - gammainc = M_2PI / m; - gammalast = M_2PI - gammainc + VUNITIZE_TOL; - for (gammaval = 0.0; gammaval <= gammalast; gammaval += gammainc) { - int ncrit; - spallVec(a_burst.a_ray.r_dir, a_spall.a_ray.r_dir, - phi, gammaval); - - if (plotline) - plotRayPoint(&a_spall.a_ray); - else - plotRayLine(&a_spall.a_ray); - - bu_semaphore_acquire(RT_SEM_WORKER); - a_spall.a_user = a_burst.a_user++; - bu_semaphore_release(RT_SEM_WORKER); - if ((ncrit = rt_shootray(&a_spall)) == -1 - && fatalerror) { - /* Fatal error in application routine. */ - brst_log("Error: ray tracing aborted.\n"); - return 0; - } - if (fbfile[0] != NUL && ncrit > 0) { - paintSpallFb(&a_spall); - hitcrit = 1; - } - if (histfile[0] != NUL) { - bu_semaphore_acquire(BU_SEM_SYSCALL); - (void) fprintf(histfp, "%d\n", ncrit); - bu_semaphore_release(BU_SEM_SYSCALL); - } - } - } - if (fbfile[0] != NUL) { - if (hitcrit) - paintCellFb(&a_spall, pixcrit, pixtarg); - else - paintCellFb(&a_spall, pixbhit, pixtarg); - } - return 1; -} - - -void -abort_RT(int UNUSED(sig)) -{ - (void) signal(SIGINT, abort_RT); - userinterrupt = 1; - return; -} - - -static void -view_pix(struct application *ap) -{ - bu_semaphore_acquire(BU_SEM_SYSCALL); - if (! TSTBIT(firemode, FM_BURST)) - prntGridOffsets(ap->a_x, ap->a_y); - if (tty) - prntTimer(NULL); - bu_semaphore_release(BU_SEM_SYSCALL); - return; -} - - -static void -view_end() -{ - if (gridfile[0] != NUL) - (void) fflush(gridfp); - if (histfile[0] != NUL) - (void) fflush(histfp); - if (plotfile[0] != NUL) - (void) fflush(plotfp); - if (outfile[0] != NUL) - (void) fflush(outfp); - if (shotlnfile[0] != NUL) - (void) fflush(shotlnfp); - prntTimer("view"); - if (noverlaps > 0) - brst_log("%d overlaps detected over %g mm thick.\n", - noverlaps, OVERLAP_TOL); - return; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/gridrotate.c b/src/burst/gridrotate.c deleted file mode 100644 index 8e83270b24f..00000000000 --- a/src/burst/gridrotate.c +++ /dev/null @@ -1,86 +0,0 @@ -/* G R I D R O T A T E . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/gridrotate.c - * - */ - -#include "common.h" - -#include - -#include "vmath.h" - - -/* - void gridRotate(fastf_t azim, fastf_t elev, fastf_t roll, - fastf_t *des_H, fastf_t *des_V) - - Creates the unit vectors H and V which are the horizontal - and vertical components of the grid in target coordinates. - The vectors are found from the azimuth and elevation of the - viewing angle according to a simplification of the rotation - matrix from grid coordinates to target coordinates. - To see that the vectors are, indeed, unit vectors, recall - the trigonometric relation: - - sin(A)^2 + cos(A)^2 = 1 . - -*/ -void -gridRotate(fastf_t azim, fastf_t elev, fastf_t roll, fastf_t *des_H, fastf_t *des_V) -{ - fastf_t sn_azm = sin(azim); - fastf_t cs_azm = cos(azim); - fastf_t sn_elv = sin(elev); - - des_H[0] = -sn_azm; - des_H[1] = cs_azm; - des_H[2] = 0.0; - des_V[0] = -sn_elv*cs_azm; - des_V[1] = -sn_elv*sn_azm; - des_V[2] = cos(elev); - - if (!ZERO(roll)) { - fastf_t tmp_V[3], tmp_H[3], prime_V[3]; - fastf_t sn_roll = sin(roll); - fastf_t cs_roll = cos(roll); - - VSCALE(tmp_V, des_V, cs_roll); - VSCALE(tmp_H, des_H, sn_roll); - VADD2(prime_V, tmp_V, tmp_H); - VSCALE(tmp_V, des_V, -sn_roll); - VSCALE(tmp_H, des_H, cs_roll); - VADD2(des_H, tmp_V, tmp_H); - VMOVE(des_V, prime_V); - } - return; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/idents.c b/src/burst/idents.c deleted file mode 100644 index 82181f7e2f3..00000000000 --- a/src/burst/idents.c +++ /dev/null @@ -1,165 +0,0 @@ -/* I D E N T S . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/idents.c - * - */ - -#include "common.h" - -#include -#include -#include -#include -#include - -#include "bu/log.h" -#include "vmath.h" - -#include "./burst.h" -#include "./extern.h" - - -#define DEBUG_IDENTS 0 - -int -findIdents(int ident, Ids *idp) -{ -#if DEBUG_IDENTS - brst_log("findIdents(%d)\n", ident); -#endif - for (idp = idp->i_next; idp != IDS_NULL; idp = idp->i_next) { -#if DEBUG_IDENTS - brst_log("lower=%d, upper=%d\n", (int) idp->i_lower, - (int) idp->i_upper); -#endif - if (ident >= (int) idp->i_lower - && ident <= (int) idp->i_upper - ) - return 1; - } -#if DEBUG_IDENTS - brst_log("returned 0\n"); -#endif - return 0; -} - - -Colors * -findColors(int ident, Colors *colp) -{ - for (colp = colp->c_next; colp != COLORS_NULL; colp = colp->c_next) { - if (ident >= (int) colp->c_lower && ident <= (int) colp->c_upper) - return colp; - } - return COLORS_NULL; -} - - -/* - void freeIdents(Ids *idp) - - Free up linked list, except for the head node. -*/ -void -freeIdents(Ids *idp) -{ - if (idp->i_next == NULL) - return; /* finished */ - freeIdents(idp->i_next); - free((char *) idp->i_next); -} - - -int -readIdents(Ids *idlist, FILE *fp) -{ - char input_buf[BUFSIZ]; - int lower, upper; - Ids *idp; - freeIdents(idlist); /* free old list if it exists */ - for (idp = idlist; - bu_fgets(input_buf, BUFSIZ, fp) != NULL; - ) { - char *token; - token = strtok(input_buf, ", -:; \t"); - if (token == NULL || sscanf(token, "%d", &lower) < 1) - continue; - token = strtok(NULL, " \t"); - if (token == NULL || sscanf(token, "%d", &upper) < 1) - upper = lower; - if ((idp->i_next = (Ids *) malloc(sizeof(Ids))) == NULL) { - Malloc_Bomb(sizeof(Ids)); - return 0; - } - idp = idp->i_next; - idp->i_lower = lower; - idp->i_upper = upper; - } - idp->i_next = NULL; - return 1; -} - - -int -readColors(Colors *colorlist, FILE *fp) -{ - char input_buf[BUFSIZ]; - int lower, upper; - int rgb[3]; - Colors *colp; - for (colp = colorlist; - bu_fgets(input_buf, BUFSIZ, fp) != NULL; - ) { - int items = sscanf(input_buf, "%d %d %d %d %d\n", &lower, &upper, &rgb[0], &rgb[1], &rgb[2]); - if (items < 5) { - if (items == EOF) - break; - else { - brst_log("readColors(): only %d items read\n", - items); - continue; - } - } - - colp->c_next = (Colors *) malloc(sizeof(Colors)); - if (colp->c_next == NULL) { - Malloc_Bomb(sizeof(Colors)); - return 0; - } - colp = colp->c_next; - colp->c_lower = lower; - colp->c_upper = upper; - VMOVE(colp->c_rgb, rgb); - } - colp->c_next = NULL; - return 1; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/paint.c b/src/burst/paint.c deleted file mode 100644 index f94ad40f44a..00000000000 --- a/src/burst/paint.c +++ /dev/null @@ -1,214 +0,0 @@ -/* P A I N T . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/paint.c - * - */ - -#include "common.h" - -#include -#include - -#include "vmath.h" -#include "raytrace.h" -#include "dm.h" - -#include "./extern.h" - - -#define DEBUG_CELLFB 0 -#define DEBUG_SPALLFB 0 - -/* Offset frame buffer coordinates to center of cell from grid lines. */ -#define CenterCell(b) (b += roundToInt((fastf_t) zoom / 2.0)) - -/* Compare one RGB pixel to another. */ -#define SAMERGB(a, b) ((a)[RED] == (b)[RED] &&\ - (a)[GRN] == (b)[GRN] &&\ - (a)[BLU] == (b)[BLU]) - -static unsigned char pixbuf[MAXDEVWID][3]; -static int gridxmargin; -static int gridymargin; - -void -gridToFb(int gx, int gy, int *fxp, int *fyp) -{ - /* map grid offsets to frame buffer coordinates */ - *fxp = (gx - gridxorg)*zoom + gridxmargin; - *fyp = (gy - gridyorg)*zoom + gridymargin; - return; -} - - -void -paintGridFb() -{ - int fx, fy; - int fxbeg, fybeg; - int fxfin, fyfin; - int fxorg, fyorg; - int fgridwid; - if (fb_clear(fbiop, pixbkgr) == -1) - return; - gridxmargin = (devwid - (gridwidth*zoom)) / 2.0; - gridymargin = (devhgt - (gridheight*zoom)) / 2.0; - gridToFb(gridxorg, gridyorg, &fxbeg, &fybeg); - gridToFb(gridxfin+1, gridyfin+1, &fxfin, &fyfin); - gridToFb(0, 0, &fxorg, &fyorg); - CenterCell(fxorg); /* center of cell */ - CenterCell(fyorg); - if (zoom == 1) { - fgridwid = gridwidth + 2; - fxfin++; - } else - fgridwid = gridwidth * zoom + 1; - - /* draw vertical lines */ - for (fx = 1; fx < fgridwid; fx++) - COPYRGB(&pixbuf[fx][0], pixbkgr); - for (fx = fxbeg; fx <= fxfin; fx += zoom) - COPYRGB(&pixbuf[fx-fxbeg][0], &pixgrid[0]); - for (fy = fybeg; fy <= fyfin; fy++) - (void) fb_write(fbiop, fxbeg, fy, (unsigned char *)pixbuf, fgridwid); - for (fy = 0; fy < devwid; fy++) - (void) fb_write(fbiop, fxorg, fy, pixaxis, 1); - - /* draw horizontal lines */ - if (zoom > 1) - for (fy = fybeg; fy <= fyfin; fy += zoom) - (void) fb_write(fbiop, - fxbeg, fy, pixgrid, fgridwid); - for (fx = 0; fx < devwid; fx++) - COPYRGB(&pixbuf[fx][0], pixaxis); - (void) fb_write(fbiop, 0, fyorg, (unsigned char *)pixbuf, devwid); - return; -} - - -void -paintCellFb(struct application *ap, unsigned char *pixpaint, unsigned char *pixexpendable) -{ - int gx, gy; - int gyfin, gxfin; - int gxorg, gyorg; - int x, y; - int cnt; -#if DEBUG_CELLFB - brst_log("paintCellFb: expendable {%d, %d, %d}\n", - pixexpendable[RED], - pixexpendable[GRN], - pixexpendable[BLU]); -#endif - gridToFb(ap->a_x, ap->a_y, &gx, &gy); - gxorg = gx+1; - gyorg = gy+1; - gxfin = zoom == 1 ? gx+zoom+1 : gx+zoom; - gyfin = zoom == 1 ? gy+zoom+1 : gy+zoom; - cnt = gxfin - gxorg; - for (y = gyorg; y < gyfin; y++) { - if (zoom != 1 && (y - gy) % zoom == 0) - continue; - bu_semaphore_acquire(BU_SEM_GENERAL); - (void) fb_read(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt); - bu_semaphore_release(BU_SEM_GENERAL); - for (x = gxorg; x < gxfin; x++) { - if (SAMERGB(&pixbuf[x-gxorg][0], pixexpendable) - ) { -#if DEBUG_CELLFB - brst_log("Clobbering:<%d, %d>{%d, %d, %d}\n", - x, y, - pixbuf[x-gxorg][RED], - pixbuf[x-gxorg][GRN], - pixbuf[x-gxorg][BLU]); -#endif - COPYRGB(&pixbuf[x-gxorg][0], pixpaint); - } -#if DEBUG_CELLFB - else - brst_log("Preserving:<%d, %d>{%d, %d, %d}\n", - x, y, - pixbuf[x-gxorg][RED], - pixbuf[x-gxorg][GRN], - pixbuf[x-gxorg][BLU]); -#endif - } - bu_semaphore_acquire(BU_SEM_GENERAL); - (void) fb_write(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt); - bu_semaphore_release(BU_SEM_GENERAL); -#if DEBUG_CELLFB - brst_log("paintCellFb: fb_write(%d, %d)\n", x, y); -#endif - } - return; -} - - -void -paintSpallFb(struct application *ap) -{ - unsigned char pixel[3]; - int x, y; - int err; - fastf_t celldist; -#if DEBUG_SPALLFB - brst_log("paintSpallFb: a_x=%d a_y=%d a_cumlen=%g cellsz=%g zoom=%d\n", - ap->a_x, ap->a_y, ap->a_cumlen, cellsz, zoom); -#endif - pixel[RED] = ap->a_color[RED] * 255; - pixel[GRN] = ap->a_color[GRN] * 255; - pixel[BLU] = ap->a_color[BLU] * 255; - gridToFb(ap->a_x, ap->a_y, &x, &y); - CenterCell(x); /* center of cell */ - CenterCell(y); - celldist = ap->a_cumlen/cellsz * zoom; - x = roundToInt(x + VDOT(ap->a_ray.r_dir, gridhor) * celldist); - y = roundToInt(y + VDOT(ap->a_ray.r_dir, gridver) * celldist); - bu_semaphore_acquire(BU_SEM_GENERAL); - err = fb_write(fbiop, x, y, pixel, 1); - bu_semaphore_release(BU_SEM_GENERAL); -#if DEBUG_SPALLFB - brst_log("paintSpallFb:gridhor=<%g, %g, %g> gridver=<%g, %g, %g>\n", - gridhor[X], gridhor[Y], gridhor[Z], - gridver[X], gridver[Y], gridver[Z]); - brst_log("paintSpallFb:fb_write(x=%d, y=%d, pixel={%d, %d, %d})\n", - x, y, - (int) pixel[RED], - (int) pixel[GRN], - (int) pixel[BLU] - ); -#endif - if (err == -1) - brst_log("Write failed to pixel <%d, %d> from cell <%d, %d>.\n", - x, y, ap->a_x, ap->a_y); - return; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/plot.c b/src/burst/plot.c deleted file mode 100644 index 3991c2e1a11..00000000000 --- a/src/burst/plot.c +++ /dev/null @@ -1,139 +0,0 @@ -/* P L O T . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/plot.c - * - */ - -#include "common.h" - -#include -#include -#include - -#include "vmath.h" -#include "bn.h" -#include "raytrace.h" -#include "bv/plot3.h" - -#include "./burst.h" -#include "./extern.h" - -void -plotInit() -{ - int x_1, y_1, z_1, x_2, y_2, z_2; - if (plotfp == NULL) - return; - x_1 = (int) rtip->mdl_min[X] - 1; - y_1 = (int) rtip->mdl_min[Y] - 1; - z_1 = (int) rtip->mdl_min[Z] - 1; - x_2 = (int) rtip->mdl_max[X] + 1; - y_2 = (int) rtip->mdl_max[Y] + 1; - z_2 = (int) rtip->mdl_max[Z] + 1; - pl_3space(plotfp, x_1, y_1, z_1, x_2, y_2, z_2); - return; -} - - -void -plotGrid(fastf_t *r_pt) -{ - if (plotfp == NULL) - return; - pl_color(plotfp, R_GRID, G_GRID, B_GRID); - pl_3point(plotfp, (int) r_pt[X], (int) r_pt[Y], (int) r_pt[Z]); - return; -} - - -void -plotRayLine(struct xray *rayp) -{ - int endpoint[3]; - if (plotfp == NULL) - return; - VJOIN1(endpoint, rayp->r_pt, cellsz, rayp->r_dir); - - bu_semaphore_acquire(BU_SEM_SYSCALL); - pl_color(plotfp, R_BURST, G_BURST, B_BURST); - - /* draw line */ - pl_3line(plotfp, - (int) rayp->r_pt[X], - (int) rayp->r_pt[Y], - (int) rayp->r_pt[Z], - endpoint[X], - endpoint[Y], - endpoint[Z] - ); - - bu_semaphore_release(BU_SEM_SYSCALL); - return; -} - - -void -plotRayPoint(struct xray *rayp) -{ - int endpoint[3]; - if (plotfp == NULL) - return; - VJOIN1(endpoint, rayp->r_pt, cellsz, rayp->r_dir); - - bu_semaphore_acquire(BU_SEM_SYSCALL); - pl_color(plotfp, R_BURST, G_BURST, B_BURST); - - /* draw point */ - pl_3point(plotfp, (int) endpoint[X], (int) endpoint[Y], (int) endpoint[Z]); - - bu_semaphore_release(BU_SEM_SYSCALL); - return; -} - - -void -plotPartition(struct hit *ihitp, struct hit *ohitp) -{ - if (plotfp == NULL) - return; - bu_semaphore_acquire(BU_SEM_SYSCALL); - pl_3line(plotfp, - (int) ihitp->hit_point[X], - (int) ihitp->hit_point[Y], - (int) ihitp->hit_point[Z], - (int) ohitp->hit_point[X], - (int) ohitp->hit_point[Y], - (int) ohitp->hit_point[Z] - ); - bu_semaphore_release(BU_SEM_SYSCALL); - return; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/prnt.c b/src/burst/prnt.c deleted file mode 100644 index 8672bea165b..00000000000 --- a/src/burst/prnt.c +++ /dev/null @@ -1,830 +0,0 @@ -/* P R N T . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/prnt.c - * - */ - -#include "common.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "vmath.h" -#include "bn.h" -#include "raytrace.h" -#include "libtermio.h" - -#include "./Sc.h" -#include "./ascii.h" -#include "./extern.h" - -#if defined(HAVE_VSNPRINTF) && !defined(HAVE_DECL_VSNPRINTF) && !defined(vsnprintf) -extern int vsnprintf(char *str, size_t size, const char *format, va_list ap); -#endif - -#define MAX_COLS 128 - -#define PHANTOM_ARMOR 111 - - -int -doMore(int *UNUSED(linesp)) -{ - return 1; -} - - -static int -f_Nerror(struct application *ap) -{ - brst_log("Couldn't compute thickness or exit point %s.\n", - "along normal direction"); - brst_log("\tpnt\t<%12.6f, %12.6f, %12.6f>\n", ap->a_ray.r_pt, brst_log); - brst_log("\tdir\t<%12.6f, %12.6f, %12.6f>\n", ap->a_ray.r_dir, brst_log); - ap->a_rbeam = 0.0; - return 0; -} - - -/* f_Normal() - -Shooting from surface of object along reversed entry normal to -compute exit point along normal direction and normal thickness. -Thickness returned in "a_rbeam". -*/ -static int -f_Normal(struct application *ap, struct partition *pt_headp, struct seg *UNUSED(segp)) -{ - struct partition *pp = pt_headp->pt_forw; - struct partition *cp; - struct hit *ohitp; - - for (cp = pp->pt_forw; - cp != pt_headp && SameCmp(pp->pt_regionp, cp->pt_regionp); - cp = cp->pt_forw - ) - ; - ohitp = cp->pt_back->pt_outhit; - ap->a_rbeam = ohitp->hit_dist - pp->pt_inhit->hit_dist; -#ifdef VDEBUG - brst_log("f_Normal: thickness=%g dout=%g din=%g\n", - ap->a_rbeam*unitconv, ohitp->hit_dist, pp->pt_inhit->hit_dist); -#endif - return 1; -} - - -void -locPerror(char *msg) -{ - if (errno > 0) - brst_log("%s: %s\n", msg, strerror(errno)); - else - brst_log("BUG: errno not set, shouldn't call perror.\n"); - return; -} - - -int -notify(char *UNUSED(str), int UNUSED(mode)) -{ - return 0; -} - - -/* - void prntAspectInit(void) - - Burst Point Library and Shotline file: header record for each view. - Ref. Figure 20., Line Number 1 and Figure 19., Line Number 1 of ICD. -*/ -void -prntAspectInit() -{ - fastf_t projarea; /* projected area */ - /* Convert to user units before squaring cell size. */ - projarea = cellsz*unitconv; - projarea *= projarea; - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 9.4f % 8.4f % 5.2f % 10.2f %-6s % 9.6f\n", - PB_ASPECT_INIT, - viewazim*RAD2DEG, /* attack azimuth in degrees */ - viewelev*RAD2DEG, /* attack elevation in degrees */ - bdist*unitconv, /* BDIST */ - projarea, /* projected area associated with burst pt. */ - units == U_INCHES ? "inches" : - units == U_FEET ? "feet" : - units == U_MILLIMETERS ? "mm" : - units == U_CENTIMETERS ? "cm" : - units == U_METERS ? "meters" : "units?", - raysolidangle - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - if (shotlnfile[0] != NUL - && fprintf(shotlnfp, - "%c % 9.4f % 8.4f % 7.2f % 7.2f %7.2f %7.2f %7.2f %-6s\n", - PS_ASPECT_INIT, - viewazim*RAD2DEG, /* attack azimuth in degrees */ - viewelev*RAD2DEG, /* attack elevation in degrees */ - cellsz*unitconv, /* shotline separation */ - modlrt*unitconv, /* maximum Y'-coordinate of target */ - modllf*unitconv, /* minimum Y'-coordinate of target */ - modlup*unitconv, /* maximum Z'-coordinate of target */ - modldn*unitconv, /* minimum Z'-coordinate of target */ - units == U_INCHES ? "inches" : - units == U_FEET ? "feet" : - units == U_MILLIMETERS ? "mm" : - units == U_CENTIMETERS ? "cm" : - units == U_METERS ? "meters" : "units?" - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", shotlnfile); - locPerror("fprintf"); - exitCleanly(1); - } - return; -} - - -/* - void prntBurstHdr(fastf_t *bpt, fastf_t *shotdir) - - This routine must be called before bursting when doing either a - ground plane burst or bursting at user-specified coordinates. The - purpose is to output fake PB_CELL_IDENT and PB_RAY_INTERSECT records - to the Burst Point Library so that the coordinates of the burst point - can be made available. - -*/ -void -prntBurstHdr(fastf_t *bpt /* burst point in model coords */, fastf_t *shotdir /* shotline direction vector */) -{ - fastf_t vec[3]; - /* Transform burst point (model coordinate system) into the shotline - coordinate system. */ - vec[Y] = VDOT(gridhor, bpt); /* Y' */ - vec[Z] = VDOT(gridver, bpt); /* Z' */ - vec[X] = -VDOT(shotdir, bpt); /* X' - shotdir is reverse of X' */ - - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 8.3f % 8.3f\n", - PB_CELL_IDENT, - vec[Y]*unitconv, - /* horizontal coordinate of burst point (Y') */ - vec[Z]*unitconv - /* vertical coordinate of burst point (Z') */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 8.2f % 8.2f %5d %2d % 7.3f % 7.2f % 7.3f %c\n", - PB_RAY_INTERSECT, - vec[X]*unitconv, /* X' coordinate of burst point */ - 0.0, /* LOS thickness of component */ - 9999, /* dummy component code number */ - 9, /* dummy space code */ - 0.0, /* N/A */ - 0.0, /* N/A */ - 0.0, /* N/A */ - '1' /* burst was generated */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } -} - - -/* - void prntCellIdent(struct application *ap) - - Burst Point Library and Shotline file: information about shotline. - Ref. Figure 20., Line Number 2 and Figure 19., Line Number 2 of ICD. - - NOTE: field width of first 2 floats compatible with PB_RAY_HEADER - record. -*/ -void -prntCellIdent(struct application *ap) -{ - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 8.3f % 8.3f\n", - PB_CELL_IDENT, - ap->a_uvec[X]*unitconv, - /* horizontal coordinate of shotline (Y') */ - ap->a_uvec[Y]*unitconv - /* vertical coordinate of shotline (Z') */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - if (shotlnfile[0] != NUL - && fprintf(shotlnfp, - "%c % 8.3f % 8.3f\n", - PS_CELL_IDENT, - ap->a_uvec[X]*unitconv, - /* horizontal coordinate of shotline (Y') */ - ap->a_uvec[Y]*unitconv - /* vertical coordinate of shotline (Z') */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", shotlnfile); - locPerror("fprintf"); - exitCleanly(1); - } - return; -} - - -/* - fastf_t getNormThickness(struct application *ap, struct partition *pp, - fastf_t cosobliquity, fastf_t normvec[3]) - - Given a partition structure with entry hit point and a private copy - of the associated normal vector, the current application structure - and the cosine of the obliquity at entry to the component, return - the normal thickness through the component at the given hit point. - -*/ -static fastf_t -getNormThickness(struct application *ap, struct partition *pp, fastf_t cosobliquity, fastf_t normvec[3]) -{ -#ifdef VDEBUG - brst_log("getNormThickness() pp 0x%x normal %g, %g, %g\n", - pp, normvec[X], normvec[Y], normvec[Z]); -#endif - if (NEAR_EQUAL(cosobliquity, 1.0, COS_TOL)) { - /* Trajectory was normal to surface, so no need - to shoot another ray. */ - fastf_t thickness = pp->pt_outhit->hit_dist - - pp->pt_inhit->hit_dist; -#ifdef VDEBUG - brst_log("getNormThickness: using existing partitions.\n"); - brst_log("\tthickness=%g dout=%g din=%g normal=%g, %g, %g\n", - thickness*unitconv, - pp->pt_outhit->hit_dist, pp->pt_inhit->hit_dist, - normvec[X], normvec[Y], normvec[Z]); -#endif - return thickness; - } else { - /* need to shoot ray */ - struct application a_thick; - struct hit *ihitp = pp->pt_inhit; - struct region *regp = pp->pt_regionp; - a_thick = *ap; - a_thick.a_hit = f_Normal; - a_thick.a_miss = f_Nerror; - a_thick.a_level++; - a_thick.a_user = regp->reg_regionid; - a_thick.a_purpose = "normal thickness"; - VMOVE(a_thick.a_ray.r_pt, ihitp->hit_point); - VSCALE(a_thick.a_ray.r_dir, normvec, -1.0); - if (rt_shootray(&a_thick) == -1 && fatalerror) { - /* Fatal error in application routine. */ - brst_log("Fatal error: raytracing aborted.\n"); - return 0.0; - } - return a_thick.a_rbeam; - } - /*NOTREACHED*/ -} - - -/* - void prntSeg(struct application *ap, struct partition *cpp, int space, - fastf_t entrynorm[3], fastf_t exitnorm[3], - int burstflag) - - Burst Point Library and Shotline file: information about each component - hit along path of main penetrator (shotline). - Ref. Figure 20., Line Number 3 and Figure 19., Line Number 2 of ICD. -*/ -void -prntSeg(struct application *ap, struct partition *cpp /* component partition */, int space, fastf_t entrynorm[3], fastf_t exitnorm[3], int burstflag /* Was a burst generated by this partition? */) -{ - fastf_t icosobliquity; /* cosine of obliquity at entry */ - fastf_t ocosobliquity; /* cosine of obliquity at exit */ - fastf_t entryangle; /* obliquity angle at entry */ - fastf_t exitangle; /* obliquity angle at exit */ - fastf_t los; /* line-of-sight thickness */ - fastf_t normthickness; /* normal thickness */ - fastf_t rotangle; /* rotation angle */ - fastf_t sinfbangle; /* sine of fall back angle */ - - /* This *should* give negative of desired result. */ - icosobliquity = VDOT(ap->a_ray.r_dir, entrynorm); - icosobliquity = -icosobliquity; - - ocosobliquity = VDOT(ap->a_ray.r_dir, exitnorm); - - if (NEAR_ZERO(exitnorm[Y], VDIVIDE_TOL) && NEAR_ZERO(exitnorm[X], VDIVIDE_TOL)) - rotangle = 0.0; - else { - rotangle = atan2(exitnorm[Y], exitnorm[X]); - rotangle *= RAD2DEG; /* convert to degrees */ - if (rotangle < 0.0) - rotangle += 360.0; - } - /* Compute sine of fallback angle. NB: the Air Force measures the - fallback angle from the horizontal (X-Y) plane. */ - sinfbangle = VDOT(exitnorm, zaxis); - - los = (cpp->pt_outhit->hit_dist-cpp->pt_inhit->hit_dist)*unitconv; -#ifdef VDEBUG - brst_log("prntSeg: los=%g dout=%g din=%g\n", - los, cpp->pt_outhit->hit_dist, cpp->pt_inhit->hit_dist); -#endif - - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 8.2f % 8.2f %5d %2d % 7.3f % 7.2f % 7.3f %c\n", - PB_RAY_INTERSECT, - (standoff - cpp->pt_inhit->hit_dist)*unitconv, - /* X'-coordinate of intersection */ - los, /* LOS thickness of component */ - cpp->pt_regionp->reg_regionid, - /* component code number */ - space, /* space code */ - sinfbangle, /* sine of fallback angle at exit */ - rotangle, /* rotation angle in degrees at exit */ - icosobliquity, /* cosine of obliquity angle at entry */ - burstflag ? '1' : '0' /* flag generation of burst */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - if (shotlnfile[0] == NUL) - return; - entryangle = NEAR_EQUAL(icosobliquity, 1.0, COS_TOL) ? - 0.0 : acos(icosobliquity) * RAD2DEG; - if ((normthickness = - getNormThickness(ap, cpp, icosobliquity, entrynorm)) <= 0.0 - && fatalerror) { - brst_log("Couldn't compute normal thickness.\n"); - brst_log("\tshotline coordinates <%g, %g>\n", - ap->a_uvec[X]*unitconv, - ap->a_uvec[Y]*unitconv - ); - brst_log("\tregion name '%s' solid name '%s'\n", - cpp->pt_regionp->reg_name, - cpp->pt_inseg->seg_stp->st_name); - return; - } - exitangle = NEAR_EQUAL(ocosobliquity, 1.0, COS_TOL) ? - 0.0 : acos(ocosobliquity) * RAD2DEG; - if (fprintf(shotlnfp, - "%c % 8.2f % 7.3f % 7.2f %5d % 8.2f % 8.2f %2d % 7.2f % 7.2f\n", - PS_SHOT_INTERSECT, - (standoff - cpp->pt_inhit->hit_dist)*unitconv, - /* X'-coordinate of intersection */ - sinfbangle, /* sine of fallback angle at exit */ - rotangle, /* rotation angle in degrees at exit */ - cpp->pt_regionp->reg_regionid, - /* component code number */ - normthickness*unitconv, - /* normal thickness of component */ - los, /* LOS thickness of component */ - space, /* space code */ - entryangle, /* entry obliquity angle in degrees */ - exitangle /* exit obliquity angle in degrees */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", shotlnfile); - locPerror("fprintf"); - exitCleanly(1); - } -} - - -/* - void prntRayHeader(fastf_t *raydir, fastf_t *shotdir, unsigned rayno) - - Burst Point Library: information about burst ray. All angles are - WRT the shotline coordinate system, represented by X', Y' and Z'. - Ref. Figure 20., Line Number 19 of ICD. - - NOTE: field width of first 2 floats compatible with PB_CELL_IDENT - record. -*/ -void -prntRayHeader(fastf_t *raydir /* burst ray direction vector */, fastf_t *shotdir /* shotline direction vector */, unsigned rayno /* ray number for this burst point */) -{ - double cosxr; /* cosine of angle between X' and raydir */ - double cosyr; /* cosine of angle between Y' and raydir */ - fastf_t azim; /* ray azim in radians */ - fastf_t sinelev; /* sine of ray elevation */ - if (outfile[0] == NUL) - return; - cosxr = -VDOT(shotdir, raydir); /* shotdir is reverse of X' */ - cosyr = VDOT(gridhor, raydir); - if (NEAR_ZERO(cosyr, VDIVIDE_TOL) && NEAR_ZERO(cosxr, VDIVIDE_TOL)) - azim = 0.0; - else - azim = atan2(cosyr, cosxr); - sinelev = VDOT(gridver, raydir); - if (fprintf(outfp, - "%c %8.3f %8.3f %6u\n", - PB_RAY_HEADER, - azim, /* ray azimuth angle WRT shotline (radians). */ - sinelev, /* sine of ray elevation angle WRT shotline. */ - rayno - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } -} - - -/* - void prntRegionHdr(struct application *ap, struct partition *pt_headp, - struct partition *pp, fastf_t entrynorm[3], - fastf_t exitnorm[3]) - - Burst Point Library: intersection along burst ray. - Ref. Figure 20., Line Number 20 of ICD. -*/ -void -prntRegionHdr(struct application *ap, struct partition *pt_headp, struct partition *pp, fastf_t entrynorm[3], fastf_t exitnorm[3]) -{ - fastf_t cosobliquity; - fastf_t normthickness; - struct hit *ihitp = pp->pt_inhit; - struct hit *ohitp = pp->pt_outhit; - struct region *regp = pp->pt_regionp; - struct xray *rayp = &ap->a_ray; - /* Get entry/exit normals and fill in hit points */ - getRtHitNorm(ihitp, pp->pt_inseg->seg_stp, rayp, - (int) pp->pt_inflip, entrynorm); - if (! chkEntryNorm(pp, rayp, entrynorm, - "spall ray component entry normal")) { -#ifdef DEBUG - prntDbgPartitions(ap, pt_headp, - "prntRegionHdr: entry normal flipped."); -#endif - } - getRtHitNorm(ohitp, pp->pt_outseg->seg_stp, rayp, - (int) pp->pt_outflip, exitnorm); - if (! chkExitNorm(pp, rayp, exitnorm, - "spall ray component exit normal")) { -#ifdef DEBUG - prntDbgPartitions(ap, pt_headp, - "prntRegionHdr: exit normal flipped."); -#endif - } - - - /* calculate cosine of obliquity angle */ - cosobliquity = VDOT(ap->a_ray.r_dir, entrynorm); - cosobliquity = -cosobliquity; -#ifdef DEBUG - if (cosobliquity - COS_TOL > 1.0) { - brst_log("cosobliquity=%12.8f\n", cosobliquity); - brst_log("normal=<%g, %g, %g>\n", - entrynorm[X], - entrynorm[Y], - entrynorm[Z] - ); - brst_log("ray direction=<%g, %g, %g>\n", - ap->a_ray.r_dir[X], - ap->a_ray.r_dir[Y], - ap->a_ray.r_dir[Z] - ); - brst_log("region name '%s'\n", regp->reg_name); - } -#endif - if (outfile[0] == NUL) - return; - - - /* Now we must find normal thickness through component. */ - normthickness = getNormThickness(ap, pp, cosobliquity, entrynorm); - bu_semaphore_acquire(BU_SEM_SYSCALL); /* lock */ - if (fprintf(outfp, - "%c % 10.3f % 9.3f % 9.3f %4d %5d % 6.3f\n", - PB_REGION_HEADER, - ihitp->hit_dist*unitconv, /* distance from burst pt. */ - (ohitp->hit_dist - ihitp->hit_dist)*unitconv, /* LOS */ - normthickness*unitconv, /* normal thickness */ - pp->pt_forw == pt_headp ? - EXIT_AIR : pp->pt_forw->pt_regionp->reg_aircode, - regp->reg_regionid, - cosobliquity - ) < 0 - ) { - bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */ - brst_log("Write failed to file (%s)!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */ -} - - -void -prntDbgPartitions(struct application *ap, struct partition *pt_headp, char *label) -{ - struct partition *dpp; - brst_log("%s (0x%x)\n", label, pt_headp); - if (ap != NULL) - brst_log("\tPnt %g, %g, %g Dir %g, %g, %g\n", - ap->a_ray.r_pt[X], - ap->a_ray.r_pt[Y], - ap->a_ray.r_pt[Z], - ap->a_ray.r_dir[X], - ap->a_ray.r_dir[Y], - ap->a_ray.r_dir[Z]); - for (dpp = pt_headp->pt_forw; dpp != pt_headp; dpp = dpp->pt_forw) { - brst_log("\t0x%x: reg \"%s\" sols \"%s\", \"%s\" in %g out %g\n", - dpp, - dpp->pt_regionp->reg_name, - dpp->pt_inseg->seg_stp->st_name, - dpp->pt_outseg->seg_stp->st_name, - dpp->pt_inhit->hit_dist, - dpp->pt_outhit->hit_dist); - brst_log("\tinstp 0x%x outstp 0x%x inhit 0x%x outhit 0x%x\n", - dpp->pt_inseg->seg_stp, dpp->pt_outseg->seg_stp, - dpp->pt_inhit, dpp->pt_outhit); - } - brst_log("--\n"); -} - - -/* - void prntShieldComp(struct application *ap, struct partition *pt_headp, - Pt_Queue *qp) -*/ -void -prntShieldComp(struct application *ap, struct partition *pt_headp, Pt_Queue *qp) -{ - fastf_t entrynorm[3], exitnorm[3]; - if (outfile[0] == NUL) - return; - if (qp == PT_Q_NULL) - return; - prntShieldComp(ap, pt_headp, qp->q_next); - prntRegionHdr(ap, pt_headp, qp->q_part, entrynorm, exitnorm); -} - - -void -prntColors(Colors *colorp, char *str) -{ - brst_log("%s:\n", str); - for (colorp = colorp->c_next; - colorp != COLORS_NULL; - colorp = colorp->c_next) { - brst_log("\t%d..%d\t%d, %d, %d\n", - (int)colorp->c_lower, - (int)colorp->c_upper, - (int)colorp->c_rgb[0], - (int)colorp->c_rgb[1], - (int)colorp->c_rgb[2] - ); - } -} - - -/* - void prntFiringCoords(fastf_t *vec) - - If the user has asked for grid coordinates to be saved, write - them to the output stream 'gridfp'. -*/ -void -prntFiringCoords(fastf_t *vec) -{ - if (gridfile[0] == '\0') - return; - assert(gridfp != (FILE *) NULL); - if (fprintf(gridfp, "%7.2f %7.2f\n", vec[X]*unitconv, vec[Y]*unitconv) - < 0) { - brst_log("Write failed to file (%s)!\n", gridfile); - locPerror("fprintf"); - exitCleanly(1); - } -} - - -void -prntGridOffsets(int UNUSED(x), int UNUSED(y)) -{ - return; -} - - -void -prntIdents(Ids *idp, char *str) -{ - brst_log("%s:\n", str); - for (idp = idp->i_next; idp != IDS_NULL; idp = idp->i_next) { - if (idp->i_lower == idp->i_upper) - brst_log("\t%d\n", (int) idp->i_lower); - else - brst_log("\t%d..%d\n", - (int)idp->i_lower, - (int)idp->i_upper - ); - } - return; -} - - -/**/ -void -prntPagedMenu(char **menu) -{ - for (; *menu != NULL; menu++) - brst_log("%s\n", *menu); - return; -} - - -/* - void prntPhantom(struct hit *hitp, int space) - - Output "phantom armor" pseudo component. This component has no - surface normal or thickness, so many zero fields are used for - conformity with the normal component output formats. -*/ -/*ARGSUSED*/ -void -prntPhantom(struct hit *hitp /* ptr. to phantom's intersection information */, int space /* space code behind phantom */) -{ - if (outfile[0] != NUL - && fprintf(outfp, - "%c % 8.2f % 8.2f %5d %2d % 7.3f % 7.3f % 7.3f %c\n", - PB_RAY_INTERSECT, - (standoff-hitp->hit_dist)*unitconv, - /* X'-coordinate of intersection */ - 0.0, /* LOS thickness of component */ - PHANTOM_ARMOR, /* component code number */ - space, /* space code */ - 0.0, /* sine of fallback angle */ - 0.0, /* rotation angle (degrees) */ - 0.0, /* cosine of obliquity angle at entry */ - '0' /* no burst from phantom armor */ - ) < 0 - ) { - brst_log("Write failed to file!\n", outfile); - locPerror("fprintf"); - exitCleanly(1); - } - if (shotlnfile[0] != NUL - && fprintf(shotlnfp, - "%c % 8.2f % 7.3f % 7.3f %5d % 8.2f % 8.2f %2d % 7.2f % 7.2f\n", - PS_SHOT_INTERSECT, - (standoff-hitp->hit_dist)*unitconv, - /* X'-coordinate of intersection */ - 0.0, /* sine of fallback angle */ - 0.0, /* rotation angle in degrees */ - PHANTOM_ARMOR, /* component code number */ - 0.0, /* normal thickness of component */ - 0.0, /* LOS thickness of component */ - space, /* space code */ - 0.0, /* entry obliquity angle in degrees */ - 0.0 /* exit obliquity angle in degrees */ - ) < 0 - ) { - brst_log("Write failed to file (%s)!\n", shotlnfile); - locPerror("fprintf"); - exitCleanly(1); - } - return; -} - - -void -prntScr(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - format = va_arg(ap, const char *); - (void) vfprintf(stderr, format, ap); - (void) fputs("\n", stderr); - va_end(ap); - return; -} - - -/* - void prntTimer(char *str) -*/ -void -prntTimer(char *str) -{ - (void) rt_read_timer(timer, TIMER_LEN-1); - brst_log("%s:\t%s\n", str == NULL ? "(null)" : str, timer); -} - - -void -prntTitle(char *title_str) -{ - if (! tty || RT_G_DEBUG) - brst_log("%s\n", title_str == NULL ? "(null)" : title_str); -} - - -void -prompt(char *str) -{ - (void) ScMvCursor(PROMPT_X, PROMPT_Y); - if (str == (char *) NULL) - (void) ScClrEOL(); - else { - (void) ScSetStandout(); - (void) fputs(str, stdout); - (void) ScClrStandout(); - } - (void) fflush(stdout); -} - - -int -qAdd(struct partition *pp, Pt_Queue **qpp) -{ - Pt_Queue *newq; - bu_semaphore_acquire(BU_SEM_SYSCALL); - if ((newq = (Pt_Queue *) malloc(sizeof(Pt_Queue))) == PT_Q_NULL) { - Malloc_Bomb(sizeof(Pt_Queue)); - bu_semaphore_release(BU_SEM_SYSCALL); - return 0; - } - bu_semaphore_release(BU_SEM_SYSCALL); - newq->q_next = *qpp; - newq->q_part = pp; - *qpp = newq; - return 1; -} - - -void -qFree(Pt_Queue *qp) -{ - if (qp == PT_Q_NULL) - return; - qFree(qp->q_next); - bu_semaphore_acquire(BU_SEM_SYSCALL); - free((char *) qp); - bu_semaphore_release(BU_SEM_SYSCALL); -} - - -void -warning(char *str) -{ - prntScr(str); -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/trie.c b/src/burst/trie.c deleted file mode 100644 index 8cb3b50307f..00000000000 --- a/src/burst/trie.c +++ /dev/null @@ -1,275 +0,0 @@ -/* T R I E . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/trie.c - * - */ - -#include "common.h" - -#include -#include -#include - -#include "bu/log.h" - -#include "./burst.h" -#include "./extern.h" -#include "./ascii.h" - - -static Func *matchTrie(); - -/* - Trie *addTrie(char *name, Trie **triepp) - - Insert the name in the trie specified by triepp, if it - doesn't already exist there. - Return pointer to leaf node associated with name. -*/ -Trie * -addTrie(char *name, Trie **triepp) -{ - Trie *curp; - if (*name == NUL) { - /* End of name, see if name already exists. */ - if (*triepp == TRIE_NULL) { - /* Name does not exist, make leaf node. */ - NewTrie(*triepp); - (*triepp)->l.t_altr = (*triepp)->l.t_next - = TRIE_NULL; - (*triepp)->l.t_func = NULL_FUNC; - } else - if ((*triepp)->n.t_next != TRIE_NULL) - /* Name is subset of another name. */ - return addTrie(name, &(*triepp)->n.t_altr); - /* else -- Name already inserted, so do nothing. */ - return *triepp; - } - /* Find matching letter, this level. */ - for (curp = *triepp; - curp != TRIE_NULL && *name != curp->n.t_char; - curp = curp->n.t_altr - ) - ; - if (curp == TRIE_NULL) { - /* No Match, this level, so create new alternate. */ - curp = *triepp; - NewTrie(*triepp); - (*triepp)->n.t_altr = curp; - (*triepp)->n.t_char = *name; - (*triepp)->n.t_next = TRIE_NULL; - return addTrie(++name, &(*triepp)->n.t_next); - } else - /* Found matching character. */ - return addTrie(++name, &curp->n.t_next); -} - - -Func * -getTrie(char *name, int buflen, Trie *triep) -{ - int orig_buflen = buflen; - Trie *curp = NULL; - - if (triep == TRIE_NULL) - return NULL_FUNC; - - /* Traverse next links to end of region name. */ - for (; triep != TRIE_NULL; triep = triep->n.t_next) { - curp = triep; - if (*name == NUL) { - /* End of user-typed name. */ - if (triep->n.t_altr != TRIE_NULL) { - /* Ambiguous at this point. */ - return NULL_FUNC; - } else { - if (buflen > 1) { - /* Complete next character. */ - *name++ = triep->n.t_char; - buflen--; - *name = NUL; - } - } - } else { - if (*name == '*') { - return matchTrie(triep); - } else { /* Not at end of user-typed name yet, traverse - alternate list to find current letter. - */ - for (; - triep != TRIE_NULL - && *name != triep->n.t_char; - triep = triep->n.t_altr - ) - ; - if (triep == TRIE_NULL) { - /* Non-existent name, truncate bad part. */ - if (buflen > 0) - *name = NUL; - return NULL_FUNC; - } else { - name++; - buflen--; - } - } - } - } - /* Clobber key-stroke, and return it. */ - if (buflen > 0 && orig_buflen != buflen) { - --name; - *name = NUL; - buflen++; - } - if (curp == TRIE_NULL) { - bu_exit(BRLCAD_ERROR, "curp == TRIE_NULL, trie.c line %d\n", __LINE__); - } - return curp->l.t_func; -} - - -#define MAX_TRIE_LEVEL (32*16) - -static Func * -matchTrie(Trie *triep) -{ - Func *func; - if (triep == TRIE_NULL) - func = NULL_FUNC; - else - if (triep->n.t_altr != TRIE_NULL) - func = NULL_FUNC; /* Ambiguous root, no match. */ - else - if (triep->n.t_next == TRIE_NULL) - func = triep->l.t_func; /* At leaf node, return datum. */ - else /* Keep going to leaf. */ - func = matchTrie(triep->n.t_next); - return func; -} - - -void -prntTrie(Trie *triep, int level) -{ - Trie *tp = triep; - static char name_buf[MAX_TRIE_LEVEL+1]; - static char *namep = NULL; - - if (tp == TRIE_NULL) - return; - if (tp->n.t_altr != TRIE_NULL) - prntTrie(tp->n.t_altr, level); - if (level == 0) - namep = name_buf; - if (namep) - *namep = tp->n.t_char; - if (tp->n.t_next == TRIE_NULL) { - /* At end of name, so print it out. */ - if (namep) - *namep = NUL; - brst_log("%s\n", name_buf); - } else { - if (namep) - namep++; - prntTrie(tp->n.t_next, level+1); - if (namep) - namep--; - } - return; -} - - -int -writeTrie(Trie *triep, int level, FILE *fp) -{ - Trie *tp = triep; - static char name_buf[MAX_TRIE_LEVEL+1], *namep = NULL; - if (tp == TRIE_NULL) - return 1; - if (tp->n.t_altr != TRIE_NULL) - (void) writeTrie(tp->n.t_altr, level, fp); - if (level == 0) - namep = name_buf; - if (!namep) - return 1; - *namep = tp->n.t_char; - if (tp->n.t_next == TRIE_NULL) { - /* At end of name, so print it out. */ - *namep = NUL; - (void) fprintf(fp, "%s\n", name_buf); - } else { - namep++; - (void) writeTrie(tp->n.t_next, level+1, fp); - namep--; - } - return 1; -} - - -int -readTrie(FILE *fp, Trie **triepp) -{ - static char name_buf[MAX_TRIE_LEVEL+1]; - while (bu_fgets(name_buf, MAX_TRIE_LEVEL, fp) != NULL) { - name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line. */ - (void) addTrie(name_buf, triepp); - } - return 1; -} - - -void -ring_Bell() -{ - (void) putchar(BEL); - return; -} - - -char * -char_To_String(int i) -{ - static char buf[4]; - if (i >= SP && i < DEL) { - buf[0] = i; - buf[1] = NUL; - } else - if (i >= NUL && i < SP) { - buf[0] = '^'; - buf[1] = i + 64; - buf[2] = NUL; - } else - if (i == DEL) - return "DL"; - else - return "EOF"; - return buf; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/burst/ui.c b/src/burst/ui.c deleted file mode 100644 index 7fb9da27780..00000000000 --- a/src/burst/ui.c +++ /dev/null @@ -1,1608 +0,0 @@ -/* U I . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - * - */ -/** @file burst/ui.c - * - */ - - -#include "common.h" - -#include -#include -#include -#include - -#include "bio.h" - -#include "vmath.h" -#include "raytrace.h" - -#include "./Sc.h" -#include "./Mm.h" -#include "./burst.h" -#include "./extern.h" -#include "./ascii.h" - - -#define DEBUG_UI 0 - - -#if defined(__GNUC__) && __GNUC__ >= 7 && !defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma GCC diagnostic ignored "-Wformat-truncation" -#endif - - -static char promptbuf[LNBUFSZ]; - -#define AddCmd(nm, f) \ - { \ - Trie *p; \ - if ((p = addTrie(nm, &cmdtrie)) == TRIE_NULL) \ - prntScr("BUG: addTrie(%s) returned NULL.", nm); \ - else \ - p->l.t_func = f; \ - } - -#define GetBool(var, ptr) \ - if (getInput(ptr)) { \ - if (ptr->buffer[0] == 'y') \ - var = 1; \ - else \ - if (ptr->buffer[0] == 'n') \ - var = 0; \ - else { \ - (void) snprintf(scrbuf, LNBUFSZ, "Illegal input \"%s\".", ptr->buffer); \ - warning(scrbuf); \ - return; \ - } \ - (ptr)++; \ - } - -#define GetVar(var, ptr, conv)\ - {\ - if (! batchmode) {\ - (void) snprintf((ptr)->buffer, LNBUFSZ, (ptr)->fmt, var*conv);\ - (void) getInput(ptr);\ - if ((sscanf((ptr)->buffer, (ptr)->fmt, &(var))) != 1) {\ - bu_strlcpy((ptr)->buffer, "", LNBUFSZ);\ - return;\ - }\ - (ptr)++;\ - } else {\ - char *tokptr = strtok(cmdptr, WHITESPACE);\ - if (tokptr == NULL || sscanf(tokptr, (ptr)->fmt, &(var)) != 1) {\ - brst_log("ERROR -- command syntax:\n");\ - brst_log("\t%s\n", cmdbuf);\ - brst_log("\tcommand (%s): argument (%s) is of wrong type, %s expected.\n", \ - cmdptr, tokptr == NULL ? "(null)" : tokptr, \ - (ptr)->fmt);\ - }\ - cmdptr = NULL;\ - }\ - } - -typedef struct { - char *prompt; - char buffer[LNBUFSZ]; - char *fmt; - char *range; -} Input; - -/* local menu functions, names all start with M */ -static void MattackDir(); -static void MautoBurst(); -static void MburstArmor(); -static void MburstAir(); -static void MburstDist(); -static void MburstFile(); -static void McellSize(); -static void McolorFile(); -static void Mcomment(); -static void MconeHalfAngle(); -static void McritComp(); -static void MdeflectSpallCone(); -static void Mdither(); -static void MenclosePortion(); -static void MencloseTarget(); -static void MerrorFile(); -static void Mexecute(); -static void MfbFile(); -static void MgedFile(); -static void MgridFile(); -static void MgroundPlane(); -static void MhistFile(); -static void Minput2dShot(); -static void Minput3dShot(); -static void MinputBurst(); -static void MmaxBarriers(); -static void MmaxSpallRays(); -static void Mnop(); -static void Mobjects(); -static void Moverlaps(); -static void MplotFile(); -static void Mread2dShotFile(); -static void Mread3dShotFile(); -static void MreadBurstFile(); -static void MreadCmdFile(); -static void MshotlineFile(); -static void Munits(); -static void MwriteCmdFile(); -static void Mhelp(); -static void Mquit(); - -/* local utility functions */ -static HmMenu *addMenu(); -static int getInput(); -static int unitStrToInt(); -static void addItem(); - -typedef struct ftable Ftable; -struct ftable -{ - char *name; - char *help; - Ftable *next; - Func *func; -}; - - -Ftable shot2dmenu[] = -{ - { "read-2d-shot-file", - "input shotline coordinates from file", - 0, Mread2dShotFile }, - { "input-2d-shot", - "type in shotline coordinates", - 0, Minput2dShot }, - { "execute", "begin ray tracing", 0, Mexecute }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable shot3dmenu[] = -{ - { "read-3d-shot-file", - "input shotline coordinates from file", - 0, Mread3dShotFile }, - { "input-3d-shot", - "type in shotline coordinates", - 0, Minput3dShot }, - { "execute", "begin ray tracing", 0, Mexecute }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable shotcoordmenu[] = -{ - { "target coordinate system", - "specify shotline location in model coordinates (3-d)", - shot3dmenu, 0 }, - { "shotline coordinate system", - "specify shotline location in attack coordinates (2-d)", - shot2dmenu, 0 }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable gridmenu[] = -{ - { "enclose-target", - "generate a grid which covers the entire target", - 0, MencloseTarget }, - { "enclose-portion", - "generate a grid which covers a portion of the target", - 0, MenclosePortion }, - { "execute", "begin ray tracing", 0, Mexecute }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable locoptmenu[] = -{ - { "envelope", - "generate a grid of shotlines", gridmenu, 0 }, - { "discrete shots", - "specify each shotline by coordinates", shotcoordmenu, 0 }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable burstcoordmenu[] = -{ - { "read-burst-file", - "input burst coordinates from file", - 0, MreadBurstFile }, - { "burst-coordinates", - "specify each burst point in target coordinates (3-d)", - 0, MinputBurst }, - { "execute", "begin ray tracing", 0, Mexecute }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable burstoptmenu[] = -{ - { "burst-distance", - "fuzing distance to burst point from impact", - 0, MburstDist }, - { "cone-half-angle", - "degrees from spall cone axis to limit burst rays", - 0, MconeHalfAngle }, - { "deflect-spall-cone", - "spall cone axis perturbed halfway to normal direction", - 0, MdeflectSpallCone }, - { "max-spall-rays", - "maximum rays generated per burst point (ray density)", - 0, MmaxSpallRays }, - { "max-barriers", - "maximum number of shielding components along spall ray", - 0, MmaxBarriers }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable burstlocmenu[] = -{ - { "burst point coordinates", - "input explicit burst points in 3-d target coordinates", - burstcoordmenu, 0 }, - { "ground-plane", - "burst on impact with ground plane", - 0, MgroundPlane }, - { "shotline-burst", - "burst along shotline on impact with critical components", - 0, MautoBurst }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable burstmenu[] = -{ - { "bursting method", - "choose method of creating burst points", - burstlocmenu, 0 }, - { "bursting parameters", - "configure spall cone generation options", - burstoptmenu, 0 }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable shotlnmenu[] = -{ - { "attack-direction", - "shotline orientation WRT target", 0, MattackDir }, - { "cell-size", - "shotline separation or coverage (1-D)", 0, McellSize }, - { "dither-cells", - "randomize location of shotline within grid cell", - 0, Mdither }, - { "shotline location", - "positioning of shotlines", locoptmenu, 0 }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable targetmenu[] = -{ - { "target-file", - "MGED data base file name", 0, MgedFile }, - { "target-objects", - "objects to read from MGED file", 0, Mobjects }, - { "burst-air-file", - "file containing space codes for triggering burst points", - 0, MburstAir }, - { "burst-armor-file", - "file containing armor codes for triggering burst points", - 0, MburstArmor }, - { "critical-comp-file", "file containing critical component codes", - 0, McritComp }, - { "color-file", "file containing component ident to color mappings", - 0, McolorFile }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable prefmenu[] = -{ - { "report-overlaps", - "enable or disable the reporting of overlaps", - 0, Moverlaps }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable filemenu[] = -{ - { "read-input-file", - "read commands from a file", 0, MreadCmdFile }, - { "shotline-file", - "name shotline output file", 0, MshotlineFile }, - { "burst-file", - "name burst point output file", 0, MburstFile }, - { "error-file", - "redirect error diagnostics to file", 0, MerrorFile }, - { "histogram-file", - "name file for graphing hits on critical components", - 0, MhistFile }, - { "grid-file", - "name file for storing grid points", - 0, MgridFile }, - { "image-file", - "name frame buffer device", 0, MfbFile }, - { "plot-file", - "name UNIX plot output file", 0, MplotFile }, - { "write-input-file", - "save input up to this point in a session file", - 0, MwriteCmdFile }, - { NULL, NULL, 0, NULL }, -}; - - -Ftable mainmenu[] = -{ - { "units", - "units for input and output interpretation", 0, Munits }, - { "project files", - "set up input/output files for this analysis", - filemenu, 0 }, - { "target files", - "identify target-specific input files", targetmenu, 0 }, - { "shotlines", - "shotline generation (grid specification)", shotlnmenu, 0 }, - { "burst points", - "burst point generation", burstmenu, 0 }, - { CMD_COMMENT, "add a comment to the session file", 0, Mcomment }, - { "execute", "begin ray tracing", 0, Mexecute }, - { "preferences", - "options for tailoring behavior of user interface", - prefmenu, 0 }, - { "help", - "get a list of available commands", 0, Mhelp }, - { "quit", - "stop reading commands, exit the application", 0, Mquit }, - { NULL, NULL, 0, NULL }, -}; - - -static void -addItem(Ftable *tp, HmItem *itemp) -{ - itemp->text = tp->name; - itemp->help = tp->help; - itemp->next = addMenu(tp->next); - itemp->dfn = 0; - itemp->bfn = 0; - itemp->hfn = tp->func; - return; -} - - -static HmMenu * -addMenu(Ftable *tp) -{ - HmMenu *menup; - HmItem *itemp; - Ftable *ftp = tp; - int cnt; - int done = 0; - if (ftp == NULL) - return NULL; - for (cnt = 0; ftp->name != NULL; ftp++) - cnt++; - cnt++; /* Must include space for NULL entry. */ - menup = MmAllo(HmMenu); - menup->item = MmVAllo(cnt, HmItem); - menup->generator = 0; - menup->prevtop = 0; - menup->prevhit = 0; - menup->sticky = 1; - /* menup->item should now be as long as tp. */ - for (ftp = tp, itemp = menup->item; - ! done; - ftp++, itemp++ - ) { - addItem(ftp, itemp); - if (ftp->name == NULL) /* Must include NULL entry. */ - done = 1; - } - return menup; -} - -void -closeUi() -{ - ScMvCursor(1, ScLI); - return; -} - - -static int -getInput(Input *ip) -{ - if (! batchmode) { - int c; - char *p; - char *defaultp = ip->buffer; - if (*defaultp == NUL) - defaultp = "no default"; - if (ip->range != NULL) - (void) snprintf(promptbuf, LNBUFSZ, "%s ? (%s)[%s] ", - ip->prompt, ip->range, defaultp); - else - (void) snprintf(promptbuf, LNBUFSZ, "%s ? [%s] ", - ip->prompt, defaultp); - prompt(promptbuf); - for (p = ip->buffer; (c = HmGetchar()) != '\n';) - if (p - ip->buffer < LNBUFSZ-1) - *p++ = c; - /* In case user hit CR only, do not disturb buffer. */ - if (p != ip->buffer) - *p = '\0'; - prompt((char *) NULL); - } else { - char *str = strtok(cmdptr, WHITESPACE); - if (str == NULL) - return 0; - bu_strlcpy(ip->buffer, str, LNBUFSZ); - cmdptr = NULL; - } - return 1; -} - - -/* - void initCmds(void) - - Initialize the keyword commands. -*/ -static void -initCmds(Ftable *tp) -{ - for (; tp->name != NULL; tp++) { - if (tp->next != NULL) - initCmds(tp->next); - else - AddCmd(tp->name, tp->func); - } - return; -} - - -/* - void initMenus(void) - - Initialize the hierarchical menus. -*/ -static void -initMenus(Ftable *tp) -{ - mainhmenu = addMenu(tp); - return; -} - - -int -initUi() -{ - initMenus(mainmenu); - initCmds(mainmenu); - return 1; -} - - -static int -unitStrToInt(char *str) -{ - if (BU_STR_EQUAL(str, UNITS_INCHES)) - return U_INCHES; - if (BU_STR_EQUAL(str, UNITS_FEET)) - return U_FEET; - if (BU_STR_EQUAL(str, UNITS_MILLIMETERS)) - return U_MILLIMETERS; - if (BU_STR_EQUAL(str, UNITS_CENTIMETERS)) - return U_CENTIMETERS; - if (BU_STR_EQUAL(str, UNITS_METERS)) - return U_METERS; - return U_BAD; -} - - -/*ARGSUSED*/ -static void -MattackDir(HmItem *itemp) -{ - static Input input[] = { - { "Attack azimuth", "", "%lf", "degrees" }, - { "Attack elevation", "", "%lf", "degrees" }, - }; - Input *ip = input; - GetVar(viewazim, ip, RAD2DEG); - GetVar(viewelev, ip, RAD2DEG); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%g %g", - itemp != NULL ? itemp->text : cmdname, - viewazim, viewelev); - logCmd(scrbuf); - viewazim /= RAD2DEG; - viewelev /= RAD2DEG; - return; -} - - -/*ARGSUSED*/ -static void -MautoBurst(HmItem *itemp) -{ - static Input input[] = { - { "Burst along shotline", "n", "%d", "y or n" }, - { "Require burst air", "y", "%d", "y or n" } - }; - Input *ip = input; - GetBool(shotburst, ip); - if (shotburst) { - GetBool(reqburstair, ip); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s %s", - itemp != NULL ? itemp->text : cmdname, - shotburst ? "yes" : "no", - reqburstair ? "yes" : "no"); - } else - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - shotburst ? "yes" : "no"); - logCmd(scrbuf); - - if (shotburst) - firemode &= ~FM_BURST; /* disable discrete burst points */ - return; -} - - -/*ARGSUSED*/ -static void -MburstAir(HmItem *itemp) -{ - static Input input[] = { - { "Name of burst air file", "", "%s", 0 }, - }; - Input *ip = input; - FILE *airfp; - if (getInput(ip)) - bu_strlcpy(airfile, ip->buffer, LNBUFSZ); - else - airfile[0] = NUL; - if ((airfp = fopen(airfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - airfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - airfile); - logCmd(scrbuf); - notify("Reading burst air idents", NOTIFY_APPEND); - readIdents(&airids, airfp); - (void) fclose(airfp); - notify(NULL, NOTIFY_DELETE); - return; -} - - -/*ARGSUSED*/ -static void -MburstArmor(HmItem *itemp) -{ - static Input input[] = { - { "Name of burst armor file", "", "%s", 0 }, - }; - Input *ip = input; - FILE *armorfp; - if (getInput(ip)) - bu_strlcpy(armorfile, ip->buffer, LNBUFSZ); - else - armorfile[0] = NUL; - if ((armorfp = fopen(armorfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - armorfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%s", - itemp != NULL ? itemp->text : cmdname, - armorfile); - logCmd(scrbuf); - notify("Reading burst armor idents", NOTIFY_APPEND); - readIdents(&armorids, armorfp); - (void) fclose(armorfp); - notify(NULL, NOTIFY_DELETE); - return; -} - - -/*ARGSUSED*/ -static void -MburstDist(HmItem *itemp) -{ - static Input input[] = { - { "Burst distance", "", "%lf", 0 }, - }; - Input *ip = input; - GetVar(bdist, ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%g", - itemp != NULL ? itemp->text : cmdname, - bdist); - logCmd(scrbuf); - bdist /= unitconv; /* convert to millimeters */ - return; -} - - -/*ARGSUSED*/ -static void -MburstFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of burst output file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(outfile, ip->buffer, LNBUFSZ); - else - outfile[0] = NUL; - if ((outfp = fopen(outfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - outfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - outfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -McellSize(HmItem *itemp) -{ - static Input input[] = { - { "Cell size", "", "%lf", 0 } - }; - Input *ip = input; - GetVar(cellsz, ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%g", - itemp != NULL ? itemp->text : cmdname, - cellsz); - logCmd(scrbuf); - cellsz /= unitconv; /* convert to millimeters */ - return; -} - - -/*ARGSUSED*/ -static void -McolorFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of ident-to-color mapping file", - "", "%s", 0 }, - }; - Input *ip = input; - FILE *colorfp; - - if (getInput(ip)) - bu_strlcpy(colorfile, ip->buffer, LNBUFSZ); - else - colorfile[0] = NUL; - if ((colorfp = fopen(colorfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - colorfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - colorfile); - logCmd(scrbuf); - notify("Reading ident-to-color mappings", NOTIFY_APPEND); - readColors(&colorids, colorfp); - fclose(colorfp); - notify(NULL, NOTIFY_DELETE); - return; -} - - -/*ARGSUSED*/ -static void -Mcomment(HmItem *UNUSED(itemp)) -{ - static Input input[] = { - { "Comment", " ", "%s", 0 }, - }; - Input *ip = input; - if (! batchmode) { - if (getInput(ip)) { - (void) snprintf(scrbuf, LNBUFSZ, "%c%s", - CHAR_COMMENT, ip->buffer); - logCmd(scrbuf); - bu_strlcpy(ip->buffer, " ", LNBUFSZ); /* restore default */ - } - } else - logCmd(cmdptr); - return; -} - - -/*ARGSUSED*/ -static void -Mhelp(HmItem *UNUSED(itemp)) -{ - brst_log("\nAvailable Commands" - "\n------------------\n"); - prntTrie(cmdtrie, 0); -} - - -/*ARGSUSED*/ -static void -Mquit(HmItem *UNUSED(itemp)) -{ - bu_exit(EXIT_SUCCESS, "Quitting application.\n"); -} - - -/*ARGSUSED*/ -static void -MconeHalfAngle(HmItem *itemp) -{ - static Input input[] = { - { "Cone angle", "", "%lf", "degrees" }, - }; - Input *ip = input; - GetVar(conehfangle, ip, RAD2DEG); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%g", - itemp != NULL ? itemp->text : cmdname, - conehfangle); - logCmd(scrbuf); - conehfangle /= RAD2DEG; - return; -} - - -/*ARGSUSED*/ -static void -McritComp(HmItem *itemp) -{ - static Input input[] = { - { "Name of critical component file", "", "%s", 0 }, - }; - Input *ip = input; - FILE *critfp; - if (getInput(ip)) - bu_strlcpy(critfile, ip->buffer, LNBUFSZ); - else - critfile[0] = NUL; - if ((critfp = fopen(critfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - critfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%s", - itemp != NULL ? itemp->text : cmdname, - critfile); - logCmd(scrbuf); - notify("Reading critical component idents", NOTIFY_APPEND); - readIdents(&critids, critfp); - (void) fclose(critfp); - notify(NULL, NOTIFY_DELETE); - return; -} - - -/*ARGSUSED*/ -static void -MdeflectSpallCone(HmItem *itemp) -{ - static Input input[] = { - { "Deflect cone", "n", "%d", "y or n" }, - }; - Input *ip = input; - GetBool(deflectcone, ip); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%s", - itemp != NULL ? itemp->text : cmdname, - deflectcone ? "yes" : "no"); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -Mdither(HmItem *itemp) -{ - static Input input[] = { - { "Dither cells", "n", "%d", "y or n" }, - }; - Input *ip = input; - GetBool(dithercells, ip); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - dithercells ? "yes" : "no"); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MenclosePortion(HmItem *itemp) -{ - static Input input[] = { - { "Left border of grid", "", "%lf", 0 }, - { "Right border of grid", "", "%lf", 0 }, - { "Bottom border of grid", "", "%lf", 0 }, - { "Top border of grid", "", "%lf", 0 }, - }; - Input *ip = input; - GetVar(gridlf, ip, unitconv); - GetVar(gridrt, ip, unitconv); - GetVar(griddn, ip, unitconv); - GetVar(gridup, ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, - "%s\t\t%g %g %g %g", - itemp != NULL ? itemp->text : cmdname, - gridlf, gridrt, griddn, gridup); - logCmd(scrbuf); - gridlf /= unitconv; /* convert to millimeters */ - gridrt /= unitconv; - griddn /= unitconv; - gridup /= unitconv; - firemode = FM_PART; - return; -} - - -/*ARGSUSED*/ -static void -MencloseTarget(HmItem *itemp) -{ - (void) snprintf(scrbuf, LNBUFSZ, - "%s", - itemp != NULL ? itemp->text : cmdname); - logCmd(scrbuf); - firemode = FM_GRID; - return; -} - - -static void -MerrorFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of error output file", "", "%s", 0 }, - }; - Input *ip = input; - static int errfd = -1; - - if (getInput(ip)) { - bu_strlcpy(errfile, ip->buffer, LNBUFSZ); - /* ensure that error log is truncated */ - errfd = open(errfile, O_BINARY|O_TRUNC|O_CREAT|O_WRONLY, 0644); - } else { - errfd = 2; /* write to stderr */ - } - - if (errfd == -1) { - locPerror(errfile); - return; - } - /* TODO: we need a copy of stderr on non-termlib platforms or this doesn't - * work. Note: is this still true after termlib support removal?? */ - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - errfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -Mexecute(HmItem *itemp) -{ - static int gottree = 0; - int loaderror = 0; - (void) snprintf(scrbuf, LNBUFSZ, - "%s", - itemp != NULL ? itemp->text : cmdname); - logCmd(scrbuf); - if (gedfile[0] == NUL) { - warning("No target file has been specified."); - return; - } - notify("Reading target data base", NOTIFY_APPEND); - rt_prep_timer(); - if (rtip == RTI_NULL - && (rtip = rt_dirbuild(gedfile, title, TITLE_LEN)) - == RTI_NULL) { - warning("Ray tracer failed to read the target file."); - return; - } - prntTimer("dir"); - notify(NULL, NOTIFY_DELETE); - /* Add air into int trees, must be set after rt_dirbuild() and - before rt_gettree(). - */ - rtip->useair = 1; - if (! gottree) { - char *ptr, *obj; - rt_prep_timer(); - for (ptr = objects; - (obj = strtok(ptr, WHITESPACE)) != NULL; - ptr = NULL - ) { - (void) snprintf(scrbuf, LNBUFSZ, "Loading \"%s\"", obj); - notify(scrbuf, NOTIFY_APPEND); - if (rt_gettree(rtip, obj) != 0) { - (void) snprintf(scrbuf, LNBUFSZ, - "Bad object \"%s\".", - obj); - warning(scrbuf); - loaderror = 1; - } - notify(NULL, NOTIFY_DELETE); - } - gottree = 1; - prntTimer("load"); - } - if (loaderror) - return; - if (rtip->needprep) { - notify("Prepping solids", NOTIFY_APPEND); - rt_prep_timer(); - rt_prep(rtip); - prntTimer("prep"); - notify(NULL, NOTIFY_DELETE); - } - gridInit(); - if (nriplevels > 0) - spallInit(); - (void) signal(SIGINT, abort_sig); - gridModel(); - (void) signal(SIGINT, norml_sig); - return; -} - - -/*ARGSUSED*/ -static void -MfbFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of frame buffer device", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(fbfile, ip->buffer, LNBUFSZ); - else - fbfile[0] = NUL; - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - fbfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MgedFile(HmItem *itemp) -{ - static Input input[] = { { "Name of target (MGED) file", "", "%s", 0 }, - }; - Input *ip = input; - - if (getInput(ip)) - bu_strlcpy(gedfile, ip->buffer, LNBUFSZ); - - if (!bu_file_exists(gedfile, NULL)) { - (void) snprintf(scrbuf, LNBUFSZ, - "Unable to find file \"%s\"", - gedfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - gedfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MgridFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of grid file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(gridfile, ip->buffer, LNBUFSZ); - else - histfile[0] = NUL; - if ((gridfp = fopen(gridfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - gridfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - gridfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MgroundPlane(HmItem *itemp) -{ - static Input input[] = { - { "Activate ground plane bursting", - "n", "%d", "y or n" }, - { "Distance of target origin above ground plane", - "", "%lf", 0 }, - { "Distance out positive X-axis of target to edge", - "", "%lf", 0 }, - { "Distance out negative X-axis of target to edge", - "", "%lf", 0 }, - { "Distance out positive Y-axis of target to edge", - "", "%lf", 0 }, - { "Distance out negative Y-axis of target to edge", - "", "%lf", 0 }, - }; - Input *ip = input; - GetBool(groundburst, ip); - if (groundburst) { - GetVar(grndht, ip, unitconv); - GetVar(grndfr, ip, unitconv); - GetVar(grndbk, ip, unitconv); - GetVar(grndlf, ip, unitconv); - GetVar(grndrt, ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\tyes %g %g %g %g %g", - itemp != NULL ? itemp->text : cmdname, - grndht, grndfr, grndbk, grndlf, grndrt); - grndht /= unitconv; /* convert to millimeters */ - grndfr /= unitconv; - grndbk /= unitconv; - grndlf /= unitconv; - grndrt /= unitconv; - } else - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\tno", - itemp != NULL ? itemp->text : cmdname - ); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MhistFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of histogram file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(histfile, ip->buffer, LNBUFSZ); - else - histfile[0] = NUL; - if ((histfp = fopen(histfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - histfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - histfile); - logCmd(scrbuf); - return; -} - - -static void -MinputBurst(HmItem *itemp) -{ - static Input input[] = { - { "X-coordinate of burst point", "", "%lf", 0 }, - { "Y-coordinate of burst point", "", "%lf", 0 }, - { "Z-coordinate of burst point", "", "%lf", 0 }, - }; - Input *ip = input; - GetVar(burstpoint[X], ip, unitconv); - GetVar(burstpoint[Y], ip, unitconv); - GetVar(burstpoint[Z], ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%g %g %g", - itemp != NULL ? itemp->text : cmdname, - burstpoint[X], burstpoint[Y], burstpoint[Z]); - logCmd(scrbuf); - burstpoint[X] /= unitconv; /* convert to millimeters */ - burstpoint[Y] /= unitconv; - burstpoint[Z] /= unitconv; - firemode = FM_BURST | FM_3DIM; - return; -} - - -/*ARGSUSED*/ -static void -Minput2dShot(HmItem *itemp) -{ - static Input input[] = { - { "Y'-coordinate of shotline", "", "%lf", 0 }, - { "Z'-coordinate of shotline", "", "%lf", 0 }, - }; - Input *ip = input; - GetVar(fire[X], ip, unitconv); - GetVar(fire[Y], ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%g %g", - itemp != NULL ? itemp->text : cmdname, - fire[X], fire[Y]); - logCmd(scrbuf); - fire[X] /= unitconv; /* convert to millimeters */ - fire[Y] /= unitconv; - firemode = FM_SHOT; - return; -} - - -/*ARGSUSED*/ -static void -Minput3dShot(HmItem *itemp) -{ - static Input input[] = { - { "X-coordinate of shotline", "", "%lf", 0 }, - { "Y-coordinate of shotline", "", "%lf", 0 }, - { "Z-coordinate of shotline", "", "%lf", 0 }, - }; - Input *ip = input; - GetVar(fire[X], ip, unitconv); - GetVar(fire[Y], ip, unitconv); - GetVar(fire[Z], ip, unitconv); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%g %g %g", - itemp != NULL ? itemp->text : cmdname, - fire[X], fire[Y], fire[Z]); - logCmd(scrbuf); - fire[X] /= unitconv; /* convert to millimeters */ - fire[Y] /= unitconv; - fire[Z] /= unitconv; - firemode = FM_SHOT | FM_3DIM; - return; -} - - -/*ARGSUSED*/ -static void -Mnop(HmItem *UNUSED(itemp)) -{ - return; -} - - -/*ARGSUSED*/ -static void -Mobjects(HmItem *itemp) -{ - static Input input[] = { - { "List of objects from target file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(objects, ip->buffer, LNBUFSZ); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - objects); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -Moverlaps(HmItem *itemp) -{ - static Input input[] = { - { "Report overlaps", "y", "%d", "y or n" }, - }; - Input *ip = input; - GetBool(reportoverlaps, ip); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - reportoverlaps ? "yes" : "no"); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MmaxBarriers(HmItem *itemp) -{ - static Input input[] = { - { "Maximum spall barriers per ray", "", "%d", 0 }, - }; - Input *ip = input; - GetVar(nbarriers, ip, 1); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%d", - itemp != NULL ? itemp->text : cmdname, - nbarriers); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MmaxSpallRays(HmItem *itemp) -{ - static Input input[] = { - { "Maximum rays per burst", "", "%d", 0 }, - }; - Input *ip = input; - GetVar(nspallrays, ip, 1); - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%d", - itemp != NULL ? itemp->text : cmdname, - nspallrays); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MplotFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of UNIX plot file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(plotfile, ip->buffer, LNBUFSZ); - else - plotfile[0] = NUL; - if ((plotfp = fopen(plotfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - plotfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - plotfile); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -Mread2dShotFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of 2-D shot input file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(shotfile, ip->buffer, LNBUFSZ); - if ((shotfp = fopen(shotfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - shotfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%s", - itemp != NULL ? itemp->text : cmdname, - shotfile); - logCmd(scrbuf); - firemode = FM_SHOT | FM_FILE; - return; -} - - -/*ARGSUSED*/ -static void -Mread3dShotFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of 3-D shot input file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(shotfile, ip->buffer, LNBUFSZ); - if ((shotfp = fopen(shotfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - shotfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t%s", - itemp != NULL ? itemp->text : cmdname, - shotfile); - logCmd(scrbuf); - firemode = FM_SHOT | FM_FILE | FM_3DIM; - return; -} - - -/*ARGSUSED*/ -static void -MreadBurstFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of 3-D burst input file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(burstfile, ip->buffer, LNBUFSZ); - if ((burstfp = fopen(burstfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - burstfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - burstfile); - logCmd(scrbuf); - firemode = FM_BURST | FM_3DIM | FM_FILE; - return; -} - - -/*ARGSUSED*/ -static void -MreadCmdFile(HmItem *UNUSED(itemp)) -{ - static Input input[] = { - { "Name of command file", "", "%s", 0 }, - }; - Input *ip = input; - char cmdfile[LNBUFSZ]; - FILE *cmdfp; - if (getInput(ip)) { - bu_strlcpy(cmdfile, ip->buffer, LNBUFSZ); - if ((cmdfp = fopen(cmdfile, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - cmdfile); - warning(scrbuf); - return; - } - readBatchInput(cmdfp); - (void) fclose(cmdfp); - } - return; -} - - -/*ARGSUSED*/ -static void -MshotlineFile(HmItem *itemp) -{ - static Input input[] = { - { "Name of shotline output file", "", "%s", 0 }, - }; - Input *ip = input; - if (getInput(ip)) - bu_strlcpy(shotlnfile, ip->buffer, LNBUFSZ); - else - shotlnfile[0] = NUL; - if ((shotlnfp = fopen(shotlnfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - shotlnfile); - warning(scrbuf); - return; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t%s", - itemp != NULL ? itemp->text : cmdname, - shotlnfile); - logCmd(scrbuf); - return; -} - - -HmItem units_items[] = -{ - { - UNITS_MILLIMETERS, - "interpret inputs and convert outputs to millimeters", - NULL, NULL, NULL, Mnop, 0 }, - { - UNITS_CENTIMETERS, - "interpret inputs and convert outputs to centimeters", - NULL, NULL, NULL, Mnop, 0 }, - { - UNITS_METERS, - "interpret inputs and convert outputs to meters", - NULL, NULL, NULL, Mnop, 0 }, - { - UNITS_INCHES, - "interpret inputs and convert outputs to inches", - NULL, NULL, NULL, Mnop, 0 }, - { - UNITS_FEET, - "interpret inputs and convert outputs to feet", - NULL, NULL, NULL, Mnop, 0 }, - { NULL, NULL, NULL, NULL, NULL, NULL, 0 }, -}; -HmMenu units_hmenu = { units_items, 0, 0, 0, 0 }; - -/*ARGSUSED*/ -static void -Munits(HmItem *itemp) -{ - char *unitstr; - HmItem *itemptr; - if (itemp != NULL) { - if ((itemptr = HmHit(&units_hmenu)) == (HmItem *) NULL) - return; - unitstr = itemptr->text; - } else - unitstr = strtok(cmdptr, WHITESPACE); - units = unitStrToInt(unitstr); - if (units == U_BAD) { - (void) snprintf(scrbuf, LNBUFSZ, "Illegal units \"%s\"", unitstr); - warning(scrbuf); - return; - } - switch (units) { - case U_INCHES : - unitconv = 3.937008e-02; - break; - case U_FEET : - unitconv = 3.280840e-03; - break; - case U_MILLIMETERS : - unitconv = 1.0; - break; - case U_CENTIMETERS : - unitconv = 1.0e-01; - break; - case U_METERS : - unitconv = 1.0e-03; - break; - } - (void) snprintf(scrbuf, LNBUFSZ, "%s\t\t\t%s", - itemp != NULL ? itemp->text : cmdname, - unitstr); - logCmd(scrbuf); - return; -} - - -/*ARGSUSED*/ -static void -MwriteCmdFile(HmItem *UNUSED(itemp)) -{ - static Input input[] = { - { "Name of command file", "", "%s", 0 }, - }; - Input *ip = input; - char cmdfile[LNBUFSZ]; - FILE *cmdfp = NULL; - FILE *inpfp = NULL; - if (getInput(ip)) { - bu_strlcpy(cmdfile, ip->buffer, LNBUFSZ); - if ((cmdfp = fopen(cmdfile, "wb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Write access denied for \"%s\"", - cmdfile); - warning(scrbuf); - return; - } - } - - if ((inpfp = fopen(tmpfname, "rb")) == NULL) { - (void) snprintf(scrbuf, LNBUFSZ, - "Read access denied for \"%s\"", - tmpfname); - warning(scrbuf); - if (cmdfp) - (void)fclose(cmdfp); - return; - } - while (bu_fgets(scrbuf, LNBUFSZ, inpfp) != NULL) - fputs(scrbuf, cmdfp); - - if (cmdfp) - (void) fclose(cmdfp); - (void) fclose(inpfp); - - return; -} - - -void -intr_sig(int UNUSED(sig)) -{ - static Input input[] = { - { "Really quit ? ", "n", "%d", "y or n" }, - }; - Input *ip = input; - (void) signal(SIGINT, intr_sig); - if (getInput(ip)) { - if (ip->buffer[0] == 'y') - exitCleanly(SIGINT); - else - if (ip->buffer[0] != 'n') { - (void) snprintf(scrbuf, LNBUFSZ, - "Illegal input \"%s\".", - ip->buffer); - warning(scrbuf); - return; - } - } - return; -} - - -void -logCmd(char *cmd) -{ - prntScr("%s", cmd); /* avoid possible problems with '%' in string */ - if (fprintf(tmpfp, "%s\n", cmd) < 0) { - locPerror("fprintf"); - exitCleanly(1); - } else - (void) fflush(tmpfp); - return; -} - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/bwish/CMakeLists.txt b/src/bwish/CMakeLists.txt index 30111d62ff5..c3d14ad9b86 100644 --- a/src/bwish/CMakeLists.txt +++ b/src/bwish/CMakeLists.txt @@ -5,6 +5,7 @@ if(TARGET libtclcad) ${TERMIO_INCLUDE_DIRS} ${TCLCAD_INCLUDE_DIRS} ${TCL_INCLUDE_PATH} + ${CMAKE_CURRENT_SOURCE_DIR}/../libtermio ) if (TK_INCLUDE_PATH) set(BWISH_INCLUDE_DIRS ${BWISH_INCLUDE_DIRS} ${TK_INCLUDE_PATH}) @@ -14,10 +15,6 @@ if(TARGET libtclcad) set(btclsh_libs libtclcad libbu ${TCL_LIBRARY}) - if(TARGET libtermio) - set(btclsh_libs ${btclsh_libs} libtermio) - endif(TARGET libtermio) - # Define the btclsh target BRLCAD_ADDEXEC(btclsh "main.c;cmd.c;input.c" "${btclsh_libs}") @@ -30,10 +27,6 @@ if(TARGET libtclcad) set(bwish_libs libtclcad libbu ${TCL_LIBRARY} ${TK_LIBRARY} ${IMM32_LIBRARY} ${COMCTL32_LIBRARY}) - if(TARGET libtermio) - set(bwish_libs ${bwish_libs} libtermio) - endif(TARGET libtermio) - BRLCAD_ADDEXEC(bwish "main.c;cmd.c;input.c" "${bwish_libs}" GUI) set_property(TARGET bwish APPEND PROPERTY COMPILE_DEFINITIONS "BWISH=1") set_target_properties(bwish PROPERTIES FOLDER "BRL-CAD Executables") diff --git a/src/bwish/cmd.c b/src/bwish/cmd.c index a2bc34d09a1..a1866abed2d 100644 --- a/src/bwish/cmd.c +++ b/src/bwish/cmd.c @@ -46,7 +46,6 @@ #include "bu/cmd.h" #include "bu/malloc.h" #include "bu/str.h" -#include "libtermio.h" struct bu_cmdhist { struct bu_vls h_command; diff --git a/src/bwish/input.c b/src/bwish/input.c index bda9d4ff497..8ed085022d6 100644 --- a/src/bwish/input.c +++ b/src/bwish/input.c @@ -45,7 +45,10 @@ /* interface headers */ #include "tcl.h" -#include "libtermio.h" + +#ifndef HAVE_WINDOWS_H +# include "libtermio.h" +#endif /* for strict c90 */ #ifndef HAVE_DECL_GETTIMEOFDAY diff --git a/src/bwish/main.c b/src/bwish/main.c index e5705735952..7a3ce1e0fe2 100644 --- a/src/bwish/main.c +++ b/src/bwish/main.c @@ -35,7 +35,10 @@ #include #include "bio.h" -#include "libtermio.h" +#ifndef HAVE_WINDOWS_H +# define LIBTERMIO_IMPLEMENTATION +# include "libtermio.h" +#endif #ifdef HAVE_SYS_SELECT_H # include /* for select */ diff --git a/src/conv/CMakeLists.txt b/src/conv/CMakeLists.txt index ecffeb7c32c..c9315c51998 100644 --- a/src/conv/CMakeLists.txt +++ b/src/conv/CMakeLists.txt @@ -7,7 +7,6 @@ verbose_add_subdirectory("src/conv" 3dm) verbose_add_subdirectory("src/conv" asc) verbose_add_subdirectory("src/conv" gcv) verbose_add_subdirectory("src/conv" step) -verbose_add_subdirectory("src/conv" csg) verbose_add_subdirectory("src/conv" gltf) verbose_add_subdirectory("src/conv" iges) diff --git a/src/conv/csg/CMakeLists.txt b/src/conv/csg/CMakeLists.txt deleted file mode 100644 index d59b4301c3f..00000000000 --- a/src/conv/csg/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -set(CSG_INCLUDE_DIRS - ${GCV_INCLUDE_DIRS} - ${BU_INCLUDE_DIRS} - ) -BRLCAD_INCLUDE_DIRS(CSG_INCLUDE_DIRS) - -# Also want local dirs -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ) - -find_package(LEMON) -PERPLEX_TARGET(csg_scanner csg_scanner.perplex) -LEMON_TARGET(csg_parser csg_parser.lemon) -ADD_PERPLEX_LEMON_DEPENDENCY(csg_scanner csg_parser) - -DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/csg_parser_csg_parser/csg_parser.lemon) - -set(CSG_SRCS - csg.c - ${PERPLEX_csg_scanner_SRC} - ${LEMON_csg_parser_SRC} - ) - -BRLCAD_ADDEXEC(csg "${CSG_SRCS}" "libgcv;libbu" NO_STRICT NO_INSTALL) -set_property(TARGET csg APPEND PROPERTY INCLUDE_DIRECTORIES "${PERPLEX_csg_scanner_INCLUDE_DIR}") -set_property(TARGET csg APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_csg_parser_INCLUDE_DIR}") - - -CMAKEFILES(csg.h csg_parser.lemon csg_scanner.perplex) -CMAKEFILES(CMakeLists.txt) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/src/conv/csg/csg.c b/src/conv/csg/csg.c deleted file mode 100644 index fa8b31d082b..00000000000 --- a/src/conv/csg/csg.c +++ /dev/null @@ -1,97 +0,0 @@ -/* C S G . C - * BRL-CAD - * - * Copyright (c) 2013-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ - -#include "common.h" -#include -#include -#include "csg.h" - - -static void * -parse_alloc(size_t size) -{ - return bu_malloc(size, "parse_alloc"); -} - - -int -main(int argc, char *argv[]) -{ - FILE *inputFile, *outputFile; - void *parser; - int tokenID; - perplex_t scanner; - token_t *tokenData; - app_data_t appData; - - bu_setprogname(argv[0]); - - if (argc != 3) { - fprintf(stderr, "Usage: %s input output\n", argv[0]); - exit(1); - } - - inputFile = fopen(argv[1], "r"); - if (!inputFile) - bu_exit(BRLCAD_ERROR, "ERROR: Unable to open input file\n"); - - outputFile = fopen(argv[2], "w"); - if (!outputFile) - bu_exit(BRLCAD_ERROR, "ERROR: Unable to open output file\n"); - - scanner = perplexFileScanner(inputFile); - perplexSetExtra(scanner, &appData); - appData.outfile = outputFile; - appData.example_text = 0; - bu_vls_init(&appData.description); - bu_vls_init(&appData.tags); - - parser = ParseAlloc(parse_alloc); - - BU_GET(tokenData, token_t); - bu_vls_init(&tokenData->value); - appData.tokenData = tokenData; - - while ((tokenID = yylex(scanner)) != YYEOF) { - Parse(parser, tokenID, tokenData, &appData); - BU_GET(tokenData, token_t); - bu_vls_init(&tokenData->value); - appData.tokenData = tokenData; - } - Parse(parser, 0, tokenData, &appData); - - ParseFree(parser, free); - perplexFree(scanner); - fclose(inputFile); - fclose(outputFile); - - return 0; -} - - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/conv/csg/csg.h b/src/conv/csg/csg.h deleted file mode 100644 index da513d5aff4..00000000000 --- a/src/conv/csg/csg.h +++ /dev/null @@ -1,74 +0,0 @@ -/* C S G . H - * BRL-CAD - * - * Copyright (c) 2013-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ - -#ifndef CONV_CSG_CSG_H -#define CONV_CSG_CSG_H - -#include "common.h" -#include -#include -#include "bu.h" - -typedef struct { - struct bu_vls value; -} token_t; - -/* this structure is the dom2dox app_data_t structure with some - * useless fields deleted - */ -typedef struct { - token_t *tokenData; - FILE *outfile; - int example_text; - struct bu_vls description; - struct bu_vls tags; -} app_data_t; - -/* lemon prototypes */ -void *ParseAlloc(void *(*mallocProc)(size_t)); -void ParseFree(void *parser, void (*freeProc)(void *)); -void Parse(void *yyp, int yymajor, token_t *tokenData, app_data_t *appData); -void ParseTrace(FILE *fp, char *s); - -/* definitions generated by lemon */ -#include "csg_parser.h" - -/* definitions generated by perplex */ -#include "csg_scanner.h" - -/* utils */ -#define END_EXAMPLE \ - if (appData->example_text) { \ - bu_vls_strcat(&appData->description, "\n\\endcode\n\n"); \ - appData->example_text = 0; \ - } - - -#endif /* CONV_CSG_CSG_H */ - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/conv/csg/csg_parser.lemon b/src/conv/csg/csg_parser.lemon deleted file mode 100644 index 2515862481e..00000000000 --- a/src/conv/csg/csg_parser.lemon +++ /dev/null @@ -1,92 +0,0 @@ -/* C S G _ P A R S E R . L E M O N - * BRL-CAD - * - * Copyright (c) 2013-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ - -%include { -#include -#include -#include "csg.h" - -#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) && !defined(__clang__) -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wunused-parameter" - -#endif -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wunused-variable" -# pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -} - -%token_type {token_t *} -%extra_argument {app_data_t *appData} - -%left LCURLY GROUP_END. -%left LSB RSB. -%left LB RB. - -start_symbol ::= code. -code ::= groupb. - -groupb ::= GROUP_BEGIN group_content GROUP_END. -{printf("group() { something }\n");} -group_content ::= groupb. -group_content ::= . -group_content ::= entry group_content. -{printf("entry\n");} - -entry ::= TXT LB params RB LCURLY ceva GROUP_END. -{printf("function_name( parameters ){smth}\n");} -ceva ::= entry. -{printf("{function_name( parameters ){smth}}\n");} -ceva ::= . -{printf("function_name( parameters ){}\n");} - -params ::= param_type params. -{printf("param\n");} -params ::= . -{printf("no param\n");} - -param_type ::= assign. -{printf("param type = assign\n");} -param_type ::= array_of_vectors. -{printf("param type = array_of_vectors\n");} - -assign ::= TXT EQ expr. -{printf("txt = X\n");} - -expr ::= array_of_vectors. -{printf("X from the assign is array_of_vectors\n");} -expr ::= INTEGER. -{printf("X from the assign is INTEGER\n");} -expr ::= TXT. -{printf("X from the assign is txt\n");} - - -array_of_vectors ::= LSB vecs. -{printf("[ something\n");} -vecs ::= vector vecs. -vecs ::= RSB. -{printf("something ]\n");} - -vector ::= LSB INTEGER INTEGER INTEGER RSB. -{printf("[ int int int ]\n");} -vector ::= LSB INTEGER INTEGER INTEGER INTEGER RSB. -{printf("[ int int int int ]\n");} diff --git a/src/conv/csg/csg_scanner.perplex b/src/conv/csg/csg_scanner.perplex deleted file mode 100644 index 6fe4c76fd4b..00000000000 --- a/src/conv/csg/csg_scanner.perplex +++ /dev/null @@ -1,129 +0,0 @@ -/* C S G _ S C A N N E R . P E R P L E X - * BRL-CAD - * - * Copyright (c) 2013-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ - -/* We get some dead store warnings from re2c output - there's not too much we - * can do about that, so we add the "ifndef __clang_analyzer__" disabler - * documented by https://clang-analyzer.llvm.org/faq.html to disable running - * the analyzer on the generated code. - * - * This is not ideal (clang devs discourages use of ifndef __clang_analyzer__) - * but even using bundled tools it's not clear to me that fixing dead store - * issues is doable - even in theory - without very sophisticated support from - * the tool itself. A basic code generator (i.e. one that can't perform whole - * system analysis on its state) will likely not know if it is safe to skip - * assigning zero to a variable in one part of the code, since whether or not - * that variable is going to get used could depend on a lot of subtle - * consequences of generator expressions and settings. - * - * If clang adds support in the future for only disabling specific warnings, we - * should adjust this to disable just the dead store warnings. It may also be - * worth seeing if newer generations of re2c are doing (or at some point in the - * future decide to do) some sort of sophisticated logic analysis to produce - * cleaner output, but newer re2c versions are be more difficult to bootstrap; - * upstream did not adopt our porting of re2c from bison to lemon, and bison is - * more difficult to build on Windows. - */ -#ifndef __clang_analyzer__ - -/* perplex input file */ -#include "csg.h" - - -/* condition states - no idea what this enum does but I modified it according -to what I used below */ -enum {INITIAL, code}; - -%% -<> => code { continue; } - -integer = [1-9][0-9]*; - -lb = "("; -rb = ")"; -lsb = "["; // left square bracket -rsb = "]"; // right square bracket - -lcurly = "{"; -eq = "="; - -optional_ws = [ \t]*; - -group_begin = "group() {"; -txt = [a-z]+; -group_end = "}"; - - - - { -(optional_ws)(group_begin) { - YYSETCONDITION(code); - return GROUP_BEGIN; - } - -(optional_ws)(txt) { - return TXT; - } - -(optional_ws)(group_end) { - YYSETCONDITION(code); - return GROUP_END; - } - -(optional_ws)(integer) { - YYSETCONDITION(code); - return INTEGER; - } - -(optional_ws)(lb) { - YYSETCONDITION(code); - return LB; - } - -(optional_ws)(rb) { - YYSETCONDITION(code); - return RB; - } - -(optional_ws)(lsb) { - YYSETCONDITION(code); - return LSB; - } - -(optional_ws)(rsb) { - YYSETCONDITION(code); - return RSB; - } - -(optional_ws)(eq) { - YYSETCONDITION(code); - return EQ; - } - -(optional_ws)(lcurly) { - YYSETCONDITION(code); - return LCURLY; - } - -[^] { continue; } -} - - -%% -#endif // clang static analyzer suppression diff --git a/src/conv/dxf/g-dxf.c b/src/conv/dxf/g-dxf.c index c3aaa6d46f0..767cf7a73ef 100644 --- a/src/conv/dxf/g-dxf.c +++ b/src/conv/dxf/g-dxf.c @@ -531,7 +531,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ gcv_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)&gcvwriter); /* callback for gcv_region_end */ if (regions_tried>0) { diff --git a/src/conv/g-acad.c b/src/conv/g-acad.c index 6ffe0a5f49c..1dc7e4cf81e 100644 --- a/src/conv/g-acad.c +++ b/src/conv/g-acad.c @@ -636,7 +636,7 @@ main(int argc, char **argv) &tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (regions_tried>0) { diff --git a/src/conv/g-egg.c b/src/conv/g-egg.c index 70fbb8193ff..1bfbade1194 100644 --- a/src/conv/g-egg.c +++ b/src/conv/g-egg.c @@ -328,7 +328,7 @@ main(int argc, char *argv[]) &tree_state, /* state */ NULL, /* start func */ use_mc?gcv_region_end_mc:use_bottess?gcv_bottess_region_end:gcv_region_end, /* end func */ - use_mc?NULL:nmg_booltree_leaf_tess, /* leaf func */ + use_mc?NULL:rt_booltree_leaf_tess, /* leaf func */ (void *)&gcvwriter); /* client_data */ fprintf(conv_data.fp, "}\n"); } diff --git a/src/conv/g-nff.c b/src/conv/g-nff.c index 146225fd1f3..ecd53f1e811 100644 --- a/src/conv/g-nff.c +++ b/src/conv/g-nff.c @@ -486,7 +486,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (regions_tried > 0) { diff --git a/src/conv/g-obj.c b/src/conv/g-obj.c index 1fbc39115f4..3c90c78d9b5 100644 --- a/src/conv/g-obj.c +++ b/src/conv/g-obj.c @@ -276,7 +276,7 @@ main(int argc, const char **argv) &tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (regions_tried>0) { diff --git a/src/conv/g-vrml.c b/src/conv/g-vrml.c index 4d518078366..3f2569a4e12 100644 --- a/src/conv/g-vrml.c +++ b/src/conv/g-vrml.c @@ -308,7 +308,7 @@ leaf_tess1(struct db_tree_state *tsp, const struct db_full_path *pathp, struct r if (ip->idb_type != ID_BOT) { pmp->num_nonbots++; - return nmg_booltree_leaf_tess(tsp, pathp, ip, client_data); + return rt_booltree_leaf_tess(tsp, pathp, ip, client_data); } bot = (struct rt_bot_internal *)ip->idb_ptr; @@ -750,7 +750,7 @@ main(int argc, char **argv) &tree_state, 0, nmg_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)&pm); /* in librt/nmg_bool.c */ goto out; } diff --git a/src/conv/g-x3d.c b/src/conv/g-x3d.c index 1e5c791f591..12f96e80445 100644 --- a/src/conv/g-x3d.c +++ b/src/conv/g-x3d.c @@ -265,7 +265,7 @@ leaf_tess(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt if (ip->idb_type != ID_BOT) { pmp->num_nonbots++; - return nmg_booltree_leaf_tess(tsp, pathp, ip, client_data); + return rt_booltree_leaf_tess(tsp, pathp, ip, client_data); } bot = (struct rt_bot_internal *)ip->idb_ptr; @@ -288,7 +288,7 @@ leaf_tess(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt pmp->num_nonbots++; - return nmg_booltree_leaf_tess(tsp, pathp, ip, client_data); + return rt_booltree_leaf_tess(tsp, pathp, ip, client_data); } diff --git a/src/conv/g-xxx_facets.c b/src/conv/g-xxx_facets.c index 2ea67668d00..29fda7627a4 100644 --- a/src/conv/g-xxx_facets.c +++ b/src/conv/g-xxx_facets.c @@ -193,7 +193,7 @@ main(int argc, char **argv) &tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (regions_tried>0) { diff --git a/src/conv/iges/g-iges.c b/src/conv/iges/g-iges.c index 9da7421a24a..13cdc2de7e6 100644 --- a/src/conv/iges/g-iges.c +++ b/src/conv/iges/g-iges.c @@ -345,7 +345,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ do_nmg_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) @@ -392,7 +392,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ do_nmg_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) @@ -544,45 +544,49 @@ do_nmg_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, u if (output_file == NULL) fp_dir = stdout; else { - char *multi_name; - size_t len; - int unique = 0; - char suffix[SUFFIX_LEN+1]; /* construct a unique file name */ - len = strlen(output_file) + strlen(dp->d_namep) + 6 + SUFFIX_LEN; - multi_name = (char *)bu_malloc(sizeof(char)*len, "multi_name"); - snprintf(multi_name, len, "%s/%s.igs", output_file, dp->d_namep); - bu_strlcpy(suffix, "a", sizeof(suffix)); - suffix[0]--; + struct bu_vls multi_name = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&multi_name, "%s/%s.igs", output_file, dp->d_namep); + int unique = bu_file_readable(bu_vls_cstr(&multi_name)); + int suffix_len = 0; while (!unique) { - if (bu_file_readable(multi_name)) { - break; + suffix_len++; + if (suffix_len > SUFFIX_LEN) { + // Too long + bu_vls_free(&multi_name); + bu_log("too many files with the same name (%s)\n", dp->d_namep); + bu_exit(1, "Cannot create a unique filename, \n"); } + char cchar = 'a'; + bu_vls_putc(&multi_name, cchar); + unique = bu_file_readable(bu_vls_cstr(&multi_name)); + if (unique) + break; - /* not unique, try adding a suffix */ - len = strlen(suffix); - i = len - 1; - suffix[i]++; - while (suffix[i] > 'z' && i > 0) { - suffix[i] = 'a'; - i--; - suffix[i]++; + /* not unique, try incrementing the final char suffix */ + while (cchar < 'z') { + bu_vls_trunc(&multi_name, -1); + cchar++; + bu_vls_putc(&multi_name, cchar); + unique = bu_file_readable(bu_vls_cstr(&multi_name)); + if (unique) + break; } + if (unique) + break; - if (suffix[0] > 'z' && len < SUFFIX_LEN) { - for (i = 0; i <= len; i++) - suffix[i] = 'a'; - } else if (suffix[0] > 'z' && len >= SUFFIX_LEN) { - bu_log("too many files with the same name (%s)\n", dp->d_namep); - bu_exit(1, "Cannot create a unique filename, \n"); - } - snprintf(multi_name, len, "%s/%s%.6s.igs", output_file, dp->d_namep, suffix); + /* No go - restore the letter to a and keep going */ + bu_vls_trunc(&multi_name, -1); + bu_vls_putc(&multi_name, 'a'); } - if ((fp_dir = fopen(multi_name, "wb")) == NULL) { + + if ((fp_dir = fopen(bu_vls_cstr(&multi_name), "wb")) == NULL) { perror("g-iges"); - bu_exit(1, "Cannot open output file: %s\n", multi_name); + bu_exit(1, "Cannot open output file: %s\n", bu_vls_cstr(&multi_name)); } + + bu_vls_free(&multi_name); } /* Open the temporary file for the parameter section */ diff --git a/src/conv/iges/iges.c b/src/conv/iges/iges.c index c181a21c20c..62f78b0689b 100644 --- a/src/conv/iges/iges.c +++ b/src/conv/iges/iges.c @@ -2766,7 +2766,7 @@ has_non_union_ops(union tree *tp) RT_CK_TREE(tp); if (tp->tr_op == OP_SOLID || tp->tr_op == OP_REGION || tp->tr_op == OP_NOP || - tp->tr_op == OP_NMG_TESS || tp->tr_op == OP_DB_LEAF) { + tp->tr_op == OP_TESS || tp->tr_op == OP_DB_LEAF) { return 0; } diff --git a/src/conv/jack/g-jack.c b/src/conv/jack/g-jack.c index 40b10598427..842f18d6c1e 100644 --- a/src/conv/jack/g-jack.c +++ b/src/conv/jack/g-jack.c @@ -556,7 +556,7 @@ main(int argc, char **argv) &jack_tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ fprintf(fp_fig, "\troot=%s_seg.base;\n", bu_vls_addr(&base_seg)); diff --git a/src/conv/nmg/asc-nmg.c b/src/conv/nmg/asc-nmg.c index 19cd807a72a..c50ac99401e 100644 --- a/src/conv/nmg/asc-nmg.c +++ b/src/conv/nmg/asc-nmg.c @@ -55,7 +55,8 @@ usage(void) int main(int argc, char **argv) { - char *afile = "-", *bfile = "nmg.g"; + char *afile = NULL; + char *bfile = "nmg.g"; FILE *fpin; struct rt_wdb *fpout; @@ -83,7 +84,7 @@ main(int argc, char **argv) argv[0], afile); bu_exit(1, NULL); } - bu_log("%s: will be reading from file %s\n",argv[0],afile); + bu_log("%s: will be reading from file %s\n",argv[0],afile); } /* Get BRL-CAD output data base name. */ diff --git a/src/conv/off/g-off.c b/src/conv/off/g-off.c index 81e1415ff70..31fe2f99f11 100644 --- a/src/conv/off/g-off.c +++ b/src/conv/off/g-off.c @@ -189,7 +189,7 @@ main(int argc, char **argv) &jack_tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ fprintf(fp_fig, "\troot=%s_seg.base;\n", bu_vls_addr(&base_seg)); diff --git a/src/conv/raw/g-raw.c b/src/conv/raw/g-raw.c index afe3b6d89d5..c4171ace3f7 100644 --- a/src/conv/raw/g-raw.c +++ b/src/conv/raw/g-raw.c @@ -348,7 +348,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ use_mc?gcv_region_end_mc:gcv_region_end, - use_mc?NULL:nmg_booltree_leaf_tess, + use_mc?NULL:rt_booltree_leaf_tess, (void *)&gcvwriter); if (regions_tried>0) { diff --git a/src/conv/step/ap203e2-g/CMakeLists.txt b/src/conv/step/ap203e2-g/CMakeLists.txt index eef31ca4169..e638211694e 100644 --- a/src/conv/step/ap203e2-g/CMakeLists.txt +++ b/src/conv/step/ap203e2-g/CMakeLists.txt @@ -230,10 +230,10 @@ set(ap203e2g_LIBS librt libbu libbrep - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND ap203e2g_LIBS ${ap203e2g_LIBS}) diff --git a/src/conv/step/ap214-g/CMakeLists.txt b/src/conv/step/ap214-g/CMakeLists.txt index 9dc41077895..47affbfd0c1 100644 --- a/src/conv/step/ap214-g/CMakeLists.txt +++ b/src/conv/step/ap214-g/CMakeLists.txt @@ -232,10 +232,10 @@ set(ap214g_LIBS librt libbu libbrep - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND ap214g_LIBS ${ap214g_LIBS}) diff --git a/src/conv/step/ap242-g/CMakeLists.txt b/src/conv/step/ap242-g/CMakeLists.txt index d3577ffb9d6..f9a5cec90a1 100644 --- a/src/conv/step/ap242-g/CMakeLists.txt +++ b/src/conv/step/ap242-g/CMakeLists.txt @@ -231,10 +231,10 @@ set(ap242g_LIBS librt libbu libbrep - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND ap242g_LIBS ${ap242g_LIBS}) diff --git a/src/conv/step/g-ap203e2/CMakeLists.txt b/src/conv/step/g-ap203e2/CMakeLists.txt index 1af7f70f5e0..6e1f8fa0f43 100644 --- a/src/conv/step/g-ap203e2/CMakeLists.txt +++ b/src/conv/step/g-ap203e2/CMakeLists.txt @@ -38,10 +38,10 @@ set(gap203e2_LIBS libbrep libbn libbu - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND gap203e2_LIBS ${gap203e2_LIBS}) diff --git a/src/conv/step/g-ap214/CMakeLists.txt b/src/conv/step/g-ap214/CMakeLists.txt index 76bf5c19bd1..641fe48adbb 100644 --- a/src/conv/step/g-ap214/CMakeLists.txt +++ b/src/conv/step/g-ap214/CMakeLists.txt @@ -39,10 +39,10 @@ set(gap214_LIBS libbrep libbn libbu - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND gap214_LIBS ${gap214_LIBS}) diff --git a/src/conv/step/g-ap242/CMakeLists.txt b/src/conv/step/g-ap242/CMakeLists.txt index 3084b4d85fb..a9297bbca8a 100644 --- a/src/conv/step/g-ap242/CMakeLists.txt +++ b/src/conv/step/g-ap242/CMakeLists.txt @@ -35,10 +35,10 @@ set(gap242_LIBS libbrep libbn libbu - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND gap242_LIBS ${gap242_LIBS}) diff --git a/src/conv/step/g-step/CMakeLists.txt b/src/conv/step/g-step/CMakeLists.txt index 10fe62002da..f91a6dbca55 100644 --- a/src/conv/step/g-step/CMakeLists.txt +++ b/src/conv/step/g-step/CMakeLists.txt @@ -8,7 +8,7 @@ BRLCAD_INCLUDE_DIRS(STEPCODE_INCLUDE_DIRS) link_directories(${CMAKE_BINARY_DIR}/${LIB_DIR}) -set(STEP_SCHEMA_FILE ${CMAKE_SOURCE_DIR}/src/other/ext/stepcode/data/ap203/ap203.exp) +set(STEP_SCHEMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../step-g/ap203.exp) add_definitions(-DAP203) GENERATE_SCHEMA_INPUTS(${STEP_SCHEMA_FILE} gstep) @@ -39,10 +39,10 @@ if (BRLCAD_ENABLE_STEP) libbrep libbn libbu - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) diff --git a/src/conv/step/ifc-g/CMakeLists.txt b/src/conv/step/ifc-g/CMakeLists.txt index a711cacb43c..4ee34cf1a4d 100644 --- a/src/conv/step/ifc-g/CMakeLists.txt +++ b/src/conv/step/ifc-g/CMakeLists.txt @@ -24,10 +24,10 @@ set(ifcg_LIBS librt libbu libbrep - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) list(APPEND ifcg_LIBS ${ifcg_LIBS}) diff --git a/src/conv/step/step-g/CMakeLists.txt b/src/conv/step/step-g/CMakeLists.txt index 88d5c4bad7f..55b93ef17e4 100644 --- a/src/conv/step/step-g/CMakeLists.txt +++ b/src/conv/step/step-g/CMakeLists.txt @@ -8,7 +8,7 @@ BRLCAD_INCLUDE_DIRS(AP203_INCLUDE_DIRS) link_directories(${CMAKE_BINARY_DIR}/${LIB_DIR}) -set(STEP_SCHEMA_FILE ${CMAKE_SOURCE_DIR}/src/other/ext/stepcode/data/ap203/ap203.exp) +set(STEP_SCHEMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/ap203.exp) add_definitions(-DAP203) GENERATE_SCHEMA_INPUTS(${STEP_SCHEMA_FILE} stepg) @@ -460,10 +460,10 @@ if (BRLCAD_ENABLE_STEP) librt libbu libbrep - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ${OPENNURBS_LIBRARIES} ) @@ -480,7 +480,10 @@ if (BRLCAD_ENABLE_STEP) endif(HIDE_INTERNAL_SYMBOLS) endif (BRLCAD_ENABLE_STEP) -CMAKEFILES(CMakeLists.txt) +CMAKEFILES( + CMakeLists.txt + ap203.exp + ) # Local Variables: # tab-width: 8 diff --git a/src/conv/step/step-g/ap203.exp b/src/conv/step/step-g/ap203.exp new file mode 100644 index 00000000000..b7fa02566d8 --- /dev/null +++ b/src/conv/step/step-g/ap203.exp @@ -0,0 +1,5331 @@ +(* This is a MODIFIED version of AP203 Amd. 1. + The change was to remove a useless IF...ELSE...ENDIF statement that always evaluated + the same way. Statements in the branch that were never executed caused problems with + libexpress, and it was easier to modify the schema than to come up with a generic + fix for libexpress. This change does *not* affect the behavior of the schema. + + Based on: + AIM long form for ISO 10303-203 amendment 1 + ISO TC184/SC4/WG3 N916 + Larry McKee + 2000-05-04 +*) + +SCHEMA config_control_design; + + CONSTANT +(* FIXME: gcc error on next statement with c99/POSIX: + Syntax error: "(" unexpected +*) + dummy_gri : geometric_representation_item := representation_item('') || + geometric_representation_item(); + dummy_tri : topological_representation_item := representation_item('') + || topological_representation_item(); + END_CONSTANT; + + TYPE ahead_or_behind = ENUMERATION OF + (ahead, + behind); + END_TYPE; -- ahead_or_behind + + TYPE approved_item = SELECT + (product_definition_formation, + product_definition, + configuration_effectivity, + configuration_item, + security_classification, + change_request, + change, + start_request, + start_work, + certification, + contract); + END_TYPE; -- approved_item + + TYPE area_measure = REAL; + END_TYPE; -- area_measure + + TYPE axis2_placement = SELECT + (axis2_placement_2d, + axis2_placement_3d); + END_TYPE; -- axis2_placement + + TYPE b_spline_curve_form = ENUMERATION OF + (polyline_form, + circular_arc, + elliptic_arc, + parabolic_arc, + hyperbolic_arc, + unspecified); + END_TYPE; -- b_spline_curve_form + + TYPE b_spline_surface_form = ENUMERATION OF + (plane_surf, + cylindrical_surf, + conical_surf, + spherical_surf, + toroidal_surf, + surf_of_revolution, + ruled_surf, + generalised_cone, + quadric_surf, + surf_of_linear_extrusion, + unspecified); + END_TYPE; -- b_spline_surface_form + + TYPE boolean_operand = SELECT + (solid_model); + END_TYPE; -- boolean_operand + + TYPE certified_item = SELECT + (supplied_part_relationship); + END_TYPE; -- certified_item + + TYPE change_request_item = SELECT + (product_definition_formation); + END_TYPE; -- change_request_item + + TYPE characterized_definition = SELECT + (characterized_product_definition, + shape_definition); + END_TYPE; -- characterized_definition + + TYPE characterized_product_definition = SELECT + (product_definition, + product_definition_relationship); + END_TYPE; -- characterized_product_definition + + TYPE classified_item = SELECT + (product_definition_formation, + assembly_component_usage); + END_TYPE; -- classified_item + + TYPE context_dependent_measure = REAL; + END_TYPE; -- context_dependent_measure + + TYPE contracted_item = SELECT + (product_definition_formation); + END_TYPE; -- contracted_item + + TYPE count_measure = NUMBER; + END_TYPE; -- count_measure + + TYPE curve_on_surface = SELECT + (pcurve, + surface_curve, + composite_curve_on_surface); + END_TYPE; -- curve_on_surface + + TYPE date_time_item = SELECT + (product_definition, + change_request, + start_request, + change, + start_work, + approval_person_organization, + contract, + security_classification, + certification); + END_TYPE; -- date_time_item + + TYPE date_time_select = SELECT + (date, + local_time, + date_and_time); + END_TYPE; -- date_time_select + + TYPE day_in_month_number = INTEGER; + END_TYPE; -- day_in_month_number + + TYPE day_in_week_number = INTEGER; + WHERE + wr1: ((1 <= SELF) AND (SELF <= 7)); + END_TYPE; -- day_in_week_number + + TYPE day_in_year_number = INTEGER; + END_TYPE; -- day_in_year_number + + TYPE descriptive_measure = STRING; + END_TYPE; -- descriptive_measure + + TYPE dimension_count = INTEGER; + WHERE + wr1: (SELF > 0); + END_TYPE; -- dimension_count + + TYPE founded_item_select = SELECT + (founded_item, + representation_item); + END_TYPE; -- founded_item_select + + TYPE geometric_set_select = SELECT + (point, + curve, + surface); + END_TYPE; -- geometric_set_select + + TYPE hour_in_day = INTEGER; + WHERE + wr1: ((0 <= SELF) AND (SELF < 24)); + END_TYPE; -- hour_in_day + + TYPE identifier = STRING; + END_TYPE; -- identifier + + TYPE knot_type = ENUMERATION OF + (uniform_knots, + unspecified, + quasi_uniform_knots, + piecewise_bezier_knots); + END_TYPE; -- knot_type + + TYPE label = STRING; + END_TYPE; -- label + + TYPE length_measure = REAL; + END_TYPE; -- length_measure + + TYPE list_of_reversible_topology_item = LIST [0:?] OF + reversible_topology_item; + END_TYPE; -- list_of_reversible_topology_item + + TYPE mass_measure = REAL; + END_TYPE; -- mass_measure + + TYPE measure_value = SELECT + (length_measure, + mass_measure, + plane_angle_measure, + solid_angle_measure, + area_measure, + volume_measure, + parameter_value, + context_dependent_measure, + descriptive_measure, + positive_length_measure, + positive_plane_angle_measure, + count_measure); + END_TYPE; -- measure_value + + TYPE minute_in_hour = INTEGER; + WHERE + wr1: ((0 <= SELF) AND (SELF <= 59)); + END_TYPE; -- minute_in_hour + + TYPE month_in_year_number = INTEGER; + WHERE + wr1: ((1 <= SELF) AND (SELF <= 12)); + END_TYPE; -- month_in_year_number + + TYPE parameter_value = REAL; + END_TYPE; -- parameter_value + + TYPE pcurve_or_surface = SELECT + (pcurve, + surface); + END_TYPE; -- pcurve_or_surface + + TYPE person_organization_item = SELECT + (change, + start_work, + change_request, + start_request, + configuration_item, + product, + product_definition_formation, + product_definition, + contract, + security_classification); + END_TYPE; -- person_organization_item + + TYPE person_organization_select = SELECT + (person, + organization, + person_and_organization); + END_TYPE; -- person_organization_select + + TYPE plane_angle_measure = REAL; + END_TYPE; -- plane_angle_measure + + TYPE positive_length_measure = length_measure; + WHERE + wr1: (SELF > 0); + END_TYPE; -- positive_length_measure + + TYPE positive_plane_angle_measure = plane_angle_measure; + WHERE + wr1: (SELF > 0); + END_TYPE; -- positive_plane_angle_measure + + TYPE preferred_surface_curve_representation = ENUMERATION OF + (curve_3d, + pcurve_s1, + pcurve_s2); + END_TYPE; -- preferred_surface_curve_representation + + TYPE reversible_topology = SELECT + (reversible_topology_item, + list_of_reversible_topology_item, + set_of_reversible_topology_item); + END_TYPE; -- reversible_topology + + TYPE reversible_topology_item = SELECT + (edge, + path, + face, + face_bound, + closed_shell, + open_shell); + END_TYPE; -- reversible_topology_item + + TYPE second_in_minute = REAL; + WHERE + wr1: ((0 <= SELF) AND (SELF < 60)); + END_TYPE; -- second_in_minute + + TYPE set_of_reversible_topology_item = SET [0:?] OF + reversible_topology_item; + END_TYPE; -- set_of_reversible_topology_item + + TYPE shape_definition = SELECT + (product_definition_shape, + shape_aspect, + shape_aspect_relationship); + END_TYPE; -- shape_definition + + TYPE shell = SELECT + (vertex_shell, + wire_shell, + open_shell, + closed_shell); + END_TYPE; -- shell + + TYPE si_prefix = ENUMERATION OF + (exa, + peta, + tera, + giga, + mega, + kilo, + hecto, + deca, + deci, + centi, + milli, + micro, + nano, + pico, + femto, + atto); + END_TYPE; -- si_prefix + + TYPE si_unit_name = ENUMERATION OF + (metre, + gram, + second, + ampere, + kelvin, + mole, + candela, + radian, + steradian, + hertz, + newton, + pascal, + joule, + watt, + coulomb, + volt, + farad, + ohm, + siemens, + weber, + tesla, + henry, + degree_celsius, + lumen, + lux, + becquerel, + gray, + sievert); + END_TYPE; -- si_unit_name + + TYPE solid_angle_measure = REAL; + END_TYPE; -- solid_angle_measure + + TYPE source = ENUMERATION OF + (made, + bought, + not_known); + END_TYPE; -- source + + TYPE specified_item = SELECT + (product_definition, + shape_aspect); + END_TYPE; -- specified_item + + TYPE start_request_item = SELECT + (product_definition_formation); + END_TYPE; -- start_request_item + + TYPE supported_item = SELECT + (action_directive, + action, + action_method); + END_TYPE; -- supported_item + + TYPE surface_model = SELECT + (shell_based_surface_model); + END_TYPE; -- surface_model + + TYPE text = STRING; + END_TYPE; -- text + + TYPE transformation = SELECT + (item_defined_transformation, + functionally_defined_transformation); + END_TYPE; -- transformation + + TYPE transition_code = ENUMERATION OF + (discontinuous, + continuous, + cont_same_gradient, + cont_same_gradient_same_curvature); + END_TYPE; -- transition_code + + TYPE trimming_preference = ENUMERATION OF + (cartesian, + parameter, + unspecified); + END_TYPE; -- trimming_preference + + TYPE trimming_select = SELECT + (cartesian_point, + parameter_value); + END_TYPE; -- trimming_select + + TYPE unit = SELECT + (named_unit); + END_TYPE; -- unit + + TYPE vector_or_direction = SELECT + (vector, + direction); + END_TYPE; -- vector_or_direction + + TYPE volume_measure = REAL; + END_TYPE; -- volume_measure + + TYPE week_in_year_number = INTEGER; + WHERE + wr1: ((1 <= SELF) AND (SELF <= 53)); + END_TYPE; -- week_in_year_number + + TYPE wireframe_model = SELECT + (shell_based_wireframe_model, + edge_based_wireframe_model); + END_TYPE; -- wireframe_model + + TYPE work_item = SELECT + (product_definition_formation); + END_TYPE; -- work_item + + TYPE year_number = INTEGER; + END_TYPE; -- year_number + + ENTITY action; + name : label; + description : text; + chosen_method : action_method; + END_ENTITY; -- action + + ENTITY action_assignment + ABSTRACT SUPERTYPE; + assigned_action : action; + END_ENTITY; -- action_assignment + + ENTITY action_directive; + name : label; + description : text; + analysis : text; + comment : text; + requests : SET [1:?] OF versioned_action_request; + END_ENTITY; -- action_directive + + ENTITY action_method; + name : label; + description : text; + consequence : text; + purpose : text; + END_ENTITY; -- action_method + + ENTITY action_request_assignment + ABSTRACT SUPERTYPE; + assigned_action_request : versioned_action_request; + END_ENTITY; -- action_request_assignment + + ENTITY action_request_solution; + method : action_method; + request : versioned_action_request; + END_ENTITY; -- action_request_solution + + ENTITY action_request_status; + status : label; + assigned_request : versioned_action_request; + END_ENTITY; -- action_request_status + + ENTITY action_status; + status : label; + assigned_action : executed_action; + END_ENTITY; -- action_status + + ENTITY address; + internal_location : OPTIONAL label; + street_number : OPTIONAL label; + street : OPTIONAL label; + postal_box : OPTIONAL label; + town : OPTIONAL label; + region : OPTIONAL label; + postal_code : OPTIONAL label; + country : OPTIONAL label; + facsimile_number : OPTIONAL label; + telephone_number : OPTIONAL label; + electronic_mail_address : OPTIONAL label; + telex_number : OPTIONAL label; + WHERE + wr1: (EXISTS(internal_location) OR EXISTS(street_number) OR EXISTS( + street) OR EXISTS(postal_box) OR EXISTS(town) OR EXISTS( + region) OR EXISTS(postal_code) OR EXISTS(country) OR EXISTS( + facsimile_number) OR EXISTS(telephone_number) OR EXISTS( + electronic_mail_address) OR EXISTS(telex_number)); + END_ENTITY; -- address + + ENTITY advanced_brep_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SOLID_BREP', + 'CONFIG_CONTROL_DESIGN.FACETED_BREP', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2: (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SOLID_BREP', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) > + 0); + wr3: (SIZEOF(QUERY ( msb <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SOLID_BREP' IN TYPEOF(it)) ) + | (NOT (SIZEOF(QUERY ( csh <* msb_shells(msb) | (NOT ( + SIZEOF(QUERY ( fcs <* csh\connected_face_set.cfs_faces | ( + NOT ('CONFIG_CONTROL_DESIGN.ADVANCED_FACE' + IN TYPEOF(fcs))) )) = 0)) )) = 0)) )) = 0); + wr4: (SIZEOF(QUERY ( msb <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SOLID_BREP' IN TYPEOF(it)) ) + | ('CONFIG_CONTROL_DESIGN.ORIENTED_CLOSED_SHELL' IN TYPEOF( + msb\manifold_solid_brep.outer)) )) = 0); + wr5: (SIZEOF(QUERY ( brv <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.BREP_WITH_VOIDS' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( csh <* brv\brep_with_voids.voids | csh\ + oriented_closed_shell.orientation )) = 0)) )) = 0); + wr6: (SIZEOF(QUERY ( mi <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | (NOT + ('CONFIG_CONTROL_DESIGN.ADVANCED_BREP_SHAPE_REPRESENTATION' + IN TYPEOF(mi\mapped_item.mapping_source. + mapped_representation))) )) = 0); + END_ENTITY; -- advanced_brep_shape_representation + + ENTITY advanced_face + SUBTYPE OF (face_surface); + WHERE + wr1 : (SIZEOF(['CONFIG_CONTROL_DESIGN.ELEMENTARY_SURFACE', + 'CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE', + 'CONFIG_CONTROL_DESIGN.SWEPT_SURFACE'] * TYPEOF( + face_geometry)) = 1); + wr2 : (SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds.bound\path. + edge_list | (NOT ('CONFIG_CONTROL_DESIGN.EDGE_CURVE' IN + TYPEOF(oe\oriented_edge.edge_element))) )) = 0)) )) = 0); + wr3 : (SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds.bound\path. + edge_list | (NOT (SIZEOF(['CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.POLYLINE', + 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE', + 'CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE'] * TYPEOF(oe. + edge_element\edge_curve.edge_geometry)) = 1)) )) = 0)) )) = + 0); + wr4 : (SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds.bound\path. + edge_list | (NOT (('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN + TYPEOF(oe\edge.edge_start)) AND ( + 'CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN TYPEOF(oe\edge. + edge_start\vertex_point.vertex_geometry)) AND ( + 'CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(oe\edge. + edge_end)) AND ('CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN + TYPEOF(oe\edge.edge_end\vertex_point.vertex_geometry)))) )) + = 0)) )) = 0); + wr5 : (SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | ('CONFIG_CONTROL_DESIGN.ORIENTED_PATH' IN TYPEOF( + elp_fbnds.bound)) )) = 0); + wr6 : ((NOT ('CONFIG_CONTROL_DESIGN.SWEPT_SURFACE' IN TYPEOF( + face_geometry))) OR (SIZEOF(['CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.POLYLINE', + 'CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE'] * TYPEOF( + face_geometry\swept_surface.swept_curve)) = 1)); + wr7 : (SIZEOF(QUERY ( vlp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.VERTEX_LOOP' + IN TYPEOF(bnds.bound)) ) + | (NOT (('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF( + vlp_fbnds\face_bound.bound\vertex_loop.loop_vertex)) AND ( + 'CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN TYPEOF(vlp_fbnds + \face_bound.bound\vertex_loop.loop_vertex\vertex_point. + vertex_geometry)))) )) = 0); + wr8 : (SIZEOF(QUERY ( bnd <* bounds | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP', + 'CONFIG_CONTROL_DESIGN.VERTEX_LOOP'] * TYPEOF(bnd.bound)) = + 1)) )) = 0); + wr9 : (SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds.bound\path. + edge_list | (('CONFIG_CONTROL_DESIGN.SURFACE_CURVE' IN + TYPEOF(oe\oriented_edge.edge_element\edge_curve. + edge_geometry)) AND (NOT (SIZEOF(QUERY ( sc_ag <* oe. + edge_element\edge_curve.edge_geometry\surface_curve. + associated_geometry | (NOT ('CONFIG_CONTROL_DESIGN.PCURVE' + IN TYPEOF(sc_ag))) )) = 0))) )) = 0)) )) = 0); + wr10: (((NOT ('CONFIG_CONTROL_DESIGN.SWEPT_SURFACE' IN TYPEOF( + face_geometry))) OR (NOT ('CONFIG_CONTROL_DESIGN.POLYLINE' + IN TYPEOF(face_geometry\swept_surface.swept_curve))) OR ( + SIZEOF(face_geometry\swept_surface.swept_curve\polyline. + points) >= 3)) AND (SIZEOF(QUERY ( elp_fbnds <* + QUERY ( bnds <* bounds | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' + IN TYPEOF(bnds.bound)) ) | (NOT (SIZEOF(QUERY ( oe <* + elp_fbnds.bound\path.edge_list | (( + 'CONFIG_CONTROL_DESIGN.POLYLINE' IN TYPEOF(oe\oriented_edge + .edge_element\edge_curve.edge_geometry)) AND (NOT (SIZEOF( + oe\oriented_edge.edge_element\edge_curve.edge_geometry\ + polyline.points) >= 3))) )) = 0)) )) = 0)); + END_ENTITY; -- advanced_face + + ENTITY alternate_product_relationship; + name : label; + definition : text; + alternate : product; + base : product; + basis : text; + UNIQUE + ur1 : alternate, base; + WHERE + wr1: (alternate :<>: base); + END_ENTITY; -- alternate_product_relationship + + ENTITY application_context; + application : text; + INVERSE + context_elements : SET [1:?] OF application_context_element FOR + frame_of_reference; + END_ENTITY; -- application_context + + ENTITY application_context_element + SUPERTYPE OF (ONEOF (product_context,product_definition_context, + product_concept_context)); + name : label; + frame_of_reference : application_context; + END_ENTITY; -- application_context_element + + ENTITY application_protocol_definition; + status : label; + application_interpreted_model_schema_name : label; + application_protocol_year : year_number; + application : application_context; + END_ENTITY; -- application_protocol_definition + + ENTITY approval; + status : approval_status; + level : label; + END_ENTITY; -- approval + + ENTITY approval_assignment + ABSTRACT SUPERTYPE; + assigned_approval : approval; + END_ENTITY; -- approval_assignment + + ENTITY approval_date_time; + date_time : date_time_select; + dated_approval : approval; + END_ENTITY; -- approval_date_time + + ENTITY approval_person_organization; + person_organization : person_organization_select; + authorized_approval : approval; + role : approval_role; + END_ENTITY; -- approval_person_organization + + ENTITY approval_relationship; + name : label; + description : text; + relating_approval : approval; + related_approval : approval; + END_ENTITY; -- approval_relationship + + ENTITY approval_role; + role : label; + END_ENTITY; -- approval_role + + ENTITY approval_status; + name : label; + END_ENTITY; -- approval_status + + ENTITY area_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.AREA_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- area_measure_with_unit + + ENTITY area_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 2) AND (SELF\ + named_unit.dimensions.mass_exponent = 0) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- area_unit + + ENTITY assembly_component_usage + SUPERTYPE OF (ONEOF (next_assembly_usage_occurrence, + specified_higher_usage_occurrence,promissory_usage_occurrence)) + SUBTYPE OF (product_definition_usage); + reference_designator : OPTIONAL identifier; + END_ENTITY; -- assembly_component_usage + + ENTITY assembly_component_usage_substitute; + name : label; + definition : text; + base : assembly_component_usage; + substitute : assembly_component_usage; + UNIQUE + ur1 : base, substitute; + WHERE + wr1: (base.relating_product_definition :=: substitute. + relating_product_definition); + wr2: (base :<>: substitute); + END_ENTITY; -- assembly_component_usage_substitute + + ENTITY axis1_placement + SUBTYPE OF (placement); + axis : OPTIONAL direction; + DERIVE + z : direction := NVL(normalise(axis),dummy_gri || + direction([0,0,1])); + WHERE + wr1: (SELF\geometric_representation_item.dim = 3); + END_ENTITY; -- axis1_placement + + ENTITY axis2_placement_2d + SUBTYPE OF (placement); + ref_direction : OPTIONAL direction; + DERIVE + p : LIST [2:2] OF direction := build_2axes(ref_direction); + WHERE + wr1: (SELF\geometric_representation_item.dim = 2); + END_ENTITY; -- axis2_placement_2d + + ENTITY axis2_placement_3d + SUBTYPE OF (placement); + axis : OPTIONAL direction; + ref_direction : OPTIONAL direction; + DERIVE + p : LIST [3:3] OF direction := build_axes(axis,ref_direction); + WHERE + wr1: (SELF\placement.location.dim = 3); + wr2: ((NOT EXISTS(axis)) OR (axis.dim = 3)); + wr3: ((NOT EXISTS(ref_direction)) OR (ref_direction.dim = 3)); + wr4: ((NOT EXISTS(axis)) OR (NOT EXISTS(ref_direction)) OR ( + cross_product(axis,ref_direction).magnitude > 0)); + END_ENTITY; -- axis2_placement_3d + + ENTITY b_spline_curve + SUPERTYPE OF (ONEOF (uniform_curve,b_spline_curve_with_knots, + quasi_uniform_curve,bezier_curve) ANDOR rational_b_spline_curve) + SUBTYPE OF (bounded_curve); + degree : INTEGER; + control_points_list : LIST [2:?] OF cartesian_point; + curve_form : b_spline_curve_form; + closed_curve : LOGICAL; + self_intersect : LOGICAL; + DERIVE + upper_index_on_control_points : INTEGER := SIZEOF( + control_points_list) - 1; + control_points : ARRAY [0: + upper_index_on_control_points] OF + cartesian_point := list_to_array( + control_points_list,0, + upper_index_on_control_points); + WHERE + wr1: (('CONFIG_CONTROL_DESIGN.UNIFORM_CURVE' IN TYPEOF(SELF)) OR ( + 'CONFIG_CONTROL_DESIGN.QUASI_UNIFORM_CURVE' IN TYPEOF(SELF)) + OR ('CONFIG_CONTROL_DESIGN.BEZIER_CURVE' IN TYPEOF(SELF)) OR + ('CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE_WITH_KNOTS' IN + TYPEOF(SELF))); + END_ENTITY; -- b_spline_curve + + ENTITY b_spline_curve_with_knots + SUBTYPE OF (b_spline_curve); + knot_multiplicities : LIST [2:?] OF INTEGER; + knots : LIST [2:?] OF parameter_value; + knot_spec : knot_type; + DERIVE + upper_index_on_knots : INTEGER := SIZEOF(knots); + WHERE + wr1: constraints_param_b_spline(degree,upper_index_on_knots, + upper_index_on_control_points,knot_multiplicities,knots); + wr2: (SIZEOF(knot_multiplicities) = upper_index_on_knots); + END_ENTITY; -- b_spline_curve_with_knots + + ENTITY b_spline_surface + SUPERTYPE OF (ONEOF (b_spline_surface_with_knots,uniform_surface, + quasi_uniform_surface,bezier_surface) ANDOR + rational_b_spline_surface) + SUBTYPE OF (bounded_surface); + u_degree : INTEGER; + v_degree : INTEGER; + control_points_list : LIST [2:?] OF LIST [2:?] OF cartesian_point; + surface_form : b_spline_surface_form; + u_closed : LOGICAL; + v_closed : LOGICAL; + self_intersect : LOGICAL; + DERIVE + u_upper : INTEGER := SIZEOF(control_points_list) - 1; + v_upper : INTEGER := SIZEOF(control_points_list[1]) - 1; + control_points : ARRAY [0:u_upper] OF ARRAY [0:v_upper] OF + cartesian_point := make_array_of_array( + control_points_list,0,u_upper,0,v_upper); + WHERE + wr1: (('CONFIG_CONTROL_DESIGN.UNIFORM_SURFACE' IN TYPEOF(SELF)) OR ( + 'CONFIG_CONTROL_DESIGN.QUASI_UNIFORM_SURFACE' IN + TYPEOF(SELF)) + OR ('CONFIG_CONTROL_DESIGN.BEZIER_SURFACE' IN TYPEOF(SELF)) + OR ('CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE_WITH_KNOTS' IN + TYPEOF(SELF))); + END_ENTITY; -- b_spline_surface + + ENTITY b_spline_surface_with_knots + SUBTYPE OF (b_spline_surface); + u_multiplicities : LIST [2:?] OF INTEGER; + v_multiplicities : LIST [2:?] OF INTEGER; + u_knots : LIST [2:?] OF parameter_value; + v_knots : LIST [2:?] OF parameter_value; + knot_spec : knot_type; + DERIVE + knot_u_upper : INTEGER := SIZEOF(u_knots); + knot_v_upper : INTEGER := SIZEOF(v_knots); + WHERE + wr1: constraints_param_b_spline(SELF\b_spline_surface.u_degree, + knot_u_upper,SELF\b_spline_surface.u_upper,u_multiplicities, + u_knots); + wr2: constraints_param_b_spline(SELF\b_spline_surface.v_degree, + knot_v_upper,SELF\b_spline_surface.v_upper,v_multiplicities, + v_knots); + wr3: (SIZEOF(u_multiplicities) = knot_u_upper); + wr4: (SIZEOF(v_multiplicities) = knot_v_upper); + END_ENTITY; -- b_spline_surface_with_knots + + ENTITY bezier_curve + SUBTYPE OF (b_spline_curve); + END_ENTITY; -- bezier_curve + + ENTITY bezier_surface + SUBTYPE OF (b_spline_surface); + END_ENTITY; -- bezier_surface + + ENTITY boundary_curve + SUBTYPE OF (composite_curve_on_surface); + WHERE + wr1: SELF\composite_curve.closed_curve; + END_ENTITY; -- boundary_curve + + ENTITY bounded_curve + SUPERTYPE OF (ONEOF (polyline,b_spline_curve,trimmed_curve, + bounded_pcurve,bounded_surface_curve,composite_curve)) + SUBTYPE OF (curve); + END_ENTITY; -- bounded_curve + + ENTITY bounded_pcurve + SUBTYPE OF (pcurve, bounded_curve); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.BOUNDED_CURVE' IN TYPEOF(SELF\pcurve. + reference_to_curve.items[1])); + END_ENTITY; -- bounded_pcurve + + ENTITY bounded_surface + SUPERTYPE OF (ONEOF (b_spline_surface,rectangular_trimmed_surface, + curve_bounded_surface,rectangular_composite_surface)) + SUBTYPE OF (surface); + END_ENTITY; -- bounded_surface + + ENTITY bounded_surface_curve + SUBTYPE OF (surface_curve, bounded_curve); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.BOUNDED_CURVE' IN TYPEOF(SELF\ + surface_curve.curve_3d)); + END_ENTITY; -- bounded_surface_curve + + ENTITY brep_with_voids + SUBTYPE OF (manifold_solid_brep); + voids : SET [1:?] OF oriented_closed_shell; + END_ENTITY; -- brep_with_voids + + ENTITY calendar_date + SUBTYPE OF (date); + day_component : day_in_month_number; + month_component : month_in_year_number; + WHERE + wr1: valid_calendar_date(SELF); + END_ENTITY; -- calendar_date + + ENTITY cartesian_point + SUBTYPE OF (point); + coordinates : LIST [1:3] OF length_measure; + END_ENTITY; -- cartesian_point + + ENTITY cartesian_transformation_operator + SUPERTYPE OF (cartesian_transformation_operator_3d) + SUBTYPE OF (geometric_representation_item, + functionally_defined_transformation); + axis1 : OPTIONAL direction; + axis2 : OPTIONAL direction; + local_origin : cartesian_point; + scale : OPTIONAL REAL; + DERIVE + scl : REAL := NVL(scale,1); + WHERE + wr1: (scl > 0); + END_ENTITY; -- cartesian_transformation_operator + + ENTITY cartesian_transformation_operator_3d + SUBTYPE OF (cartesian_transformation_operator); + axis3 : OPTIONAL direction; + DERIVE + u : LIST [3:3] OF direction := base_axis(3,SELF\ + cartesian_transformation_operator.axis1,SELF\ + cartesian_transformation_operator.axis2,axis3); + WHERE + wr1: (SELF\geometric_representation_item.dim = 3); + END_ENTITY; -- cartesian_transformation_operator_3d + + ENTITY cc_design_approval + SUBTYPE OF (approval_assignment); + items : SET [1:?] OF approved_item; + END_ENTITY; -- cc_design_approval + + ENTITY cc_design_certification + SUBTYPE OF (certification_assignment); + items : SET [1:?] OF certified_item; + END_ENTITY; -- cc_design_certification + + ENTITY cc_design_contract + SUBTYPE OF (contract_assignment); + items : SET [1:?] OF contracted_item; + END_ENTITY; -- cc_design_contract + + ENTITY cc_design_date_and_time_assignment + SUBTYPE OF (date_and_time_assignment); + items : SET [1:?] OF date_time_item; + WHERE + wr1: cc_design_date_time_correlation(SELF); + END_ENTITY; -- cc_design_date_and_time_assignment + + ENTITY cc_design_person_and_organization_assignment + SUBTYPE OF (person_and_organization_assignment); + items : SET [1:?] OF person_organization_item; + WHERE + wr1: cc_design_person_and_organization_correlation(SELF); + END_ENTITY; -- cc_design_person_and_organization_assignment + + ENTITY cc_design_security_classification + SUBTYPE OF (security_classification_assignment); + items : SET [1:?] OF classified_item; + END_ENTITY; -- cc_design_security_classification + + ENTITY cc_design_specification_reference + SUBTYPE OF (document_reference); + items : SET [1:?] OF specified_item; + END_ENTITY; -- cc_design_specification_reference + + ENTITY certification; + name : label; + purpose : text; + kind : certification_type; + END_ENTITY; -- certification + + ENTITY certification_assignment + ABSTRACT SUPERTYPE; + assigned_certification : certification; + END_ENTITY; -- certification_assignment + + ENTITY certification_type; + description : label; + END_ENTITY; -- certification_type + + ENTITY change + SUBTYPE OF (action_assignment); + items : SET [1:?] OF work_item; + END_ENTITY; -- change + + ENTITY change_request + SUBTYPE OF (action_request_assignment); + items : SET [1:?] OF change_request_item; + END_ENTITY; -- change_request + + ENTITY circle + SUBTYPE OF (conic); + radius : positive_length_measure; + END_ENTITY; -- circle + + ENTITY closed_shell + SUBTYPE OF (connected_face_set); + END_ENTITY; -- closed_shell + + ENTITY composite_curve + SUBTYPE OF (bounded_curve); + segments : LIST [1:?] OF composite_curve_segment; + self_intersect : LOGICAL; + DERIVE + n_segments : INTEGER := SIZEOF(segments); + closed_curve : LOGICAL := segments[n_segments].transition <> + discontinuous; + WHERE + wr1: (((NOT closed_curve) AND (SIZEOF(QUERY ( temp <* segments | ( + temp.transition = discontinuous) )) = 1)) OR (closed_curve + AND (SIZEOF(QUERY ( temp <* segments | (temp.transition = + discontinuous) )) = 0))); + END_ENTITY; -- composite_curve + + ENTITY composite_curve_on_surface + SUPERTYPE OF (boundary_curve) + SUBTYPE OF (composite_curve); + DERIVE + basis_surface : SET [0:2] OF surface := get_basis_surface(SELF); + WHERE + wr1: (SIZEOF(basis_surface) > 0); + wr2: constraints_composite_curve_on_surface(SELF); + END_ENTITY; -- composite_curve_on_surface + + ENTITY composite_curve_segment + SUBTYPE OF (founded_item); + transition : transition_code; + same_sense : BOOLEAN; + parent_curve : curve; + INVERSE + using_curves : BAG [1:?] OF composite_curve FOR segments; + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.BOUNDED_CURVE' IN TYPEOF(parent_curve)); + END_ENTITY; -- composite_curve_segment + + ENTITY configuration_design; + configuration : configuration_item; + design : product_definition_formation; + UNIQUE + ur1 : configuration, design; + END_ENTITY; -- configuration_design + + ENTITY configuration_effectivity + SUBTYPE OF (product_definition_effectivity); + configuration : configuration_design; + UNIQUE + ur1 : configuration, usage, id; + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_USAGE' IN TYPEOF( + SELF\product_definition_effectivity.usage)); + END_ENTITY; -- configuration_effectivity + + ENTITY configuration_item; + id : identifier; + name : label; + description : OPTIONAL text; + item_concept : product_concept; + purpose : OPTIONAL label; + UNIQUE + ur1 : id; + END_ENTITY; -- configuration_item + + ENTITY conic + SUPERTYPE OF (ONEOF (circle,ellipse,hyperbola,parabola)) + SUBTYPE OF (curve); + position : axis2_placement; + END_ENTITY; -- conic + + ENTITY conical_surface + SUBTYPE OF (elementary_surface); + radius : length_measure; + semi_angle : plane_angle_measure; + WHERE + wr1: (radius >= 0); + END_ENTITY; -- conical_surface + + ENTITY connected_edge_set + SUBTYPE OF (topological_representation_item); + ces_edges : SET [1:?] OF edge; + END_ENTITY; -- connected_edge_set + + ENTITY connected_face_set + SUPERTYPE OF (ONEOF (closed_shell,open_shell)) + SUBTYPE OF (topological_representation_item); + cfs_faces : SET [1:?] OF face; + END_ENTITY; -- connected_face_set + + ENTITY context_dependent_shape_representation; + representation_relation : shape_representation_relationship; + represented_product_relation : product_definition_shape; + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_RELATIONSHIP' IN + TYPEOF(SELF.represented_product_relation.definition)); + END_ENTITY; -- context_dependent_shape_representation + + ENTITY context_dependent_unit + SUBTYPE OF (named_unit); + name : label; + END_ENTITY; -- context_dependent_unit + + ENTITY contract; + name : label; + purpose : text; + kind : contract_type; + END_ENTITY; -- contract + + ENTITY contract_assignment + ABSTRACT SUPERTYPE; + assigned_contract : contract; + END_ENTITY; -- contract_assignment + + ENTITY contract_type; + description : label; + END_ENTITY; -- contract_type + + ENTITY conversion_based_unit + SUBTYPE OF (named_unit); + name : label; + conversion_factor : measure_with_unit; + END_ENTITY; -- conversion_based_unit + + ENTITY coordinated_universal_time_offset; + hour_offset : hour_in_day; + minute_offset : OPTIONAL minute_in_hour; + sense : ahead_or_behind; + END_ENTITY; -- coordinated_universal_time_offset + + ENTITY curve + SUPERTYPE OF (ONEOF (line,conic,pcurve,surface_curve,offset_curve_3d, + curve_replica)) + SUBTYPE OF (geometric_representation_item); + END_ENTITY; -- curve + + ENTITY curve_bounded_surface + SUBTYPE OF (bounded_surface); + basis_surface : surface; + boundaries : SET [1:?] OF boundary_curve; + implicit_outer : BOOLEAN; + WHERE + wr1: (NOT (implicit_outer AND ( + 'CONFIG_CONTROL_DESIGN.OUTER_BOUNDARY_CURVE' IN TYPEOF( + boundaries)))); + wr2: ((NOT implicit_outer) OR ( + 'CONFIG_CONTROL_DESIGN.BOUNDED_SURFACE' IN TYPEOF( + basis_surface))); + wr3: (SIZEOF(QUERY ( temp <* boundaries | ( + 'CONFIG_CONTROL_DESIGN.OUTER_BOUNDARY_CURVE' + IN TYPEOF(temp)) )) <= 1); + wr4: (SIZEOF(QUERY ( temp <* boundaries | (temp\ + composite_curve_on_surface.basis_surface[1] <> SELF. + basis_surface) )) = 0); + END_ENTITY; -- curve_bounded_surface + + ENTITY curve_replica + SUBTYPE OF (curve); + parent_curve : curve; + transformation : cartesian_transformation_operator; + WHERE + wr1: (transformation.dim = parent_curve.dim); + wr2: acyclic_curve_replica(SELF,parent_curve); + END_ENTITY; -- curve_replica + + ENTITY cylindrical_surface + SUBTYPE OF (elementary_surface); + radius : positive_length_measure; + END_ENTITY; -- cylindrical_surface + + ENTITY date + SUPERTYPE OF (ONEOF (calendar_date,ordinal_date, + week_of_year_and_day_date)); + year_component : year_number; + END_ENTITY; -- date + + ENTITY date_and_time; + date_component : date; + time_component : local_time; + END_ENTITY; -- date_and_time + + ENTITY date_and_time_assignment + ABSTRACT SUPERTYPE; + assigned_date_and_time : date_and_time; + role : date_time_role; + END_ENTITY; -- date_and_time_assignment + + ENTITY date_time_role; + name : label; + END_ENTITY; -- date_time_role + + ENTITY dated_effectivity + SUBTYPE OF (effectivity); + effectivity_start_date : date_and_time; + effectivity_end_date : OPTIONAL date_and_time; + END_ENTITY; -- dated_effectivity + + ENTITY definitional_representation + SUBTYPE OF (representation); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.PARAMETRIC_REPRESENTATION_CONTEXT' IN + TYPEOF(SELF\representation.context_of_items)); + END_ENTITY; -- definitional_representation + + ENTITY degenerate_pcurve + SUBTYPE OF (point); + basis_surface : surface; + reference_to_curve : definitional_representation; + WHERE + wr1: (SIZEOF(reference_to_curve\representation.items) = 1); + wr2: ('CONFIG_CONTROL_DESIGN.CURVE' IN TYPEOF(reference_to_curve\ + representation.items[1])); + wr3: (reference_to_curve\representation.items[1]\ + geometric_representation_item.dim = 2); + END_ENTITY; -- degenerate_pcurve + + ENTITY degenerate_toroidal_surface + SUBTYPE OF (toroidal_surface); + select_outer : BOOLEAN; + WHERE + wr1: (major_radius < minor_radius); + END_ENTITY; -- degenerate_toroidal_surface + + ENTITY design_context + SUBTYPE OF (product_definition_context); + WHERE + wr1: (SELF.life_cycle_stage = 'design'); + END_ENTITY; -- design_context + + ENTITY design_make_from_relationship + SUBTYPE OF (product_definition_relationship); + END_ENTITY; -- design_make_from_relationship + + ENTITY dimensional_exponents; + length_exponent : REAL; + mass_exponent : REAL; + time_exponent : REAL; + electric_current_exponent : REAL; + thermodynamic_temperature_exponent : REAL; + amount_of_substance_exponent : REAL; + luminous_intensity_exponent : REAL; + END_ENTITY; -- dimensional_exponents + + ENTITY directed_action + SUBTYPE OF (executed_action); + directive : action_directive; + END_ENTITY; -- directed_action + + ENTITY direction + SUBTYPE OF (geometric_representation_item); + direction_ratios : LIST [2:3] OF REAL; + WHERE + wr1: (SIZEOF(QUERY ( tmp <* direction_ratios | (tmp <> 0) )) > 0); + END_ENTITY; -- direction + + ENTITY document; + id : identifier; + name : label; + description : text; + kind : document_type; + UNIQUE + ur1 : id; + END_ENTITY; -- document + + ENTITY document_reference + ABSTRACT SUPERTYPE; + assigned_document : document; + source : label; + END_ENTITY; -- document_reference + + ENTITY document_relationship; + name : label; + description : text; + relating_document : document; + related_document : document; + END_ENTITY; -- document_relationship + + ENTITY document_type; + product_data_type : label; + END_ENTITY; -- document_type + + ENTITY document_usage_constraint; + source : document; + subject_element : label; + subject_element_value : text; + END_ENTITY; -- document_usage_constraint + + ENTITY document_with_class + SUBTYPE OF (document); + class : identifier; + END_ENTITY; -- document_with_class + + ENTITY edge + SUPERTYPE OF (ONEOF (edge_curve,oriented_edge)) + SUBTYPE OF (topological_representation_item); + edge_start : vertex; + edge_end : vertex; + END_ENTITY; -- edge + + ENTITY edge_based_wireframe_model + SUBTYPE OF (geometric_representation_item); + ebwm_boundary : SET [1:?] OF connected_edge_set; + END_ENTITY; -- edge_based_wireframe_model + + ENTITY edge_based_wireframe_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2: (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) + >= 1); + wr3: (SIZEOF(QUERY ( ebwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( eb <* ebwm\ + edge_based_wireframe_model.ebwm_boundary | (NOT (SIZEOF( + QUERY ( edges <* eb.ces_edges | (NOT ( + 'CONFIG_CONTROL_DESIGN.EDGE_CURVE' IN TYPEOF(edges))) )) + = 0)) )) = 0)) )) = 0); + wr4: (SIZEOF(QUERY ( ebwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( eb <* ebwm\ + edge_based_wireframe_model.ebwm_boundary | (NOT (SIZEOF( + QUERY ( pline_edges <* QUERY ( edges <* eb.ces_edges | ( + 'CONFIG_CONTROL_DESIGN.POLYLINE' IN TYPEOF(edges\edge_curve. + edge_geometry)) ) | (NOT (SIZEOF(pline_edges\edge_curve. + edge_geometry\polyline.points) > 2)) )) = 0)) )) = 0)) )) = + 0); + wr5: (SIZEOF(QUERY ( ebwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( eb <* ebwm\ + edge_based_wireframe_model.ebwm_boundary | (NOT (SIZEOF( + QUERY ( edges <* eb.ces_edges | (NOT (( + 'CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(edges. + edge_start)) AND ('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN + TYPEOF(edges.edge_end)))) )) = 0)) )) = 0)) )) = 0); + wr6: (SIZEOF(QUERY ( ebwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( eb <* ebwm\ + edge_based_wireframe_model.ebwm_boundary | (NOT (SIZEOF( + QUERY ( edges <* eb.ces_edges | (NOT + valid_wireframe_edge_curve(edges\edge_curve.edge_geometry)) + )) = 0)) )) = 0)) )) = 0); + wr7: (SIZEOF(QUERY ( ebwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.EDGE_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( eb <* ebwm\ + edge_based_wireframe_model.ebwm_boundary | (NOT (SIZEOF( + QUERY ( edges <* eb.ces_edges | (NOT ( + valid_wireframe_vertex_point(edges.edge_start\vertex_point. + vertex_geometry) AND valid_wireframe_vertex_point(edges. + edge_end\vertex_point.vertex_geometry))) )) = 0)) )) = 0)) + )) = 0); + wr8: (SIZEOF(QUERY ( mi <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | (NOT + (('CONFIG_CONTROL_DESIGN.' + + 'EDGE_BASED_WIREFRAME_SHAPE_REPRESENTATION') IN TYPEOF(mi\ + mapped_item.mapping_source.mapped_representation))) )) = 0); + wr9: (SELF.context_of_items\geometric_representation_context. + coordinate_space_dimension = 3); + END_ENTITY; -- edge_based_wireframe_shape_representation + + ENTITY edge_curve + SUBTYPE OF (edge, geometric_representation_item); + edge_geometry : curve; + same_sense : BOOLEAN; + END_ENTITY; -- edge_curve + + ENTITY edge_loop + SUBTYPE OF (loop, path); + DERIVE + ne : INTEGER := SIZEOF(SELF\path.edge_list); + WHERE + wr1: (SELF\path.edge_list[1].edge_start :=: SELF\path.edge_list[ne]. + edge_end); + END_ENTITY; -- edge_loop + + ENTITY effectivity + SUPERTYPE OF (ONEOF (serial_numbered_effectivity,dated_effectivity, + lot_effectivity)); + id : identifier; + END_ENTITY; -- effectivity + + ENTITY elementary_surface + SUPERTYPE OF (ONEOF (plane,cylindrical_surface,conical_surface, + spherical_surface,toroidal_surface)) + SUBTYPE OF (surface); + position : axis2_placement_3d; + END_ENTITY; -- elementary_surface + + ENTITY ellipse + SUBTYPE OF (conic); + semi_axis_1 : positive_length_measure; + semi_axis_2 : positive_length_measure; + END_ENTITY; -- ellipse + + ENTITY evaluated_degenerate_pcurve + SUBTYPE OF (degenerate_pcurve); + equivalent_point : cartesian_point; + END_ENTITY; -- evaluated_degenerate_pcurve + + ENTITY executed_action + SUBTYPE OF (action); + END_ENTITY; -- executed_action + + ENTITY face + SUPERTYPE OF (ONEOF (face_surface,oriented_face)) + SUBTYPE OF (topological_representation_item); + bounds : SET [1:?] OF face_bound; + WHERE + wr1: (NOT mixed_loop_type_set(list_to_set(list_face_loops(SELF)))); + wr2: (SIZEOF(QUERY ( temp <* bounds | ( + 'CONFIG_CONTROL_DESIGN.FACE_OUTER_BOUND' IN TYPEOF(temp)) )) + <= 1); + END_ENTITY; -- face + + ENTITY face_bound + SUBTYPE OF (topological_representation_item); + bound : loop; + orientation : BOOLEAN; + END_ENTITY; -- face_bound + + ENTITY face_outer_bound + SUBTYPE OF (face_bound); + END_ENTITY; -- face_outer_bound + + ENTITY face_surface + SUBTYPE OF (face, geometric_representation_item); + face_geometry : surface; + same_sense : BOOLEAN; + END_ENTITY; -- face_surface + + ENTITY faceted_brep + SUBTYPE OF (manifold_solid_brep); + END_ENTITY; -- faceted_brep + + ENTITY faceted_brep_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( it <* items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.FACETED_BREP', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2: (SIZEOF(QUERY ( it <* items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.FACETED_BREP', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) > + 0); + wr3: (SIZEOF(QUERY ( fbrep <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.FACETED_BREP' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( csh <* msb_shells(fbrep) | (NOT (SIZEOF( + QUERY ( fcs <* csh\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.FACE_SURFACE' IN TYPEOF(fcs)) AND ( + 'CONFIG_CONTROL_DESIGN.PLANE' IN TYPEOF(fcs\face_surface. + face_geometry)) AND ('CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' + IN TYPEOF(fcs\face_surface.face_geometry\elementary_surface. + position.location)))) )) = 0)) )) = 0)) )) = 0); + wr4: (SIZEOF(QUERY ( fbrep <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.FACETED_BREP' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( csh <* msb_shells(fbrep) | (NOT (SIZEOF( + QUERY ( fcs <* csh\connected_face_set.cfs_faces | (NOT ( + SIZEOF(QUERY ( bnds <* fcs.bounds | ( + 'CONFIG_CONTROL_DESIGN.FACE_OUTER_BOUND' IN TYPEOF(bnds)) )) + = 1)) )) = 0)) )) = 0)) )) = 0); + wr5: (SIZEOF(QUERY ( msb <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SOLID_BREP' IN TYPEOF(it)) ) + | ('CONFIG_CONTROL_DESIGN.ORIENTED_CLOSED_SHELL' IN TYPEOF( + msb\manifold_solid_brep.outer)) )) = 0); + wr6: (SIZEOF(QUERY ( brv <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.BREP_WITH_VOIDS' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( csh <* brv\brep_with_voids.voids | csh\ + oriented_closed_shell.orientation )) = 0)) )) = 0); + wr7: (SIZEOF(QUERY ( mi <* QUERY ( it <* items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | (NOT + ('CONFIG_CONTROL_DESIGN.FACETED_BREP_SHAPE_REPRESENTATION' + IN TYPEOF(mi\mapped_item.mapping_source. + mapped_representation))) )) = 0); + END_ENTITY; -- faceted_brep_shape_representation + + ENTITY founded_item; + END_ENTITY; -- founded_item + + ENTITY functionally_defined_transformation; + name : label; + description : text; + END_ENTITY; -- functionally_defined_transformation + + ENTITY geometric_curve_set + SUBTYPE OF (geometric_set); + WHERE + wr1: (SIZEOF(QUERY ( temp <* SELF\geometric_set.elements | ( + 'CONFIG_CONTROL_DESIGN.SURFACE' IN TYPEOF(temp)) )) = 0); + END_ENTITY; -- geometric_curve_set + + ENTITY geometric_representation_context + SUBTYPE OF (representation_context); + coordinate_space_dimension : dimension_count; + END_ENTITY; -- geometric_representation_context + + ENTITY geometric_representation_item + SUPERTYPE OF (ONEOF (point,direction,vector,placement, + cartesian_transformation_operator,curve,surface,edge_curve, + face_surface,poly_loop,vertex_point,solid_model, + shell_based_surface_model,shell_based_wireframe_model, + edge_based_wireframe_model,geometric_set)) + SUBTYPE OF (representation_item); + DERIVE + dim : dimension_count := dimension_of(SELF); + WHERE + wr1: (SIZEOF(QUERY ( using_rep <* using_representations(SELF) | ( + NOT ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_REPRESENTATION_CONTEXT' IN + TYPEOF(using_rep.context_of_items))) )) = 0); + END_ENTITY; -- geometric_representation_item + + ENTITY geometric_set + SUPERTYPE OF (geometric_curve_set) + SUBTYPE OF (geometric_representation_item); + elements : SET [1:?] OF geometric_set_select; + END_ENTITY; -- geometric_set + + ENTITY geometrically_bounded_surface_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2: (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) > + 0); + wr3: (SIZEOF(QUERY ( mi <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | (NOT + ((('CONFIG_CONTROL_DESIGN.' + + 'GEOMETRICALLY_BOUNDED_SURFACE_SHAPE_REPRESENTATION') IN + TYPEOF(mi\mapped_item.mapping_source.mapped_representation)) + AND (SIZEOF(QUERY ( mr_it <* mi\mapped_item.mapping_source. + mapped_representation.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET' IN TYPEOF(mr_it)) )) > + 0))) )) = 0); + wr4: (SIZEOF(QUERY ( gs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( pnt <* QUERY ( gsel <* gs\geometric_set. + elements | ('CONFIG_CONTROL_DESIGN.POINT' IN TYPEOF(gsel)) ) + | (NOT gbsf_check_point(pnt)) )) = 0)) )) = 0); + wr5: (SIZEOF(QUERY ( gs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( cv <* QUERY ( gsel <* gs\geometric_set. + elements | ('CONFIG_CONTROL_DESIGN.CURVE' IN TYPEOF(gsel)) ) + | (NOT gbsf_check_curve(cv)) )) = 0)) )) = 0); + wr6: (SIZEOF(QUERY ( gs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET' IN TYPEOF(it)) ) | ( + NOT (SIZEOF(QUERY ( sf <* QUERY ( gsel <* gs\geometric_set. + elements | ('CONFIG_CONTROL_DESIGN.SURFACE' IN + TYPEOF(gsel)) ) | (NOT gbsf_check_surface(sf)) )) + = 0)) )) = 0); + wr7: (SIZEOF(QUERY ( gs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_SET' IN TYPEOF(it)) ) | ( + SIZEOF(QUERY ( gsel <* gs\geometric_set.elements | ( + 'CONFIG_CONTROL_DESIGN.SURFACE' IN TYPEOF(gsel)) )) > 0) )) + > 0); + END_ENTITY; -- geometrically_bounded_surface_shape_representation + + ENTITY geometrically_bounded_wireframe_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF(TYPEOF(it) * [ + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM']) = 1)) )) = 0); + wr2: (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF(TYPEOF(it) * [ + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM']) = 1) )) >= 1); + wr3: (SIZEOF(QUERY ( gcs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET' IN TYPEOF(it)) ) + | (NOT (SIZEOF(QUERY ( crv <* QUERY ( elem <* gcs\ + geometric_set.elements | ('CONFIG_CONTROL_DESIGN.CURVE' IN + TYPEOF(elem)) ) | (NOT valid_geometrically_bounded_wf_curve( + crv)) )) = 0)) )) = 0); + wr4: (SIZEOF(QUERY ( gcs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET' IN TYPEOF(it)) ) + | (NOT (SIZEOF(QUERY ( pnts <* QUERY ( elem <* gcs\ + geometric_set.elements | ('CONFIG_CONTROL_DESIGN.POINT' IN + TYPEOF(elem)) ) | (NOT valid_geometrically_bounded_wf_point( + pnts)) )) = 0)) )) = 0); + wr5: (SIZEOF(QUERY ( gcs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET' IN TYPEOF(it)) ) + | (NOT (SIZEOF(QUERY ( cnc <* QUERY ( elem <* gcs\ + geometric_set.elements | ('CONFIG_CONTROL_DESIGN.CONIC' IN + TYPEOF(elem)) ) | (NOT ( + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D' IN TYPEOF(cnc\ + conic.position))) )) = 0)) )) = 0); + wr6: (SIZEOF(QUERY ( gcs <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_CURVE_SET' IN TYPEOF(it)) ) + | (NOT (SIZEOF(QUERY ( pline <* QUERY ( elem <* gcs\ + geometric_set.elements | ('CONFIG_CONTROL_DESIGN.POLYLINE' + IN TYPEOF(elem)) ) | (NOT (SIZEOF(pline\polyline.points) + > 2)) )) = 0)) )) = 0); + wr7: (SIZEOF(QUERY ( mi <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | (NOT + (('CONFIG_CONTROL_DESIGN.' + + 'GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION') IN + TYPEOF(mi\mapped_item.mapping_source.mapped_representation) + )) )) = 0); + END_ENTITY; -- geometrically_bounded_wireframe_shape_representation + + ENTITY global_uncertainty_assigned_context + SUBTYPE OF (representation_context); + uncertainty : SET [1:?] OF uncertainty_measure_with_unit; + END_ENTITY; -- global_uncertainty_assigned_context + + ENTITY global_unit_assigned_context + SUBTYPE OF (representation_context); + units : SET [1:?] OF unit; + END_ENTITY; -- global_unit_assigned_context + + ENTITY hyperbola + SUBTYPE OF (conic); + semi_axis : positive_length_measure; + semi_imag_axis : positive_length_measure; + END_ENTITY; -- hyperbola + + ENTITY intersection_curve + SUBTYPE OF (surface_curve); + WHERE + wr1: (SIZEOF(SELF\surface_curve.associated_geometry) = 2); + wr2: (associated_surface(SELF\surface_curve.associated_geometry[1]) + <> associated_surface(SELF\surface_curve.associated_geometry + [2])); + END_ENTITY; -- intersection_curve + + ENTITY item_defined_transformation; + name : label; + description : text; + transform_item_1 : representation_item; + transform_item_2 : representation_item; + END_ENTITY; -- item_defined_transformation + + ENTITY length_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.LENGTH_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- length_measure_with_unit + + ENTITY length_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 1) AND (SELF\ + named_unit.dimensions.mass_exponent = 0) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- length_unit + + ENTITY line + SUBTYPE OF (curve); + pnt : cartesian_point; + dir : vector; + WHERE + wr1: (dir.dim = pnt.dim); + END_ENTITY; -- line + + ENTITY local_time; + hour_component : hour_in_day; + minute_component : OPTIONAL minute_in_hour; + second_component : OPTIONAL second_in_minute; + zone : coordinated_universal_time_offset; + WHERE + wr1: valid_time(SELF); + END_ENTITY; -- local_time + + ENTITY loop + SUPERTYPE OF (ONEOF (vertex_loop,edge_loop,poly_loop)) + SUBTYPE OF (topological_representation_item); + END_ENTITY; -- loop + + ENTITY lot_effectivity + SUBTYPE OF (effectivity); + effectivity_lot_id : identifier; + effectivity_lot_size : measure_with_unit; + END_ENTITY; -- lot_effectivity + + ENTITY manifold_solid_brep + SUBTYPE OF (solid_model); + outer : closed_shell; + END_ENTITY; -- manifold_solid_brep + + ENTITY manifold_surface_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1 : (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2 : (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) + > 0); + wr3 : (SIZEOF(QUERY ( mi <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | ( + NOT (('CONFIG_CONTROL_DESIGN.'+ + 'MANIFOLD_SURFACE_SHAPE_REPRESENTATION' + IN TYPEOF(mi\mapped_item.mapping_source. + mapped_representation)) AND (SIZEOF(QUERY ( mr_it <* mi\ + mapped_item.mapping_source.mapped_representation.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(mr_it)) )) > 0))) )) = 0); + wr4 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( sh <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.OPEN_SHELL', + 'CONFIG_CONTROL_DESIGN.ORIENTED_CLOSED_SHELL', + 'CONFIG_CONTROL_DESIGN.CLOSED_SHELL'] * TYPEOF(sh)) = 1)) + )) = 0)) )) = 0); + wr5 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT ( + SIZEOF(['CONFIG_CONTROL_DESIGN.FACE_SURFACE', + 'CONFIG_CONTROL_DESIGN.ORIENTED_FACE'] * TYPEOF(fa)) = 1)) + )) = 0)) )) = 0)) )) = 0); + wr6 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( f_sf <* QUERY ( fa <* cfs\connected_face_set. + cfs_faces | ('CONFIG_CONTROL_DESIGN.FACE_SURFACE' IN + TYPEOF(fa)) ) | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(f_sf)) OR ( + SIZEOF(['CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE', + 'CONFIG_CONTROL_DESIGN.ELEMENTARY_SURFACE', + 'CONFIG_CONTROL_DESIGN.OFFSET_SURFACE', + 'CONFIG_CONTROL_DESIGN.SURFACE_REPLICA', + 'CONFIG_CONTROL_DESIGN.SWEPT_SURFACE'] * TYPEOF(f_sf\ + face_surface.face_geometry)) = 1))) )) = 0)) )) = 0)) )) = + 0); + wr7 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR + msf_surface_check(fa\face_surface.face_geometry))) )) + = 0)) )) = 0)) )) = 0); + wr8 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( bnds <* fa.bounds | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP', + 'CONFIG_CONTROL_DESIGN.VERTEX_LOOP'] * TYPEOF(bnds.bound)) + = 1)) )) = 0))) )) = 0)) )) = 0)) )) = 0); + wr9 : (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds\path.edge_list | ( + NOT ('CONFIG_CONTROL_DESIGN.EDGE_CURVE' IN TYPEOF(oe. + edge_element))))) = 0)))) = 0))))) = 0)) )) = 0)) )) = 0); + wr10: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe_cv <* QUERY ( oe <* elp_fbnds\ + path.edge_list | ('CONFIG_CONTROL_DESIGN.EDGE_CURVE' IN + TYPEOF(oe.edge_element)) ) | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE', + 'CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA', + 'CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D', + 'CONFIG_CONTROL_DESIGN.PCURVE', + 'CONFIG_CONTROL_DESIGN.POLYLINE', + 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE'] * TYPEOF(oe_cv. + edge_element\edge_curve.edge_geometry)) = 1)) )) = 0)) )) = + 0))) )) = 0)) )) = 0)) )) = 0); + wr11: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds\path.edge_list | ( + NOT msf_curve_check(oe.edge_element\edge_curve. + edge_geometry)) )) = 0)) )) = 0))) )) + = 0)) )) = 0)) )) = 0); + wr12: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds\path.edge_list | ( + NOT (('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(oe. + edge_element.edge_start)) AND ( + 'CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(oe. + edge_element.edge_end)))) )) = 0)) )) = 0))) )) = 0)) )) = + 0)) )) = 0); + wr13: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( elp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(QUERY ( oe <* elp_fbnds\path.edge_list | ( + NOT ((SIZEOF(['CONFIG_CONTROL_DESIGN.CARTESIAN_POINT', + 'CONFIG_CONTROL_DESIGN.DEGENERATE_PCURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_CURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_SURFACE'] * TYPEOF(oe. + edge_element.edge_start\vertex_point.vertex_geometry)) = 1) + AND (SIZEOF(['CONFIG_CONTROL_DESIGN.CARTESIAN_POINT', + 'CONFIG_CONTROL_DESIGN.DEGENERATE_PCURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_CURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_SURFACE'] * TYPEOF(oe. + edge_element.edge_end\vertex_point.vertex_geometry)) + = 1))) )) = 0)) )) = 0))) )) = 0)) )) = 0)) )) = 0); + wr14: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( vlp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.VERTEX_LOOP' + IN TYPEOF(bnds.bound)) ) + | (NOT ('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF( + vlp_fbnds\vertex_loop.loop_vertex))) )) = 0))) )) = 0)) )) + = 0)) )) = 0); + wr15: (SIZEOF(QUERY ( sbsm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_SURFACE_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( cfs <* sbsm\ + shell_based_surface_model.sbsm_boundary | (NOT (SIZEOF( + QUERY ( fa <* cfs\connected_face_set.cfs_faces | (NOT (( + 'CONFIG_CONTROL_DESIGN.ADVANCED_FACE' IN TYPEOF(fa)) OR ( + SIZEOF(QUERY ( vlp_fbnds <* QUERY ( bnds <* fa.bounds | ( + 'CONFIG_CONTROL_DESIGN.VERTEX_LOOP' + IN TYPEOF(bnds.bound)) ) + | (NOT (SIZEOF(['CONFIG_CONTROL_DESIGN.CARTESIAN_POINT', + 'CONFIG_CONTROL_DESIGN.DEGENERATE_PCURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_CURVE', + 'CONFIG_CONTROL_DESIGN.POINT_ON_SURFACE'] * TYPEOF( + vlp_fbnds\vertex_loop.loop_vertex\vertex_point. + vertex_geometry)) = 1)) )) = 0))) )) + = 0)) )) = 0)) )) = 0); + END_ENTITY; -- manifold_surface_shape_representation + + ENTITY mapped_item + SUBTYPE OF (representation_item); + mapping_source : representation_map; + mapping_target : representation_item; + WHERE + wr1: acyclic_mapped_representation(using_representations(SELF), + [SELF]); + END_ENTITY; -- mapped_item + + ENTITY mass_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.MASS_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- mass_measure_with_unit + + ENTITY mass_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 0) AND (SELF\ + named_unit.dimensions.mass_exponent = 1) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- mass_unit + + ENTITY measure_with_unit + SUPERTYPE OF (ONEOF (length_measure_with_unit,mass_measure_with_unit, + plane_angle_measure_with_unit,solid_angle_measure_with_unit, + area_measure_with_unit,volume_measure_with_unit)); + value_component : measure_value; + unit_component : unit; + WHERE + wr1: valid_units(SELF); + END_ENTITY; -- measure_with_unit + + ENTITY mechanical_context + SUBTYPE OF (product_context); + WHERE + wr1: (SELF.discipline_type = 'mechanical'); + END_ENTITY; -- mechanical_context + + ENTITY named_unit + SUPERTYPE OF (ONEOF (si_unit,conversion_based_unit, + context_dependent_unit) ANDOR ONEOF (length_unit,mass_unit, + plane_angle_unit,solid_angle_unit,area_unit,volume_unit)); + dimensions : dimensional_exponents; + END_ENTITY; -- named_unit + + ENTITY next_assembly_usage_occurrence + SUBTYPE OF (assembly_component_usage); + END_ENTITY; -- next_assembly_usage_occurrence + + ENTITY offset_curve_3d + SUBTYPE OF (curve); + basis_curve : curve; + distance : length_measure; + self_intersect : LOGICAL; + ref_direction : direction; + WHERE + wr1: ((basis_curve.dim = 3) AND (ref_direction.dim = 3)); + END_ENTITY; -- offset_curve_3d + + ENTITY offset_surface + SUBTYPE OF (surface); + basis_surface : surface; + distance : length_measure; + self_intersect : LOGICAL; + END_ENTITY; -- offset_surface + + ENTITY open_shell + SUBTYPE OF (connected_face_set); + END_ENTITY; -- open_shell + + ENTITY ordinal_date + SUBTYPE OF (date); + day_component : day_in_year_number; + WHERE + wr1: (((NOT leap_year(SELF.year_component)) AND (1 <= day_component) + AND (day_component <= 365)) OR (leap_year(SELF. + year_component) AND (1 <= day_component) AND (day_component + <= 366))); + END_ENTITY; -- ordinal_date + + ENTITY organization; + id : OPTIONAL identifier; + name : label; + description : text; + END_ENTITY; -- organization + + ENTITY organization_relationship; + name : label; + description : text; + relating_organization : organization; + related_organization : organization; + END_ENTITY; -- organization_relationship + + ENTITY organizational_address + SUBTYPE OF (address); + organizations : SET [1:?] OF organization; + description : text; + END_ENTITY; -- organizational_address + + ENTITY organizational_project; + name : label; + description : text; + responsible_organizations : SET [1:?] OF organization; + END_ENTITY; -- organizational_project + + ENTITY oriented_closed_shell + SUBTYPE OF (closed_shell); + closed_shell_element : closed_shell; + orientation : BOOLEAN; + DERIVE + SELF\connected_face_set.cfs_faces : SET [1:?] OF face := + conditional_reverse(SELF.orientation,SELF. + closed_shell_element.cfs_faces); + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.ORIENTED_CLOSED_SHELL' IN TYPEOF( + SELF.closed_shell_element))); + END_ENTITY; -- oriented_closed_shell + + ENTITY oriented_edge + SUBTYPE OF (edge); + edge_element : edge; + orientation : BOOLEAN; + DERIVE + SELF\edge.edge_start : vertex := boolean_choose(SELF.orientation, + SELF.edge_element.edge_start,SELF. + edge_element.edge_end); + SELF\edge.edge_end : vertex := boolean_choose(SELF.orientation, + SELF.edge_element.edge_end,SELF. + edge_element.edge_start); + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.ORIENTED_EDGE' IN TYPEOF(SELF. + edge_element))); + END_ENTITY; -- oriented_edge + + ENTITY oriented_face + SUBTYPE OF (face); + face_element : face; + orientation : BOOLEAN; + DERIVE + SELF\face.bounds : SET [1:?] OF face_bound := conditional_reverse( + SELF.orientation,SELF.face_element.bounds); + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.ORIENTED_FACE' IN TYPEOF(SELF. + face_element))); + END_ENTITY; -- oriented_face + + ENTITY oriented_open_shell + SUBTYPE OF (open_shell); + open_shell_element : open_shell; + orientation : BOOLEAN; + DERIVE + SELF\connected_face_set.cfs_faces : SET [1:?] OF face := + conditional_reverse(SELF. + orientation,SELF. + open_shell_element.cfs_faces); + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.ORIENTED_OPEN_SHELL' IN TYPEOF( + SELF.open_shell_element))); + END_ENTITY; -- oriented_open_shell + + ENTITY oriented_path + SUBTYPE OF (path); + path_element : path; + orientation : BOOLEAN; + DERIVE + SELF\path.edge_list : LIST [1:?] OF UNIQUE oriented_edge := + conditional_reverse(SELF.orientation,SELF. + path_element.edge_list); + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.ORIENTED_PATH' IN TYPEOF(SELF. + path_element))); + END_ENTITY; -- oriented_path + + ENTITY outer_boundary_curve + SUBTYPE OF (boundary_curve); + END_ENTITY; -- outer_boundary_curve + + ENTITY parabola + SUBTYPE OF (conic); + focal_dist : length_measure; + WHERE + wr1: (focal_dist <> 0); + END_ENTITY; -- parabola + + ENTITY parametric_representation_context + SUBTYPE OF (representation_context); + END_ENTITY; -- parametric_representation_context + + ENTITY path + SUPERTYPE OF (ONEOF (edge_loop,oriented_path)) + SUBTYPE OF (topological_representation_item); + edge_list : LIST [1:?] OF UNIQUE oriented_edge; + WHERE + wr1: path_head_to_tail(SELF); + END_ENTITY; -- path + + ENTITY pcurve + SUBTYPE OF (curve); + basis_surface : surface; + reference_to_curve : definitional_representation; + WHERE + wr1: (SIZEOF(reference_to_curve\representation.items) = 1); + wr2: ('CONFIG_CONTROL_DESIGN.CURVE' IN TYPEOF(reference_to_curve\ + representation.items[1])); + wr3: (reference_to_curve\representation.items[1]\ + geometric_representation_item.dim = 2); + END_ENTITY; -- pcurve + + ENTITY person; + id : identifier; + last_name : OPTIONAL label; + first_name : OPTIONAL label; + middle_names : OPTIONAL LIST [1:?] OF label; + prefix_titles : OPTIONAL LIST [1:?] OF label; + suffix_titles : OPTIONAL LIST [1:?] OF label; + UNIQUE + ur1 : id; + WHERE + wr1: (EXISTS(last_name) OR EXISTS(first_name)); + END_ENTITY; -- person + + ENTITY person_and_organization; + the_person : person; + the_organization : organization; + END_ENTITY; -- person_and_organization + + ENTITY person_and_organization_assignment + ABSTRACT SUPERTYPE; + assigned_person_and_organization : person_and_organization; + role : person_and_organization_role; + END_ENTITY; -- person_and_organization_assignment + + ENTITY person_and_organization_role; + name : label; + END_ENTITY; -- person_and_organization_role + + ENTITY personal_address + SUBTYPE OF (address); + people : SET [1:?] OF person; + description : text; + END_ENTITY; -- personal_address + + ENTITY placement + SUPERTYPE OF (ONEOF (axis1_placement,axis2_placement_2d, + axis2_placement_3d)) + SUBTYPE OF (geometric_representation_item); + location : cartesian_point; + END_ENTITY; -- placement + + ENTITY plane + SUBTYPE OF (elementary_surface); + END_ENTITY; -- plane + + ENTITY plane_angle_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.PLANE_ANGLE_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- plane_angle_measure_with_unit + + ENTITY plane_angle_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 0) AND (SELF\ + named_unit.dimensions.mass_exponent = 0) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- plane_angle_unit + + ENTITY point + SUPERTYPE OF (ONEOF (cartesian_point,point_on_curve,point_on_surface, + point_replica,degenerate_pcurve)) + SUBTYPE OF (geometric_representation_item); + END_ENTITY; -- point + + ENTITY point_on_curve + SUBTYPE OF (point); + basis_curve : curve; + point_parameter : parameter_value; + END_ENTITY; -- point_on_curve + + ENTITY point_on_surface + SUBTYPE OF (point); + basis_surface : surface; + point_parameter_u : parameter_value; + point_parameter_v : parameter_value; + END_ENTITY; -- point_on_surface + + ENTITY point_replica + SUBTYPE OF (point); + parent_pt : point; + transformation : cartesian_transformation_operator; + WHERE + wr1: (transformation.dim = parent_pt.dim); + wr2: acyclic_point_replica(SELF,parent_pt); + END_ENTITY; -- point_replica + + ENTITY poly_loop + SUBTYPE OF (loop, geometric_representation_item); + polygon : LIST [3:?] OF UNIQUE cartesian_point; + END_ENTITY; -- poly_loop + + ENTITY polyline + SUBTYPE OF (bounded_curve); + points : LIST [2:?] OF cartesian_point; + END_ENTITY; -- polyline + + ENTITY product; + id : identifier; + name : label; + description : text; + frame_of_reference : SET [1:?] OF product_context; + UNIQUE + ur1 : id; + END_ENTITY; -- product + + ENTITY product_category; + name : label; + description : OPTIONAL text; + END_ENTITY; -- product_category + + ENTITY product_category_relationship; + name : label; + description : text; + category : product_category; + sub_category : product_category; + WHERE + wr1: acyclic_product_category_relationship(SELF,[SELF.sub_category]); + END_ENTITY; -- product_category_relationship + + ENTITY product_concept; + id : identifier; + name : label; + description : text; + market_context : product_concept_context; + UNIQUE + ur1 : id; + END_ENTITY; -- product_concept + + ENTITY product_concept_context + SUBTYPE OF (application_context_element); + market_segment_type : label; + END_ENTITY; -- product_concept_context + + ENTITY product_context + SUBTYPE OF (application_context_element); + discipline_type : label; + END_ENTITY; -- product_context + + ENTITY product_definition; + id : identifier; + description : text; + formation : product_definition_formation; + frame_of_reference : product_definition_context; + END_ENTITY; -- product_definition + + ENTITY product_definition_context + SUBTYPE OF (application_context_element); + life_cycle_stage : label; + END_ENTITY; -- product_definition_context + + ENTITY product_definition_effectivity + SUBTYPE OF (effectivity); + usage : product_definition_relationship; + UNIQUE + ur1 : usage, id; + END_ENTITY; -- product_definition_effectivity + + ENTITY product_definition_formation; + id : identifier; + description : text; + of_product : product; + UNIQUE + ur1 : id, of_product; + END_ENTITY; -- product_definition_formation + + ENTITY product_definition_formation_with_specified_source + SUBTYPE OF (product_definition_formation); + make_or_buy : source; + END_ENTITY; -- product_definition_formation_with_specified_source + + ENTITY product_definition_relationship; + id : identifier; + name : label; + description : text; + relating_product_definition : product_definition; + related_product_definition : product_definition; + END_ENTITY; -- product_definition_relationship + + ENTITY product_definition_shape + SUBTYPE OF (property_definition); + UNIQUE + ur1 : definition; + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.SHAPE_DEFINITION' IN TYPEOF(SELF\ + property_definition.definition))); + END_ENTITY; -- product_definition_shape + + ENTITY product_definition_usage + SUPERTYPE OF (assembly_component_usage) + SUBTYPE OF (product_definition_relationship); + UNIQUE + ur1 : id, relating_product_definition, related_product_definition; + WHERE + wr1: acyclic_product_definition_relationship(SELF,[SELF\ + product_definition_relationship.related_product_definition], + 'CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_USAGE'); + END_ENTITY; -- product_definition_usage + + ENTITY product_definition_with_associated_documents + SUBTYPE OF (product_definition); + documentation_ids : SET [1:?] OF document; + END_ENTITY; -- product_definition_with_associated_documents + + ENTITY product_related_product_category + SUBTYPE OF (product_category); + products : SET [1:?] OF product; + END_ENTITY; -- product_related_product_category + + ENTITY promissory_usage_occurrence + SUBTYPE OF (assembly_component_usage); + END_ENTITY; -- promissory_usage_occurrence + + ENTITY property_definition; + name : label; + description : text; + definition : characterized_definition; + END_ENTITY; -- property_definition + + ENTITY property_definition_representation; + definition : property_definition; + used_representation : representation; + END_ENTITY; -- property_definition_representation + + ENTITY quantified_assembly_component_usage + SUBTYPE OF (assembly_component_usage); + quantity : measure_with_unit; + END_ENTITY; -- quantified_assembly_component_usage + + ENTITY quasi_uniform_curve + SUBTYPE OF (b_spline_curve); + END_ENTITY; -- quasi_uniform_curve + + ENTITY quasi_uniform_surface + SUBTYPE OF (b_spline_surface); + END_ENTITY; -- quasi_uniform_surface + + ENTITY rational_b_spline_curve + SUBTYPE OF (b_spline_curve); + weights_data : LIST [2:?] OF REAL; + DERIVE + weights : ARRAY [0:upper_index_on_control_points] OF REAL := + list_to_array(weights_data,0, + upper_index_on_control_points); + WHERE + wr1: (SIZEOF(weights_data) = SIZEOF(SELF\b_spline_curve. + control_points_list)); + wr2: curve_weights_positive(SELF); + END_ENTITY; -- rational_b_spline_curve + + ENTITY rational_b_spline_surface + SUBTYPE OF (b_spline_surface); + weights_data : LIST [2:?] OF LIST [2:?] OF REAL; + DERIVE + weights : ARRAY [0:u_upper] OF ARRAY [0:v_upper] OF REAL := + make_array_of_array(weights_data,0,u_upper,0,v_upper); + WHERE + wr1: ((SIZEOF(weights_data) = SIZEOF(SELF\b_spline_surface. + control_points_list)) AND (SIZEOF(weights_data[1]) = SIZEOF( + SELF\b_spline_surface.control_points_list[1]))); + wr2: surface_weights_positive(SELF); + END_ENTITY; -- rational_b_spline_surface + + ENTITY rectangular_composite_surface + SUBTYPE OF (bounded_surface); + segments : LIST [1:?] OF LIST [1:?] OF surface_patch; + DERIVE + n_u : INTEGER := SIZEOF(segments); + n_v : INTEGER := SIZEOF(segments[1]); + WHERE + wr1: ([] = QUERY ( s <* segments | (n_v <> SIZEOF(s)) )); + wr2: constraints_rectangular_composite_surface(SELF); + END_ENTITY; -- rectangular_composite_surface + + ENTITY rectangular_trimmed_surface + SUBTYPE OF (bounded_surface); + basis_surface : surface; + u1 : parameter_value; + u2 : parameter_value; + v1 : parameter_value; + v2 : parameter_value; + usense : BOOLEAN; + vsense : BOOLEAN; + WHERE + wr1: (u1 <> u2); + wr2: (v1 <> v2); + wr3: ((('CONFIG_CONTROL_DESIGN.ELEMENTARY_SURFACE' IN TYPEOF( + basis_surface)) AND (NOT ('CONFIG_CONTROL_DESIGN.PLANE' IN + TYPEOF(basis_surface)))) OR ( + 'CONFIG_CONTROL_DESIGN.SURFACE_OF_REVOLUTION' IN TYPEOF( + basis_surface)) OR (usense = (u2 > u1))); + wr4: (('CONFIG_CONTROL_DESIGN.SPHERICAL_SURFACE' IN TYPEOF( + basis_surface)) OR ('CONFIG_CONTROL_DESIGN.TOROIDAL_SURFACE' + IN TYPEOF(basis_surface)) OR (vsense = (v2 > v1))); + END_ENTITY; -- rectangular_trimmed_surface + + ENTITY reparametrised_composite_curve_segment + SUBTYPE OF (composite_curve_segment); + param_length : parameter_value; + WHERE + wr1: (param_length > 0); + END_ENTITY; -- reparametrised_composite_curve_segment + + ENTITY representation; + name : label; + items : SET [1:?] OF representation_item; + context_of_items : representation_context; + END_ENTITY; -- representation + + ENTITY representation_context; + context_identifier : identifier; + context_type : text; + INVERSE + representations_in_context : SET [1:?] OF representation FOR + context_of_items; + END_ENTITY; -- representation_context + + ENTITY representation_item; + name : label; + WHERE + wr1: (SIZEOF(using_representations(SELF)) > 0); + END_ENTITY; -- representation_item + + ENTITY representation_map; + mapping_origin : representation_item; + mapped_representation : representation; + INVERSE + map_usage : SET [1:?] OF mapped_item FOR mapping_source; + WHERE + wr1: item_in_context(SELF.mapping_origin,SELF.mapped_representation. + context_of_items); + END_ENTITY; -- representation_map + + ENTITY representation_relationship; + name : label; + description : text; + rep_1 : representation; + rep_2 : representation; + END_ENTITY; -- representation_relationship + + ENTITY representation_relationship_with_transformation + SUBTYPE OF (representation_relationship); + transformation_operator : transformation; + WHERE + wr1: (SELF\representation_relationship.rep_1.context_of_items :<>: + SELF\representation_relationship.rep_2.context_of_items); + END_ENTITY; -- representation_relationship_with_transformation + + ENTITY seam_curve + SUBTYPE OF (surface_curve); + WHERE + wr1: (SIZEOF(SELF\surface_curve.associated_geometry) = 2); + wr2: (associated_surface(SELF\surface_curve.associated_geometry[1]) + = associated_surface(SELF\surface_curve.associated_geometry[ + 2])); + wr3: ('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(SELF\surface_curve. + associated_geometry[1])); + wr4: ('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(SELF\surface_curve. + associated_geometry[2])); + END_ENTITY; -- seam_curve + + ENTITY security_classification; + name : label; + purpose : text; + security_level : security_classification_level; + END_ENTITY; -- security_classification + + ENTITY security_classification_assignment + ABSTRACT SUPERTYPE; + assigned_security_classification : security_classification; + END_ENTITY; -- security_classification_assignment + + ENTITY security_classification_level; + name : label; + END_ENTITY; -- security_classification_level + + ENTITY serial_numbered_effectivity + SUBTYPE OF (effectivity); + effectivity_start_id : identifier; + effectivity_end_id : OPTIONAL identifier; + END_ENTITY; -- serial_numbered_effectivity + + ENTITY shape_aspect; + name : label; + description : text; + of_shape : product_definition_shape; + product_definitional : LOGICAL; + END_ENTITY; -- shape_aspect + + ENTITY shape_aspect_relationship; + name : label; + description : text; + relating_shape_aspect : shape_aspect; + related_shape_aspect : shape_aspect; + END_ENTITY; -- shape_aspect_relationship + + ENTITY shape_definition_representation + SUBTYPE OF (property_definition_representation); + WHERE + wr1: (('CONFIG_CONTROL_DESIGN.SHAPE_DEFINITION' IN TYPEOF(SELF. + definition.definition)) OR ( + 'CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_SHAPE' IN TYPEOF( + SELF.definition))); + wr2: ('CONFIG_CONTROL_DESIGN.SHAPE_REPRESENTATION' IN TYPEOF(SELF. + used_representation)); + END_ENTITY; -- shape_definition_representation + + ENTITY shape_representation + SUBTYPE OF (representation); + END_ENTITY; -- shape_representation + + ENTITY shape_representation_relationship + SUBTYPE OF (representation_relationship); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.SHAPE_REPRESENTATION' IN (TYPEOF(SELF\ + representation_relationship.rep_1) + TYPEOF(SELF\ + representation_relationship.rep_2))); + END_ENTITY; -- shape_representation_relationship + + ENTITY shell_based_surface_model + SUBTYPE OF (geometric_representation_item); + sbsm_boundary : SET [1:?] OF shell; + WHERE + wr1: constraints_geometry_shell_based_surface_model(SELF); + END_ENTITY; -- shell_based_surface_model + + ENTITY shell_based_wireframe_model + SUBTYPE OF (geometric_representation_item); + sbwm_boundary : SET [1:?] OF shell; + WHERE + wr1: constraints_geometry_shell_based_wireframe_model(SELF); + END_ENTITY; -- shell_based_wireframe_model + + ENTITY shell_based_wireframe_shape_representation + SUBTYPE OF (shape_representation); + WHERE + wr1 : (SIZEOF(QUERY ( it <* SELF.items | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM', + 'CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D'] * TYPEOF(it)) = + 1)) )) = 0); + wr2 : (SIZEOF(QUERY ( it <* SELF.items | (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL', + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM'] * TYPEOF(it)) = 1) )) + >= 1); + wr3 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( eloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN + TYPEOF(wsb)) ) | (NOT (SIZEOF(QUERY ( el <* eloop\path. + edge_list | (NOT ('CONFIG_CONTROL_DESIGN.EDGE_CURVE' IN + TYPEOF(el.edge_element))) )) = 0)) )) + = 0)) )) = 0)) )) = 0); + wr4 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( eloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN + TYPEOF(wsb)) ) | (NOT (SIZEOF(QUERY ( pline_el <* + QUERY ( el <* eloop\path.edge_list | ( + 'CONFIG_CONTROL_DESIGN.POLYLINE' IN TYPEOF(el.edge_element\ + edge_curve.edge_geometry)) ) | (NOT (SIZEOF(pline_el. + edge_element\edge_curve.edge_geometry\polyline.points) + > 2)) )) = 0)) )) = 0)) )) = 0)) )) = 0); + wr5 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( eloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN + TYPEOF(wsb)) ) | (NOT (SIZEOF(QUERY ( el <* eloop\path. + edge_list | (NOT valid_wireframe_edge_curve(el.edge_element + \edge_curve.edge_geometry)) )) = 0)) )) = 0)) )) = 0)) )) = + 0); + wr6 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( eloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN + TYPEOF(wsb)) ) | (NOT (SIZEOF(QUERY ( el <* eloop\path. + edge_list | (NOT (('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN + TYPEOF(el.edge_element.edge_start)) AND ( + 'CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(el. + edge_element.edge_end)))) )) = 0)) )) + = 0)) )) = 0)) )) = 0); + wr7 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( eloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.EDGE_LOOP' IN + TYPEOF(wsb)) ) | (NOT (SIZEOF(QUERY ( el <* eloop\path. + edge_list | (NOT (valid_wireframe_vertex_point(el. + edge_element.edge_start\vertex_point.vertex_geometry) AND + valid_wireframe_vertex_point(el.edge_element.edge_end\ + vertex_point.vertex_geometry))) )) = 0)) )) + = 0)) )) = 0)) )) = 0); + wr8 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( vloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.VERTEX_LOOP' IN + TYPEOF(wsb)) ) | (NOT ( + 'CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(vloop\ + vertex_loop.loop_vertex))) )) = 0)) )) = 0)) )) = 0); + wr9 : (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( ws <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(sb)) ) | (NOT + (SIZEOF(QUERY ( vloop <* QUERY ( wsb <* ws\wire_shell. + wire_shell_extent | ('CONFIG_CONTROL_DESIGN.VERTEX_LOOP' IN + TYPEOF(wsb)) ) | (NOT valid_wireframe_vertex_point(vloop\ + vertex_loop.loop_vertex\vertex_point.vertex_geometry)) )) = + 0)) )) = 0)) )) = 0); + wr10: (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( vs <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.VERTEX_SHELL' IN TYPEOF(sb)) ) | ( + NOT ('CONFIG_CONTROL_DESIGN.VERTEX_POINT' IN TYPEOF(vs\ + vertex_shell.vertex_shell_extent.loop_vertex))) )) = 0)) )) + = 0); + wr11: (SIZEOF(QUERY ( sbwm <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.SHELL_BASED_WIREFRAME_MODEL' IN + TYPEOF(it)) ) | (NOT (SIZEOF(QUERY ( vs <* QUERY ( sb <* + sbwm\shell_based_wireframe_model.sbwm_boundary | ( + 'CONFIG_CONTROL_DESIGN.VERTEX_SHELL' IN TYPEOF(sb)) ) | ( + NOT valid_wireframe_vertex_point(vs\vertex_shell. + vertex_shell_extent.loop_vertex\vertex_point. + vertex_geometry)) )) = 0)) )) = 0); + wr12: (SIZEOF(QUERY ( mi <* QUERY ( it <* SELF.items | ( + 'CONFIG_CONTROL_DESIGN.MAPPED_ITEM' IN TYPEOF(it)) ) | ( + NOT (('CONFIG_CONTROL_DESIGN.' + + 'SHELL_BASED_WIREFRAME_SHAPE_REPRESENTATION') IN TYPEOF(mi\ + mapped_item.mapping_source.mapped_representation))) )) + = 0); + wr13: (SELF.context_of_items\geometric_representation_context. + coordinate_space_dimension = 3); + END_ENTITY; -- shell_based_wireframe_shape_representation + + ENTITY si_unit + SUBTYPE OF (named_unit); + prefix : OPTIONAL si_prefix; + name : si_unit_name; + DERIVE + SELF\named_unit.dimensions : dimensional_exponents := + dimensions_for_si_unit(SELF.name); + END_ENTITY; -- si_unit + + ENTITY solid_angle_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.SOLID_ANGLE_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- solid_angle_measure_with_unit + + ENTITY solid_angle_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 0) AND (SELF\ + named_unit.dimensions.mass_exponent = 0) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- solid_angle_unit + + ENTITY solid_model + SUPERTYPE OF (manifold_solid_brep) + SUBTYPE OF (geometric_representation_item); + END_ENTITY; -- solid_model + + ENTITY specified_higher_usage_occurrence + SUBTYPE OF (assembly_component_usage); + upper_usage : assembly_component_usage; + next_usage : next_assembly_usage_occurrence; + UNIQUE + ur1 : upper_usage, next_usage; + WHERE + wr1: (SELF :<>: upper_usage); + wr2: (SELF\product_definition_relationship. + relating_product_definition :=: upper_usage. + relating_product_definition); + wr3: (SELF\product_definition_relationship. + related_product_definition :=: next_usage. + related_product_definition); + wr4: (upper_usage.related_product_definition :=: next_usage. + relating_product_definition); + wr5: (NOT ('CONFIG_CONTROL_DESIGN.PROMISSORY_USAGE_OCCURRENCE' IN + TYPEOF(upper_usage))); + END_ENTITY; -- specified_higher_usage_occurrence + + ENTITY spherical_surface + SUBTYPE OF (elementary_surface); + radius : positive_length_measure; + END_ENTITY; -- spherical_surface + + ENTITY start_request + SUBTYPE OF (action_request_assignment); + items : SET [1:?] OF start_request_item; + END_ENTITY; -- start_request + + ENTITY start_work + SUBTYPE OF (action_assignment); + items : SET [1:?] OF work_item; + END_ENTITY; -- start_work + + ENTITY supplied_part_relationship + SUBTYPE OF (product_definition_relationship); + END_ENTITY; -- supplied_part_relationship + + ENTITY surface + SUPERTYPE OF (ONEOF (elementary_surface,swept_surface,bounded_surface, + offset_surface,surface_replica)) + SUBTYPE OF (geometric_representation_item); + END_ENTITY; -- surface + + ENTITY surface_curve + SUPERTYPE OF (ONEOF (intersection_curve,seam_curve) ANDOR + bounded_surface_curve) + SUBTYPE OF (curve); + curve_3d : curve; + associated_geometry : LIST [1:2] OF pcurve_or_surface; + master_representation : preferred_surface_curve_representation; + DERIVE + basis_surface : SET [1:2] OF surface := get_basis_surface(SELF); + WHERE + wr1: (curve_3d.dim = 3); + wr2: (('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(associated_geometry[ + 1])) OR (master_representation <> pcurve_s1)); + wr3: (('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(associated_geometry[ + 2])) OR (master_representation <> pcurve_s2)); + wr4: (NOT ('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(curve_3d))); + END_ENTITY; -- surface_curve + + ENTITY surface_of_linear_extrusion + SUBTYPE OF (swept_surface); + extrusion_axis : vector; + END_ENTITY; -- surface_of_linear_extrusion + + ENTITY surface_of_revolution + SUBTYPE OF (swept_surface); + axis_position : axis1_placement; + DERIVE + axis_line : line := dummy_gri || curve() || line(axis_position. + location,dummy_gri || vector(axis_position.z,1)); + END_ENTITY; -- surface_of_revolution + + ENTITY surface_patch + SUBTYPE OF (founded_item); + parent_surface : bounded_surface; + u_transition : transition_code; + v_transition : transition_code; + u_sense : BOOLEAN; + v_sense : BOOLEAN; + INVERSE + using_surfaces : BAG [1:?] OF rectangular_composite_surface FOR + segments; + WHERE + wr1: (NOT ('CONFIG_CONTROL_DESIGN.CURVE_BOUNDED_SURFACE' IN TYPEOF( + parent_surface))); + END_ENTITY; -- surface_patch + + ENTITY surface_replica + SUBTYPE OF (surface); + parent_surface : surface; + transformation : cartesian_transformation_operator_3d; + WHERE + wr1: acyclic_surface_replica(SELF,parent_surface); + END_ENTITY; -- surface_replica + + ENTITY swept_surface + SUPERTYPE OF (ONEOF (surface_of_linear_extrusion, + surface_of_revolution)) + SUBTYPE OF (surface); + swept_curve : curve; + END_ENTITY; -- swept_surface + + ENTITY topological_representation_item + SUPERTYPE OF (ONEOF (vertex,edge,face_bound,face,vertex_shell, + wire_shell,connected_edge_set,connected_face_set,loop ANDOR path)) + SUBTYPE OF (representation_item); + END_ENTITY; -- topological_representation_item + + ENTITY toroidal_surface + SUBTYPE OF (elementary_surface); + major_radius : positive_length_measure; + minor_radius : positive_length_measure; + END_ENTITY; -- toroidal_surface + + ENTITY trimmed_curve + SUBTYPE OF (bounded_curve); + basis_curve : curve; + trim_1 : SET [1:2] OF trimming_select; + trim_2 : SET [1:2] OF trimming_select; + sense_agreement : BOOLEAN; + master_representation : trimming_preference; + WHERE + wr1: ((HIINDEX(trim_1) = 1) OR (TYPEOF(trim_1[1]) <> + TYPEOF(trim_1[2]))); + wr2: ((HIINDEX(trim_2) = 1) OR (TYPEOF(trim_2[1]) <> + TYPEOF(trim_2[2]))); + END_ENTITY; -- trimmed_curve + + ENTITY uncertainty_measure_with_unit + SUBTYPE OF (measure_with_unit); + name : label; + description : text; + WHERE + wr1: valid_measure_value(SELF\measure_with_unit.value_component); + END_ENTITY; -- uncertainty_measure_with_unit + + ENTITY uniform_curve + SUBTYPE OF (b_spline_curve); + END_ENTITY; -- uniform_curve + + ENTITY uniform_surface + SUBTYPE OF (b_spline_surface); + END_ENTITY; -- uniform_surface + + ENTITY vector + SUBTYPE OF (geometric_representation_item); + orientation : direction; + magnitude : length_measure; + WHERE + wr1: (magnitude >= 0); + END_ENTITY; -- vector + + ENTITY versioned_action_request; + id : identifier; + version : label; + purpose : text; + description : text; + END_ENTITY; -- versioned_action_request + + ENTITY vertex + SUBTYPE OF (topological_representation_item); + END_ENTITY; -- vertex + + ENTITY vertex_loop + SUBTYPE OF (loop); + loop_vertex : vertex; + END_ENTITY; -- vertex_loop + + ENTITY vertex_point + SUBTYPE OF (vertex, geometric_representation_item); + vertex_geometry : point; + END_ENTITY; -- vertex_point + + ENTITY vertex_shell + SUBTYPE OF (topological_representation_item); + vertex_shell_extent : vertex_loop; + END_ENTITY; -- vertex_shell + + ENTITY volume_measure_with_unit + SUBTYPE OF (measure_with_unit); + WHERE + wr1: ('CONFIG_CONTROL_DESIGN.VOLUME_UNIT' IN TYPEOF(SELF\ + measure_with_unit.unit_component)); + END_ENTITY; -- volume_measure_with_unit + + ENTITY volume_unit + SUBTYPE OF (named_unit); + WHERE + wr1: ((SELF\named_unit.dimensions.length_exponent = 3) AND (SELF\ + named_unit.dimensions.mass_exponent = 0) AND (SELF\ + named_unit.dimensions.time_exponent = 0) AND (SELF\ + named_unit.dimensions.electric_current_exponent = 0) AND ( + SELF\named_unit.dimensions. + thermodynamic_temperature_exponent = 0) AND (SELF\named_unit + .dimensions.amount_of_substance_exponent = 0) AND (SELF\ + named_unit.dimensions.luminous_intensity_exponent = 0)); + END_ENTITY; -- volume_unit + + ENTITY week_of_year_and_day_date + SUBTYPE OF (date); + week_component : week_in_year_number; + day_component : OPTIONAL day_in_week_number; + END_ENTITY; -- week_of_year_and_day_date + + ENTITY wire_shell + SUBTYPE OF (topological_representation_item); + wire_shell_extent : SET [1:?] OF loop; + WHERE + wr1: (NOT mixed_loop_type_set(wire_shell_extent)); + END_ENTITY; -- wire_shell + + RULE acu_requires_security_classification FOR (assembly_component_usage, + cc_design_security_classification); + WHERE + wr1: (SIZEOF(QUERY ( acu <* assembly_component_usage | (NOT (SIZEOF( + QUERY ( ccdsc <* cc_design_security_classification | (acu IN + ccdsc.items) )) = 1)) )) = 0); + END_RULE; -- acu_requires_security_classification + + RULE application_context_requires_ap_definition FOR (application_context, + application_protocol_definition); + WHERE + wr1: (SIZEOF(QUERY ( ac <* application_context | (NOT (SIZEOF( + QUERY ( apd <* application_protocol_definition | ((ac :=: apd. + application) AND (apd. + application_interpreted_model_schema_name = + 'config_control_design')) )) = 1)) )) = 0); + END_RULE; -- application_context_requires_ap_definition + + RULE approval_date_time_constraints FOR (approval_date_time); + WHERE + wr1: (SIZEOF(QUERY ( adt <* approval_date_time | (NOT (SIZEOF(TYPEOF( + adt.date_time) * ['CONFIG_CONTROL_DESIGN.DATE_AND_TIME']) + = 1)) )) = 0); + END_RULE; -- approval_date_time_constraints + + RULE approval_person_organization_constraints FOR ( + approval_person_organization); + WHERE + wr1: (SIZEOF(QUERY ( apo <* approval_person_organization | (NOT ( + SIZEOF(TYPEOF(apo.person_organization) * [ + 'CONFIG_CONTROL_DESIGN.PERSON_AND_ORGANIZATION']) + = 1)) )) = 0); + END_RULE; -- approval_person_organization_constraints + + RULE approval_requires_approval_date_time FOR (approval, + approval_date_time); + WHERE + wr1: (SIZEOF(QUERY ( app <* approval | (NOT (SIZEOF(QUERY ( adt <* + approval_date_time | (app :=: adt.dated_approval) )) = 1)) )) + = 0); + END_RULE; -- approval_requires_approval_date_time + + RULE approval_requires_approval_person_organization FOR (approval, + approval_person_organization); + WHERE + wr1: (SIZEOF(QUERY ( app <* approval | (NOT (SIZEOF(QUERY ( apo <* + approval_person_organization | (app :=: apo. + authorized_approval) )) >= 1)) )) = 0); + END_RULE; -- approval_requires_approval_person_organization + + RULE approvals_are_assigned FOR (approval, approval_assignment); + WHERE + wr1: (SIZEOF(QUERY ( app <* approval | (NOT (SIZEOF(QUERY ( aa <* + approval_assignment | (app :=: aa.assigned_approval) )) + >= 1)) )) = 0); + END_RULE; -- approvals_are_assigned + + RULE as_required_quantity FOR (measure_with_unit); + WHERE + wr1: (SIZEOF(QUERY ( m <* measure_with_unit | (( + 'CONFIG_CONTROL_DESIGN.DESCRIPTIVE_MEASURE' IN TYPEOF(m. + value_component)) AND (NOT (m.value_component = + 'as_required'))) )) = 0); + END_RULE; -- as_required_quantity + + RULE certification_requires_approval FOR (certification, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( cert <* certification | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (cert IN ccda.items) )) = + 1)) )) = 0); + END_RULE; -- certification_requires_approval + + RULE certification_requires_date_time FOR (certification, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( cert <* certification | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | (cert IN + ccdta.items) )) = 1)) )) = 0); + END_RULE; -- certification_requires_date_time + + RULE change_request_requires_approval FOR (change_request, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( cr <* change_request | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (cr IN ccda.items) )) + = 1)) )) = 0); + END_RULE; -- change_request_requires_approval + + RULE change_request_requires_date_time FOR (change_request, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( cr <* change_request | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | (cr IN + ccdta.items) )) = 1)) )) = 0); + END_RULE; -- change_request_requires_date_time + + RULE change_request_requires_person_organization FOR (change_request, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( cr <* change_request | (NOT (SIZEOF( + QUERY ( ccpoa <* cc_design_person_and_organization_assignment + | (cr IN ccpoa.items) )) >= 1)) )) = 0); + END_RULE; -- change_request_requires_person_organization + + RULE change_requires_approval FOR (change, cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( chg <* change | (NOT (SIZEOF(QUERY ( ccda <* + cc_design_approval | (chg IN ccda.items) )) = 1)) )) = 0); + END_RULE; -- change_requires_approval + + RULE change_requires_date_time FOR (change, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( chg <* change | (NOT (SIZEOF(QUERY ( ccdta <* + cc_design_date_and_time_assignment | ((chg IN ccdta.items) AND + (ccdta.role.name = 'start_date')) )) = 1)) )) = 0); + END_RULE; -- change_requires_date_time + + RULE compatible_dimension FOR (cartesian_point, direction, + representation_context, geometric_representation_context); + WHERE + wr1: (SIZEOF(QUERY ( x <* cartesian_point | (SIZEOF(QUERY ( y <* + geometric_representation_context | (item_in_context(x,y) AND ( + HIINDEX(x.coordinates) <> y.coordinate_space_dimension)) )) > + 0) )) = 0); + wr2: (SIZEOF(QUERY ( x <* direction | (SIZEOF(QUERY ( y <* + geometric_representation_context | (item_in_context(x,y) AND ( + HIINDEX(x.direction_ratios) <> y.coordinate_space_dimension)) + )) > 0) )) = 0); + END_RULE; -- compatible_dimension + + RULE configuration_item_requires_approval FOR (configuration_item, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( ci <* configuration_item | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (ci IN ccda.items) )) + = 1)) )) = 0); + END_RULE; -- configuration_item_requires_approval + + RULE configuration_item_requires_person_organization FOR ( + configuration_item, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( ci <* configuration_item | (NOT (SIZEOF( + QUERY ( ccdpoa <* cc_design_person_and_organization_assignment + | (ci IN ccdpoa.items) )) = 1)) )) = 0); + END_RULE; -- configuration_item_requires_person_organization + + RULE contract_requires_approval FOR (contract, cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( c <* contract | (NOT (SIZEOF(QUERY ( ccda <* + cc_design_approval | (c IN ccda.items) )) = 1)) )) = 0); + END_RULE; -- contract_requires_approval + + RULE contract_requires_person_organization FOR (contract, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( c <* contract | (NOT (SIZEOF(QUERY ( ccdpoa <* + cc_design_person_and_organization_assignment | (c IN ccdpoa. + items) )) = 1)) )) = 0); + END_RULE; -- contract_requires_person_organization + + RULE coordinated_assembly_and_shape FOR (next_assembly_usage_occurrence); + WHERE + wr1: (SIZEOF(QUERY ( nauo <* next_assembly_usage_occurrence | (NOT + assembly_shape_is_defined(nauo,'CONFIG_CONTROL_DESIGN')) )) = + 0); + END_RULE; -- coordinated_assembly_and_shape + + RULE dependent_instantiable_action_directive FOR (action_directive); + WHERE + wr1: (SIZEOF(QUERY ( ad <* action_directive | (NOT (SIZEOF(USEDIN(ad, + '')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_action_directive + + RULE dependent_instantiable_approval_status FOR (approval_status); + WHERE + wr1: (SIZEOF(QUERY ( ast <* approval_status | (NOT (SIZEOF(USEDIN(ast, + '')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_approval_status + + RULE dependent_instantiable_certification_type FOR (certification_type); + WHERE + wr1: (SIZEOF(QUERY ( ct <* certification_type | (NOT (SIZEOF(USEDIN(ct, + '')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_certification_type + + RULE dependent_instantiable_contract_type FOR (contract_type); + WHERE + wr1: (SIZEOF(QUERY ( ct <* contract_type | (NOT (SIZEOF(USEDIN(ct,'')) + >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_contract_type + + RULE dependent_instantiable_date FOR (date); + WHERE + wr1: (SIZEOF(QUERY ( dt <* date | (NOT (SIZEOF(USEDIN(dt,'')) >= 1)) )) + = 0); + END_RULE; -- dependent_instantiable_date + + RULE dependent_instantiable_date_time_role FOR (date_time_role); + WHERE + wr1: (SIZEOF(QUERY ( dtr <* date_time_role | (NOT (SIZEOF(USEDIN(dtr, + '')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_date_time_role + + RULE dependent_instantiable_document_type FOR (document_type); + WHERE + wr1: (SIZEOF(QUERY ( dt <* document_type | (NOT (SIZEOF(USEDIN(dt,'')) + >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_document_type + + RULE dependent_instantiable_named_unit FOR (named_unit); + WHERE + wr1: (SIZEOF(QUERY ( nu <* named_unit | (NOT (SIZEOF(USEDIN(nu,'')) >= + 1)) )) = 0); + END_RULE; -- dependent_instantiable_named_unit + + RULE dependent_instantiable_parametric_representation_context FOR ( + parametric_representation_context); + WHERE + wr1: (SIZEOF(QUERY ( prc <* parametric_representation_context | (NOT ( + SIZEOF(USEDIN(prc,'')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_parametric_representation_context + + RULE dependent_instantiable_person_and_organization_role FOR ( + person_and_organization_role); + WHERE + wr1: (SIZEOF(QUERY ( poar <* person_and_organization_role | (NOT ( + SIZEOF(USEDIN(poar,'')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_person_and_organization_role + + RULE dependent_instantiable_representation_item FOR + (representation_item); + WHERE + wr1: (SIZEOF(QUERY ( ri <* representation_item | (NOT (SIZEOF(USEDIN( + ri,'')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_representation_item + + RULE dependent_instantiable_security_classification_level FOR ( + security_classification_level); + WHERE + wr1: (SIZEOF(QUERY ( scl <* security_classification_level | (NOT ( + SIZEOF(USEDIN(scl,'')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_security_classification_level + + RULE dependent_instantiable_shape_representation FOR ( + shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( sr <* shape_representation | (NOT (SIZEOF(USEDIN( + sr,'')) >= 1)) )) = 0); + END_RULE; -- dependent_instantiable_shape_representation + + RULE design_context_for_property FOR (product_definition); + WHERE + wr1: (SIZEOF(QUERY ( pd <* product_definition | ((SIZEOF(USEDIN(pd, + 'CONFIG_CONTROL_DESIGN.' + 'PROPERTY_DEFINITION.DEFINITION') + + QUERY ( pdr <* USEDIN(pd,'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_RELATIONSHIP.RELATED_PRODUCT_DEFINITION') + | (SIZEOF(USEDIN(pdr, + 'CONFIG_CONTROL_DESIGN.PROPERTY_DEFINITION.' + 'DEFINITION')) + >= 1) )) >= 1) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.DESIGN_CONTEXT' IN TYPEOF(pd. + frame_of_reference)))) )) = 0); + END_RULE; -- design_context_for_property + + RULE document_to_product_definition FOR ( + cc_design_specification_reference); + WHERE + wr1: (SIZEOF(QUERY ( sp <* cc_design_specification_reference | (NOT (( + (('CONFIG_CONTROL_DESIGN.DOCUMENT_RELATIONSHIP.' + + 'RELATING_DOCUMENT') IN ROLESOF(sp\document_reference. + assigned_document)) AND (SIZEOF(QUERY ( it <* sp.items | (NOT + ('CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION' IN TYPEOF(it))) )) + = 0)) OR (NOT (('CONFIG_CONTROL_DESIGN.DOCUMENT_RELATIONSHIP.' + + 'RELATING_DOCUMENT') IN ROLESOF(sp\document_reference. + assigned_document))))) )) = 0); + END_RULE; -- document_to_product_definition + + RULE effectivity_requires_approval FOR (effectivity, cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( eff <* effectivity | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (eff IN ccda.items) )) = + 1)) )) = 0); + END_RULE; -- effectivity_requires_approval + + RULE geometric_representation_item_3d FOR + (geometric_representation_item); + WHERE + wr1: (SIZEOF(QUERY ( gri <* geometric_representation_item | (NOT (( + dimension_of(gri) = 3) OR (SIZEOF(QUERY ( ur <* + using_representations(gri) | ( + 'CONFIG_CONTROL_DESIGN.DEFINITIONAL_REPRESENTATION' IN TYPEOF( + ur)) )) > 0))) )) = 0); + END_RULE; -- geometric_representation_item_3d + + RULE global_unit_assignment FOR (global_unit_assigned_context); + WHERE + wr1: (SIZEOF(QUERY ( guac <* global_unit_assigned_context | (NOT ( + SIZEOF(guac.units) = 3)) )) = 0); + wr2: (SIZEOF(QUERY ( guac <* global_unit_assigned_context | (NOT (( + SIZEOF(QUERY ( u <* guac.units | ( + 'CONFIG_CONTROL_DESIGN.LENGTH_UNIT' IN TYPEOF(u)) )) = 1) AND + (SIZEOF(QUERY ( u <* guac.units | ( + 'CONFIG_CONTROL_DESIGN.PLANE_ANGLE_UNIT' IN TYPEOF(u)) )) = 1) + AND (SIZEOF(QUERY ( u <* guac.units | ( + 'CONFIG_CONTROL_DESIGN.SOLID_ANGLE_UNIT' IN TYPEOF(u)) )) + = 1))) )) = 0); + END_RULE; -- global_unit_assignment + + RULE no_shape_for_make_from FOR (design_make_from_relationship); + WHERE + wr1: (SIZEOF(QUERY ( dmfr <* design_make_from_relationship | (NOT ( + SIZEOF(QUERY ( pd <* USEDIN(dmfr,'CONFIG_CONTROL_DESIGN.' + + 'PROPERTY_DEFINITION.DEFINITION') | ( + 'CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_SHAPE' + IN TYPEOF(pd)) )) = 0)) )) = 0); + END_RULE; -- no_shape_for_make_from + + RULE no_shape_for_supplied_part FOR (supplied_part_relationship); + WHERE + wr1: (SIZEOF(QUERY ( spr <* supplied_part_relationship | (NOT (SIZEOF( + QUERY ( pd <* USEDIN(spr,'CONFIG_CONTROL_DESIGN.' + + 'PROPERTY_DEFINITION.DEFINITION') | ( + 'CONFIG_CONTROL_DESIGN.PRODUCT_DEFINITION_SHAPE' + IN TYPEOF(pd)) )) = 0)) )) = 0); + END_RULE; -- no_shape_for_supplied_part + + RULE product_concept_requires_configuration_item FOR (product_concept, + configuration_item); + WHERE + wr1: (SIZEOF(QUERY ( pc <* product_concept | (NOT (SIZEOF( + QUERY ( ci <* configuration_item | (pc :=: ci.item_concept) )) + >= 1)) )) = 0); + END_RULE; -- product_concept_requires_configuration_item + + RULE product_definition_requires_approval FOR (product_definition, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( pd <* product_definition | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (pd IN ccda.items) )) + = 1)) )) = 0); + END_RULE; -- product_definition_requires_approval + + RULE product_definition_requires_date_time FOR (product_definition, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( pd <* product_definition | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | (pd IN + ccdta.items) )) = 1)) )) = 0); + END_RULE; -- product_definition_requires_date_time + + RULE product_definition_requires_person_organization FOR ( + product_definition, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( pd <* product_definition | (NOT (SIZEOF( + QUERY ( ccdpoa <* cc_design_person_and_organization_assignment + | (pd IN ccdpoa.items) )) = 1)) )) = 0); + END_RULE; -- product_definition_requires_person_organization + + RULE product_requires_person_organization FOR (product, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( prod <* product | (NOT (SIZEOF(QUERY ( ccdpoa <* + cc_design_person_and_organization_assignment | (prod IN ccdpoa + .items) )) = 1)) )) = 0); + END_RULE; -- product_requires_person_organization + + RULE product_requires_product_category FOR (product, + product_related_product_category); + WHERE + wr1: (SIZEOF(QUERY ( prod <* product | (NOT (SIZEOF(QUERY ( prpc <* + product_related_product_category | ((prod IN prpc.products) + AND (prpc.name IN ['assembly','inseparable_assembly','detail', + 'customer_furnished_equipment'])) )) = 1)) )) = 0); + END_RULE; -- product_requires_product_category + + RULE product_requires_version FOR (product, + product_definition_formation); + WHERE + wr1: (SIZEOF(QUERY ( prod <* product | (NOT (SIZEOF(QUERY ( pdf <* + product_definition_formation | (prod :=: pdf.of_product) )) >= + 1)) )) = 0); + END_RULE; -- product_requires_version + + RULE product_version_requires_approval FOR (product_definition_formation, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( pdf <* product_definition_formation | (NOT ( + SIZEOF(QUERY ( ccda <* cc_design_approval | + (pdf IN ccda.items) )) = 1)) )) = 0); + END_RULE; -- product_version_requires_approval + + RULE product_version_requires_person_organization FOR ( + product_definition_formation, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( pdf <* product_definition_formation | (NOT ( + SIZEOF(QUERY ( ccdpoa <* + cc_design_person_and_organization_assignment | ((pdf IN ccdpoa + .items) AND (ccdpoa.role.name = 'creator')) )) = 1)) )) = 0); + wr2: (SIZEOF(QUERY ( pdf <* product_definition_formation | (NOT ( + SIZEOF(QUERY ( ccdpoa <* + cc_design_person_and_organization_assignment | ((pdf IN ccdpoa + .items) AND (ccdpoa.role.name IN ['design_supplier', + 'part_supplier'])) )) >= 1)) )) = 0); + END_RULE; -- product_version_requires_person_organization + + RULE product_version_requires_security_classification FOR ( + product_definition_formation, + cc_design_security_classification); + WHERE + wr1: (SIZEOF(QUERY ( pdf <* product_definition_formation | (NOT ( + SIZEOF(QUERY ( ccdsc <* cc_design_security_classification | ( + pdf IN ccdsc.items) )) = 1)) )) = 0); + END_RULE; -- product_version_requires_security_classification + + RULE restrict_action_request_status FOR (action_request_status); + WHERE + wr1: (SIZEOF(QUERY ( ars <* action_request_status | (NOT (ars.status + IN ['proposed','in_work','issued','hold'])) )) = 0); + END_RULE; -- restrict_action_request_status + + RULE restrict_approval_status FOR (approval_status); + WHERE + wr1: (SIZEOF(QUERY ( ast <* approval_status | (NOT (ast.name IN [ + 'approved','not_yet_approved','disapproved','withdrawn'])) )) + = 0); + END_RULE; -- restrict_approval_status + + RULE restrict_certification_type FOR (certification_type); + WHERE + wr1: (SIZEOF(QUERY ( ct <* certification_type | (NOT (ct.description + IN ['design_supplier','part_supplier'])) )) = 0); + END_RULE; -- restrict_certification_type + + RULE restrict_contract_type FOR (contract_type); + WHERE + wr1: (SIZEOF(QUERY ( ct <* contract_type | (NOT (ct.description IN [ + 'fixed_price','cost_plus'])) )) = 0); + END_RULE; -- restrict_contract_type + + RULE restrict_date_time_role FOR (date_time_role); + WHERE + wr1: (SIZEOF(QUERY ( dtr <* date_time_role | (NOT (dtr.name IN [ + 'creation_date','request_date','release_date','start_date', + 'contract_date','certification_date','sign_off_date', + 'classification_date','declassification_date'])) )) = 0); + END_RULE; -- restrict_date_time_role + + RULE restrict_document_type FOR (document_type); + WHERE + wr1: (SIZEOF(QUERY ( dt <* document_type | (NOT (dt.product_data_type + IN ['material_specification','process_specification', + 'design_specification','surface_finish_specification', + 'cad_filename','drawing'])) )) = 0); + END_RULE; -- restrict_document_type + + RULE restrict_person_organization_role FOR + (person_and_organization_role); + WHERE + wr1: (SIZEOF(QUERY ( por <* person_and_organization_role | (NOT (por. + name IN ['request_recipient','initiator','part_supplier', + 'design_supplier','configuration_manager','contractor', + 'classification_officer','creator','design_owner'])) )) = 0); + END_RULE; -- restrict_person_organization_role + + RULE restrict_product_category_value FOR ( + product_related_product_category); + WHERE + wr1: (SIZEOF(QUERY ( prpc <* product_related_product_category | (NOT ( + prpc.name IN ['assembly','detail', + 'customer_furnished_equipment','inseparable_assembly','cast', + 'coined','drawn','extruded','forged','formed','machined', + 'molded','rolled','sheared'])) )) = 0); + END_RULE; -- restrict_product_category_value + + RULE restrict_security_classification_level FOR ( + security_classification_level); + WHERE + wr1: (SIZEOF(QUERY ( scl <* security_classification_level | (NOT (scl. + name IN ['unclassified','classified','proprietary', + 'confidential','secret','top_secret'])) )) = 0); + END_RULE; -- restrict_security_classification_level + + RULE security_classification_optional_date_time FOR ( + security_classification, cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sc <* security_classification | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | ((sc IN + ccdta.items) AND ('declassification_date' = ccdta.role.name)) + )) <= 1)) )) = 0); + END_RULE; -- security_classification_optional_date_time + + RULE security_classification_requires_approval FOR ( + security_classification, cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( sc <* security_classification | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (sc IN ccda.items) )) + = 1)) )) = 0); + END_RULE; -- security_classification_requires_approval + + RULE security_classification_requires_date_time FOR ( + security_classification, cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sc <* security_classification | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | ((sc IN + ccdta.items) AND ('classification_date' = ccdta.role.name)) )) + = 1)) )) = 0); + END_RULE; -- security_classification_requires_date_time + + RULE security_classification_requires_person_organization FOR ( + security_classification, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sc <* security_classification | (NOT (SIZEOF( + QUERY ( ccdpoa <* cc_design_person_and_organization_assignment + | (sc IN ccdpoa.items) )) = 1)) )) = 0); + END_RULE; -- security_classification_requires_person_organization + + RULE start_request_requires_approval FOR (start_request, + cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( sr <* start_request | (NOT (SIZEOF( + QUERY ( ccda <* cc_design_approval | (sr IN ccda.items) )) + = 1)) )) = 0); + END_RULE; -- start_request_requires_approval + + RULE start_request_requires_date_time FOR (start_request, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sr <* start_request | (NOT (SIZEOF( + QUERY ( ccdta <* cc_design_date_and_time_assignment | (sr IN + ccdta.items) )) = 1)) )) = 0); + END_RULE; -- start_request_requires_date_time + + RULE start_request_requires_person_organization FOR (start_request, + cc_design_person_and_organization_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sr <* start_request | (NOT (SIZEOF( + QUERY ( ccdpoa <* cc_design_person_and_organization_assignment + | (sr IN ccdpoa.items) )) >= 1)) )) = 0); + END_RULE; -- start_request_requires_person_organization + + RULE start_work_requires_approval FOR (start_work, cc_design_approval); + WHERE + wr1: (SIZEOF(QUERY ( sw <* start_work | (NOT (SIZEOF(QUERY ( ccda <* + cc_design_approval | (sw IN ccda.items) )) = 1)) )) = 0); + END_RULE; -- start_work_requires_approval + + RULE start_work_requires_date_time FOR (start_work, + cc_design_date_and_time_assignment); + WHERE + wr1: (SIZEOF(QUERY ( sw <* start_work | (NOT (SIZEOF(QUERY ( ccdta <* + cc_design_date_and_time_assignment | ((sw IN ccdta.items) AND + (ccdta.role.name = 'start_date')) )) = 1)) )) = 0); + END_RULE; -- start_work_requires_date_time + + RULE subtype_mandatory_action FOR (action); + WHERE + wr1: (SIZEOF(QUERY ( act <* action | (NOT ( + 'CONFIG_CONTROL_DESIGN.DIRECTED_ACTION' IN TYPEOF(act))) )) = + 0); + END_RULE; -- subtype_mandatory_action + + RULE subtype_mandatory_effectivity FOR (effectivity); + WHERE + wr1: (SIZEOF(QUERY ( eff <* effectivity | (NOT ((SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SERIAL_NUMBERED_EFFECTIVITY', + 'CONFIG_CONTROL_DESIGN.LOT_EFFECTIVITY', + 'CONFIG_CONTROL_DESIGN.DATED_EFFECTIVITY'] * TYPEOF(eff)) = 1) + AND ('CONFIG_CONTROL_DESIGN.CONFIGURATION_EFFECTIVITY' IN + TYPEOF(eff)))) )) = 0); + END_RULE; -- subtype_mandatory_effectivity + + RULE subtype_mandatory_product_context FOR (product_context); + WHERE + wr1: (SIZEOF(QUERY ( pc <* product_context | (NOT ( + 'CONFIG_CONTROL_DESIGN.MECHANICAL_CONTEXT' IN TYPEOF(pc))) )) + = 0); + END_RULE; -- subtype_mandatory_product_context + + RULE subtype_mandatory_product_definition_formation FOR ( + product_definition_formation); + WHERE + wr1: (SIZEOF(QUERY ( pdf <* product_definition_formation | (NOT (( + 'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE') IN + TYPEOF(pdf))) )) = 0); + END_RULE; -- subtype_mandatory_product_definition_formation + + RULE subtype_mandatory_product_definition_usage FOR ( + product_definition_usage); + WHERE + wr1: (SIZEOF(QUERY ( pdu <* product_definition_usage | (NOT (( + 'CONFIG_CONTROL_DESIGN.' + 'ASSEMBLY_COMPONENT_USAGE') IN + TYPEOF(pdu))) )) = 0); + END_RULE; -- subtype_mandatory_product_definition_usage + + RULE subtype_mandatory_representation FOR (representation); + WHERE + wr1: (SIZEOF(QUERY ( rep <* representation | (NOT ( + 'CONFIG_CONTROL_DESIGN.SHAPE_REPRESENTATION' IN TYPEOF(rep))) + )) = 0); + END_RULE; -- subtype_mandatory_representation + + RULE subtype_mandatory_representation_context FOR ( + representation_context); + WHERE + wr1: (SIZEOF(QUERY ( rep_cntxt <* representation_context | (NOT ( + 'CONFIG_CONTROL_DESIGN.GEOMETRIC_REPRESENTATION_CONTEXT' IN + TYPEOF(rep_cntxt))) )) = 0); + END_RULE; -- subtype_mandatory_representation_context + + RULE subtype_mandatory_shape_representation FOR (shape_representation); + WHERE + wr1: (SIZEOF(QUERY ( sr <* shape_representation | (NOT ((SIZEOF([ + 'CONFIG_CONTROL_DESIGN.' + + 'ADVANCED_BREP_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.FACETED_BREP_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.MANIFOLD_SURFACE_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.' + + 'EDGE_BASED_WIREFRAME_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.' + + 'SHELL_BASED_WIREFRAME_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.' + + 'GEOMETRICALLY_BOUNDED_SURFACE_SHAPE_REPRESENTATION', + 'CONFIG_CONTROL_DESIGN.' + + 'GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION'] * + TYPEOF(sr)) = 1) OR (SIZEOF(QUERY ( it <* sr\representation. + items | (NOT ('CONFIG_CONTROL_DESIGN.AXIS2_PLACEMENT_3D' IN + TYPEOF(it))) )) = 0) OR (SIZEOF(QUERY ( sdr <* QUERY ( pdr <* + USEDIN(sr, + 'CONFIG_CONTROL_DESIGN.PROPERTY_DEFINITION_REPRESENTATION.' + + 'USED_REPRESENTATION') | ( + 'CONFIG_CONTROL_DESIGN.SHAPE_DEFINITION_REPRESENTATION' IN + TYPEOF(pdr)) ) | (NOT (SIZEOF([ + 'CONFIG_CONTROL_DESIGN.SHAPE_ASPECT', + 'CONFIG_CONTROL_DESIGN.SHAPE_ASPECT_RELATIONSHIP'] * TYPEOF( + sdr.definition.definition)) = 1)) )) = 0))) )) = 0); + END_RULE; -- subtype_mandatory_shape_representation + + RULE unique_version_change_order_rule FOR (change); + WHERE + wr1: (SIZEOF(QUERY ( c <* change | (NOT unique_version_change_order(c. + assigned_action)) )) = 0); + END_RULE; -- unique_version_change_order_rule + + RULE versioned_action_request_requires_solution FOR ( + versioned_action_request, action_request_solution); + WHERE + wr1: (SIZEOF(QUERY ( ar <* versioned_action_request | (NOT (SIZEOF( + QUERY ( ars <* action_request_solution | (ar :=: ars.request) + )) >= 1)) )) = 0); + END_RULE; -- versioned_action_request_requires_solution + + RULE versioned_action_request_requires_status FOR ( + versioned_action_request, action_request_status); + WHERE + wr1: (SIZEOF(QUERY ( ar <* versioned_action_request | (NOT (SIZEOF( + QUERY ( ars <* action_request_status | (ar :=: ars. + assigned_request) )) = 1)) )) = 0); + END_RULE; -- versioned_action_request_requires_status + + FUNCTION acyclic_curve_replica(rep: curve_replica; + parent: curve): BOOLEAN; + IF NOT ('CONFIG_CONTROL_DESIGN.CURVE_REPLICA' IN TYPEOF(parent)) THEN + RETURN(TRUE); + END_IF; + IF parent :=: rep THEN RETURN(FALSE); + ELSE + RETURN(acyclic_curve_replica(rep,parent\curve_replica.parent_curve)); + END_IF; + END_FUNCTION; -- acyclic_curve_replica + + FUNCTION acyclic_mapped_representation(parent_set: SET OF representation; + children_set: SET OF representation_item): BOOLEAN; + LOCAL + i : INTEGER; + x : SET OF representation_item; + y : SET OF representation_item; + END_LOCAL; + x := QUERY ( z <* children_set | ('CONFIG_CONTROL_DESIGN.MAPPED_ITEM' + IN TYPEOF(z)) ); + IF SIZEOF(x) > 0 THEN + REPEAT i := 1 TO HIINDEX(x) BY 1; + IF x[i]\mapped_item.mapping_source.mapped_representation IN + parent_set THEN RETURN(FALSE); + END_IF; + IF NOT acyclic_mapped_representation(parent_set + x[i]\mapped_item + .mapping_source.mapped_representation,x[i]\mapped_item. + mapping_source.mapped_representation.items) THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + END_IF; + x := children_set - x; + IF SIZEOF(x) > 0 THEN + REPEAT i := 1 TO HIINDEX(x) BY 1; + y := QUERY ( z <* bag_to_set(USEDIN(x[i],'')) | ( + 'CONFIG_CONTROL_DESIGN.REPRESENTATION_ITEM' IN TYPEOF(z)) ); + IF NOT acyclic_mapped_representation(parent_set,y) THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + END_IF; + RETURN(TRUE); + END_FUNCTION; -- acyclic_mapped_representation + + FUNCTION acyclic_point_replica(rep: point_replica; + parent: point): BOOLEAN; + IF NOT ('CONFIG_CONTROL_DESIGN.POINT_REPLICA' IN TYPEOF(parent)) THEN + RETURN(TRUE); + END_IF; + IF parent :=: rep THEN RETURN(FALSE); + ELSE + RETURN(acyclic_point_replica(rep,parent\point_replica.parent_pt)); + END_IF; + END_FUNCTION; -- acyclic_point_replica + + FUNCTION acyclic_product_category_relationship( + relation: product_category_relationship; + children: SET OF product_category): LOGICAL; + LOCAL + i : INTEGER; + x : SET OF product_category_relationship; + local_children : SET OF product_category; + END_LOCAL; + REPEAT i := 1 TO HIINDEX(children) BY 1; + IF relation.category :=: children[i] THEN RETURN(FALSE); + END_IF; + END_REPEAT; + x := bag_to_set(USEDIN(relation.category,'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_CATEGORY_RELATIONSHIP.SUB_CATEGORY')); + local_children := children + relation.category; + IF SIZEOF(x) > 0 THEN + REPEAT i := 1 TO HIINDEX(x) BY 1; + IF NOT acyclic_product_category_relationship(x[i],local_children) + THEN RETURN(FALSE); + END_IF; + END_REPEAT; + END_IF; + RETURN(TRUE); + END_FUNCTION; -- acyclic_product_category_relationship + + FUNCTION acyclic_product_definition_relationship( + relation: product_definition_relationship; + relatives: SET [1:?] OF product_definition; + specific_relation: STRING): LOGICAL; + LOCAL + x : SET OF product_definition_relationship; + END_LOCAL; + IF relation.relating_product_definition IN relatives THEN + RETURN(FALSE); + END_IF; + x := QUERY ( pd <* bag_to_set(USEDIN(relation. + relating_product_definition,'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_RELATIONSHIP.' + 'RELATED_PRODUCT_DEFINITION')) + | (specific_relation IN TYPEOF(pd)) ); + REPEAT i := 1 TO HIINDEX(x) BY 1; + IF NOT acyclic_product_definition_relationship(x[i],relatives + + relation.relating_product_definition,specific_relation) THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + RETURN(TRUE); + END_FUNCTION; -- acyclic_product_definition_relationship + + FUNCTION acyclic_surface_replica(rep: surface_replica; + parent: surface): BOOLEAN; + IF NOT ('CONFIG_CONTROL_DESIGN.SURFACE_REPLICA' IN TYPEOF(parent)) + THEN + RETURN(TRUE); + END_IF; + IF parent :=: rep THEN RETURN(FALSE); + ELSE + RETURN(acyclic_surface_replica(rep,parent\surface_replica. + parent_surface)); + END_IF; + END_FUNCTION; -- acyclic_surface_replica + + FUNCTION assembly_shape_is_defined(assy: next_assembly_usage_occurrence; + schma: STRING): BOOLEAN; + LOCAL + srr_set : SET OF shape_representation_relationship := []; + i : INTEGER; + j : INTEGER; + sdr_set : SET OF shape_definition_representation := []; + pr1_set : SET OF property_definition := []; + pdrel_set : SET OF product_definition_relationship := []; + pr2_set : SET OF property_definition := []; + END_LOCAL; + pr1_set := bag_to_set(USEDIN(assy.related_product_definition,schma + + '.PROPERTY_DEFINITION.DEFINITION')); + REPEAT i := 1 TO HIINDEX(pr1_set) BY 1; + sdr_set := sdr_set + QUERY ( pdr <* USEDIN(pr1_set[i],schma + + '.PROPERTY_DEFINITION_REPRESENTATION.DEFINITION') | ((schma + + '.SHAPE_DEFINITION_REPRESENTATION') IN TYPEOF(pdr)) ); + END_REPEAT; + pdrel_set := bag_to_set(USEDIN(assy.related_product_definition,schma + + '.PRODUCT_DEFINITION_RELATIONSHIP.' + + 'RELATED_PRODUCT_DEFINITION')); + REPEAT j := 1 TO HIINDEX(pdrel_set) BY 1; + pr2_set := pr2_set + USEDIN(pdrel_set[j],schma + + '.PROPERTY_DEFINITION.DEFINITION'); + END_REPEAT; + REPEAT i := 1 TO HIINDEX(pr2_set) BY 1; + sdr_set := sdr_set + QUERY ( pdr <* USEDIN(pr2_set[i],schma + + '.PROPERTY_DEFINITION_REPRESENTATION.DEFINITION') | ((schma + + '.SHAPE_DEFINITION_REPRESENTATION') IN TYPEOF(pdr)) ); + END_REPEAT; + IF SIZEOF(sdr_set) > 0 THEN + REPEAT i := 1 TO HIINDEX(sdr_set) BY 1; + srr_set := QUERY ( rr <* bag_to_set(USEDIN(sdr_set[i]\ + property_definition_representation.used_representation,schma + + '.REPRESENTATION_RELATIONSHIP.REP_2')) | ((schma + + '.SHAPE_REPRESENTATION_RELATIONSHIP') IN TYPEOF(rr)) ); + IF SIZEOF(srr_set) > 0 THEN + REPEAT j := 1 TO HIINDEX(srr_set) BY 1; + IF SIZEOF(QUERY ( pdr <* bag_to_set(USEDIN(srr_set[j]\ + representation_relationship.rep_1,schma + + '.PROPERTY_DEFINITION_REPRESENTATION.USED_REPRESENTATION')) + | ((schma + '.SHAPE_DEFINITION_REPRESENTATION') IN TYPEOF( + pdr)) ) * QUERY ( pdr <* bag_to_set(USEDIN(assy. + relating_product_definition,schma + + '.PROPERTY_DEFINITION_REPRESENTATION.DEFINITION')) | (( + schma + '.SHAPE_DEFINITION_REPRESENTATION') IN + TYPEOF(pdr)) )) >= 1 THEN + IF SIZEOF(QUERY ( cdsr <* USEDIN(srr_set[j],schma + + '.CONTEXT_DEPENDENT_SHAPE_REPRESENTATION.' + + 'REPRESENTATION_RELATION') | (NOT (cdsr\ + context_dependent_shape_representation. + represented_product_relation\property_definition. + definition :=: assy)) )) > 0 THEN + RETURN(FALSE); + END_IF; + END_IF; + END_REPEAT; + END_IF; + END_REPEAT; + END_IF; + RETURN(TRUE); + END_FUNCTION; -- assembly_shape_is_defined + + FUNCTION associated_surface(arg: pcurve_or_surface): surface; + LOCAL + surf : surface; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(arg) THEN + surf := arg.basis_surface; + ELSE + surf := arg; + END_IF; + RETURN(surf); + END_FUNCTION; -- associated_surface + + FUNCTION bag_to_set(the_bag: BAG OF GENERIC:intype + ): SET OF GENERIC:intype; + LOCAL + i : INTEGER; + the_set : SET OF GENERIC:intype := []; + END_LOCAL; + IF SIZEOF(the_bag) > 0 THEN + REPEAT i := 1 TO HIINDEX(the_bag) BY 1; + the_set := the_set + the_bag[i]; + END_REPEAT; + END_IF; + RETURN(the_set); + END_FUNCTION; -- bag_to_set + + FUNCTION base_axis(dim: INTEGER; axis1, axis2, axis3: direction + ): LIST [2:3] OF direction; + LOCAL + u : LIST [2:3] OF direction; + d1 : direction; + d2 : direction; + factor : REAL; + END_LOCAL; + IF dim = 3 THEN + d1 := NVL(normalise(axis3),dummy_gri || direction([0,0,1])); + d2 := first_proj_axis(d1,axis1); + u := [d2,second_proj_axis(d1,d2,axis2),d1]; + ELSE + IF EXISTS(axis1) THEN + d1 := normalise(axis1); + u := [d1,orthogonal_complement(d1)]; + IF EXISTS(axis2) THEN + factor := dot_product(axis2,u[2]); + IF factor < 0 THEN + u[2].direction_ratios[1] := -u[2].direction_ratios[1]; + u[2].direction_ratios[2] := -u[2].direction_ratios[2]; + END_IF; + END_IF; + ELSE + IF EXISTS(axis2) THEN + d1 := normalise(axis2); + u := [orthogonal_complement(d1),d1]; + u[1].direction_ratios[1] := -u[1].direction_ratios[1]; + u[1].direction_ratios[2] := -u[1].direction_ratios[2]; + ELSE + u := [dummy_gri || direction([1,0]),dummy_gri || + direction([0,1])]; + END_IF; + END_IF; + END_IF; + RETURN(u); + END_FUNCTION; -- base_axis + + FUNCTION boolean_choose(b: BOOLEAN; + choice1, choice2: GENERIC:item): GENERIC:item; + IF b THEN + RETURN(choice1); + ELSE + RETURN(choice2); + END_IF; + END_FUNCTION; -- boolean_choose + + FUNCTION build_2axes(ref_direction: direction): LIST [2:2] OF direction; + LOCAL + d : direction := NVL(normalise(ref_direction),dummy_gri || + direction([1,0])); + END_LOCAL; + RETURN([d,orthogonal_complement(d)]); + END_FUNCTION; -- build_2axes + + FUNCTION build_axes(axis, ref_direction: direction + ): LIST [3:3] OF direction; + LOCAL + d1 : direction; + d2 : direction; + END_LOCAL; + d1 := NVL(normalise(axis),dummy_gri || direction([0,0,1])); + d2 := first_proj_axis(d1,ref_direction); + RETURN([d2,normalise(cross_product(d1,d2)).orientation,d1]); + END_FUNCTION; -- build_axes + + FUNCTION cc_design_date_time_correlation + (e : cc_design_date_and_time_assignment ) : BOOLEAN; + LOCAL + dt_role : STRING; + END_LOCAL; + dt_role := e\date_and_time_assignment.role.name; + CASE dt_role OF + 'creation_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'request_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF ( + ['CONFIG_CONTROL_DESIGN.CHANGE_REQUEST', + 'CONFIG_CONTROL_DESIGN.START_REQUEST'] * + TYPEOF (x)) = 1)) + THEN RETURN(FALSE); + END_IF; + 'release_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF ( + ['CONFIG_CONTROL_DESIGN.CHANGE', + 'CONFIG_CONTROL_DESIGN.START_WORK'] * + TYPEOF (x)) = 1)) + THEN RETURN(FALSE); + END_IF; + 'start_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF ( + ['CONFIG_CONTROL_DESIGN.CHANGE', + 'CONFIG_CONTROL_DESIGN.START_WORK'] * + TYPEOF (x)) = 1)) + THEN RETURN(FALSE); + END_IF; + 'sign_off_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'APPROVAL_PERSON_ORGANIZATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'contract_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.CONTRACT' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'certification_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.CERTIFICATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'classification_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'SECURITY_CLASSIFICATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'declassification_date' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'SECURITY_CLASSIFICATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + OTHERWISE : RETURN(TRUE); + END_CASE; + RETURN (TRUE); + END_FUNCTION; -- cc_design_date_time_correlation + + FUNCTION cc_design_person_and_organization_correlation + (e : cc_design_person_and_organization_assignment ) : BOOLEAN; + LOCAL + po_role : STRING; + END_LOCAL; + po_role := e\person_and_organization_assignment.role.name; + CASE po_role OF + 'request_recipient' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF(['CONFIG_CONTROL_DESIGN.' + + 'CHANGE_REQUEST', + 'CONFIG_CONTROL_DESIGN.' + + 'START_REQUEST'] * + TYPEOF (x)) = 1)) + THEN RETURN(FALSE); + END_IF; + 'initiator' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF(['CONFIG_CONTROL_DESIGN.' + + 'CHANGE_REQUEST', + 'CONFIG_CONTROL_DESIGN.' + + 'START_REQUEST', + 'CONFIG_CONTROL_DESIGN.' + + 'START_WORK', + 'CONFIG_CONTROL_DESIGN.' + + 'CHANGE'] * + TYPEOF (x)) = 1)) + THEN RETURN(FALSE); + END_IF; + 'creator' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + SIZEOF (['CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_FORMATION', + 'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION'] * + TYPEOF (x)) = 1)) + THEN RETURN (FALSE); + END_IF; + 'part_supplier' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_FORMATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'design_supplier' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'PRODUCT_DEFINITION_FORMATION' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'design_owner' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.PRODUCT' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'configuration_manager' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'CONFIGURATION_ITEM' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'contractor' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.CONTRACT' + IN TYPEOF (x))) + THEN RETURN(FALSE); + END_IF; + 'classification_officer' : IF SIZEOF (e.items) <> + SIZEOF (QUERY (x <* e.items | + 'CONFIG_CONTROL_DESIGN.' + + 'SECURITY_CLASSIFICATION' + IN TYPEOF (x))) THEN + RETURN(FALSE); + END_IF; + OTHERWISE : RETURN(TRUE); + END_CASE; + RETURN (TRUE); + END_FUNCTION; -- cc_design_person_and_organization_correlation + + FUNCTION closed_shell_reversed(a_shell: closed_shell + ): oriented_closed_shell; + LOCAL + the_reverse : oriented_closed_shell; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.ORIENTED_CLOSED_SHELL' IN TYPEOF(a_shell) + THEN + the_reverse := dummy_tri || connected_face_set(a_shell\ + connected_face_set.cfs_faces) || closed_shell() || + oriented_closed_shell(a_shell\oriented_closed_shell. + closed_shell_element,NOT a_shell\oriented_closed_shell. + orientation); + ELSE + the_reverse := dummy_tri || connected_face_set(a_shell\ + connected_face_set.cfs_faces) || closed_shell() || + oriented_closed_shell(a_shell,FALSE); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- closed_shell_reversed + + FUNCTION conditional_reverse(p: BOOLEAN; + an_item: reversible_topology): reversible_topology; + IF p THEN RETURN(an_item); + ELSE + RETURN(topology_reversed(an_item)); + END_IF; + END_FUNCTION; -- conditional_reverse + + FUNCTION constraints_composite_curve_on_surface( + c: composite_curve_on_surface): BOOLEAN; + LOCAL + n_segments : INTEGER := SIZEOF(c.segments); + END_LOCAL; + REPEAT k := 1 TO n_segments BY 1; + IF (NOT ('CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(c\composite_curve. + segments[k].parent_curve))) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE' IN TYPEOF(c\composite_curve + .segments[k].parent_curve))) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.COMPOSITE_CURVE_ON_SURFACE' IN TYPEOF(c\ + composite_curve.segments[k].parent_curve))) THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + RETURN(TRUE); + END_FUNCTION; -- constraints_composite_curve_on_surface + + FUNCTION constraints_geometry_shell_based_surface_model( + m: shell_based_surface_model): BOOLEAN; + LOCAL + result : BOOLEAN := TRUE; + END_LOCAL; + REPEAT j := 1 TO SIZEOF(m.sbsm_boundary) BY 1; + IF (NOT ('CONFIG_CONTROL_DESIGN.OPEN_SHELL' IN TYPEOF(m. + sbsm_boundary[j]))) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.CLOSED_SHELL' IN + TYPEOF(m.sbsm_boundary[j]))) THEN + result := FALSE; + RETURN(result); + END_IF; + END_REPEAT; + RETURN(result); + END_FUNCTION; -- constraints_geometry_shell_based_surface_model + + FUNCTION constraints_geometry_shell_based_wireframe_model( + m: shell_based_wireframe_model): BOOLEAN; + LOCAL + result : BOOLEAN := TRUE; + END_LOCAL; + REPEAT j := 1 TO SIZEOF(m.sbwm_boundary) BY 1; + IF (NOT ('CONFIG_CONTROL_DESIGN.WIRE_SHELL' IN TYPEOF(m. + sbwm_boundary[j]))) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.VERTEX_SHELL' IN + TYPEOF(m.sbwm_boundary[j]))) + THEN result := FALSE; + RETURN(result); + END_IF; + END_REPEAT; + RETURN(result); + END_FUNCTION; -- constraints_geometry_shell_based_wireframe_model + + FUNCTION constraints_param_b_spline(degree, up_knots, up_cp: INTEGER; + knot_mult: LIST OF INTEGER; + knots: LIST OF parameter_value): BOOLEAN; + LOCAL + k : INTEGER; + sum : INTEGER; + result : BOOLEAN := TRUE; + END_LOCAL; + sum := knot_mult[1]; + REPEAT i := 2 TO up_knots BY 1; + sum := sum + knot_mult[i]; + END_REPEAT; + IF (degree < 1) OR (up_knots < 2) OR (up_cp < degree) OR (sum <> ( + degree + up_cp + 2)) THEN result := FALSE; + RETURN(result); + END_IF; + k := knot_mult[1]; + IF (k < 1) OR (k > (degree + 1)) THEN result := FALSE; + RETURN(result); + END_IF; + REPEAT i := 2 TO up_knots BY 1; + IF (knot_mult[i] < 1) OR (knots[i] <= knots[i - 1]) THEN + result := FALSE; + RETURN(result); + END_IF; + k := knot_mult[i]; + IF (i < up_knots) AND (k > degree) THEN + result := FALSE; + RETURN(result); + END_IF; + IF (i = up_knots) AND (k > (degree + 1)) THEN + result := FALSE; + RETURN(result); + END_IF; + END_REPEAT; + RETURN(result); + END_FUNCTION; -- constraints_param_b_spline + + FUNCTION constraints_rectangular_composite_surface( + s: rectangular_composite_surface): BOOLEAN; + REPEAT i := 1 TO s.n_u BY 1; + REPEAT j := 1 TO s.n_v BY 1; + IF NOT (('CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE' IN TYPEOF(s. + segments[i][j].parent_surface)) OR ( + 'CONFIG_CONTROL_DESIGN.RECTANGULAR_TRIMMED_SURFACE' IN TYPEOF(s + .segments[i][j].parent_surface))) THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + END_REPEAT; + REPEAT i := 1 TO s.n_u - 1 BY 1; + REPEAT j := 1 TO s.n_v BY 1; + IF s.segments[i][j].u_transition = discontinuous THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + END_REPEAT; + REPEAT i := 1 TO s.n_u BY 1; + REPEAT j := 1 TO s.n_v - 1 BY 1; + IF s.segments[i][j].v_transition = discontinuous THEN + RETURN(FALSE); + END_IF; + END_REPEAT; + END_REPEAT; + RETURN(TRUE); + END_FUNCTION; -- constraints_rectangular_composite_surface + + FUNCTION cross_product(arg1, arg2: direction): vector; + LOCAL + v2 : LIST [3:3] OF REAL; + v1 : LIST [3:3] OF REAL; + mag : REAL; + res : direction; + result : vector; + END_LOCAL; + IF (NOT EXISTS(arg1)) OR (arg1.dim = 2) OR (NOT EXISTS(arg2)) OR (arg2 + .dim = 2) THEN RETURN(?); + ELSE + BEGIN + v1 := normalise(arg1).direction_ratios; + v2 := normalise(arg2).direction_ratios; + res := dummy_gri || direction([(v1[2] * v2[3]) - (v1[3] * v2[2]),( + v1[3] * v2[1]) - (v1[1] * v2[3]),(v1[1] * v2[2]) - (v1[2] * v2[ + 1])]); + mag := 0; + REPEAT i := 1 TO 3 BY 1; + mag := mag + (res.direction_ratios[i] * res.direction_ratios[i]); + END_REPEAT; + IF mag > 0 THEN + result := dummy_gri || vector(res,SQRT(mag)); + ELSE + result := dummy_gri || vector(arg1,0); + END_IF; + RETURN(result); + END; + END_IF; + END_FUNCTION; -- cross_product + + FUNCTION curve_weights_positive(b: rational_b_spline_curve): BOOLEAN; + LOCAL + result : BOOLEAN := TRUE; + END_LOCAL; + REPEAT i := 0 TO b.upper_index_on_control_points BY 1; + IF b.weights[i] <= 0 THEN result := FALSE; + RETURN(result); + END_IF; + END_REPEAT; + RETURN(result); + END_FUNCTION; -- curve_weights_positive + + FUNCTION derive_dimensional_exponents(x: unit): dimensional_exponents; + LOCAL + i : INTEGER; + result : dimensional_exponents := dimensional_exponents(0,0,0,0,0,0,0); + END_LOCAL; + result := x.dimensions; + RETURN(result); + END_FUNCTION; -- derive_dimensional_exponents + + FUNCTION dimension_of(item: geometric_representation_item + ): dimension_count; + LOCAL + x : SET OF representation; + y : representation_context; + END_LOCAL; + x := using_representations(item); + y := x[1].context_of_items; + RETURN(y\geometric_representation_context.coordinate_space_dimension); + END_FUNCTION; -- dimension_of + + FUNCTION dimensions_for_si_unit(n: si_unit_name + ): dimensional_exponents; + CASE n OF + metre : RETURN(dimensional_exponents(1,0,0,0,0,0,0)); + gram : RETURN(dimensional_exponents(0,1,0,0,0,0,0)); + second : RETURN(dimensional_exponents(0,0,1,0,0,0,0)); + ampere : RETURN(dimensional_exponents(0,0,0,1,0,0,0)); + kelvin : RETURN(dimensional_exponents(0,0,0,0,1,0,0)); + mole : RETURN(dimensional_exponents(0,0,0,0,0,1,0)); + candela : RETURN(dimensional_exponents(0,0,0,0,0,0,1)); + radian : RETURN(dimensional_exponents(0,0,0,0,0,0,0)); + steradian : RETURN(dimensional_exponents(0,0,0,0,0,0,0)); + hertz : RETURN(dimensional_exponents(0,0,-1,0,0,0,0)); + newton : RETURN(dimensional_exponents(1,1,-2,0,0,0,0)); + pascal : RETURN(dimensional_exponents(-1,1,-2,0,0,0,0)); + joule : RETURN(dimensional_exponents(2,1,-2,0,0,0,0)); + watt : RETURN(dimensional_exponents(2,1,-3,0,0,0,0)); + coulomb : RETURN(dimensional_exponents(0,0,1,1,0,0,0)); + volt : RETURN(dimensional_exponents(2,1,-3,-1,0,0,0)); + farad : RETURN(dimensional_exponents(-2,-1,4,1,0,0,0)); + ohm : RETURN(dimensional_exponents(2,1,-3,-2,0,0,0)); + siemens : RETURN(dimensional_exponents(-2,-1,3,2,0,0,0)); + weber : RETURN(dimensional_exponents(2,1,-2,-1,0,0,0)); + tesla : RETURN(dimensional_exponents(0,1,-2,-1,0,0,0)); + henry : RETURN(dimensional_exponents(2,1,-2,-2,0,0,0)); + degree_celsius : RETURN(dimensional_exponents(0,0,0,0,1,0,0)); + lumen : RETURN(dimensional_exponents(0,0,0,0,0,0,1)); + lux : RETURN(dimensional_exponents(-2,0,0,0,0,0,1)); + becquerel : RETURN(dimensional_exponents(0,0,-1,0,0,0,0)); + gray : RETURN(dimensional_exponents(2,0,-2,0,0,0,0)); + sievert : RETURN(dimensional_exponents(2,0,-2,0,0,0,0)); + END_CASE; + END_FUNCTION; -- dimensions_for_si_unit + + FUNCTION dot_product(arg1, arg2: direction): REAL; + LOCAL + ndim : INTEGER; + scalar : REAL; + vec1 : direction; + vec2 : direction; + END_LOCAL; + IF (NOT EXISTS(arg1)) OR (NOT EXISTS(arg2)) THEN + scalar := ?; + ELSE + IF arg1.dim <> arg2.dim THEN scalar := ?; + ELSE + BEGIN + vec1 := normalise(arg1); + vec2 := normalise(arg2); + ndim := arg1.dim; + scalar := 0; + REPEAT i := 1 TO ndim BY 1; + scalar := scalar + (vec1.direction_ratios[i] * vec2. + direction_ratios[i]); + END_REPEAT; + END; + END_IF; + END_IF; + RETURN(scalar); + END_FUNCTION; -- dot_product + + FUNCTION edge_reversed(an_edge: edge): oriented_edge; + LOCAL + the_reverse : oriented_edge; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.ORIENTED_EDGE' IN TYPEOF(an_edge) THEN + the_reverse := dummy_tri || edge(an_edge.edge_end,an_edge.edge_start) + || oriented_edge(an_edge\oriented_edge.edge_element,NOT an_edge\ + oriented_edge.orientation); + ELSE + the_reverse := dummy_tri || edge(an_edge.edge_end,an_edge.edge_start) + || oriented_edge(an_edge,FALSE); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- edge_reversed + + FUNCTION face_bound_reversed(a_face_bound: face_bound): face_bound; + LOCAL + the_reverse : face_bound; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.FACE_OUTER_BOUND' IN TYPEOF(a_face_bound) + THEN + the_reverse := dummy_tri || face_bound(a_face_bound\face_bound.bound, + NOT a_face_bound\face_bound.orientation) || face_outer_bound(); + ELSE + the_reverse := dummy_tri || face_bound(a_face_bound.bound,NOT + a_face_bound.orientation); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- face_bound_reversed + + FUNCTION face_reversed(a_face: face): oriented_face; + LOCAL + the_reverse : oriented_face; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.ORIENTED_FACE' IN TYPEOF(a_face) THEN + the_reverse := dummy_tri || face(set_of_topology_reversed(a_face. + bounds)) || oriented_face(a_face\oriented_face.face_element,NOT + a_face\oriented_face.orientation); + ELSE + the_reverse := dummy_tri || face(set_of_topology_reversed(a_face. + bounds)) || oriented_face(a_face,FALSE); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- face_reversed + + FUNCTION first_proj_axis(z_axis, arg: direction): direction; + LOCAL + x_vec : vector; + v : direction; + z : direction; + x_axis : direction; + END_LOCAL; + IF NOT EXISTS(z_axis) THEN RETURN(?); + ELSE + z := normalise(z_axis); + IF NOT EXISTS(arg) THEN + IF z.direction_ratios <> [1,0,0] THEN + v := dummy_gri || direction([1,0,0]); + ELSE + v := dummy_gri || direction([0,1,0]); + END_IF; + ELSE + IF arg.dim <> 3 THEN RETURN(?); + END_IF; + IF cross_product(arg,z).magnitude = 0 THEN RETURN(?); + ELSE + v := normalise(arg); + END_IF; + END_IF; + x_vec := scalar_times_vector(dot_product(v,z),z); + x_axis := vector_difference(v,x_vec).orientation; + x_axis := normalise(x_axis); + END_IF; + RETURN(x_axis); + END_FUNCTION; -- first_proj_axis + + FUNCTION gbsf_check_curve(cv: curve): BOOLEAN; + IF SIZEOF(['CONFIG_CONTROL_DESIGN.BOUNDED_CURVE', + 'CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA', + 'CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D'] * TYPEOF(cv)) > 1 THEN + RETURN(FALSE); + ELSE + IF SIZEOF(['CONFIG_CONTROL_DESIGN.CIRCLE', + 'CONFIG_CONTROL_DESIGN.ELLIPSE'] * TYPEOF(cv)) = 1 THEN + RETURN(TRUE); + ELSE + IF (('CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE' IN TYPEOF(cv)) AND (cv + \b_spline_curve.self_intersect = FALSE)) OR (cv\b_spline_curve. + self_intersect = UNKNOWN) THEN + RETURN(TRUE); + ELSE + IF (('CONFIG_CONTROL_DESIGN.COMPOSITE_CURVE' IN TYPEOF(cv)) AND + (cv\composite_curve.self_intersect = FALSE)) OR (cv\ + composite_curve.self_intersect = UNKNOWN) THEN + RETURN(SIZEOF(QUERY ( seg <* cv\composite_curve.segments | ( + NOT gbsf_check_curve(seg.parent_curve)) )) = 0); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA' IN TYPEOF(cv) THEN + RETURN(gbsf_check_curve(cv\curve_replica.parent_curve)); + ELSE + IF ('CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D' IN TYPEOF(cv)) + AND ((cv\offset_curve_3d.self_intersect = FALSE) OR (cv\ + offset_curve_3d.self_intersect = UNKNOWN)) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.POLYLINE' IN + TYPEOF(cv.basis_curve))) THEN + RETURN(gbsf_check_curve(cv\offset_curve_3d.basis_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(cv) THEN + RETURN(gbsf_check_curve(cv\pcurve.reference_to_curve\ + representation.items[1]) AND gbsf_check_surface(cv\ + pcurve.basis_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POLYLINE' IN TYPEOF(cv) THEN + IF SIZEOF(cv\polyline.points) >= 3 THEN + RETURN(TRUE); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE' IN TYPEOF(cv) + THEN + IF gbsf_check_curve(cv\surface_curve.curve_3d) THEN + REPEAT i := 1 TO SIZEOF(cv\surface_curve. + associated_geometry) BY 1; + IF 'CONFIG_CONTROL_DESIGN.SURFACE' IN TYPEOF(cv\ + surface_curve.associated_geometry[i]) THEN + IF NOT gbsf_check_surface(cv\surface_curve. + associated_geometry[i]) THEN + RETURN(FALSE); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(cv + \surface_curve.associated_geometry[i]) + THEN + IF NOT gbsf_check_curve(cv\surface_curve. + associated_geometry[i]) THEN + RETURN(FALSE); + END_IF; + END_IF; + END_IF; + END_REPEAT; + RETURN(TRUE); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.TRIMMED_CURVE' IN TYPEOF( + cv) THEN + IF SIZEOF(['CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.PARABOLA', + 'CONFIG_CONTROL_DESIGN.HYPERBOLA'] * TYPEOF(cv\ + trimmed_curve.basis_curve)) = 1 THEN + RETURN(TRUE); + ELSE + RETURN(gbsf_check_curve(cv\trimmed_curve. + basis_curve)); + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- gbsf_check_curve + + FUNCTION gbsf_check_point(pnt: point): BOOLEAN; + IF 'CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN TYPEOF(pnt) THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POINT_ON_CURVE' IN TYPEOF(pnt) THEN + RETURN(gbsf_check_curve(pnt\point_on_curve.basis_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POINT_ON_SURFACE' IN TYPEOF(pnt) THEN + RETURN(gbsf_check_surface(pnt\point_on_surface.basis_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.DEGENERATE_PCURVE' IN TYPEOF(pnt) + THEN + RETURN(gbsf_check_curve(pnt\degenerate_pcurve. + reference_to_curve\representation.items[1]) AND + gbsf_check_surface(pnt\degenerate_pcurve.basis_surface)); + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- gbsf_check_point + + FUNCTION gbsf_check_surface(sf: surface): BOOLEAN; + IF (('CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE' IN TYPEOF(sf)) AND (sf\ + b_spline_surface.self_intersect = FALSE)) OR (sf\b_spline_surface. + self_intersect = UNKNOWN) THEN RETURN(TRUE); + ELSE + IF SIZEOF(['CONFIG_CONTROL_DESIGN.SPHERICAL_SURFACE', + 'CONFIG_CONTROL_DESIGN.TOROIDAL_SURFACE'] * TYPEOF(sf)) = 1 THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CURVE_BOUNDED_SURFACE' IN TYPEOF(sf) + THEN + IF SIZEOF(['CONFIG_CONTROL_DESIGN.CONICAL_SURFACE', + 'CONFIG_CONTROL_DESIGN.CYLINDRICAL_SURFACE', + 'CONFIG_CONTROL_DESIGN.PLANE'] * TYPEOF(sf\ + curve_bounded_surface.basis_surface)) = 1 THEN + RETURN(SIZEOF(QUERY ( bcurve <* sf\curve_bounded_surface. + boundaries | (NOT gbsf_check_curve(bcurve)) )) = 0); + ELSE + IF gbsf_check_surface(sf\curve_bounded_surface.basis_surface) + THEN + RETURN(SIZEOF(QUERY ( bcurve <* sf\curve_bounded_surface. + boundaries | (NOT gbsf_check_curve(bcurve)) )) = 0); + END_IF; + END_IF; + ELSE + IF (('CONFIG_CONTROL_DESIGN.OFFSET_SURFACE' IN TYPEOF(sf)) AND ( + sf\offset_surface.self_intersect = FALSE)) OR (sf\ + offset_surface.self_intersect = UNKNOWN) THEN + RETURN(gbsf_check_surface(sf\offset_surface.basis_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.RECTANGULAR_COMPOSITE_SURFACE' IN + TYPEOF(sf) THEN + REPEAT i := 1 TO SIZEOF(sf\rectangular_composite_surface. + segments) BY 1; + REPEAT j := 1 TO SIZEOF(sf\rectangular_composite_surface. + segments[i]) BY 1; + IF NOT gbsf_check_surface(sf\ + rectangular_composite_surface.segments[i][j]. + parent_surface) THEN RETURN(FALSE); + END_IF; + END_REPEAT; + END_REPEAT; + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.RECTANGULAR_TRIMMED_SURFACE' IN + TYPEOF(sf) THEN + IF SIZEOF(['CONFIG_CONTROL_DESIGN.CONICAL_SURFACE', + 'CONFIG_CONTROL_DESIGN.CYLINDRICAL_SURFACE', + 'CONFIG_CONTROL_DESIGN.PLANE'] * TYPEOF(sf\ + rectangular_trimmed_surface.basis_surface)) = 1 THEN + RETURN(TRUE); + ELSE + RETURN(gbsf_check_surface(sf\rectangular_trimmed_surface + .basis_surface)); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.SURFACE_REPLICA' IN TYPEOF(sf) + THEN + RETURN(gbsf_check_surface(sf\surface_replica. + parent_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.SWEPT_SURFACE' IN TYPEOF(sf) + THEN + RETURN(gbsf_check_curve(sf\swept_surface.swept_curve)); + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- gbsf_check_surface + + FUNCTION get_basis_surface(c: curve_on_surface): SET [0:2] OF surface; + LOCAL + surfs : SET [0:2] OF surface; + n : INTEGER; + END_LOCAL; + surfs := []; + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(c) THEN + surfs := [c\pcurve.basis_surface]; + ELSE + IF 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE' IN TYPEOF(c) THEN + n := SIZEOF(c\surface_curve.associated_geometry); + REPEAT i := 1 TO n BY 1; + surfs := surfs + associated_surface(c\surface_curve. + associated_geometry[i]); + END_REPEAT; + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.COMPOSITE_CURVE_ON_SURFACE' IN TYPEOF(c) + THEN + n := SIZEOF(c\composite_curve.segments); + surfs := get_basis_surface(c\composite_curve.segments[1]. + parent_curve); + IF n > 1 THEN + REPEAT i := 2 TO n BY 1; + surfs := surfs * get_basis_surface(c\composite_curve.segments[i] + .parent_curve); + END_REPEAT; + END_IF; + END_IF; + RETURN(surfs); + END_FUNCTION; -- get_basis_surface + + FUNCTION item_in_context(item: representation_item; + cntxt: representation_context): BOOLEAN; + LOCAL + i : INTEGER; + y : BAG OF representation_item; + END_LOCAL; + IF SIZEOF(USEDIN(item,'CONFIG_CONTROL_DESIGN.REPRESENTATION.ITEMS') * + cntxt.representations_in_context) > 0 THEN RETURN(TRUE); + ELSE + y := QUERY ( z <* USEDIN(item,'') | ( + 'CONFIG_CONTROL_DESIGN.REPRESENTATION_ITEM' IN TYPEOF(z)) ); + IF SIZEOF(y) > 0 THEN + REPEAT i := 1 TO HIINDEX(y) BY 1; + IF item_in_context(y[i],cntxt) THEN RETURN(TRUE); + END_IF; + END_REPEAT; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- item_in_context + + FUNCTION leap_year(year: year_number): BOOLEAN; + IF (((year MOD 4) = 0) AND ((year MOD 100) <> 0)) OR ((year MOD 400) = + 0) THEN RETURN(TRUE); + ELSE + RETURN(FALSE); + END_IF; + END_FUNCTION; -- leap_year + + FUNCTION list_face_loops(f: face): LIST [0:?] OF loop; + LOCAL + loops : LIST [0:?] OF loop := []; + END_LOCAL; + REPEAT i := 1 TO SIZEOF(f.bounds) BY 1; + loops := loops + f.bounds[i].bound; + END_REPEAT; + RETURN(loops); + END_FUNCTION; -- list_face_loops + + FUNCTION list_of_topology_reversed( + a_list: list_of_reversible_topology_item + ): list_of_reversible_topology_item; + LOCAL + the_reverse : list_of_reversible_topology_item; + END_LOCAL; + the_reverse := []; + REPEAT i := 1 TO SIZEOF(a_list) BY 1; + the_reverse := topology_reversed(a_list[i]) + the_reverse; + END_REPEAT; + RETURN(the_reverse); + END_FUNCTION; -- list_of_topology_reversed + + FUNCTION list_to_array(lis: LIST [0:?] OF GENERIC:t; + low, u: INTEGER): ARRAY OF GENERIC:t; + LOCAL + n : INTEGER; + res : ARRAY [low:u] OF GENERIC:t; + END_LOCAL; + n := SIZEOF(lis); + IF n <> ((u - low) + 1) THEN RETURN(?); + ELSE + res := [lis[1],n]; + REPEAT i := 2 TO n BY 1; + res[(low + i) - 1] := lis[i]; + END_REPEAT; + RETURN(res); + END_IF; + END_FUNCTION; -- list_to_array + + FUNCTION list_to_set(l: LIST [0:?] OF GENERIC:t): SET OF GENERIC:t; + LOCAL + s : SET OF GENERIC:t := []; + END_LOCAL; + REPEAT i := 1 TO SIZEOF(l) BY 1; + s := s + l[i]; + END_REPEAT; + RETURN(s); + END_FUNCTION; -- list_to_set + + FUNCTION make_array_of_array(lis: LIST [1:?] OF LIST [1:?] OF GENERIC:t; + low1, u1, low2, u2: INTEGER): ARRAY OF ARRAY OF GENERIC:t; + LOCAL + res : ARRAY [low1:u1] OF ARRAY [low2:u2] OF GENERIC:t; + END_LOCAL; + IF ((u1 - low1) + 1) <> SIZEOF(lis) THEN RETURN(?); + END_IF; + IF ((u2 - low2) + 1) <> SIZEOF(lis[1]) THEN RETURN(?); + END_IF; + res := [list_to_array(lis[1],low2,u2),(u1 - low1) + 1]; + REPEAT i := 2 TO HIINDEX(lis) BY 1; + IF ((u2 - low2) + 1) <> SIZEOF(lis[i]) THEN RETURN(?); + END_IF; + res[(low1 + i) - 1] := list_to_array(lis[i],low2,u2); + END_REPEAT; + RETURN(res); + END_FUNCTION; -- make_array_of_array + + FUNCTION mixed_loop_type_set(l: SET [0:?] OF loop): LOGICAL; + LOCAL + poly_loop_type : LOGICAL; + END_LOCAL; + IF SIZEOF(l) <= 1 THEN RETURN(FALSE); + END_IF; + poly_loop_type := 'CONFIG_CONTROL_DESIGN.POLY_LOOP' IN TYPEOF(l[1]); + REPEAT i := 2 TO SIZEOF(l) BY 1; + IF ('CONFIG_CONTROL_DESIGN.POLY_LOOP' IN TYPEOF(l[i])) <> + poly_loop_type THEN RETURN(TRUE); + END_IF; + END_REPEAT; + RETURN(FALSE); + END_FUNCTION; -- mixed_loop_type_set + + FUNCTION msb_shells(brep: manifold_solid_brep + ): SET [1:?] OF closed_shell; + IF SIZEOF(QUERY ( msbtype <* TYPEOF(brep) | (msbtype LIKE + '*BREP_WITH_VOIDS') )) >= 1 THEN + RETURN(brep\brep_with_voids.voids + brep.outer); + ELSE + RETURN([brep.outer]); + END_IF; + END_FUNCTION; -- msb_shells + + FUNCTION msf_curve_check(cv: curve): BOOLEAN; + IF SIZEOF(['CONFIG_CONTROL_DESIGN.BOUNDED_CURVE', + 'CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA', + 'CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D'] * TYPEOF(cv)) > 1 THEN + RETURN(FALSE); + ELSE + IF (('CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE' IN TYPEOF(cv)) AND (cv\ + b_spline_curve.self_intersect = FALSE)) OR (cv\b_spline_curve. + self_intersect = UNKNOWN) THEN RETURN(TRUE); + ELSE + IF SIZEOF(['CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.LINE'] * TYPEOF(cv)) = 1 THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA' IN TYPEOF(cv) THEN + RETURN(msf_curve_check(cv\curve_replica.parent_curve)); + ELSE + IF ('CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D' IN TYPEOF(cv)) AND + ((cv\offset_curve_3d.self_intersect = FALSE) OR (cv\ + offset_curve_3d.self_intersect = UNKNOWN)) AND (NOT ( + 'CONFIG_CONTROL_DESIGN.POLYLINE' + IN TYPEOF(cv.basis_curve))) THEN + RETURN(msf_curve_check(cv\offset_curve_3d.basis_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(cv) THEN + RETURN(msf_curve_check(cv\pcurve.reference_to_curve\ + representation.items[1]) AND msf_surface_check(cv\ + pcurve.basis_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.SURFACE_CURVE' IN TYPEOF(cv) + THEN + IF msf_curve_check(cv\surface_curve.curve_3d) THEN + REPEAT i := 1 TO SIZEOF(cv\surface_curve. + associated_geometry) BY 1; + IF 'CONFIG_CONTROL_DESIGN.SURFACE' IN TYPEOF(cv\ + surface_curve.associated_geometry[i]) THEN + IF NOT msf_surface_check(cv\surface_curve. + associated_geometry[i]) THEN + RETURN(FALSE); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.PCURVE' IN TYPEOF(cv\ + surface_curve.associated_geometry[i]) THEN + IF NOT msf_curve_check(cv\surface_curve. + associated_geometry[i]) THEN + RETURN(FALSE); + END_IF; + END_IF; + END_IF; + END_REPEAT; + RETURN(TRUE); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.POLYLINE' IN TYPEOF(cv) THEN + IF SIZEOF(cv\polyline.points) >= 3 THEN + RETURN(TRUE); + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- msf_curve_check + + FUNCTION msf_surface_check(surf: surface): BOOLEAN; + IF 'CONFIG_CONTROL_DESIGN.ELEMENTARY_SURFACE' IN TYPEOF(surf) THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.SWEPT_SURFACE' IN TYPEOF(surf) THEN + RETURN(msf_curve_check(surf\swept_surface.swept_curve)); + ELSE + IF (('CONFIG_CONTROL_DESIGN.OFFSET_SURFACE' IN TYPEOF(surf)) AND ( + surf\offset_surface.self_intersect = FALSE)) OR (surf\ + offset_surface.self_intersect = UNKNOWN) THEN + RETURN(msf_surface_check(surf\offset_surface.basis_surface)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.SURFACE_REPLICA' IN TYPEOF(surf) THEN + RETURN(msf_surface_check(surf\surface_replica.parent_surface)); + ELSE + IF (('CONFIG_CONTROL_DESIGN.B_SPLINE_SURFACE' IN TYPEOF(surf)) + AND (surf\b_spline_surface.self_intersect = FALSE)) OR ( + surf\b_spline_surface.self_intersect = UNKNOWN) THEN + RETURN(TRUE); + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- msf_surface_check + + FUNCTION normalise(arg: vector_or_direction): vector_or_direction; + LOCAL + ndim : INTEGER; + v : direction; + vec : vector; + mag : REAL; + result : vector_or_direction; + END_LOCAL; + IF NOT EXISTS(arg) THEN result := ?; + ELSE + ndim := arg.dim; + IF 'CONFIG_CONTROL_DESIGN.VECTOR' IN TYPEOF(arg) THEN + BEGIN + v := dummy_gri || direction(arg.orientation.direction_ratios); + IF arg.magnitude = 0 THEN RETURN(?); + ELSE + vec := dummy_gri || vector(v,1); + END_IF; + END; + ELSE + v := dummy_gri || direction(arg.direction_ratios); + END_IF; + mag := 0; + REPEAT i := 1 TO ndim BY 1; + mag := mag + (v.direction_ratios[i] * v.direction_ratios[i]); + END_REPEAT; + IF mag > 0 THEN + mag := SQRT(mag); + REPEAT i := 1 TO ndim BY 1; + v.direction_ratios[i] := v.direction_ratios[i] / mag; + END_REPEAT; + IF 'CONFIG_CONTROL_DESIGN.VECTOR' IN TYPEOF(arg) THEN + vec.orientation := v; + result := vec; + ELSE + result := v; + END_IF; + ELSE + RETURN(?); + END_IF; + END_IF; + RETURN(result); + END_FUNCTION; -- normalise + + FUNCTION open_shell_reversed(a_shell: open_shell): oriented_open_shell; + LOCAL + the_reverse : oriented_open_shell; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.ORIENTED_OPEN_SHELL' IN TYPEOF(a_shell) + THEN + the_reverse := dummy_tri || connected_face_set(a_shell\ + connected_face_set.cfs_faces) || open_shell() || + oriented_open_shell(a_shell\oriented_open_shell. + open_shell_element,NOT a_shell\oriented_open_shell.orientation); + ELSE + the_reverse := dummy_tri || connected_face_set(a_shell\ + connected_face_set.cfs_faces) || open_shell() || + oriented_open_shell(a_shell,FALSE); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- open_shell_reversed + + FUNCTION orthogonal_complement(vec: direction): direction; + LOCAL + result : direction; + END_LOCAL; + IF (vec.dim <> 2) OR (NOT EXISTS(vec)) THEN RETURN(?); + ELSE + result := dummy_gri || direction([-vec.direction_ratios[2],vec. + direction_ratios[1]]); + RETURN(result); + END_IF; + END_FUNCTION; -- orthogonal_complement + + FUNCTION path_head_to_tail(a_path: path): LOGICAL; + LOCAL + n : INTEGER; + p : BOOLEAN := TRUE; + END_LOCAL; + n := SIZEOF(a_path.edge_list); + REPEAT i := 2 TO n BY 1; + p := p AND (a_path.edge_list[i - 1].edge_end :=: a_path.edge_list[i] + .edge_start); + END_REPEAT; + RETURN(p); + END_FUNCTION; -- path_head_to_tail + + FUNCTION path_reversed(a_path: path): oriented_path; + LOCAL + the_reverse : oriented_path; + END_LOCAL; + IF 'CONFIG_CONTROL_DESIGN.ORIENTED_PATH' IN TYPEOF(a_path) THEN + the_reverse := dummy_tri || path(list_of_topology_reversed(a_path. + edge_list)) || oriented_path(a_path\oriented_path.path_element, + NOT a_path\oriented_path.orientation); + ELSE + the_reverse := dummy_tri || path(list_of_topology_reversed(a_path. + edge_list)) || oriented_path(a_path,FALSE); + END_IF; + RETURN(the_reverse); + END_FUNCTION; -- path_reversed + + FUNCTION scalar_times_vector(scalar: REAL; + vec: vector_or_direction): vector; + LOCAL + v : direction; + mag : REAL; + result : vector; + END_LOCAL; + IF (NOT EXISTS(scalar)) OR (NOT EXISTS(vec)) THEN RETURN(?); + ELSE + IF 'CONFIG_CONTROL_DESIGN.VECTOR' IN TYPEOF(vec) THEN + v := dummy_gri || direction(vec.orientation.direction_ratios); + mag := scalar * vec.magnitude; + ELSE + v := dummy_gri || direction(vec.direction_ratios); + mag := scalar; + END_IF; + IF mag < 0 THEN + REPEAT i := 1 TO SIZEOF(v.direction_ratios) BY 1; + v.direction_ratios[i] := -v.direction_ratios[i]; + END_REPEAT; + mag := -mag; + END_IF; + result := dummy_gri || vector(normalise(v),mag); + END_IF; + RETURN(result); + END_FUNCTION; -- scalar_times_vector + + FUNCTION second_proj_axis(z_axis, x_axis, arg: direction + ): direction; + LOCAL + temp : vector; + v : direction; + y_axis : vector; + END_LOCAL; + IF NOT EXISTS(arg) THEN + v := dummy_gri || direction([0,1,0]); + ELSE + v := arg; + END_IF; + temp := scalar_times_vector(dot_product(v,z_axis),z_axis); + y_axis := vector_difference(v,temp); + temp := scalar_times_vector(dot_product(v,x_axis),x_axis); + y_axis := vector_difference(y_axis,temp); + y_axis := normalise(y_axis); + RETURN(y_axis.orientation); + END_FUNCTION; -- second_proj_axis + + FUNCTION set_of_topology_reversed(a_set: set_of_reversible_topology_item + ): set_of_reversible_topology_item; + LOCAL + the_reverse : set_of_reversible_topology_item; + END_LOCAL; + the_reverse := []; + REPEAT i := 1 TO SIZEOF(a_set) BY 1; + the_reverse := the_reverse + topology_reversed(a_set[i]); + END_REPEAT; + RETURN(the_reverse); + END_FUNCTION; -- set_of_topology_reversed + + FUNCTION shell_reversed(a_shell: shell): shell; + IF 'CONFIG_CONTROL_DESIGN.OPEN_SHELL' IN TYPEOF(a_shell) THEN + RETURN(open_shell_reversed(a_shell)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CLOSED_SHELL' IN TYPEOF(a_shell) THEN + RETURN(closed_shell_reversed(a_shell)); + ELSE + RETURN(?); + END_IF; + END_IF; + END_FUNCTION; -- shell_reversed + + FUNCTION surface_weights_positive(b: rational_b_spline_surface + ): BOOLEAN; + LOCAL + result : BOOLEAN := TRUE; + END_LOCAL; + REPEAT i := 0 TO b.u_upper BY 1; + REPEAT j := 0 TO b.v_upper BY 1; + IF b.weights[i][j] <= 0 THEN result := FALSE; + RETURN(result); + END_IF; + END_REPEAT; + END_REPEAT; + RETURN(result); + END_FUNCTION; -- surface_weights_positive + + FUNCTION topology_reversed(an_item: reversible_topology + ): reversible_topology; + IF 'CONFIG_CONTROL_DESIGN.EDGE' IN TYPEOF(an_item) THEN + RETURN(edge_reversed(an_item)); + END_IF; + IF 'CONFIG_CONTROL_DESIGN.PATH' IN TYPEOF(an_item) THEN + RETURN(path_reversed(an_item)); + END_IF; + IF 'CONFIG_CONTROL_DESIGN.FACE_BOUND' IN TYPEOF(an_item) THEN + RETURN(face_bound_reversed(an_item)); + END_IF; + IF 'CONFIG_CONTROL_DESIGN.FACE' IN TYPEOF(an_item) THEN + RETURN(face_reversed(an_item)); + END_IF; + IF 'CONFIG_CONTROL_DESIGN.SHELL' IN TYPEOF(an_item) THEN + RETURN(shell_reversed(an_item)); + END_IF; + IF 'SET' IN TYPEOF(an_item) THEN + RETURN(set_of_topology_reversed(an_item)); + END_IF; + IF 'LIST' IN TYPEOF(an_item) THEN + RETURN(list_of_topology_reversed(an_item)); + END_IF; + RETURN(?); + END_FUNCTION; -- topology_reversed + + FUNCTION unique_version_change_order(c: action): BOOLEAN; + LOCAL + ords : action_directive := c\directed_action.directive; + assign : SET OF change_request := []; + versions : SET OF product_definition_formation := []; + END_LOCAL; + REPEAT i := 1 TO SIZEOF(ords.requests) BY 1; + assign := assign + QUERY ( ara <* bag_to_set(USEDIN(ords.requests[i], + 'CONFIG_CONTROL_DESIGN.ACTION_REQUEST_ASSIGNMENT.' + + 'ASSIGNED_ACTION_REQUEST')) | ( + 'CONFIG_CONTROL_DESIGN.CHANGE_REQUEST' IN TYPEOF(ara)) ); + END_REPEAT; + REPEAT k := 1 TO SIZEOF(assign) BY 1; + versions := versions + assign[k].items; + END_REPEAT; + RETURN(SIZEOF(QUERY ( vers <* versions | (NOT (SIZEOF( + QUERY ( other_vers <* (versions - vers) | (vers.of_product :=: + other_vers.of_product) )) = 0)) )) = 0); + END_FUNCTION; -- unique_version_change_order + + FUNCTION using_items(item: founded_item_select; + checked_items: SET OF founded_item_select + ): SET OF founded_item_select; + LOCAL + next_items : SET OF founded_item_select; + new_check_items : SET OF founded_item_select; + result_items : SET OF founded_item_select; + END_LOCAL; + result_items := []; + new_check_items := checked_items + item; + next_items := QUERY ( z <* bag_to_set(USEDIN(item,'')) | (( + 'CONFIG_CONTROL_DESIGN.REPRESENTATION_ITEM' IN TYPEOF(z)) OR ( + 'CONFIG_CONTROL_DESIGN.FOUNDED_ITEM' IN TYPEOF(z))) ); + IF SIZEOF(next_items) > 0 THEN + REPEAT i := 1 TO HIINDEX(next_items) BY 1; + IF NOT (next_items[i] IN new_check_items) THEN + result_items := result_items + next_items[i] + using_items( + next_items[i],new_check_items); + END_IF; + END_REPEAT; + END_IF; + RETURN(result_items); + END_FUNCTION; -- using_items + + FUNCTION using_representations(item: founded_item_select + ): SET OF representation; + LOCAL + results : SET OF representation; + intermediate_items : SET OF founded_item_select; + result_bag : BAG OF representation; + END_LOCAL; + results := []; + result_bag := USEDIN(item, + 'CONFIG_CONTROL_DESIGN.REPRESENTATION.ITEMS'); + IF SIZEOF(result_bag) > 0 THEN + REPEAT i := 1 TO HIINDEX(result_bag) BY 1; + results := results + result_bag[i]; + END_REPEAT; + END_IF; + intermediate_items := using_items(item,[]); + IF SIZEOF(intermediate_items) > 0 THEN + REPEAT i := 1 TO HIINDEX(intermediate_items) BY 1; + result_bag := USEDIN(intermediate_items[i], + 'CONFIG_CONTROL_DESIGN.REPRESENTATION.ITEMS'); + IF SIZEOF(result_bag) > 0 THEN + REPEAT j := 1 TO HIINDEX(result_bag) BY 1; + results := results + result_bag[j]; + END_REPEAT; + END_IF; + END_REPEAT; + END_IF; + RETURN(results); + END_FUNCTION; -- using_representations + + FUNCTION valid_calendar_date(date: calendar_date): LOGICAL; + IF NOT ((1 <= date.day_component) AND (date.day_component <= 31)) + THEN RETURN(FALSE); + END_IF; + CASE date.month_component OF + 4 : RETURN((1 <= date.day_component) AND (date. + day_component <= 30)); + 6 : RETURN((1 <= date.day_component) AND (date. + day_component <= 30)); + 9 : RETURN((1 <= date.day_component) AND (date. + day_component <= 30)); + 11 : RETURN((1 <= date.day_component) AND (date. + day_component <= 30)); + 2 : BEGIN + IF leap_year(date.year_component) THEN + RETURN((1 <= date.day_component) AND + (date.day_component <= 29)); + ELSE + RETURN((1 <= date.day_component) AND + (date.day_component <= 28)); + END_IF; + END; + OTHERWISE : RETURN(TRUE); + END_CASE; + END_FUNCTION; -- valid_calendar_date + + FUNCTION valid_geometrically_bounded_wf_curve(crv: curve): BOOLEAN; + IF SIZEOF(['CONFIG_CONTROL_DESIGN.POLYLINE', + 'CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE', + 'CONFIG_CONTROL_DESIGN.ELLIPSE','CONFIG_CONTROL_DESIGN.CIRCLE'] * + TYPEOF(crv)) = 1 THEN RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.TRIMMED_CURVE' IN TYPEOF(crv) THEN + IF SIZEOF(['CONFIG_CONTROL_DESIGN.LINE', + 'CONFIG_CONTROL_DESIGN.PARABOLA', + 'CONFIG_CONTROL_DESIGN.HYPERBOLA'] * TYPEOF(crv\trimmed_curve. + basis_curve)) = 1 THEN RETURN(TRUE); + ELSE + RETURN(valid_geometrically_bounded_wf_curve(crv\trimmed_curve. + basis_curve)); + END_IF; + ELSE + IF 'CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D' IN TYPEOF(crv) THEN + RETURN(valid_geometrically_bounded_wf_curve(crv\offset_curve_3d. + basis_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA' IN TYPEOF(crv) THEN + RETURN(valid_geometrically_bounded_wf_curve(crv\curve_replica. + parent_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.COMPOSITE_CURVE' IN TYPEOF(crv) + THEN + RETURN(SIZEOF(QUERY ( ccs <* crv\composite_curve.segments | + (NOT valid_geometrically_bounded_wf_curve(ccs. + parent_curve)) )) = 0); + END_IF; + END_IF; + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- valid_geometrically_bounded_wf_curve + + FUNCTION valid_geometrically_bounded_wf_point(pnt: point): BOOLEAN; + IF 'CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN TYPEOF(pnt) THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POINT_ON_CURVE' IN TYPEOF(pnt) THEN + RETURN(valid_geometrically_bounded_wf_curve(pnt\point_on_curve. + basis_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POINT_REPLICA' IN TYPEOF(pnt) THEN + RETURN(valid_geometrically_bounded_wf_point(pnt\point_replica. + parent_pt)); + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- valid_geometrically_bounded_wf_point + + FUNCTION valid_measure_value(m: measure_value): BOOLEAN; + IF 'REAL' IN TYPEOF(m) THEN + RETURN(m > 0); + ELSE + IF 'INTEGER' IN TYPEOF(m) THEN RETURN(m > 0); + ELSE + RETURN(TRUE); + END_IF; + END_IF; + END_FUNCTION; -- valid_measure_value + + FUNCTION valid_time(time: local_time): BOOLEAN; + IF EXISTS(time.second_component) THEN + RETURN(EXISTS(time.minute_component)); + ELSE + RETURN(TRUE); + END_IF; + END_FUNCTION; -- valid_time + + FUNCTION valid_units(m: measure_with_unit): BOOLEAN; + IF 'CONFIG_CONTROL_DESIGN.LENGTH_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(1,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.MASS_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,1,0,0,0,0,0) THEN + RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.TIME_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,1,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.ELECTRIC_CURRENT_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,1,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.THERMODYNAMIC_TEMPERATURE_MEASURE' IN + TYPEOF(m.value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,1,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.AMOUNT_OF_SUBSTANCE_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,1,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.LUMINOUS_INTENSITY_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,0,1) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.PLANE_ANGLE_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.SOLID_ANGLE_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.AREA_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(2,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.VOLUME_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(3,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.RATIO_MEASURE' IN TYPEOF(m.value_component) + THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.POSITIVE_LENGTH_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(1,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.POSITIVE_PLANE_ANGLE_MEASURE' IN TYPEOF(m. + value_component) THEN + IF derive_dimensional_exponents(m.unit_component) <> + dimensional_exponents(0,0,0,0,0,0,0) THEN RETURN(FALSE); + END_IF; + END_IF; + RETURN(TRUE); + END_FUNCTION; -- valid_units + + FUNCTION valid_wireframe_edge_curve(crv: curve): BOOLEAN; + IF SIZEOF(['CONFIG_CONTROL_DESIGN.LINE','CONFIG_CONTROL_DESIGN.CONIC', + 'CONFIG_CONTROL_DESIGN.B_SPLINE_CURVE', + 'CONFIG_CONTROL_DESIGN.POLYLINE'] * TYPEOF(crv)) = 1 THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.CURVE_REPLICA' IN TYPEOF(crv) THEN + RETURN(valid_wireframe_edge_curve(crv\curve_replica.parent_curve)); + ELSE + IF 'CONFIG_CONTROL_DESIGN.OFFSET_CURVE_3D' IN TYPEOF(crv) THEN + RETURN(valid_wireframe_edge_curve(crv\offset_curve_3d. + basis_curve)); + END_IF; + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- valid_wireframe_edge_curve + + FUNCTION valid_wireframe_vertex_point(pnt: point): BOOLEAN; + IF 'CONFIG_CONTROL_DESIGN.CARTESIAN_POINT' IN TYPEOF(pnt) THEN + RETURN(TRUE); + ELSE + IF 'CONFIG_CONTROL_DESIGN.POINT_REPLICA' IN TYPEOF(pnt) THEN + RETURN(valid_wireframe_vertex_point(pnt\point_replica.parent_pt)); + END_IF; + END_IF; + RETURN(FALSE); + END_FUNCTION; -- valid_wireframe_vertex_point + + FUNCTION vector_difference(arg1, arg2: vector_or_direction + ): vector; + LOCAL + ndim : INTEGER; + mag2 : REAL; + mag1 : REAL; + mag : REAL; + res : direction; + vec1 : direction; + vec2 : direction; + result : vector; + END_LOCAL; + IF (NOT EXISTS(arg1)) OR (NOT EXISTS(arg2)) OR (arg1.dim <> arg2.dim) + THEN RETURN(?); + ELSE + BEGIN + IF 'CONFIG_CONTROL_DESIGN.VECTOR' IN TYPEOF(arg1) THEN + mag1 := arg1.magnitude; + vec1 := arg1.orientation; + ELSE + mag1 := 1; + vec1 := arg1; + END_IF; + IF 'CONFIG_CONTROL_DESIGN.VECTOR' IN TYPEOF(arg2) THEN + mag2 := arg2.magnitude; + vec2 := arg2.orientation; + ELSE + mag2 := 1; + vec2 := arg2; + END_IF; + vec1 := normalise(vec1); + vec2 := normalise(vec2); + ndim := SIZEOF(vec1.direction_ratios); + mag := 0; + res := dummy_gri || direction(vec1.direction_ratios); + REPEAT i := 1 TO ndim BY 1; + res.direction_ratios[i] := (mag1 * vec1.direction_ratios[i]) + ( + mag2 * vec2.direction_ratios[i]); + mag := mag + (res.direction_ratios[i] * res.direction_ratios[i]); + END_REPEAT; + IF mag > 0 THEN + result := dummy_gri || vector(res,SQRT(mag)); + ELSE + result := dummy_gri || vector(vec1,0); + END_IF; + END; + END_IF; + RETURN(result); + END_FUNCTION; -- vector_difference + +END_SCHEMA; -- config_control_design diff --git a/src/conv/step/util/CMakeLists.txt b/src/conv/step/util/CMakeLists.txt index 05e391236d8..bb497cc47f7 100644 --- a/src/conv/step/util/CMakeLists.txt +++ b/src/conv/step/util/CMakeLists.txt @@ -7,7 +7,7 @@ BRLCAD_INCLUDE_DIRS(STEPCODE_INCLUDE_DIRS) link_directories(${CMAKE_BINARY_DIR}/${LIB_DIR}) -set(STEP_SCHEMA_FILE ${CMAKE_SOURCE_DIR}/src/other/ext/stepcode/data/ap203/ap203.exp) +set(STEP_SCHEMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../step-g/ap203.exp) add_definitions(-DAP203) GENERATE_SCHEMA_INPUTS(${STEP_SCHEMA_FILE} list_elements) @@ -17,10 +17,10 @@ set(list_elements_srcs ${express_srcs} list_elements.cpp) if (BRLCAD_ENABLE_STEP) set(lelem_LIBS libbu - steputils - stepeditor - stepdai - stepcore + ${STEPCODE_UTILS_LIBRARY} + ${STEPCODE_EDITOR_LIBRARY} + ${STEPCODE_DAI_LIBRARY} + ${STEPCODE_CORE_LIBRARY} ) BRLCAD_ADDEXEC(list_elements "${list_elements_srcs}" "${lelem_LIBS}" NO_STRICT NO_INSTALL) diff --git a/src/conv/stl/g-stl.c b/src/conv/stl/g-stl.c index 0eba09e50a2..82c20ffe800 100644 --- a/src/conv/stl/g-stl.c +++ b/src/conv/stl/g-stl.c @@ -475,7 +475,7 @@ main(int argc, char *argv[]) &tree_state, 0, /* take all regions */ use_mc?gcv_region_end_mc:gcv_region_end, - use_mc?NULL:nmg_booltree_leaf_tess, + use_mc?NULL:rt_booltree_leaf_tess, (void *)&gcvwriter); if (regions_tried>0) { diff --git a/src/external/Creo/CMakeLists.txt b/src/external/Creo/CMakeLists.txt index 742cd61eab9..893c5c0bcfc 100644 --- a/src/external/Creo/CMakeLists.txt +++ b/src/external/Creo/CMakeLists.txt @@ -520,7 +520,7 @@ else(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS) set(CREO_DIRS "${CMAKE_CURRENT_BINARY_DIR}/../../../include" "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/other/openNURBS" + "${OPENNURBS_INCLUDE_DIRS}" ) BRLCAD_INCLUDE_DIRS(CREO_DIRS) diff --git a/src/external/Creo/main.cpp b/src/external/Creo/main.cpp index 0caa61ed668..99ffe493fe1 100644 --- a/src/external/Creo/main.cpp +++ b/src/external/Creo/main.cpp @@ -56,6 +56,7 @@ creo_conv_info_init(struct creo_conv_info *cinfo) cinfo->xform_mode = XFORM_NONE; /* xform mode */ + cinfo->dbip = NULL; cinfo->wdbp = NULL; /* Units - model */ @@ -644,7 +645,7 @@ doit(char *UNUSED(dialog), char *UNUSED(compnent), ProAppData UNUSED(appdata)) } } else { /* Create new file */ - if ((cinfo->dbip = db_create(out_fname, 5)) != DBI_NULL) + if ((cinfo->dbip = db_create(out_fname, BRLCAD_DB_FORMAT_LATEST)) != DBI_NULL) cinfo->wdbp = wdb_dbopen(cinfo->dbip, RT_WDB_TYPE_DB_DISK); else { creo_log(NULL, MSG_STATUS, "FAILURE: Unable to open output file \"%s\" ", out_fname); diff --git a/src/external/Cubit/CMakeLists.txt b/src/external/Cubit/CMakeLists.txt index b919a479502..5511e0dd13f 100644 --- a/src/external/Cubit/CMakeLists.txt +++ b/src/external/Cubit/CMakeLists.txt @@ -10,7 +10,7 @@ else(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS) set(SAT_DIRS "${CMAKE_CURRENT_BINARY_DIR}/../../../include" "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/other/openNURBS" + "${OPENNURBS_INCLUDE_DIRS}" ${ZLIB_INCLUDE_DIRS} ${REGEX_INCLUDE_DIRS} ) diff --git a/src/external/Unigraphics/CMakeLists.txt b/src/external/Unigraphics/CMakeLists.txt index d4f75d5a4cb..2086e0ebbec 100644 --- a/src/external/Unigraphics/CMakeLists.txt +++ b/src/external/Unigraphics/CMakeLists.txt @@ -14,7 +14,7 @@ else(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS) set(UG_DIRS "${CMAKE_CURRENT_BINARY_DIR}/../../../include" "${CMAKE_CURRENT_SOURCE_DIR}/../../../include" - "${CMAKE_CURRENT_SOURCE_DIR}/../../../src/other/openNURBS" + "${OPENNURBS_INCLUDE_DIRS}" ${ZLIB_INCLUDE_DIRS} ${REGEX_INCLUDE_DIRS} ${TCL_INCLUDE_PATH} diff --git a/src/fb/CMakeLists.txt b/src/fb/CMakeLists.txt index bd7499b3965..e2d0a52ce45 100644 --- a/src/fb/CMakeLists.txt +++ b/src/fb/CMakeLists.txt @@ -5,6 +5,7 @@ set(FBBIN_INCLUDE_DIRS ${PKG_INCLUDE_DIRS} ${DM_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../libtermio ) BRLCAD_INCLUDE_DIRS(FBBIN_INCLUDE_DIRS) @@ -27,13 +28,8 @@ BRLCAD_ADDEXEC(fbclear fbclear.c libdm FOLDER Fb) ADD_TARGET_DEPS(fbclear dm_plugins) BRLCAD_ADDEXEC(fbcmap fbcmap.c libdm FOLDER Fb) ADD_TARGET_DEPS(fbcmap dm_plugins) - -if(TARGET libtermio) - BRLCAD_ADDEXEC(fbcolor fbcolor.c "libdm;libtermio" FOLDER Fb) - ADD_TARGET_DEPS(fbcolor dm_plugins) -else(TARGET libtermio) - CMAKEFILES(fbcolor.c) -endif(TARGET libtermio) +BRLCAD_ADDEXEC(fbcolor fbcolor.c "libdm" FOLDER Fb) +ADD_TARGET_DEPS(fbcolor dm_plugins) BRLCAD_ADDEXEC(fbfade "fbfade.c;ioutil.c" libdm FOLDER Fb) ADD_TARGET_DEPS(fbfade dm_plugins) BRLCAD_ADDEXEC(fbframe fbframe.c libdm FOLDER Fb) @@ -50,20 +46,12 @@ BRLCAD_ADDEXEC(fblabel fblabel.c libdm FOLDER Fb) ADD_TARGET_DEPS(fblabel dm_plugins) BRLCAD_ADDEXEC(fbline fbline.c libdm FOLDER Fb) ADD_TARGET_DEPS(fbline dm_plugins) -if(TARGET libtermio) - BRLCAD_ADDEXEC(fbpoint fbpoint.c "libdm;libbu;libtermio;libpkg" FOLDER Fb) - ADD_TARGET_DEPS(fbpoint dm_plugins) -else(TARGET libtermio) - CMAKEFILES(fbpoint.c) -endif(TARGET libtermio) +BRLCAD_ADDEXEC(fbpoint fbpoint.c "libdm;libbu;libpkg" FOLDER Fb) +ADD_TARGET_DEPS(fbpoint dm_plugins) BRLCAD_ADDEXEC(fbstretch "fbstretch.c;ioutil.c" libdm FOLDER Fb) ADD_TARGET_DEPS(fbstretch dm_plugins) -if(TARGET libtermio) - BRLCAD_ADDEXEC(fbzoom fbzoom.c "libdm;libtermio" FOLDER Fb) - ADD_TARGET_DEPS(fbzoom dm_plugins) -else(TARGET libtermio) - CMAKEFILES(fbzoom.c) -endif(TARGET libtermio) +BRLCAD_ADDEXEC(fbzoom fbzoom.c "libdm" FOLDER Fb) +ADD_TARGET_DEPS(fbzoom dm_plugins) BRLCAD_ADDEXEC(gif-fb "gif-fb.c;ioutil.c" libdm FOLDER Fb) ADD_TARGET_DEPS(gif-fb dm_plugins) BRLCAD_ADDEXEC(gif2fb gif2fb.c libdm FOLDER Fb) @@ -80,7 +68,12 @@ ADD_TARGET_DEPS(png-fb dm_plugins) BRLCAD_ADDEXEC(spm-fb spm-fb.c "libdm;libbn" FOLDER Fb) ADD_TARGET_DEPS(spm-fb dm_plugins) -CMAKEFILES(CMakeLists.txt) +CMAKEFILES( + CMakeLists.txt + fbcolor.c + fbpoint.c + fbzoom.c + ) # Local Variables: # tab-width: 8 diff --git a/src/fb/fb-png.c b/src/fb/fb-png.c index b9980606ee0..f61df7d627b 100644 --- a/src/fb/fb-png.c +++ b/src/fb/fb-png.c @@ -62,7 +62,7 @@ int get_args(int argc, char **argv) { int c; - char *file_name = "-"; + char *file_name = NULL; while ((c = bu_getopt(argc, argv, "ciF:s:w:n:g:#:h?")) != -1) { switch (c) { diff --git a/src/fb/fbcolor.c b/src/fb/fbcolor.c index b235bdba883..e184532da54 100644 --- a/src/fb/fbcolor.c +++ b/src/fb/fbcolor.c @@ -29,6 +29,14 @@ #include #include +#include + +#define LIBTERMIO_IMPLEMENTATION +#if defined(HAVE_CONIO_H) +# include +#else +# include "libtermio.h" +#endif #include "bio.h" @@ -37,7 +45,6 @@ #include "bu/getopt.h" #include "bu/exit.h" #include "dm.h" -#include "libtermio.h" #define COMMA ',' @@ -130,9 +137,11 @@ main(int argc, char **argv) fb_write(fbp, 0, i, buf, 256); /* Set RAW mode */ +#ifndef HAVE_CONIO_H save_Tty(0); set_Raw(0); clr_Echo(0); +#endif do { /* Build color map for current value */ @@ -173,7 +182,11 @@ main(int argc, char **argv) } while (doKeyPad()); fb_wmap(fbp, &old_map); + +#ifndef HAVE_CONIO_H reset_Tty(0); +#endif + (void) fprintf(stdout, "\n"); /* Move off of the output line. */ return 0; } @@ -193,13 +206,19 @@ i v select intensity value\r\n\ q quit\r\n\ \\n Exit\r\n"; + int doKeyPad(void) { int ch; +#if defined(HAVE_CONIO_H) + if ((ch = getch()) == EOF) + return 0; /* done */ +#else if ((ch = getchar()) == EOF) return 0; /* done */ +#endif switch (ch) { default : @@ -367,9 +386,6 @@ rgbhsv(int *rgb, int *hsv) * * convert hue saturation and value to red, green, blue */ - -double modf(double, double *); - void hsvrgb(int *hsv, int *rgb) { diff --git a/src/fb/fbpoint.c b/src/fb/fbpoint.c index 413c90daf36..55c953bf5d1 100644 --- a/src/fb/fbpoint.c +++ b/src/fb/fbpoint.c @@ -38,6 +38,7 @@ #include "bu/getopt.h" #include "vmath.h" #include "dm.h" +#define LIBTERMIO_IMPLEMENTATION #include "libtermio.h" diff --git a/src/fb/fbzoom.c b/src/fb/fbzoom.c index dc66ca13a4a..b499eaf5b94 100644 --- a/src/fb/fbzoom.c +++ b/src/fb/fbzoom.c @@ -37,6 +37,7 @@ #include "vmath.h" #include "dm.h" +#define LIBTERMIO_IMPLEMENTATION #include "libtermio.h" @@ -174,8 +175,13 @@ doKeyPad(void) { int ch; +#if defined(HAVE_CONIO_H) + if ((ch = getch()) == EOF) + return 0; /* done */ +#else if ((ch = getchar()) == EOF) return 0; /* done */ +#endif ch &= ~0x80; /* strip off parity bit */ switch (ch) { case '?' : diff --git a/src/gtools/CMakeLists.txt b/src/gtools/CMakeLists.txt index 25c9c7a94c9..fc26e913ed1 100644 --- a/src/gtools/CMakeLists.txt +++ b/src/gtools/CMakeLists.txt @@ -1,5 +1,3 @@ -set(LDIR "${BRLCAD_SOURCE_DIR}/src/other/ext/linenoise") - set(GTOOLS_INCLUDE_DIRS ${BU_INCLUDE_DIRS} ${RT_INCLUDE_DIRS} @@ -7,39 +5,30 @@ set(GTOOLS_INCLUDE_DIRS ${TCLCAD_INCLUDE_DIRS} ${GED_INCLUDE_DIRS} ${PKG_INCLUDE_DIRS} - ${LDIR} + ${LINENOISE_INCLUDE_DIRS} ) list(REMOVE_DUPLICATES GTOOLS_INCLUDE_DIRS) BRLCAD_INCLUDE_DIRS(GTOOLS_INCLUDE_DIRS) BRLCAD_ADDDATA(gtransfer.c sample_applications) + +BRLCAD_ADDEXEC(ganalyze ganalyze.cpp "libanalyze;librt;libbu;libpkg;${LINENOISE_LIBRARIES}" NO_INSTALL) +set_property(TARGET ganalyze APPEND PROPERTY COMPILE_DEFINITIONS "LINENOISE_DLL_IMPORTS") + +BRLCAD_ADDEXEC(gchecker gchecker.cpp "libged;librt;libbu") BRLCAD_ADDEXEC(gex "gex.cpp" "libbu;librt") BRLCAD_ADDEXEC(glint glint.cpp "librt;${M_LIBRARY}") BRLCAD_ADDEXEC(gqa gqa.c "libged;librt") -BRLCAD_ADDEXEC(gchecker gchecker.cpp "libged;librt;libbu") -set(GSH_SRCS - gsh.cpp - ${LDIR}/utf8.c - ${LDIR}/linenoise.c - ${LDIR}/stringbuf.c - ) -BRLCAD_ADDEXEC(gsh "${GSH_SRCS}" "libged;libdm;libbu") +BRLCAD_ADDEXEC(gsh gsh.cpp "libged;libdm;libbu;${LINENOISE_LIBRARIES}") +set_property(TARGET gsh APPEND PROPERTY COMPILE_DEFINITIONS "LINENOISE_DLL_IMPORTS") add_dependencies(gsh dm_plugins) BRLCAD_ADDEXEC(gtransfer gtransfer.c "librt;libpkg" NO_INSTALL) -set(GANALYZE_SRCS - ganalyze.cpp - ${LDIR}/utf8.c - ${LDIR}/linenoise.c - ${LDIR}/stringbuf.c - ) -BRLCAD_ADDEXEC(ganalyze "${GANALYZE_SRCS}" "libanalyze;librt;libbu;libpkg" NO_INSTALL) - add_subdirectory(beset) add_subdirectory(gdiff) - +add_subdirectory(gist) add_subdirectory(tests) CMAKEFILES( diff --git a/src/gtools/beset/beset.c b/src/gtools/beset/beset.c index 579d55b625b..c986ac88723 100644 --- a/src/gtools/beset/beset.c +++ b/src/gtools/beset/beset.c @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { source_db = db_open(argv[ac+1], DB_OPEN_READWRITE); db_dirbuild(source_db); - pop.db_c = db_create("testdb", 5); + pop.db_c = db_create("testdb", BRLCAD_DB_FORMAT_LATEST); db_close(pop.db_c); @@ -154,7 +154,7 @@ int main(int argc, char *argv[]) { total_fitness = 0.0f; snprintf(dbname, 256, "gen%.3d", g); - pop.db_c = db_create(dbname, 5); + pop.db_c = db_create(dbname, BRLCAD_DB_FORMAT_LATEST); pop_gop(REPRODUCE, argv[ac+2], NULL, argv[ac+2], NULL, source_db, pop.db_c, &rt_uniresource); diff --git a/src/gtools/beset/population.c b/src/gtools/beset/population.c index 274882770dc..6c4e19130dd 100644 --- a/src/gtools/beset/population.c +++ b/src/gtools/beset/population.c @@ -99,7 +99,7 @@ pop_spawn (struct population *p) char shape[256]; - p->db_p = db_create("gen000", 5); + p->db_p = db_create("gen000", BRLCAD_DB_FORMAT_LATEST); struct rt_wdb *wdbp = wdb_dbopen(p->db_p, RT_WDB_TYPE_DB_DISK); for (i = 0; i < p->size; i++) { diff --git a/src/gtools/gdiff/merge.c b/src/gtools/gdiff/merge.c index 6d89a69c002..8a76dd0f46e 100644 --- a/src/gtools/gdiff/merge.c +++ b/src/gtools/gdiff/merge.c @@ -237,7 +237,7 @@ diff3_merge(struct db_i *left_dbip, struct db_i *ancestor_dbip, struct db_i *rig if (bu_file_exists(bu_vls_addr(state->merge_file), NULL)) return -1; bu_log("Merging into %s\n", bu_vls_addr(state->merge_file)); - if ((merged_dbip = db_create(bu_vls_addr(state->merge_file), 5)) == DBI_NULL) return -1; + if ((merged_dbip = db_create(bu_vls_addr(state->merge_file), BRLCAD_DB_FORMAT_LATEST)) == DBI_NULL) return -1; for (i = 0; i < (int)BU_PTBL_LEN(results); i++) { int added = 0; diff --git a/src/gtools/gist/CMakeLists.txt b/src/gtools/gist/CMakeLists.txt new file mode 100644 index 00000000000..254413eaecc --- /dev/null +++ b/src/gtools/gist/CMakeLists.txt @@ -0,0 +1,67 @@ +set(gist_ignore_files + CMakeLists.txt + CONTRIBUTING.md + FactsHandler.h + IFPainter.h + InformationGatherer.h + LICENSE + Options.h + PerspectiveGatherer.h + Position.h + README.md + RenderHandler.h + TODO + pch.h + picohash.h +) + +set(GIST_SRCS + FactsHandler.cpp + IFPainter.cpp + InformationGatherer.cpp + main.cpp + Options.cpp + PerspectiveGatherer.cpp + Position.cpp + RenderHandler.cpp +) + +CMAKEFILES(${gist_ignore_files} ${GIST_SRCS}) + +find_package(OpenCV COMPONENTS core features2d imgproc highgui) +# FIND_PACKAGE(OpenCV) +if(NOT OpenCV_FOUND) + message("OpenCV is DISABLED") + return() +endif(NOT OpenCV_FOUND) +message("Found OpenCV: ${OpenCV_LIBRARIES}") + +set(GIST_INCLUDE_DIRS + ${BU_INCLUDE_DIRS} + ${RT_INCLUDE_DIRS} + ${GED_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} +) +list(REMOVE_DUPLICATES GIST_INCLUDE_DIRS) +include_directories(${GIST_INCLUDE_DIRS}) + +BRLCAD_ADDEXEC(gist "${GIST_SRCS}" "libbu;librt;libged;${OpenCV_LIBRARIES};") + +# FIXME: should be cxx_std_14, but uses std::filesystem. should use libbu. +target_compile_features(gist PRIVATE cxx_std_17) + +if (CMAKE_SHARED_LIBRARY_SUFFIX STREQUAL ".dll") + add_custom_command(TARGET gist POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND_EXPAND_LISTS + ) +endif (CMAKE_SHARED_LIBRARY_SUFFIX STREQUAL ".dll") + + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/src/gtools/gist/CONTRIBUTING.md b/src/gtools/gist/CONTRIBUTING.md new file mode 100644 index 00000000000..71499b1b2c4 --- /dev/null +++ b/src/gtools/gist/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contributing to BRL-CAD Report Generator + +First off, thank you for considering contributing to Report Generator! Your help and support are greatly appreciated. + +The following guidelines will help you understand how to contribute to this project. By participating in this project, you agree to abide by these guidelines. + +## How to Contribute + +### Reporting Bugs + +- Before reporting a bug, please search the issue tracker to ensure it hasn't already been reported. +- If you can't find a similar issue, create a new one with a clear title and description, and include as much relevant information as possible. +- Label the issue with the `bug` label. + +### Suggesting Enhancements + +- Before suggesting an enhancement, search the issue tracker to ensure it hasn't already been suggested. +- If you can't find a similar suggestion, create a new issue with a clear title and description, and explain why the enhancement would benefit the project. +- Label the issue with the `enhancement` label. + +### Pull Requests + +- Fork the repository and create your branch from `main`. +- If you've changed APIs, update the documentation. +- Ensure the test suite passes. +- Issue that pull request with a description of the issue name and number it aims to resolve! + +## Style Guidelines + +- Follow the coding style used throughout the project, such as indentation, comments, and naming conventions. +- Write clean, well-documented, and easy-to-understand code. +- Add comments and explanations where necessary. +- Make small, focused commits with clear and descriptive commit messages. + +## Code of Conduct + +By participating in this project, you agree that your contributions will be licensed under its MIT License. + +## Additional Resources + +- [How to Create a Pull Request on GitHub](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) +- [GitHub Help Documentation](https://docs.github.com/en/github) + +Thank you for contributing to BRL-CAD Report Generator! diff --git a/src/gtools/gist/FactsHandler.cpp b/src/gtools/gist/FactsHandler.cpp new file mode 100644 index 00000000000..20dbb5ff065 --- /dev/null +++ b/src/gtools/gist/FactsHandler.cpp @@ -0,0 +1,303 @@ +/* F A C T S H A N D L E R . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "FactsHandler.h" +#include "RenderHandler.h" + + +void +makeTopSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) +{ + //Draw black rectangle + if (info.getInfo("classification") == "CONFIDENTIAL") { + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0, 0, 255)); + } + else { + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0, 0, 0)); + } + + int textHeight = 3 * height / 8; + int textYOffset = (height - textHeight) / 2; + std::vector text; + std::vector text2; + + if (info.getInfo("classification") != "") { + text.push_back("Owner: " + info.getInfo("owner")); + text.push_back("MD5 Checksum: " + info.getInfo("checksum")); + text2.push_back("Last Updated: " + info.getInfo("lastUpdate")); + text2.push_back("Source File: " + info.getInfo("file")); + img.justifyWithCenterWord(offsetX, offsetY + textYOffset, textHeight, width, info.getInfo("classification"), text, text2, TO_WHITE); + } + else { + text.push_back("Owner: " + info.getInfo("owner")); + text.push_back("Checksum: " + info.getInfo("checksum")); + text.push_back("Last Updated : " + info.getInfo("lastUpdate")); + text.push_back("Source File : " + info.getInfo("file")); + img.justify(offsetX, offsetY + textYOffset, textHeight, width, text, TO_WHITE); + } +} + + +void +makeBottomSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) +{ + //Draw black rectangle + if (info.getInfo("classification") == "CONFIDENTIAL") { + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0, 0, 255)); + } + else { + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(0, 0, 0)); + } + + int textHeight = 3 * height / 8; + int textYOffset = (height - textHeight) / 2; + std::vector text; + std::vector text2; + + if (info.getInfo("classification") != "") { + text.push_back("Preparer: " + info.getInfo("preparer")); + text2.push_back("Date Generated : " + info.getInfo("dateGenerated")); + img.justifyWithCenterWord(offsetX, offsetY + textYOffset, textHeight, width, info.getInfo("classification"), text, text2, TO_WHITE); + } + else { + text.push_back("Preparer: " + info.getInfo("preparer")); + text.push_back("Date Generated : " + info.getInfo("dateGenerated")); + img.justify(offsetX, offsetY + textYOffset, textHeight, width, text, TO_WHITE); + } +} + + +void +makeFileInfoSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options &opt) +{ + //Determine units + std::string unit; + if (opt.isDefaultLength()) { + unit = info.getInfo("units"); + } + else { + unit = opt.getUnitLength(); + } + + // draw bounding rectangle + img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(220, 220, 220)); + + int headerOffset = width / 20; + int textOffset = width / 10; + int textHeight = height / 50; + int textYOffset = textHeight * 8 / 5; + + // Verification Calculations + // Calculate column offsets +// int col1Offset = (offsetX + width / 4) - textOffset; +// int col2Offset = offsetX + width / 2; +// int col3Offset = (offsetX + (width*3) / 4) + textOffset; + + int curiX = 0; + + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Geometry Type", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("representation")); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Orientation", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, opt.getOrientationRightLeft() + ", " + opt.getOrientationZYUp()); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Entity Summary", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("primitives") + " primitives, " + info.getInfo("regions") + " regions"); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("assemblies") + " assemblies, " + info.getInfo("total") + " total"); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Units", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("units")); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Dimensions (x, y, z)", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("dimX") + " " + unit); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("dimY") + " " + unit); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("dimZ") + " " + unit); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Presented Area (az/el)", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("surfaceArea00") + " (0/0)"); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("surfaceArea090") + " (0/90)"); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("surfaceArea900") + " (90/0)"); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Approximate Volume", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("volume")); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Mass", TO_BOLD); + img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("mass")); + curiX++; + img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Notes", TO_BOLD); + img.textWrapping(offsetX + textOffset, offsetY + curiX * textYOffset, offsetX + width, (offsetY + curiX * textYOffset) + textHeight * 3, width, textHeight, opt.getNotes(), TO_ELLIPSIS, (width*height)/11000); + +} + + +void +makeHeirarchySection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options& opt) +{ + // img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, 3, cv::Scalar(0, 0, 0)); + +// int textOffset = width / 10; + int textHeight = height / 20; +// int textXOffset = textHeight * 53 / 5; +// int textYOffset = textHeight * 8 / 5; + + // img.drawTextCentered(offsetX + width / 2, offsetY + textHeight, textHeight, width, "Object Hierarchy", TO_BOLD); + + size_t N = 4; // number of sub components you want + int offY = height / 2 + offsetY; + int offX = offsetX + 5; + int imgH = height / 2; + int imgW = (width - 5*fmin(N, info.largestComponents.size()-1)) / fmin(N, info.largestComponents.size()-1); + + int centerPt = offX + imgW/2 + (fmin(N-1, info.largestComponents.size()-2)*imgW) / 2; + + // main component + std::string render = renderPerspective(DETAILED, opt, info.largestComponents[0].name); + //img.drawImageFitted(offX + width/10, offsetY + textHeight/3, imgW, imgH, render); + img.drawTextCentered(offsetX + width / 2, offY - 180, textHeight, width, info.largestComponents[0].name, TO_BOLD); + + img.drawLine(offX + imgW/2, offY - 100, offX + fmin(N-1, info.largestComponents.size()-2)*imgW + imgW/2, offY - 100, 3, cv::Scalar(94, 58, 32)); + img.drawLine(centerPt, offY-100, centerPt, offY-130, 3, cv::Scalar(94, 58, 32)); + img.drawCirc(centerPt, offY-130, 7, -1, cv::Scalar(94, 58, 32)); + // img.drawCirc(centerPt, offY-30, 20, 3, cv::Scalar(94, 58, 32)); + + // entity summary +// int curiX = 0; + // img.drawTextRightAligned(offsetX + width*9/10, offsetY + 20 + curiX * textYOffset, textHeight/1.3, width, "Groups & Assemblies:", TO_BOLD); + // img.drawText(offsetX + width*9/10, offsetY + 20 + curiX++ * textYOffset, textHeight/1.3, width, " " + info.getInfo("groups_assemblies"), TO_BOLD); + // img.drawTextRightAligned(offsetX + width*9/10, offsetY + 20 + curiX * textYOffset, textHeight/1.3, width, "Regions & Parts:", TO_BOLD); + // img.drawText(offsetX + width*9/10, offsetY + 20 + curiX++ * textYOffset, textHeight/1.3, width, " " + info.getInfo("regions_parts"), TO_BOLD); + // img.drawTextRightAligned(offsetX + width*9/10, offsetY + 20 + curiX * textYOffset, textHeight/1.3, width, "Primitive Shapes:", TO_BOLD); + // img.drawText(offsetX + width*9/10, offsetY + 20 + curiX++ * textYOffset, textHeight/1.3, width, " " + info.getInfo("primitives"), TO_BOLD); + + + // sub components + for (int i = 1; i < fmin(N, info.largestComponents.size()); i++) { + render = renderPerspective(GHOST, opt, info.largestComponents[i].name, info.largestComponents[0].name); + // std::cout << "INSIDE factshandler DBG: " << render << std::endl; + img.drawImageFitted(offX + (i-1)*imgW, offY, imgW, imgH, render); + img.drawTextCentered(offX + (i-1)*imgW + imgW/2, offY-70, textHeight, width, info.largestComponents[i].name, TO_BOLD); + img.drawLine(offX + (i-1)*imgW + imgW/2, offY-100, offX + (i-1)*imgW + imgW/2, offY-70, 3, cv::Scalar(94, 58, 32)); + img.drawCirc(offX + (i-1)*imgW + imgW/2, offY-70, 7, -1, cv::Scalar(94, 58, 32)); + // img.drawCirc(offX + (i-1)*imgW + imgW/2, offY+10, 20, 3, cv::Scalar(94, 58, 32)); + // img.drawLine(offX + (i-1)*imgW + imgW/2 - imgW/10, offY+10, offX + (i-1)*imgW + imgW/2 + imgW/10, offY+10, 3, cv::Scalar(0, 0, 0)); + } + + if (info.largestComponents.size() > N) { + // render the smaller sub components all in one + std::string subcomponents = ""; + for (size_t i = N; i < info.largestComponents.size(); i++) + subcomponents += info.largestComponents[i].name + " "; + render = renderPerspective(GHOST, opt, subcomponents, info.largestComponents[0].name); + img.drawImageFitted(offX + (N-1)*imgW, offY, imgW, imgH, render); + img.drawTextCentered(offX + (N-1)*imgW + imgW/2, offY-70, textHeight, width, "...", TO_BOLD); + img.drawLine(offX + (N-1)*imgW + imgW/2, offY-100, offX + (N-1)*imgW + imgW/2, offY-70, 3, cv::Scalar(94, 58, 32)); + img.drawCirc(offX + (N-1)*imgW + imgW/2, offY-70, 7, -1, cv::Scalar(94, 58, 32)); + // img.drawCirc(offX + (N-1)*imgW + imgW/2, offY+10, 20, 3, cv::Scalar(94, 58, 32)); + // img.drawLine(offX + (N-1)*imgW + imgW/2 - imgW/10, offY+10, offX + (N-1)*imgW + imgW/2 + imgW/10, offY+10, 3, cv::Scalar(0, 0, 0)); + } +} + + + +// void makeVerificationSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) { +// // img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(220, 220, 220)); + +// int headerOffset = width / 20; +// int textOffset = width / 10; +// int textHeight = height / 30; +// int textYOffset = textHeight * 8 / 5; + +// img.drawTextCentered(offsetX + width / 2, offsetY + textHeight, textHeight, width, "Verification", TO_BOLD); + +// int curiX = 3; + + +// img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Unit", TO_BOLD); +// img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("units")); + +// curiX++; +// img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Approximate Volume", TO_BOLD); +// img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("volume")); +// curiX++; +// img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Surface Area", TO_BOLD); +// img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("surfaceArea") + " (Projected)"); +// //img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, "(Sample) 128 m^2 (Projected)"); +// curiX++; +// img.drawText(offsetX + headerOffset, offsetY + curiX++ * textYOffset, textHeight, width, "Mass", TO_BOLD); +// img.drawText(offsetX + textOffset, offsetY + curiX++ * textYOffset, textHeight, width, info.getInfo("mass")); +// } + +// void makeVVSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height) { +// img.drawRect(offsetX, offsetY, offsetX + width, offsetY + height, -1, cv::Scalar(220, 220, 220)); + +// int boxOffset = width / 40; +// int textHeightTitle = height / 20; +// int textHeight = height / 30; +// int textYOffset = textHeight * 8 / 5; + +// int textOffset = 2 * boxOffset + textHeight; + +// img.drawTextCentered(offsetX + width / 2, offsetY + textHeight, textHeightTitle, width, "V&V Checks", TO_BOLD); + +// // left side +// int curX = offsetX; +// int curY = offsetY + 2 * textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Has Material Properties"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Has Optical Properties"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Has Analytical Properties"); +// curY += textOffset; + +// // right side +// curX = offsetX + width*7/16; +// curY = offsetY + 2 * textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Watertight and Solid"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Has Overlaps/Interferences"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Has Domain-Specific Issues"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Suitable for Scientific Analysis"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Suitable for Gaming/Visualization"); +// curY += textOffset; +// img.drawRect(curX + boxOffset, curY, curX + boxOffset + textHeight, curY + textHeight, 2, cv::Scalar(0, 0, 0)); +// img.drawText(curX + textOffset, curY, textHeight, width, "Suitable for 3D Printing"); +// curY += textOffset; +// } + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/FactsHandler.h b/src/gtools/gist/FactsHandler.h new file mode 100644 index 00000000000..7cfc1d6a58a --- /dev/null +++ b/src/gtools/gist/FactsHandler.h @@ -0,0 +1,52 @@ +/* F A C T S H A N D L E R . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + +/** + * The FactsHandler code autonomously modifies a section of the report page to include + * multiple textual sections of information about the graphics file. + * + * The code will automatically layout the information in its designated section after + * retreiving said information from the InformationGatherer helper file. + */ + +class InformationGatherer; +class IFPainter; + +void makeTopSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); +void makeBottomSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); +void makeFileInfoSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options& opt); +void makeVerificationSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); +void makeHeirarchySection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options& opt); +void makeVVSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height); + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/IFPainter.cpp b/src/gtools/gist/IFPainter.cpp new file mode 100644 index 00000000000..c916e40446c --- /dev/null +++ b/src/gtools/gist/IFPainter.cpp @@ -0,0 +1,535 @@ +/* I F P A I N T E R . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "IFPainter.h" + + +IFPainter::IFPainter(int width, int height) + : img(width, height, CV_8UC3, cv::Scalar(255, 255, 255)) + , standardTextWeight(2) + , boldTextWeight(4) + , heightToFontSizeMap() +{ + if (img.empty()) { + std::cerr << "ISSUE: Image Frame failed to load (in IFPainter.cpp)" << std::endl; + } +} + + +IFPainter::~IFPainter() +{ +} + + +std::pair +IFPainter::getCroppedImageDims(std::string imgPath) +{ + cv::Mat imageRaw = imread(imgPath, cv::IMREAD_UNCHANGED); // Load color image + // Convert the image to grayscale for creating the mask + cv::Mat gray_image; + cv::cvtColor(imageRaw, gray_image, cv::COLOR_BGR2GRAY); + // Create a mask of non-white pixels + cv::Mat mask = gray_image < 255; + // Find the bounding rectangle of non-white pixels + cv::Rect bounding_rect = boundingRect(mask); + // Crop the image to the bounding rectangle + cv::Mat lilImage = imageRaw(bounding_rect); + + int imgWidth = lilImage.size().width; + int imgHeight = lilImage.size().height; + + return std::pair(imgWidth, imgHeight); +} + + +void +IFPainter::drawImage(int x, int y, int width, int height, std::string imgPath) +{ + cv::Mat lilImage = imread(imgPath, cv::IMREAD_UNCHANGED); + cv::Mat resized_image; + resize(lilImage, resized_image, cv::Size(width, height), cv::INTER_LINEAR); + + //Trying to copyto the image on to the private image frame, img + cv::Mat destRoi; + try { + destRoi = img(cv::Rect(x, y, resized_image.cols, resized_image.rows)); + } catch (...) { + std::cerr << "Trying to create roi out of image boundaries" << std::endl; + return; + } + resized_image.copyTo(destRoi); +} + + +void +IFPainter::drawImageFitted(int x, int y, int width, int height, std::string imgPath) +{ + cv::Mat imageRaw = imread(imgPath, cv::IMREAD_UNCHANGED); // Load color image + // Convert the image to grayscale for creating the mask + cv::Mat gray_image; + cv::cvtColor(imageRaw, gray_image, cv::COLOR_BGR2GRAY); + // Create a mask of non-white pixels + cv::Mat mask = gray_image < 255; + // Find the bounding rectangle of non-white pixels + cv::Rect bounding_rect = boundingRect(mask); + // Crop the image to the bounding rectangle + cv::Mat lilImage = imageRaw(bounding_rect); + + int imgWidth = lilImage.size().width; + int imgHeight = lilImage.size().height; + int heightOffset = 0; + int widthOffset = 0; + + if ((double)imgWidth / imgHeight > (double)width / height) { + // image width is too large; bound on width + int newHeight = (int)(width * (double)imgHeight / imgWidth); + heightOffset = (height - newHeight) / 2; + height = newHeight; + } else { + // image height is too large; bound on height + int newWidth = (int)(height * (double)imgWidth / imgHeight); + widthOffset = (width - newWidth) / 2; + width = newWidth; + } + + cv::Mat resized_image; + + // prevent crashes + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + resize(lilImage, resized_image, cv::Size(width, height), cv::INTER_LINEAR); + + //Trying to copyto the image on to the private image frame, img + cv::Mat destRoi; + try { + destRoi = img(cv::Rect(x + widthOffset, y + heightOffset, resized_image.cols, resized_image.rows)); + } catch (...) { + std::cerr << "Trying to create roi out of image boundaries" << std::endl; + return; + } + resized_image.copyTo(destRoi); +} + + +void +IFPainter::drawDiagramFitted(int x, int y, int width, int height, std::string imgPath, std::string text) +{ + y += 65; + height -= 65; + cv::Mat imageRaw = imread(imgPath, cv::IMREAD_UNCHANGED); // Load color image + // Convert the image to grayscale for creating the mask + cv::Mat gray_image; + cv::cvtColor(imageRaw, gray_image, cv::COLOR_BGR2GRAY); + // Create a mask of non-white pixels + cv::Mat mask = gray_image < 255; + // Find the bounding rectangle of non-white pixels + cv::Rect bounding_rect = boundingRect(mask); + // Crop the image to the bounding rectangle + cv::Mat lilImage = imageRaw(bounding_rect); + + int imgWidth = lilImage.size().width; + int imgHeight = lilImage.size().height; + int heightOffset = 0; + int widthOffset = 0; + + if ((double)imgWidth / imgHeight > (double)width / height) { + // image width is too large; bound on width + int newHeight = (int)(width * (double)imgHeight / imgWidth); + heightOffset = (height - newHeight) / 2; + height = newHeight; + } else { + // image height is too large; bound on height + int newWidth = (int)(height * (double)imgWidth / imgHeight); + widthOffset = (width - newWidth) / 2; + width = newWidth; + } + + cv::Mat resized_image; + resize(lilImage, resized_image, cv::Size(width, height), cv::INTER_LINEAR); + + //Trying to copyto the image on to the private image frame, img + cv::Mat destRoi; + try { + destRoi = img(cv::Rect(x + widthOffset, y + heightOffset, resized_image.cols, resized_image.rows)); + } catch (...) { + std::cerr << "Trying to create roi out of image boundaries" << std::endl; + return; + } + resized_image.copyTo(destRoi); + + // now, draw text and line + this->drawLine(x + widthOffset, y + heightOffset - 5, x + widthOffset + width, y + heightOffset - 5, 5, cv::Scalar(0, 0, 0)); + this->drawTextCentered(x + widthOffset + width / 2, y + heightOffset - 65, 50, width, text, TO_BOLD); +} + + +//Helper funciton to support getting the width of a text +int +IFPainter::getTextWidth(int height, int width, std::string text, int flags) +{ + int fontWeight = (flags & TO_BOLD) ? boldTextWeight : standardTextWeight; + int fontSize = getFontSizeFromHeightAndWidth(height, width, text); + int textWidth = getTextSize(text, cv::FONT_HERSHEY_DUPLEX, fontSize, fontWeight, 0).width; + return textWidth; +} + + +int +IFPainter::getFontSizeFromHeightAndWidth(int height, int width, std::string text) +{ + if (heightToFontSizeMap.find(height) != heightToFontSizeMap.end()) { + return heightToFontSizeMap[height]; + } + + int fontSize = 1; + while (getTextSize("I", cv::FONT_HERSHEY_DUPLEX, fontSize, standardTextWeight, 0).height < height) + fontSize++; + fontSize--; + + heightToFontSizeMap[height] = fontSize; + while (getTextSize(text, cv::FONT_HERSHEY_DUPLEX, fontSize, standardTextWeight, 0).width > width) { + fontSize--; + } + return fontSize; +} + + +void +IFPainter::drawText(int x, int y, int height, int width, std::string text, int flags) +{ + // for now, italic text is omitted + int fontWeight = standardTextWeight; + bool isUnderline = false; + if ((flags & TO_BOLD)) { + fontWeight = boldTextWeight; + } + + if (flags & TO_UNDERLINE) { + isUnderline = true; + } + + cv::Scalar color = (flags & TO_WHITE) ? cv::Scalar(255, 255, 255) : (flags & TO_BLUE ? cv::Scalar(160, 0, 0) : cv::Scalar(0, 0, 0)); + int fontSize = getFontSizeFromHeightAndWidth(height, width, text); + + cv::Point textOrigin(x, y + height); + cv::putText(img, text, cv::Point(x, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + + if (isUnderline) { + // Compute the position of the line below the text + int baseline = 0; + cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN, fontSize, fontWeight, &baseline); + int underlineY = textOrigin.y + baseline + 2; + int underlineX1 = textOrigin.x; + int underlineX2 = underlineX1 + textSize.width; + + // Draw the line using the same color as the text + cv::line(img, cv::Point(underlineX1, underlineY), cv::Point(underlineX2, underlineY), color, 1); + } +} + + +void +IFPainter::drawTextCentered(int x, int y, int height, int width, std::string text, int flags) +{ + // for now, italic text is omitted + int fontWeight = standardTextWeight; + bool isUnderline = false; + if ((flags & TO_BOLD)) { + fontWeight = boldTextWeight; + } + + if (flags & TO_UNDERLINE) { + isUnderline = true; + } + + cv::Scalar color = (flags & TO_WHITE) ? cv::Scalar(255, 255, 255) : (flags & TO_BLUE ? cv::Scalar(160, 0, 0) : cv::Scalar(0, 0, 0)); + int fontSize = getFontSizeFromHeightAndWidth(height, width, text); + + int textWidth = getTextSize(text, cv::FONT_HERSHEY_DUPLEX, fontSize, fontWeight, 0).width; + + cv::Point textOrigin(x - textWidth/2, y + height); + cv::putText(img, text, cv::Point(x - textWidth/2, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + + if (isUnderline) { + // Compute the position of the line below the text + int baseline = 0; + cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN, fontSize, fontWeight, &baseline); + int underlineY = textOrigin.y + baseline + 2; + int underlineX1 = textOrigin.x; + int underlineX2 = underlineX1 + textSize.width; + + // Draw the line using the same color as the text + cv::line(img, cv::Point(underlineX1, underlineY), cv::Point(underlineX2, underlineY), color, 1); + } +} + + +void +IFPainter::drawTextRightAligned(int x, int y, int height, int width, std::string text, int flags) +{ + // for now, italic text is omitted + int fontWeight = standardTextWeight; + bool isUnderline = false; + if ((flags & TO_BOLD)) { + fontWeight = boldTextWeight; + } + + if (flags & TO_UNDERLINE) { + isUnderline = true; + } + + cv::Scalar color = (flags & TO_WHITE) ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0); + int fontSize = getFontSizeFromHeightAndWidth(height, width, text); + + int textWidth = getTextSize(text, cv::FONT_HERSHEY_DUPLEX, fontSize, fontWeight, 0).width; + + cv::Point textOrigin(x - textWidth, y + height); + cv::putText(img, text, cv::Point(x - textWidth, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + + if (isUnderline) { + // Compute the position of the line below the text + int baseline = 0; + cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN, fontSize, fontWeight, &baseline); + int underlineY = textOrigin.y + baseline + 2; + int underlineX1 = textOrigin.x; + int underlineX2 = underlineX1 + textSize.width; + + // Draw the line using the same color as the text + cv::line(img, cv::Point(underlineX1, underlineY), cv::Point(underlineX2, underlineY), color, 1); + } +} + + +/* This function will evenly space out all of the texts in the header + * and footer. The algorithm is to get the total lenght of all of the + * words combined and then the spacing is the total length divided by + * how many words there are + */ +void +IFPainter::justify(int x, int y, int height, int width, std::vector text, int flags) +{ + int totalTextWidth = 0; + + for (size_t i = 0; i < text.size(); i++) { + totalTextWidth += getTextWidth(height, width, text[i], flags); + } + if (totalTextWidth >= width) { + throw std::invalid_argument("Text is larger than the bounding box"); + return; + } + + int fontWeight = (flags & TO_BOLD) ? boldTextWeight : standardTextWeight; + cv::Scalar color = (flags & TO_WHITE) ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0); + int spacing = (width - totalTextWidth) / (text.size() + 1); + int xPosition = x + spacing; + + for (size_t i = 0; i < text.size(); i++) { + int fontSize = getFontSizeFromHeightAndWidth(height, width, text[i]); + cv::putText(img, text[i], cv::Point(xPosition, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + xPosition += spacing + getTextWidth(height, width, text[i], flags); + } +} + + +/* This is justification with a word being centered right in the + * middle. This is tricky now since the spacing is not going to be + * super straightforward. Essentially I split the section into 2 and I + * used the same justify algorithm for the left and right side. Which + * ever side had the smallest spacing is the spacing I will choose for + * between the words. + */ +void +IFPainter::justifyWithCenterWord(int UNUSED(x), int y, int height, int width, std::string centerWord, std::vector leftText, std::vector rightText, int flags) +{ + int confidentialWidth = getTextWidth(height, width, centerWord, flags | TO_BOLD); + + drawTextCentered(width / 2, y, height, width, centerWord, flags | TO_BOLD); + + int totalLeftWidth = 0; + for (size_t i = 0; i < leftText.size(); i++) { + totalLeftWidth += getTextWidth(height, width, leftText[i], flags); + } + + int totalRightWidth = 0; + for (size_t i = 0; i < leftText.size(); i++) { + totalRightWidth += getTextWidth(height, width, rightText[i], flags); + } + + if (totalLeftWidth >= (width / 2) - (confidentialWidth / 2) || totalRightWidth >= (width / 2) - (confidentialWidth / 2)) { + throw std::invalid_argument("Text is larger than either the left or right side"); + return; + } + + int leftSpacing = (((width / 2) - (confidentialWidth / 2)) - totalLeftWidth) / (leftText.size() + 1); + int rightSpacing = (((width / 2) - (confidentialWidth / 2)) - totalRightWidth) / (rightText.size() + 1); + int spacing; + + if (leftSpacing > rightSpacing) { + spacing = rightSpacing; + } + else { + spacing = leftSpacing; + } + + int fontWeight = (flags & TO_BOLD) ? boldTextWeight : standardTextWeight; + cv::Scalar color = (flags & TO_WHITE) ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0); + int xPosition = width / 2 - confidentialWidth / 2; + + for (int i = leftText.size() - 1; i >= 0; i--) { + xPosition = xPosition - spacing - getTextWidth(height, width, leftText[i], flags); + int fontSize = getFontSizeFromHeightAndWidth(height, width, leftText[i]); + cv::putText(img, leftText[i], cv::Point(xPosition, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + } + + xPosition = width / 2 + confidentialWidth / 2 + spacing; + for (size_t i = 0; i < rightText.size(); i++) { + int fontSize = getFontSizeFromHeightAndWidth(height, width, rightText[i]); + cv::putText(img, rightText[i], cv::Point(xPosition, y + height), cv::FONT_HERSHEY_DUPLEX, fontSize, color, fontWeight); + xPosition = xPosition + spacing + getTextWidth(height, width, rightText[i], flags); + } +} + + +// This is a text wrapping function. If a text goes beyond the set x +// or y, it will wrap around to the next line. It also has ellipsis +// fucntion. +void +IFPainter::textWrapping(int x1, int y1, int x2, int y2, int width, int height, std::string text, int ellipsis, int numOfCharactersBeforeEllipsis, int flags) +{ + if (ellipsis == TO_ELLIPSIS) { + if (numOfCharactersBeforeEllipsis < (int)text.length()) { + text = text.substr(0, numOfCharactersBeforeEllipsis) + "..."; + } + } + std::istringstream iss(text); + std::vector words; + + std::string word; + while (iss >> word) { + words.push_back(word); + } + + int x = x1; + int y = y1; + int wordWidth; + int wordWidthWithSpace; + + for (const auto& w : words) { + wordWidth = getTextWidth(height, width, w, flags); + wordWidthWithSpace = getTextWidth(height, width, w + " ", flags); + if (x + wordWidth <= x2) { + drawText(x, y, height, width, w + " ", flags); + x += wordWidthWithSpace; + } else { + if (y + height <= y2 - height) { + x = x1; + y += height; + drawText(x, y, height, width, w + " ", flags); + x += wordWidthWithSpace; + } else { + throw std::invalid_argument("Text is larger than the bounding box"); + return; + } + } + } +} + + +void +IFPainter::drawLine(int x1, int y1, int x2, int y2, int width, cv::Scalar color) +{ + int lineType = cv::LINE_8; + cv::Point start(x1, y1); + cv::Point end(x2, y2); + line(img, + start, + end, + color, + width, + lineType); +} + + +void +IFPainter::drawRect(int x1, int y1, int x2, int y2, int width, cv::Scalar color) +{ + cv::Point topLeft(x1, y1); + cv::Point bottomRight(x2, y2); + rectangle(img, + topLeft, + bottomRight, + color, + width, + cv::LINE_8); +} + + +void +IFPainter::drawCirc(int x, int y, int radius, int width, cv::Scalar color) +{ + circle(img, cv::Point(x, y), radius, color, width, cv::LINE_8); + // ellipse(img, cv::Point(x, y), cv::Size(radius, radius), 0, 0, 180, color, width, cv::LINE_8); +} + + +// void +// IFPainter::drawArc(int x, int y, int width, cv::Scalar color) { +// int lineType = cv::LINE_8; +// cv::Point center(x, y); +// for(int i=10;i<=250;i=i+10) +// { +// ellipse(image, center, Size(i, i), 0, 30, 150, color, width, lineType); +// } +// } + + +void +IFPainter::openInGUI() +{ + cv::namedWindow("Report", cv::WINDOW_AUTOSIZE); + cv::imshow("Report", this->img); + + cv::waitKey(0); //wait infinite time for a keypress + + try { + cv::destroyWindow("Report"); + } catch (std::exception& e) { + } +} + + +void +IFPainter::exportToFile(std::string filePath) +{ + cv::imwrite(filePath, this->img); +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/IFPainter.h b/src/gtools/gist/IFPainter.h new file mode 100644 index 00000000000..8086c401f27 --- /dev/null +++ b/src/gtools/gist/IFPainter.h @@ -0,0 +1,88 @@ +/* I F P A I N T E R . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#define TO_BOLD 1 +#define TO_ITAL 2 +#define TO_WHITE 4 +#define TO_ELLIPSIS 8 +#define TO_UNDERLINE 16 +#define TO_BLUE 32 + +#include "pch.h" + + +/* + * The IFPainter class serves to store the actual image frame that + * will be modified and output in the report. All drawing and + * exporting operations will be done via function calls to this class. + * + */ + +class IFPainter +{ + +private: + cv::Mat img; + + int standardTextWeight; + int boldTextWeight; + + std::map heightToFontSizeMap; + + int getFontSizeFromHeightAndWidth(int height, int width, std::string text); + +public: + + IFPainter(int width, int height); + ~IFPainter(); + + std::pair getCroppedImageDims(std::string imgPath); + + void drawImage(int x, int y, int width, int height, std::string imgPath); + void drawImageFitted(int x, int y, int width, int height, std::string imgPath); + void drawDiagramFitted(int x, int y, int width, int height, std::string imgPath, std::string text); + void drawText(int x, int y, int height, int width, std::string text, int flags = 0); + void drawTextCentered(int x, int y, int height, int width, std::string text, int flags = 0); + void drawTextRightAligned(int x, int y, int height, int width, std::string text, int flags); + void drawLine(int x1, int y1, int x2, int y2, int width, cv::Scalar color); + void drawRect(int x1, int y1, int x2, int y2, int width, cv::Scalar color); + void drawCirc(int x, int y, int radius, int width, cv::Scalar color); + // void drawArc(int x, int y, int width, cv::Scalar color); + int getTextWidth(int height, int width, std::string text, int flags = 0); + void justify(int x, int y, int height, int width, std::vector text, int flags = 0); + void justifyWithCenterWord(int x, int y, int height, int width, std::string centerWord, std::vector leftText, std::vector rightText, int flags); + void textWrapping(int x1, int y1, int x2, int y2, int width, int height, std::string text, int ellipsis, int numOfCharactersBeforeEllipsis, int flags = 0); + + void openInGUI(); + void exportToFile(std::string filePath); +}; + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/InformationGatherer.cpp b/src/gtools/gist/InformationGatherer.cpp new file mode 100644 index 00000000000..226ade681f7 --- /dev/null +++ b/src/gtools/gist/InformationGatherer.cpp @@ -0,0 +1,731 @@ +/* I N F O R M A T I O N G A T H E R E R . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "pch.h" +#include "InformationGatherer.h" + +#ifdef HAVE_WINDOWS_H +# include +# include +# include +#endif +#ifdef __APPLE__ +# include +# include +#endif + +#include "bu/log.h" + + +void +getSurfaceArea(Options* opt, std::map UNUSED(map), std::string az, std::string el, std::string comp, double& surfArea, std::string unit) +{ + //Run RTArea to get surface area + std::string command = opt->getTemppath() + "rtarea -u " + unit + " -a " + az + " -e " + el + " " + opt->getFilepath() + " " + comp + " 2>&1"; + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(command.c_str(), "r"); + + if (!pipe) + throw std::runtime_error("popen() failed!"); + + try { + while (bu_fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + + //If rtarea didn't fail, calculate area + if (result.find("Total Exposed Area") != std::string::npos) { + result = result.substr(result.find("Total Exposed Area")); + result = result.substr(0, result.find("square") - 1); + result = result.substr(result.find("=") + 1); + try { + surfArea += stod(result); + } catch (const std::invalid_argument& ia) { + std::cerr << "Invalid argument for surface area: " << result << " " << ia.what() << '\n'; + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } + } +} + + +void +getVerificationData(struct ged* g, Options* opt, std::map map, double &volume, double &mass, double &surfArea00, double &surfArea090, double &surfArea900, std::string lUnit, std::string mUnit) +{ + //Get tops + const char* tops_cmd[3] = { "tops", NULL, NULL }; + + ged_exec(g, 1, tops_cmd); + + std::stringstream ss(bu_vls_addr(g->ged_result_str)); + std::string val; + std::map listed; + std::vector toVisit; + + while (ss >> val) { + //Get surface area + getSurfaceArea(opt, map, "0", "0", val, surfArea00, lUnit); + getSurfaceArea(opt, map, "0", "90", val, surfArea090, lUnit); + getSurfaceArea(opt, map, "90", "0", val, surfArea900, lUnit); + + //Next, get regions underneath to calculate volume and mass + const char* cmd[3] = { "l", val.c_str(), NULL }; + + ged_exec(g, 2, cmd); + + std::stringstream ss2(bu_vls_addr(g->ged_result_str)); + std::string val2; + std::getline(ss2, val2); // ignore first line + + //Get initial regions + while (getline(ss2, val2)) { + //Parse components + val2 = val2.erase(0, val2.find_first_not_of(" ")); // left trim + val2 = val2.erase(val2.find_last_not_of(" ") + 1); // right trim + + if (val2[0] == 'u') { + val2 = val2.substr(val2.find(' ') + 1); // extract out u + val2 = val2.substr(0, val2.find('[')); + if (val2.find(' ') != std::string::npos) { + val2 = val2.substr(0, val2.find(' ')); + } + + std::map::iterator it; + it = listed.find(val2); + if (it == listed.end()) { + listed[val2] = true; + toVisit.push_back(val2); + } + } + } + } + + for (size_t i = 0; i < toVisit.size(); i++) { + std::string val2 = toVisit[i]; + //Get volume of region + std::string command = opt->getTemppath() + "gqa -Av -q -g 2 -u " + lUnit + ", \"cu " + lUnit + "\" " + opt->getFilepath() + " " + val2 + " 2>&1"; + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(command.c_str(), "r"); + + if (!pipe) + throw std::runtime_error("popen() failed!"); + + try { + while (bu_fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + + //Extract volume value + result = result.substr(result.find("Average total volume:") + 22); + result = result.substr(0, result.find("cu") - 1); + if (result.find("inf") == std::string::npos) { + try { + volume += stod(result); + } catch (const std::invalid_argument& ia) { + std::cerr << "Invalid argument for volume: " << result << " " << ia.what() << '\n'; + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } + } + + //Get mass of region + command = opt->getTemppath() + "gqa -Am -q -g 2 -u " + lUnit + ", \"cu " + lUnit + "\", " + mUnit + " " + opt->getFilepath() + " " + val2 + " 2>&1"; + result = ""; + pipe = popen(command.c_str(), "r"); + if (!pipe) + throw std::runtime_error("popen() failed!"); + try { + while (bu_fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + + if (result.find("Average total weight:") != std::string::npos) { + //Extract mass value + result = result.substr(result.find("Average total weight:") + 22); + result = result.substr(0, result.find(" ")); + //Mass cannot be negative or infinite + + try { + if (result.find("inf") == std::string::npos) { + if (result[0] == '-') { + result = result.substr(1); + mass += stod(result); + } + else { + mass += stod(result); + } + } + } catch (const std::invalid_argument& ia) { + std::cerr << "Invalid argument for mass: " << result << " " << ia.what() << '\n'; + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } + } + } +} + + +double +InformationGatherer::getVolume(std::string component) +{ + // Gather dimensions + const char* cmd[3] = { "bb", component.c_str(), NULL }; + + ged_exec(g, 2, cmd); + + std::stringstream ss(bu_vls_addr(g->ged_result_str)); + std::string val; + int dim_idx = 0; + + while (ss >> val) { + try { + dim_idx++; + if (dim_idx == 4) + return stod(val); + } catch (const std::exception& e) { + continue; + } + } + + return 0; +} + + +int +InformationGatherer::getNumEntities(std::string UNUSED(component)) +{ + // Find number of entities + + const char* cmd[8] = { "search", ".", "-type", "comb", "-not", "-type", "region", NULL }; + + ged_exec(g, 7, cmd); + + std::stringstream ss(bu_vls_addr(g->ged_result_str)); + std::string val; + int entities = 0; + + while (getline(ss, val)) { + entities++; + } + + return entities; +} + + +void +InformationGatherer::getMainComp() +{ + const std::string topcomp = opt->getTopComp(); + if (topcomp != "") { + const char *topname = topcomp.c_str(); + std::cout << "User input top: " << topname << std::endl; + // check if main comp exists + const char* cmd[3] = { "l", topname, NULL }; + ged_exec(g, 2, cmd); + std::string res = bu_vls_addr(g->ged_result_str); + if (res.size() == 0) { + std::cerr << "Could not find component: " << topname << std::endl; + bu_exit(BRLCAD_ERROR, "aborting.\n"); + } + + int entities = getNumEntities(topname); + double volume = getVolume(topname); + largestComponents.push_back({entities, volume, topname}); + return; + } + + const char* cmd[8] = { "search", ".", "-type", "comb", "-not", "-type", "region", NULL }; + + ged_exec(g, 7, cmd); + std::stringstream ss(bu_vls_addr(g->ged_result_str)); + std::string val; + std::vector topComponents; + + while (getline(ss, val)) { + int entities = getNumEntities(val); + double volume = getVolume(val); + topComponents.push_back({entities, volume, val}); + } + + sort(topComponents.rbegin(), topComponents.rend()); + for (size_t i = 0; i < topComponents.size(); i++) { + if (!EQUAL(topComponents[i].volume, std::numeric_limits::infinity())) { + largestComponents.push_back(topComponents[i]); + break; + } + } + + if (largestComponents.size() != 0) { + return; + } else { + const char* search_cmd[5] = { "search", ".", "-type", "comb", NULL }; + + ged_exec(g, 4, search_cmd); + std::stringstream ss2(bu_vls_addr(g->ged_result_str)); + std::string val2; + std::vector topComponents2; + + while (getline(ss2, val2)) { + int entities = getNumEntities(val2); + double volume = getVolume(val2); + topComponents2.push_back({entities, volume, val2}); + } + + sort(topComponents2.rbegin(), topComponents2.rend()); + for (size_t i = 0; i < topComponents2.size(); i++) { + if (!EQUAL(topComponents2[i].volume, std::numeric_limits::infinity())) { + largestComponents.push_back(topComponents2[i]); + break; + } + } + } +} + + +int +InformationGatherer::getEntityData(char* buf) +{ + std::stringstream ss(buf); + std::string token; + int count = 0; + + while (getline(ss, token)) { + count++; + } + + return count; +} + + +void +InformationGatherer::getSubComp() +{ + // std::string prefix = "../../../build/bin/mged -c ../../../build/bin/share/db/moss.g "; + + if (!bu_file_exists((opt->getTemppath() + "mged").c_str(), NULL) && !bu_file_exists((opt->getTemppath() + "mged.exe").c_str(), NULL)) { + bu_log("ERROR: File to executables (%s) is invalid\nPlease use (or check) the -T parameter\n", opt->getTemppath().c_str()); + bu_exit(BRLCAD_ERROR, "Bad folder, aborting.\n"); + } + + std::string pathToOutput = "output/sub_comp.txt"; + std::string retrieveSub = opt->getTemppath() + "mged -c " + opt->getFilepath() + " \"foreach {s} \\[ lt " + largestComponents[0].name + " \\] { set o \\[lindex \\$s 1\\] ; puts \\\"\\$o \\[llength \\[search \\$o \\] \\] \\\" }\" > " + pathToOutput; + system(retrieveSub.c_str()); + + if (!bu_file_exists(pathToOutput.c_str(), NULL)) { + bu_log("ERROR: %s doesn't exist\n", pathToOutput.c_str()); + bu_log("Make sure to create output directory at the same level as main.cpp!\n"); + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } + + std::fstream scFile(pathToOutput); + if (!scFile.is_open()) { + std::cerr << "failed to open file\n"; + return; + } + + std::string comp; + int numEntities = 0; + std::vector subComps; + + while (scFile >> comp >> numEntities) { + double volume = getVolume(comp); + subComps.push_back({numEntities, volume, comp}); + // std::cout << " in subcomp " << comp << " " << numEntities << " " << volume << std::endl; + } + sort(subComps.rbegin(), subComps.rend()); + largestComponents.reserve(largestComponents.size() + subComps.size()); + largestComponents.insert(largestComponents.end(), subComps.begin(), subComps.end()); + scFile.close(); +} + + +InformationGatherer::InformationGatherer(Options* options) +{ + opt = options; +} + + +InformationGatherer::~InformationGatherer() +{ + +} + + +bool +InformationGatherer::gatherInformation(std::string name) +{ + //Create folder output if needed + std::string path = std::filesystem::current_path().string() + "\\output"; + std::cout << "Writing intermediate output files to " << path << std::endl; + + if (!std::filesystem::exists(std::filesystem::path(path))) { + std::filesystem::create_directory("output"); + } + + //Open database + std::string filePath = opt->getFilepath(); + g = ged_open("db", filePath.c_str(), 1); + + //Gather title + const char* cmd[6] = { "title", NULL, NULL, NULL, NULL }; + ged_exec(g, 1, cmd); + infoMap["title"] = bu_vls_addr(g->ged_result_str); + + + //Gather DB Version + cmd[0] = "dbversion"; + cmd[1] = NULL; + ged_exec(g, 1, cmd); + infoMap["version"] = bu_vls_addr(g->ged_result_str); + + // CHECK + //Gather primitives, regions, total objects + cmd[0] = "summary"; + ged_exec(g, 1, cmd); + char* res = strtok(bu_vls_addr(g->ged_result_str), " "); + int count = 0; + while (res != NULL) { + if (count == 1) { + infoMap.insert(std::pair < std::string, std::string>("primitives", res)); + } + else if (count == 3) { + infoMap.insert(std::pair < std::string, std::string>("regions", res)); + } + else if (count == 5) { + infoMap.insert(std::pair < std::string, std::string>("non-regions", res)); + } + count++; + res = strtok(NULL, " "); + } + + // Gather units + cmd[0] = "units"; + cmd[1] = NULL; + ged_exec(g, 1, cmd); + std::string result = bu_vls_addr(g->ged_result_str); + std::size_t first = result.find_first_of("\'"); + std::size_t last = result.find_last_of("\'"); + infoMap["units"] = result.substr(first+1, last-first-1); + + //Get units to use + std::string lUnit; + if (opt->isDefaultLength()) { + lUnit = infoMap["units"]; + } + else { + lUnit = opt->getUnitLength(); + } + std::string mUnit; + if (opt->isDefaultMass()) { + mUnit = "g"; + } + else { + mUnit = opt->getUnitMass(); + } + + getMainComp(); + if (largestComponents.size() == 0) + return false; + + getSubComp(); + std::cout << "Largest Components\n"; + + for (ComponentData x : largestComponents) { + std::cout << x.name << " " << x.numEntities << " " << x.volume << std::endl; + } + + // Gather dimensions + cmd[0] = "bb"; + cmd[1] = largestComponents[0].name.c_str(); + cmd[2] = NULL; + ged_exec(g, 2, cmd); + + std::stringstream ss(bu_vls_addr(g->ged_result_str)); + std::string token; + std::vector dim_data = {"dimX", "dimY", "dimZ", "bbVolume"}; + int dim_idx = 0; + while (ss >> token) { + try { + double length = stod(token); + double convFactor = bu_units_conversion(infoMap["units"].c_str()) / bu_units_conversion(lUnit.c_str()); + std::stringstream ss2 = std::stringstream(); + ss2 << std::setprecision(5) << length*convFactor; + infoMap[dim_data[dim_idx++]] = ss2.str(); + } catch (const std::exception& e) { + continue; + } + } + + // gather group & assemblies + cmd[0] = "search"; + cmd[1] = largestComponents[0].name.c_str(); + cmd[2] = "-above"; + cmd[3] = "-type"; + cmd[4] = "region"; + cmd[5] = NULL; + ged_exec(g, 5, cmd); + infoMap["groups_assemblies"] = std::to_string(getEntityData(bu_vls_addr(g->ged_result_str))); + + // gather primitive shapes + cmd[2] = "-not"; + cmd[3] = "-type"; + cmd[4] = "comb"; + cmd[5] = NULL; + ged_exec(g, 5, cmd); + infoMap["primitives_mged"] = std::to_string(getEntityData(bu_vls_addr(g->ged_result_str))); + + // gather primitive shapes + cmd[2] = "-type"; + cmd[3] = "region"; + cmd[4] = NULL; + ged_exec(g, 4, cmd); + infoMap["regions_parts"] = std::to_string(getEntityData(bu_vls_addr(g->ged_result_str))); + + //Gather name of preparer + infoMap["preparer"] = name; + + //Gather volume and mass + double volume = 0; + double mass = 0; + double surfArea00 = 0; + double surfArea090 = 0; + double surfArea900 = 0; + getVerificationData(g, opt, infoMap, volume, mass, surfArea00, surfArea090, surfArea900, lUnit, mUnit); + ss = std::stringstream(); + ss << std::setprecision(5) << volume; + std::string vol = ss.str(); + ss = std::stringstream(); + ss << std::setprecision(5) << mass; + std::string ma = ss.str(); + ss = std::stringstream(); + ss << std::setprecision(5) << surfArea00; + std::string surf00 = ss.str(); + ss = std::stringstream(); + ss << std::setprecision(5) << surfArea090; + std::string surf090 = ss.str(); + ss = std::stringstream(); + ss << std::setprecision(5) << surfArea900; + std::string surf900 = ss.str(); + + infoMap.insert(std::pair("volume", vol + " " + lUnit + "^3")); + infoMap.insert(std::pair("surfaceArea00", surf00 + " " + lUnit + "^2")); + infoMap.insert(std::pair("surfaceArea090", surf090 + " " + lUnit + "^2")); + infoMap.insert(std::pair("surfaceArea900", surf900 + " " + lUnit + "^2")); + + if (ZERO(mass)) { + infoMap.insert(std::pair("mass", "N/A")); + } else { + infoMap.insert(std::pair("mass", ma + " " + mUnit)); + } + + //Gather representation + bool hasExplicit = false; + bool hasImplicit = false; + const char* tfilter = "-type brep -or -type bot -or -type vol -or -type sketch"; + + if (db_search(NULL, 0, tfilter, 0, NULL, g->dbip, NULL) > 0) { + hasExplicit = true; + } + tfilter = "-below -type region -not -type comb -not -type brep -not -type bot -not -type vol -not -type sketch"; + if (db_search(NULL, 0, tfilter, 0, NULL, g->dbip, NULL) > 0) { + hasImplicit = true; + } + if (hasExplicit && hasImplicit) { + infoMap.insert(std::pair("representation", "Hybrid (Explicit and Implicit)")); + } + else if (hasImplicit) { + infoMap.insert(std::pair("representation", "Implicit with Booleans")); + } + else if (hasExplicit) { + infoMap.insert(std::pair("representation", "Explicit Boundary")); + } + else { + infoMap.insert(std::pair("representation", "ERROR: Type Unknown")); + } + + //Gather assemblies + tfilter = "-above -type region"; + int assemblies = db_search(NULL, 0, tfilter, 0, NULL, g->dbip, NULL); + infoMap.insert(std::pair("assemblies", std::to_string(assemblies))); + + //Gather entity total + infoMap.insert(std::pair("total", std::to_string(assemblies + stoi(infoMap["primitives"]) + stoi(infoMap["regions"])))); + + //Close database + ged_close(g); + + //Next, use other commands to extract info + + //Gather filename + std::string owner = "username"; + +#ifdef HAVE_WINDOWS_H + /* + * Code primarily taken from https://learn.microsoft.com/en-us/windows/win32/secauthz/finding-the-owner-of-a-file-object-in-c-- + */ + bool worked = true; + DWORD dwRtnCode = 0; + PSID pSidOwner = NULL; + BOOL bRtnBool = TRUE; + LPTSTR AcctName = NULL; + LPTSTR DomainName = NULL; + DWORD dwAcctName = 1, dwDomainName = 1; + SID_NAME_USE eUse = SidTypeUnknown; + HANDLE hFile; + PSECURITY_DESCRIPTOR pSD = NULL; + + hFile = CreateFile(TEXT(opt->getFilepath().c_str()), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + worked = false; + } else { + dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD); + if (dwRtnCode != ERROR_SUCCESS) { + worked = false; + } else { + bRtnBool = LookupAccountSid(NULL, pSidOwner, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse); + AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName * sizeof(wchar_t)); + if (AcctName == NULL) { + worked = false; + } else { + DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName * sizeof(wchar_t)); + if (DomainName == NULL) { + worked = false; + } eelse { + bRtnBool = LookupAccountSid(NULL, pSidOwner, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse); + if (bRtnBool == FALSE) { + worked = false; + } else { + owner = AcctName; + } + } + } + } + } + CloseHandle(hFile); +#endif + +#ifdef __APPLE__ + struct stat fileInfo; + stat(opt->getFilepath().c_str(), &fileInfo); + uid_t ownerUID = fileInfo.st_uid; + struct passwd *pw = getpwuid(ownerUID); + if (pw == NULL) { + owner = "N/A"; + } else { + owner = pw->pw_name; + } +#endif + + infoMap.insert(std::pair("owner", owner)); + + //Gather last date updated + struct stat info; + stat(opt->getFilepath().c_str(), &info); + std::time_t update = info.st_mtime; + tm* ltm = localtime(&update); + std::string date = std::to_string(ltm->tm_mon + 1) + "/" + std::to_string(ltm->tm_mday) + "/" + std::to_string(ltm->tm_year + 1900); + infoMap.insert(std::pair < std::string, std::string>("lastUpdate", date)); + + //Gather source file + std::size_t last1 = opt->getFilepath().find_last_of("/"); + std::size_t last2 = opt->getFilepath().find_last_of("\\"); + last = last1 < last2 ? last1 : last2; + + std::string file = opt->getFilepath().substr(last+1, opt->getFilepath().length()-1); + + infoMap.insert(std::pair < std::string, std::string>("file", file)); + + //Gather date of generation + std::time_t now = time(0); + ltm = localtime(&now); + date = std::to_string(ltm->tm_mon+1) + "/" + std::to_string(ltm->tm_mday) + "/" + std::to_string(ltm->tm_year+1900); + infoMap["dateGenerated"] = date; + + //Gather name of preparer + infoMap.insert(std::pair < std::string, std::string>("preparer", opt->getName())); + + //Gather classification + std::string classification = opt->getClassification(); + for (size_t i = 0; i < classification.length(); i++) { + classification[i] = toupper(classification[i]); + } + infoMap.insert(std::pair < std::string, std::string>("classification", classification)); + + //Gather checksum + struct bu_mapped_file* gFile = NULL; + gFile = bu_open_mapped_file(opt->getFilepath().c_str(), ".g file"); + picohash_ctx_t ctx; + char digest[PICOHASH_MD5_DIGEST_LENGTH]; + std::string output; + + picohash_init_md5(&ctx); + picohash_update(&ctx, gFile->buf, gFile->buflen); + picohash_final(&ctx, digest); + + std::stringstream ss2; + + for (int i = 0; i < PICOHASH_MD5_DIGEST_LENGTH; i++) { + std::stringstream ss3; + std::string curHex; + ss3 << std::hex << std::setw(2) << std::setfill('0') << static_cast(digest[i]); + curHex = ss3.str(); + if (curHex.length() > 2) { + //Chop off the f padding + curHex = curHex.substr(curHex.length() - 2, 2); + } + ss2 << curHex; + } + + infoMap.insert(std::pair("checksum", ss2.str())); + + return true; +} + + +std::string +InformationGatherer::getInfo(std::string key) +{ + return infoMap[key]; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/InformationGatherer.h b/src/gtools/gist/InformationGatherer.h new file mode 100644 index 00000000000..188640b6d9b --- /dev/null +++ b/src/gtools/gist/InformationGatherer.h @@ -0,0 +1,85 @@ +/* I N F O R M A T I O N G A T H E R E R . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + +/** + * The InformationGatherer class gathers a multitude of information + * about a 3D model and stores it in an accessible place that can be + * used by other classes writing the report. This class itself works + * to gather all of the required information as specified in Sean + * Morrison's specifications. + */ + +// TODO: Arrange the class for this. +// this class below is a placeholder; it may not be the optimal layout + +class Options; + + +struct ComponentData { + int numEntities; + double volume; + std::string name; + + bool operator<(const ComponentData& other) const { + if (numEntities != other.numEntities) + return numEntities < other.numEntities; + if (!EQUAL(volume, other.volume)) + return volume < other.volume; + return name < other.name; + } +}; + + +class InformationGatherer +{ +private: + Options* opt; + struct ged* g; + std::map infoMap; + double getVolume(std::string component); + int getNumEntities(std::string component); + void getMainComp(); + void getSubComp(); + int getEntityData(char* buf); + +public: + std::vector largestComponents; + InformationGatherer(Options* options); + ~InformationGatherer(); + + bool gatherInformation(std::string name); + + std::string getInfo(std::string key); +}; + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/LICENSE b/src/gtools/gist/LICENSE new file mode 100644 index 00000000000..04ce484d06a --- /dev/null +++ b/src/gtools/gist/LICENSE @@ -0,0 +1,19 @@ +MIT No Attribution + +Copyright (c) 2023 United States Government as represented by the +U.S. Army Research Laboratory. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/gtools/gist/Options.cpp b/src/gtools/gist/Options.cpp new file mode 100644 index 00000000000..035375d4ce0 --- /dev/null +++ b/src/gtools/gist/Options.cpp @@ -0,0 +1,265 @@ +/* O P T I O N S . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "Options.h" + + +Options::Options() +{ + filepath = ""; + temppath = "../../../build/bin/"; + ppi = 300; + width = 3508; + length = 2480; + isFolder = false; + folderName = ""; + openGUI = false; + exportToFile = false; + overrideImages = false; + exportFolderName = ""; + fileName = ""; + name = "N/A"; + classification = ""; + rightLeft = "Right hand"; + zY = "+Z-up"; + notes = "N/A"; + uLength = "m"; + defaultLength = true; + uMass = "g"; + defaultMass = true; +} + + +Options::~Options() +{ + +} + + +void Options::setFilepath(std::string f) { + filepath = f; +} + + +void Options::setTemppath(std::string f) { + if (f[f.size() - 1] != '/' && f[f.size() - 1] != '\\') + f = f + '\\'; + temppath = f; +} + + +void Options::setPPI(int p) { + ppi = p; + width = int(ppi * 11.69); + length = int(ppi * 8.27); +} + + +void Options::setIsFolder() { + isFolder = true; +} + + +void Options::setOpenGUI() { + openGUI = true; +} + + +void Options::setExportToFile() { + exportToFile = true; +} + + +void Options::setOverrideImages() { + overrideImages = true; +} + + +void Options::setExportFolder(std::string fldr) { + exportFolderName = fldr; +} + + +void Options::setFolder(std::string n) { + folderName = n; +} + + +void Options::setFileName(std::string n) { + fileName = n; +} + + +void Options::setName(std::string n) { + name = n; +} + + +void Options::setClassification(std::string c) { + classification = c; +} + + +void Options::setOrientationRightLeft(bool rL) { + if (rL) { + rightLeft = "Left hand"; + } +} + + +void Options::setOrientationZYUp(bool zy) { + if (zy) { + zY = "+Y-up"; + } +} + + +void Options::setNotes(std::string n) { + notes = n; +} + + +void Options::setTopComp(std::string t) { + topComp = t; +} +void Options::setUnitLength(std::string l) { + uLength = l; + defaultLength = false; +} + + +void Options::setUnitMass(std::string m) { + uMass = m; + defaultMass = false; +} + + +std::string Options::getFilepath() { + return filepath; +} + + +std::string Options::getFolder() { + return folderName; +} + + +std::string Options::getExportFolder() { + return exportFolderName; +} + + +std::string Options::getTemppath() { + return temppath; +} + + +int Options::getWidth() { + return width; +} + + +int Options::getLength() { + return length; +} + + +bool Options::getIsFolder() { + return isFolder; +} + + +bool Options::getOpenGUI() { + return openGUI; +} + + +bool Options::getExportToFile() { + return exportToFile; +} + + +bool Options::getOverrideImages() { + return overrideImages; +} + + +std::string Options::getFileName() { + return fileName; +} + + +std::string Options::getName() { + return name; +} + + +std::string Options::getClassification() { + return classification; +} + + +std::string Options::getOrientationRightLeft() { + return rightLeft; +} + + +std::string Options::getOrientationZYUp() { + return zY; +} + + +std::string Options::getNotes() { + return notes; +} + + +std::string Options::getTopComp() { + return topComp; +} + + +std::string Options::getUnitLength() { + return uLength; +} + + +std::string Options::getUnitMass() { + return uMass; +} + + +bool Options::isDefaultLength() { + return defaultLength; +} + + +bool Options::isDefaultMass() { + return defaultMass; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/Options.h b/src/gtools/gist/Options.h new file mode 100644 index 00000000000..04c31825df1 --- /dev/null +++ b/src/gtools/gist/Options.h @@ -0,0 +1,138 @@ +/* O P T I O N S . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + +/* + * The Options class holds report-related parameters that can be specified by the user, such as + * specifications on which renders should be present to the screen, report dimensions, section dimensions, + * etc. + */ + +class Options +{ +public: + Options(); + ~Options(); + //Setter functions + void setFilepath(std::string f); + void setTemppath(std::string f); + void setPPI(int p); + void setIsFolder(); + void setOpenGUI(); + void setExportToFile(); + void setOverrideImages(); + void setExportFolder(std::string fldr); + void setFileName(std::string n); + void setFolder(std::string n); + void setName(std::string n); + void setClassification(std::string c); + void setOrientationRightLeft(bool rL); + void setOrientationZYUp(bool zy); + void setNotes(std::string n); + + void setTopComp(std::string t); + + void setUnitLength(std::string l); + void setUnitMass(std::string m); + + + //Getter functions + std::string getFilepath(); + std::string getTemppath(); + int getWidth(); + int getLength(); + bool getIsFolder(); + bool getOpenGUI(); + bool getExportToFile(); + bool getOverrideImages(); + std::string getFileName(); + std::string getFolder(); + std::string getExportFolder(); + std::string getName(); + std::string getClassification(); + std::string getOrientationRightLeft(); + std::string getOrientationZYUp(); + std::string getNotes(); + + std::string getTopComp(); + + std::string getUnitLength(); + std::string getUnitMass(); + bool isDefaultLength(); + bool isDefaultMass(); + +private: + // Path to file that will be used to generate report + std::string filepath; + // Path to temporary directory to store the info + std::string temppath; + // Pixels per inch + int ppi; + // Dimensions of the output, in pixels + int width; + int length; + // Whether path is a folder with multiple files or not + bool isFolder; + // Whether user specifices to open GUI as well + bool openGUI; + //Whether user decides to export to a png + bool exportToFile; + // Whether or not to override pre-existing rt/rtwizard output files + bool overrideImages; + //Name of export file + std::string fileName; + // Name of folder that contains input models + std::string folderName; + // Name of folder you want to create report.png in + std::string exportFolderName; + // Name of preparer + std::string name; + // Classification word + std::string classification; + // Orientation + std::string rightLeft; + std::string zY; + // Notes + std::string notes; + + // top component + std::string topComp; + + // Unit length + std::string uLength; + bool defaultLength; + // Unit mass + std::string uMass; + bool defaultMass; +}; + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/PerspectiveGatherer.cpp b/src/gtools/gist/PerspectiveGatherer.cpp new file mode 100644 index 00000000000..e43551fa3a0 --- /dev/null +++ b/src/gtools/gist/PerspectiveGatherer.cpp @@ -0,0 +1,162 @@ +/* P E R S P E C T I V E G A T H E R E R . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "PerspectiveGatherer.h" + + +std::map +getFaceDetails() +{ + std::map output; + + output['F'] = {FRONT, "Front", LENGTH, HEIGHT}; + output['T'] = {TOP, "Top", LENGTH, DEPTH}; + output['R'] = {RIGHT, "Right", DEPTH, HEIGHT}; + output['L'] = {LEFT, "Left", DEPTH, HEIGHT}; + output['B'] = {BACK, "Back", LENGTH, HEIGHT}; + output['b'] = {BOTTOM, "Bottom", LENGTH, DEPTH}; + //output['A'] = {DETAILED, "Ambient Occlusion"}; + + return output; +} + + +std::string +extractFileName(std::string filePath) { + return filePath.substr(filePath.find_last_of("/\\") + 1); +} + + +std::string +renderPerspective(RenderingFace face, Options& opt, std::string component, std::string ghost) +{ + // hardcode filename until options come out + std::string pathToInput = opt.getFilepath(); + std::string fileInput = extractFileName(pathToInput); + std::string pathToOutput = "output/"; + std::string fileOutput = fileInput.substr(0, fileInput.find_last_of(".")); + // std::cout << "Path to input: " << pathToInput << " " << fileOutput << std::endl; + // std::cout << "Component: " << component << std::endl; + + // do directory traversal checks + if (fileOutput.find("../") != std::string::npos) { + std::cout << "ERROR: Output file name cannot contain ../\n"; + return ""; + } + + // std::cout << "Path to output: " << pathToOutput << std::endl; + // std::cout << "Processing file: " << fileInput << std::endl; + + std::string fileString = component.substr(0, component.find(".")); + fileString = fileString.substr(0, fileString.find("/")); + // std::cout << "File string: " << fileString << std::endl; + std::string outputname = pathToOutput + fileOutput + "_" + fileString; + std::replace(outputname.begin(), outputname.end(), ' ', '_'); + + if (outputname.size() > 150) { + outputname = outputname.substr(0, 150); + } + + std::string render; + + int a, e; + switch (face) { + case FRONT: + a = 0, e = 0; + outputname += "_front.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case RIGHT: + a = 90, e = 0; + outputname += "_right.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case BACK: + a = 180, e = 0; + outputname += "_back.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case LEFT: + a = 270, e = 0; + outputname += "_left.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case TOP: + a = 0, e = 90; // may need to change "a"? + outputname += "_top.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case BOTTOM: + a = 0, e = 270; + outputname += "_bottom.png"; + render = opt.getTemppath() + "rtedge -s 1024 -W -R -a " + std::to_string(a) + " -e " + std::to_string(e) + " -o " + outputname + " -c \"set bs=1\" " + pathToInput + " " + component; + break; + case DETAILED: + a = 45, e = 45; + outputname += "_detailed.png"; + render = opt.getTemppath() + "rt -C 255/255/255 -s 1024 -A 1.5 -W -R -c \"set ambSamples=64 ambSlow=1\" -o " + outputname + " " + pathToInput + " " + component; + break; + case GHOST: + a = 35, e = 25; + outputname += "_ghost.png"; + render = opt.getTemppath() + "rtwizard -s 1024 -a " + std::to_string(a) + " -e " + std::to_string(e) + " -i " + pathToInput + " -c " + component + " -g " + ghost + " -G 10 -o " + outputname; + // render2 = "../../../build/bin/rtwizard -s 1024 -a " + a + " -e " + e + " -i " + pathToInput + " -g " + ghost + " -G 3 -o " + outputname; + break; + default: + std::cerr<< "mark added this\n"; + break; + } + + // std::cout << render << std::endl; + + + if (opt.getOverrideImages() || std::remove(outputname.c_str()) != 0) { + std::cerr << "Did not remove " << outputname << std::endl; + } + + try { + auto result2 = system(render.c_str()); + if (result2 < 0 || result2 == 127) { + bu_log("ERROR: failed to run: %s\n", render.c_str()); + bu_exit(BRLCAD_ERROR, "system() failed\n"); + } + } catch (std::exception& er) { + std::cerr << er.what() << std::endl; + } + + if (!bu_file_exists(outputname.c_str(), NULL)) { + bu_log("ERROR: %s doesn't exist\n", outputname.c_str()); + bu_log("Rendering not generated"); + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } + std::cout << "Successfully generated perspective rendering png file\n"; + + return outputname; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/PerspectiveGatherer.h b/src/gtools/gist/PerspectiveGatherer.h new file mode 100644 index 00000000000..2afdd24aecf --- /dev/null +++ b/src/gtools/gist/PerspectiveGatherer.h @@ -0,0 +1,81 @@ +/* P E R S P E C T I V E G A T H E R E R . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + + +/** + * The PerspectiveGatherer files contain utility methods for the + * RenderHandler class. + * + * These methods predominantly feature different rendering types / + * perspectives. + * + */ + +class Options; + +enum RenderingFace +{ + FRONT, + TOP, + RIGHT, + LEFT, + BACK, + BOTTOM, + DETAILED, + GHOST +}; + + +enum ModelDimension +{ + LENGTH, + DEPTH, + HEIGHT +}; + + +struct FaceDetails +{ + RenderingFace face; + std::string title; + + ModelDimension widthContributor; + ModelDimension heightContributor; +}; + + +std::map getFaceDetails(); + +// TODO: add correct parameters and return type +std::string renderPerspective(RenderingFace face, Options& opt, std::string component, std::string ghost=""); + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/Position.cpp b/src/gtools/gist/Position.cpp new file mode 100644 index 00000000000..d83be89c591 --- /dev/null +++ b/src/gtools/gist/Position.cpp @@ -0,0 +1,192 @@ +/* P O S I T I O N . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "Position.h" + + +Position::Position(int x, int y, int width, int height) : + x_(x), + y_(y), + width_(width), + height_(height) +{} + +int Position::left() const { + return x_; +} + + +int Position::right() const { + return x_ + width_; +} + + +int Position::top() const { + return y_; +} + + +int Position::bottom() const { + return y_ + height_; +} + + +int Position::centerX() const { + return x_ + width_ / 2; +} + + +int Position::centerY() const { + return y_ + height_ / 2; +} + + +cv::Point Position::topLeft() const { + return cv::Point(x_, y_); +} + + +cv::Point Position::topRight() const { + return cv::Point(x_ + width_, y_); +} + + +cv::Point Position::bottomLeft() const { + return cv::Point(x_, y_ + height_); +} + + +cv::Point Position::bottomRight() const { + return cv::Point(x_ + width_, y_ + height_); +} + + +int Position::halfWidth() const { + return width_ / 2; +} + + +int Position::thirdWidth() const { + return width_ / 3; +} + + +int Position::quarterWidth() const { + return width_ / 4; +} + + +int Position::sixthWidth() const { + return width_ / 6; +} + + +int Position::eighthWidth() const { + return width_ / 8; +} + + +int Position::halfHeight() const { + return height_ / 2; +} + + +int Position::thirdHeight() const { + return height_ / 3; +} + + +int Position::quarterHeight() const { + return height_ / 4; +} + + +int Position::sixthHeight() const { + return height_ / 6; +} + + +int Position::eighthHeight() const { + return height_ / 8; +} + + +int Position::x() const { + return x_; +} + + +int Position::y() const { + return y_; +} + + +int Position::width() const { + return width_; +} + + +int Position::height() const { + return height_; +} + + +void Position::setX(int x) { + x_ = x; +} + + +void Position::setY(int y) { + y_ = y; +} + + +void Position::setWidth(int width) { + width_ = width; +} + + +void Position::setHeight(int height) { + height_ = height; +} + + +bool Position::contains(int x, int y) const { + return x >= left() && x < right() && y >= top() && y < bottom(); +} + + +bool Position::contains(const cv::Point& point) const { + return contains(point.x, point.y); +} + + +bool Position::intersects(const Position& other) const { + return right() > other.left() && left() < other.right() && + bottom() > other.top() && top() < other.bottom(); +} +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/Position.h b/src/gtools/gist/Position.h new file mode 100644 index 00000000000..afa353684c1 --- /dev/null +++ b/src/gtools/gist/Position.h @@ -0,0 +1,93 @@ +/* P O S I T I O N . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + + +/** + * The Position class allows for us create relative positioning + * commands to layout sections and text on the image frame + * + * The code will make some commonly use positions to return based on + * the width and height of a given box and the x and y values it is + * positioned at + */ +class Position { + +public: + Position(int x, int y, int width, int height); + + int left() const; + int right() const; + int top() const; + int bottom() const; + int centerX() const; + int centerY() const; + + cv::Point topLeft() const; + cv::Point topRight() const; + cv::Point bottomLeft() const; + cv::Point bottomRight() const; + + int halfWidth() const; + int thirdWidth() const; + int quarterWidth() const; + int sixthWidth() const; + int eighthWidth() const; + + int halfHeight() const; + int thirdHeight() const; + int quarterHeight() const; + int sixthHeight() const; + int eighthHeight() const; + + int x() const; + int y() const; + int width() const; + int height() const; + + void setX(int x); + void setY(int y); + void setWidth(int width); + void setHeight(int height); + + bool contains(int x, int y) const; + bool contains(const cv::Point& point) const; + bool intersects(const Position& other) const; + +private: + int x_; + int y_; + int width_; + int height_; +}; + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/README.md b/src/gtools/gist/README.md new file mode 100644 index 00000000000..e5bd1362890 --- /dev/null +++ b/src/gtools/gist/README.md @@ -0,0 +1,95 @@ +# README + +## Introduction ## + +The goal of this effort is to auto-generate beautiful concise summaries of 3D geometry models in BRL-CAD, an open source computer-aided design (CAD) system. Leveraging capabilities in BRL-CAD, we worked on creating a tool that produces a novel “one page” summary report that includes visual, textual, and contextual information about a given 3D model. + +This tool was developed by Zhuo (Danny) Chen, Allyson Hoskinson, Andrew Plant, Mark Sturtevant, and Michael Tao, under the mentorship of Sean Morrison and Chris McGregor. + +## Requirements ## + +This code has been run and tested on: + +* C++ +* Visual Studio +* CMake + + +## External Deps ## + +* BRL-CAD - Download latest version at https://brlcad.org/wiki/Compiling +* Appleseed - Download latest version at appleseed - A modern, open source production renderer (appleseedhq.net) +* OpenCV C++ - Download lastest version at https://docs.opencv.org/4.x/df/d65/tutorial_table_of_content_introduction.html +* Boost - Download required version at Boost C++ Libraries download | SourceForge.net +* CMake - Download latest CMake at https://cmake.org/ +* Git - Download latest version at https://git-scm.com/book/en/v2/Getting-Started-Installing-Git + +## Installation ## + +Download this code repository by using git: + + `git clone https://github.com/SP23-CSCE482/visualization.git` + + +## Tests ## + +No test suites are available yet, but will be listed here soon. + +## Execute Code ## +### Setting up BRL-CAD +To build the code, run the following command in the build directory through terminal +`cmake .. -DBRLCAD_ENABLE_STRICT=NO -DBRLCAD_BUNDLED_LIBS=ON -DCMAKE_BUILD_TYPE=Release` + +Then, run the following code to compile +`make` + +To run BRL-CAD, run one of the two commands +`bin/mged` +`bin/archer` + +### Running the report generator through command line +Open terminal, and navigate to `brlcad/src/gtools/`. Clone the repository into the folder using + +`git clone https://github.com/SP23-CSCE482/visualization` + +Then, navigate into the cloned repository and create an output directory. + +`cd visualization && mkdir output` + +Compile the program using + +`g++ $(pkg-config --cflags --libs opencv4) -std=c++17 -I ../../../build/include/openNURBS -I ../../../build/include -I ../../../include *.cpp -L ../../../build/lib -lged -lrt -lbu -Wl,-rpath -Wl,../../../build/lib` + +Run the program using + +`./a.out -p path/to/file.g -f report.png` + +Example + +`./a.out -p ../../../build/share/db/m35.g -f report.png` + +### Windows OS Setup +1. Download and install OpenCV. Be sure to select “Windows” and the 4.6.0 version. +2. Download, install and compile BRL-CAD. +3. Open “BRLCAD.sln” in the build folder. +4. Search the Visual Studio Selection Explorer for “gist”. When found, right click and click “Set as Startup Project”. +5. Press the green play button towards the top middle to run! + +## Environmental Variables/Files ## + +No environmental variables are needed yet, but they will be listed here soon. + +## Deployment ## + +Since this application is a command line tool, no deployment is required. + +## References ## + +https://brlcad.org/wiki/Compiling +appleseed - A modern, open source production renderer (appleseedhq.net) + +## Support ## + +Admins looking for support should first look at the application help page and BRL-CAD wiki. +Users looking for help seek out assistance from the customer. + diff --git a/src/gtools/gist/RenderHandler.cpp b/src/gtools/gist/RenderHandler.cpp new file mode 100644 index 00000000000..f46dc7d9354 --- /dev/null +++ b/src/gtools/gist/RenderHandler.cpp @@ -0,0 +1,781 @@ +/* R E N D E R H A N D L E R . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "RenderHandler.h" + + +LayoutChoice::LayoutChoice(std::string l_map, bool l_lockRows) + : map(l_map), lockRows(l_lockRows), coordinates(), dimDetails() +{ + // make a vector to store coordinates of each item on the map AND ALSO the ambient occlusion view + for (size_t i = 0; i < map.size() + 1; ++i) + { + coordinates.emplace_back(); + } + for (size_t i = 0; i < 3; ++i) + { + dimDetails.emplace_back(-1, -1); + } +} + + +void +LayoutChoice::initCoordinates(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight) +{ + std::map faceDetails = getFaceDetails(); + + // create workingWidth and workingHeight: the area in which we + // will place orthographic views + double workingWidth = secWidth; + double workingHeight = secHeight; + + // create an array to store the starting index of each row. + std::vector rowStartingIndex; + rowStartingIndex.push_back(0); + + for (size_t i = 1; i < map.size(); ++i) { + // Each row starts after a "\n" + if (map[i - 1] == '\n') + rowStartingIndex.push_back(i); + } + + // number of rows is simply equal to the number of starting row + // indices. + int numRows = rowStartingIndex.size(); + // number of columns is equal to the distance between two starting + // indexes of rows, omitting the '\n' + int numCols = rowStartingIndex[1] - rowStartingIndex[0] - 1; + int rowLen = numCols + 1; // length of a row is the number of columns plus the newline character. + + int ambientR = -1; + int ambientC = -1; + for (int r = 0; r < numRows; ++r) { + for (int c = 0; c < numCols; ++c) { + int x = r * (numCols + 1) + c; + if (map[x] == 'A') { + ambientR = r; + ambientC = c; + break; + } + } + if (ambientR != -1) + break; + } + + // allocate some space for the dimensions + double DIM_COLUMN_SPACE = 220; + double DIM_ROW_SPACE = 80; + // then, we shall go row-major order to find dimension spots + for (int r = 0; r < numRows; ++r) { + for (int c = 0; c < numCols; ++c) { + int i = r * rowLen + c; + if (faceDetails.find(map[i]) == faceDetails.end()) + continue; + FaceDetails fdet = faceDetails[map[i]]; + + if (dimDetails[fdet.heightContributor].first == -1) { + dimDetails[fdet.heightContributor] = std::pair(i, 0); + workingWidth -= DIM_COLUMN_SPACE; + } + if (dimDetails[fdet.widthContributor].first == -1) { + dimDetails[fdet.widthContributor] = std::pair(i, 1); + workingHeight -= DIM_ROW_SPACE; + } + + } + } + + // to find the dimensions of the grid, + std::vector rowHeights; + std::vector columnWidths; + // these variables represent the total height/width of the orthographic views, without extra space. + double orthoHeight = 0; + double orthoWidth = 0; + + // traverse the first row to gather the width + for (int i = 0; i < numCols; ++i) { + double colWidth = 0; + switch (map[i]) { + case '\n': case '-': case '|': case '.': case 'A':// items with no area + break; + default: + FaceDetails fdet; + + if (map[i] == ' ') + fdet = faceDetails[map[i + rowLen]]; // check the second row to snatch the width + else + fdet = faceDetails[map[i]]; // or use myself + + ModelDimension dim = fdet.widthContributor; + + if (dim == LENGTH) + colWidth = modelLength; + else if (dim == DEPTH) + colWidth = modelDepth; + else if (dim == HEIGHT) + colWidth = modelHeight; + } + if (!lockRows) + columnWidths.push_back(colWidth); + orthoWidth += colWidth; + } + + // traverse the first column to gather the height + for (int j = 0; j < numRows; ++j) { + int i = rowLen * j; + double rowHeight = 0; + switch (map[i]) { + case '\n': case '-': case '|': case '.': case 'A':// items with no area + break; + default: + FaceDetails fdet; + + if (map[i] == ' ') + fdet = faceDetails[map[i + 1]]; // check the second column to snatch the height + else + fdet = faceDetails[map[i]]; + + ModelDimension dim = fdet.heightContributor; + + if (dim == LENGTH) + rowHeight = modelLength; + else if (dim == DEPTH) + rowHeight = modelDepth; + else if (dim == HEIGHT) + rowHeight = modelHeight; + } + if (lockRows) + rowHeights.push_back(rowHeight); + orthoHeight += rowHeight; + } + + // update workingWidth and workingHeight to incorporate ambient occ + if (ambientR == 0) { + // ambient occlusion is on right side; take off some part of working width + workingWidth *= 2.0 / 3; + } else if (ambientC == 0) { + // ambient occlusion is on bottom; take off some part of working height + workingHeight *= 2.0 / 3; + } else { + double ambientXOffset = 0; + double ambientYOffset = 0; + // ambient occlusion is in middle; search row/col to get top-left dimensions of ambient view + // this check is done to ensure that at least half of the section is for ambient occlusion + if (lockRows) { + for (int i = 0; i < ambientR; ++i) + ambientYOffset += rowHeights[i]; + + for (int i = 0; i < ambientC; ++i) { + switch (map[ambientR * rowLen + i]) { + case '-': case '|': case '.': + continue; + case '\n': case ' ': case 'A': + std::cerr << "ISSUE: Found unexpected character!" << std::endl; + /* fallthrough */ + default: + ModelDimension dim = faceDetails[map[ambientR * rowLen + i]].widthContributor; + + if (dim == LENGTH) + ambientXOffset += modelLength; + else if (dim == DEPTH) + ambientXOffset += modelDepth; + else if (dim == HEIGHT) + ambientXOffset += modelHeight; + } + } + } else { + for (int i = 0; i < ambientC; ++i) + ambientXOffset += columnWidths[i]; + + for (int i = 0; i < ambientR; ++i) { + switch (map[i * rowLen + ambientC]) { + case '-': case '|': case '.': + continue; + case '\n': case ' ': case 'A': + std::cerr << "ISSUE: Found unexpected character!" << std::endl; + /* fallthrough */ + default: + ModelDimension dim = faceDetails[map[i * rowLen + ambientC]].heightContributor; + + if (dim == LENGTH) + ambientYOffset += modelLength; + else if (dim == DEPTH) + ambientYOffset += modelDepth; + else if (dim == HEIGHT) + ambientYOffset += modelHeight; + } + } + } + + // if half of page is not used for ambient occlusion view, then adjust properly + if (ambientYOffset > orthoHeight / 2) + workingHeight *= orthoHeight / 2 / ambientYOffset; + else if (ambientXOffset > orthoWidth / 2) + workingWidth *= orthoWidth / 2 / ambientXOffset; + } + + // get aspect ratios + double orthoAspectRatio = (double)orthoHeight / orthoWidth; + double sectionAspectRatio = (double)workingHeight / workingWidth; + + // variables to store the actual width/height of the orthographic section, in image plane coordinate frame + double actualOrthoWidth = 0; + double actualOrthoHeight = 0; + + // fit the orthographic + if (orthoAspectRatio > sectionAspectRatio) { + // height of the orthographic section is relatively too large; cap the height. + double conversionFactor = workingHeight / orthoHeight; + + actualOrthoHeight = (orthoHeight * conversionFactor); + actualOrthoWidth = (orthoWidth * conversionFactor); + } else { + // width of the orthographic section is relatively too large; cap the width. + double conversionFactor = workingWidth / orthoWidth; + + actualOrthoHeight = (orthoHeight * conversionFactor); + actualOrthoWidth = (orthoWidth * conversionFactor); + } + + // calculating variables used for finding the actual coordinates + double offsetX = 0; + double offsetY = 0; + double widthConversionFactor = actualOrthoWidth / orthoWidth; + double heightConversionFactor = actualOrthoHeight / orthoHeight; + + // now, filling out the coordinates + if (lockRows) { + // all elements in a row have the same height. Iterate row by row + double curX = offsetX, curY = offsetY, curWidth = 0, curHeight = 0; + for (int r = 0; r < numRows; ++r) { + curHeight = (heightConversionFactor * rowHeights[r]); + + for (int c = 0; c < numCols; ++c) { + int i = rowLen * r + c; + + switch (map[i]) { + case '-': + // check item above for the width + curWidth = coordinates[i - rowLen][2] - coordinates[i - rowLen][0]; + break; + case '|': case '.': + // vertical lines have no width + curWidth = 0; + break; + case 'A': + curWidth = 0; + break; + default: // either ' ' or a rendering face + FaceDetails fdet; + + // search for a neighbor that has a usable width (or use your own width, if valid) + if (faceDetails.find(map[i]) != faceDetails.end()) { + fdet = faceDetails[map[i]]; + } else if (r > 0 && faceDetails.find(map[i - rowLen]) != faceDetails.end()) { + fdet = faceDetails[map[i - rowLen]]; + } else if (r < numRows - 1 && faceDetails.find(map[i + rowLen]) != faceDetails.end()) { + fdet = faceDetails[map[i + rowLen]]; + } else { + std::cerr << "FATAL: couldn't find a width to use for rendering!" << std::endl; + } + + ModelDimension dim = fdet.widthContributor; + + if (dim == LENGTH) + curWidth = (widthConversionFactor * modelLength); + else if (dim == DEPTH) + curWidth = (widthConversionFactor * modelDepth); + else if (dim == HEIGHT) + curWidth = (widthConversionFactor * modelHeight); + } + + coordinates[i].push_back(curX); + coordinates[i].push_back(curY); + coordinates[i].push_back(curX + curWidth); + coordinates[i].push_back(curY + curHeight); + + curX += curWidth; + + // add extra padding for dimensions if one exists here + for (std::pair dim : dimDetails) { + if (dim.first % rowLen == c && dim.second == 0) { + curX += DIM_COLUMN_SPACE; + break; + } + } + } + + curX = offsetX; + curY += curHeight; + + // add extra padding for dimensions if one exists here + for (std::pair dim : dimDetails) { + if (dim.first / rowLen == r && dim.second == 1) { + curY += DIM_ROW_SPACE; + break; + } + } + } + } else { + // all elements in a column have the same width. Iterate column by column + double curX = offsetX, curY = offsetY, curWidth = 0, curHeight = 0; + for (int c = 0; c < numCols; ++c) { + curWidth = (widthConversionFactor * columnWidths[c]); + + for (int r = 0; r < numRows; ++r) { + int i = rowLen * r + c; + + switch (map[i]) { + case '|': + // check item to the left for the height + curHeight = coordinates[i - 1][3] - coordinates[i - 1][1]; + break; + case '-': case '.': + // horizontal lines have no height + curHeight = 0; + break; + case 'A': + curHeight = 0; + break; + default: // either ' ' or a rendering face + FaceDetails fdet; + + // search for a neighbor that has a usable height (or use your own height, if valid) + if (faceDetails.find(map[i]) != faceDetails.end()) { + fdet = faceDetails[map[i]]; + } else if (c > 0 && faceDetails.find(map[i - 1]) != faceDetails.end()) { + fdet = faceDetails[map[i - 1]]; + } else if (c < numCols - 1 && faceDetails.find(map[i + 1]) != faceDetails.end()) { + fdet = faceDetails[map[i + 1]]; + } else { + std::cerr << "FATAL: couldn't find a height to use for rendering!" << std::endl; + } + + ModelDimension dim = fdet.heightContributor; + + if (dim == LENGTH) + curHeight = (heightConversionFactor * modelLength); + else if (dim == DEPTH) + curHeight = (heightConversionFactor * modelDepth); + else if (dim == HEIGHT) + curHeight = (heightConversionFactor * modelHeight); + } + + coordinates[i].push_back(curX); + coordinates[i].push_back(curY); + coordinates[i].push_back(curX + curWidth); + coordinates[i].push_back(curY + curHeight); + + curY += curHeight; + + for (std::pair dim : dimDetails) { + if (dim.first / rowLen == r && dim.second == 1) { + curY += DIM_ROW_SPACE; + break; + } + } + } + + curY = offsetY; + curX += curWidth; + + for (std::pair dim : dimDetails) { + if (dim.first % rowLen == c && dim.second == 0) { + curX += DIM_COLUMN_SPACE; + break; + } + } + } + } + + // iterate through all of the rows, shifting them over if necessary + for (int r = 0; r < numRows; ++r) { + // test that row can be spaced + bool works = true; + for (int c = 0; c < numCols; ++c) { + if (map[r * rowLen + c] == 'A') { + works = false; + } + } + + if (!works || numCols <= 1) + continue; + + double rowWidth = coordinates[r * rowLen + numCols - 1][2]; + double extraSpace = (secWidth - rowWidth) / (numCols - 1); + + // if columns are locked, then space out the rest of the rows as well to ensure alignment + if (!lockRows) { + for (int r2 = 0; r2 < numRows; ++r2) { + for (int c = 1; c < numCols; ++c) { + coordinates[r2 * rowLen + c][0] += extraSpace * c; + coordinates[r2 * rowLen + c][2] += extraSpace * c; + } + } + } else { + // otherwise, space out just this row + for (int c = 1; c < numCols; ++c) + { + coordinates[r * rowLen + c][0] += extraSpace * c; + coordinates[r * rowLen + c][2] += extraSpace * c; + } + } + } + + // iterate through all of the columns, shifting them over if necessary + for (int c = 0; c < numCols; ++c) { + // test that column can be spaced + bool works = true; + for (int r = 0; r < numRows; ++r) { + if (map[r * rowLen + c] == 'A') { + works = false; + } + } + + if (!works || numRows <= 1) + continue; + + double colHeight = coordinates[(numRows - 1) * rowLen + c][3]; + double extraSpace = (secHeight - colHeight) / (numRows - 1); + + // if rows are locked, then space out the rest of the columns as well to ensure alignment + if (lockRows) { + for (int c2 = 0; c2 < numCols; ++c2) { + // now, space out the column + for (int r = 1; r < numRows; ++r) { + coordinates[r * rowLen + c2][1] += extraSpace * r; + coordinates[r * rowLen + c2][3] += extraSpace * r; + } + } + } else { + // now, just space out this column + for (int r = 1; r < numRows; ++r) { + coordinates[r * rowLen + c][1] += extraSpace * r; + coordinates[r * rowLen + c][3] += extraSpace * r; + } + } + } + + // edge case: square models need extra alignment + if (this->map == "TbA\nFRA\nBLA\n") { + double minX = secWidth, maxX = 0; + // iterate through the second column to align everything + for (int r = 0; r < numRows; ++r) { + int i = r * rowLen + 1; + minX = std::min(minX, coordinates[i][0]); + maxX = std::max(maxX, coordinates[i][2]); + } + for (int r = 0; r < numRows; ++r) { + int i = r * rowLen + 1; + double offset = ((maxX - minX) - (coordinates[i][2] - coordinates[i][0])) / 2; + coordinates[i][0] += offset; + coordinates[i][2] += offset; + } + } + + // add coordinates of ambient occlusion view + coordinates[coordinates.size() - 1].push_back(0); + if (ambientC != 0) { + for (int r = ambientR; r < numRows; ++r) { + int i = r * rowLen + ambientC; + coordinates[coordinates.size() - 1][0] = std::max(coordinates[coordinates.size() - 1][0], coordinates[i][0]); + } + } + coordinates[coordinates.size() - 1].push_back(0); + if (ambientR != 0) { + for (int c = ambientC; c < numCols; ++c) { + int i = ambientR * rowLen + c; + coordinates[coordinates.size() - 1][1] = std::max(coordinates[coordinates.size() - 1][1], coordinates[i][1]); + } + } + + coordinates[coordinates.size() - 1].push_back(secWidth); + coordinates[coordinates.size() - 1].push_back(secHeight); +} + + +std::vector +LayoutChoice::getCoordinates(int mapIndex) +{ + std::vector output; + if (mapIndex == -1) { + // want the coordinates for the ambient occlusion + for (double coord : coordinates[map.size()]) + output.push_back((int)std::ceil(coord)); + } else { + // want coordinates of an index in map + for (double coord : coordinates[mapIndex]) + output.push_back((int)std::ceil(coord)); + } + return output; +} + + +double +LayoutChoice::getTotalCoverage(double ambientWidth, double ambientHeight) +{ + double sum = 0; + for (size_t i = 0; i < map.size(); ++i) { + switch (map[i]) { + case ' ': case '\n': case '-': case '|': case '.': // items with no area + break; + default: + if (coordinates[i].empty()) { + std::cerr << "ISSUE: coordinates for an important map section not initialized!" << std::endl; + break; + } + sum += (coordinates[i][2] - coordinates[i][0]) * (coordinates[i][3] - coordinates[i][1]); + } + } + + // add ambient occlusion after accounting for fitting + double maxAWidth = coordinates[map.size()][2] - coordinates[map.size()][0]; + double maxAHeight = coordinates[map.size()][3] - coordinates[map.size()][1]; + + double actRatio = ambientWidth / ambientHeight; + + if (maxAWidth / maxAHeight < actRatio) { + // height is too large; cap the height + maxAHeight = maxAWidth / actRatio; + } else { + // width is too large; cap the width + maxAWidth = maxAHeight * actRatio; + } + + sum += 0.6 * maxAWidth * maxAHeight; + + return sum; +} + + +int +LayoutChoice::getMapSize() +{ + return map.size(); +} + + +char +LayoutChoice::getMapChar(int index) +{ + return map[index]; +} + + +std::vector +initLayouts() +{ + // create layout encodings + std::vector layouts; + + // extremely long or tall models + layouts.emplace_back("T.\nF.\nb.\nB.\nRA\nLA\n", true); + layouts.emplace_back("LFRBTb\n....AA\n", false); + + // long models + layouts.emplace_back("TLR\nFAA\nbAA\nBAA\n", false); + layouts.emplace_back("TbFR\n..BL\n..AA\n", false); + layouts.emplace_back("TFR\nbBL\n.AA\n", false); + + // flat models + layouts.emplace_back("TFR\nbBL\n.AA\n", false); + layouts.emplace_back("TLB\nFRb\n.AA\n", false); + + // tall models + layouts.emplace_back("BLTb\nFRAA\n", false); + + // square models + layouts.emplace_back("TbA\nFRA\nBLA\n", true); + + return layouts; +} + + +LayoutChoice +selectLayoutFromHeuristic(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight, std::pair ambientDims) +{ + std::vector allLayouts = initLayouts(); + + double bestScore = -1; + LayoutChoice* bestLayout = NULL; + + // iterate through every layout, selecting the one that covers the most whitespace. + for (LayoutChoice& lc : allLayouts) { + lc.initCoordinates(secWidth, secHeight, modelLength, modelDepth, modelHeight); + + double score = lc.getTotalCoverage((double)ambientDims.first, (double)ambientDims.second); + + if (score > bestScore) { + bestScore = score; + bestLayout = &lc; + } + } + + if (bestLayout == NULL) { + std::cerr << "ISSUE: no layouts found. This is a major problem! In selectLayout() in RenderHandler.cpp" << std::endl; + return LayoutChoice("", true); + } + + return *bestLayout; +} + + +LayoutChoice +genLayout(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight, std::pair ambientDims) +{ + double lengthHeight = modelLength / modelHeight; + double lengthDepth = modelLength / modelDepth; + double heightDepth = modelHeight / modelDepth; + + // flat models + if (lengthHeight > 2 && heightDepth < 0.5) + return LayoutChoice("TFR\nbBL\n.AA\n", false); + if (lengthDepth > 2 && heightDepth > 2) + return LayoutChoice("TLB\nFRb\n.AA\n", false); + if (lengthDepth < 0.5 && lengthHeight < 0.5) + return LayoutChoice("TLB\nFRb\n.AA\n", false); + + // tall models + if (lengthHeight < 0.5 && heightDepth > 2) + return LayoutChoice("BLTb\nFRAA\n", false); + + // long models + if (lengthHeight > 2 && lengthDepth > 2) + return LayoutChoice("TLR\nFAA\nbAA\nBAA\n", false); + if (lengthDepth < 0.33 && heightDepth < 0.33) + return LayoutChoice("TbFR\n..BL\n..AA\n", false); + if (lengthDepth < 0.5 && heightDepth < 0.5) + return LayoutChoice("TFR\nbBL\n.AA\n", false); + + // cube models + if (lengthDepth < 1.5 && lengthDepth > 0.667 && heightDepth < 1.5 && heightDepth > 0.667 && lengthHeight < 1.5 && lengthHeight > 0.667) + return LayoutChoice("TbA\nFRA\nBLA\n", true); + + return selectLayoutFromHeuristic(secWidth, secHeight, modelLength, modelDepth, modelHeight, ambientDims); +} + + +void +makeRenderSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options& opt) +{ + // harvest model dimensions + double modelDepth = std::stod(info.getInfo("dimX")); + double modelLength = std::stod(info.getInfo("dimY")); + double modelHeight = std::stod(info.getInfo("dimZ")); + + std::map faceDetails = getFaceDetails(); + + // get ambient occlusion render + std::string aRender = renderPerspective(DETAILED, opt, info.largestComponents[0].name); + std::pair ambientDims = img.getCroppedImageDims(aRender); + + // select the layout + LayoutChoice bestLayout = genLayout(width, height, modelLength, modelDepth, modelHeight, ambientDims); + bestLayout.initCoordinates(width, height, modelLength, modelDepth, modelHeight); + + // SCALE: shrinking factor on images placed onto the IFPainter + double SCALE = 0.92; + + // render all layout elements + for (int i = 0; i < bestLayout.getMapSize(); ++i) { + char next = bestLayout.getMapChar(i); + std::vector coords = bestLayout.getCoordinates(i); + + switch (next) { + case ' ': case '\n': case '.': case 'A': // spacing character; nothing should be drawn here + break; + case '|': case '-': // draw separator line + img.drawLine(offsetX + coords[0], offsetY + coords[1], offsetX + coords[2], offsetY + coords[3], 3, cv::Scalar(100, 100, 100)); + break; + default: // draw face + std::string render = renderPerspective(faceDetails[next].face, opt, info.largestComponents[0].name); + + // find new coordinates using scaling factor + double oldW = coords[2] - coords[0]; + double oldH = coords[3] - coords[1]; + double newW = oldW * SCALE; + double newH = oldH * SCALE; + double newX = coords[0] + oldW / 2 - newW / 2; + double newY = coords[1] + oldH / 2 - newH / 2; + + img.drawImageFitted((int)(offsetX + newX), (int)(offsetY + newY), (int)std::ceil(newW), (int)std::ceil(newH), render); + break; + } + } + + // render dimensions + for (int i = 0; i < 3; ++i) { + std::pair det = bestLayout.dimDetails[i]; + + std::vector coords = bestLayout.getCoordinates(det.first); + + double oldW = coords[2] - coords[0]; + double oldH = coords[3] - coords[1]; + double newW = oldW * SCALE; + double newH = oldH * SCALE; + double newX = coords[0] + oldW / 2 - newW / 2 + offsetX; + double newY = coords[1] + oldH / 2 - newH / 2 + offsetY; + double offset = 30; + double textHeight = 40; + + std::stringstream me; + if (i == 0) me << std::setprecision(5) << modelLength; + if (i == 1) me << std::setprecision(5) << modelDepth; + if (i == 2) me << std::setprecision(5) << modelHeight; + + //Determine units + std::string unit; + if (opt.isDefaultLength()) { + unit = info.getInfo("units"); + } else { + unit = opt.getUnitLength(); + } + + me << " " << unit; + + if (det.second == 0) { + // draw to the right + img.drawLine(newX + newW + offset, newY, newX + newW + offset, newY + newH, 5, cv::Scalar(160, 0, 0)); + img.drawText(newX + newW + 3 * offset / 2, newY + newH / 2 - textHeight / 2, textHeight, 220, me.str(), TO_BLUE); + } else { + // draw below + img.drawLine(newX, newY + newH + offset, newX + newW, newY + newH + offset, 5, cv::Scalar(160, 0, 0)); + img.drawTextCentered(newX + newW / 2, newY + newH + 3 * offset / 2, textHeight, 220, me.str(), TO_BLUE); + } + } + + // render ambient occlusion view + std::string render = renderPerspective(DETAILED, opt, info.largestComponents[0].name); + std::vector coords = bestLayout.getCoordinates(-1); // fetch ambient occlusion coordinates + std::string title = info.getInfo("title"); + if (title.size() > 29) + title = title.substr(0, 27) + "..."; + img.drawDiagramFitted(offsetX + coords[0], offsetY + coords[1], coords[2] - coords[0], coords[3] - coords[1], aRender, title); +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/RenderHandler.h b/src/gtools/gist/RenderHandler.h new file mode 100644 index 00000000000..52bf61c4f4c --- /dev/null +++ b/src/gtools/gist/RenderHandler.h @@ -0,0 +1,147 @@ +/* R E N D E R H A N D L E R . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "pch.h" + + +/** + * The RenderHandler code autonomously modifies a section of the + * report page to include multiple visuals of the graphics file from a + * multitude of perspectives and rendering types (prominently ray + * tracers). + * + * The code will automatically layout the section based on the + * dimensions of the graphics file and will use the + * PerspectiveGatherer code to generate the renderings. Then, this + * code will populate its designated section on the report page with + * this information. + * + */ + +class IFPainter; +class InformationGatherer; +class Options; + +/** + * The LayoutChoice class stores a layout encoding along with + * providing the functionality to determine how to place elements on a + * page if that layout were to be selected. The class encodes a + * layout using two variables: map and "lockRows". + * + * The map is encoded as a string, storing the 2D grid which makes up + * how the images will be placed. Depending on the value of + * "lockRows", either a row-major (true) or column-major (false) + * ordering will be followed when placing the images. + * + * Each orthogonal face is encoded as a character. Each row is + * terminated by a '\n'. The mapping is as follows: F: front, T: top, + * R: right, L: left, B: back, b: bottom, A: ambient occlusion Empty + * space is encoded as a '.', where nothing should be placed. + * + * When lockRows is true, all images on the same row MUST have the + * same height. + * + * When lockRows is false, all images on the same column MUST have the + * same width. + * + * Here's an example of how LayoutChoice("TbFR\n..BL\n..AA\n", false) + * will be represented: + * + * --------------- + * | T | b | F | R | + * |---|---|---|---| + * | | | B | L | + * |---|---|-------| + * | | | Amb | + * --------------- + * + * The diagram above shows the grid layout for the preceeding + * "LayoutChoice" specification. Since "lockRows" is false, a + * column-major ordering is used. The top, bottom, front, and right + * views will be placed first at the top of the page. Then, the back + * view will be placed immediately below the front view, with the same + * width as the front view. A similar process is followed for the + * left view (placed below the right view). Finally, the ambient view + * is placed just below the back and left views. is therefore useful + * for models where the top/bottom images are tall whilst the other + * views aren't. + * + * The ambient view will not protrude any space that is not marked as + * "A". + * + * The initCoordinates() "initializes" the layout, properly setting + * the coordinates of each image depending on the model bounding box, + * maintaining both proportionality and maximum space usage. + * + * The getTotalCoverage() returns a determined value proportional to + * the amount of whitespace used. Generally, the higher this value, + * the better match this layout is for a model. + */ +struct LayoutChoice +{ +private: + std::string map; + bool lockRows; + + std::vector> coordinates; +public: + std::vector> dimDetails; + + LayoutChoice(std::string map, bool lockRows); + + void initCoordinates(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight); + + std::vector getCoordinates(int mapIndex); + + int getMapSize(); + char getMapChar(int index); + + double getTotalCoverage(double ambientWidth, double ambientHeight); +}; + + +// calls selectLayout to find the most effective layout, then paints +// it onto the designated area. +void makeRenderSection(IFPainter& img, InformationGatherer& info, int offsetX, int offsetY, int width, int height, Options& opt); + +// generate a list of layouts +std::vector initLayouts(); + +// uses a simple heuristic to determine which layout is the best for +// the object. +LayoutChoice selectLayoutFromHeuristic(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight, std::pair ambientDims); + +// the currently used method which manually picks layouts based on +// model dimension ratios. if a fit isn't found (i.e. awkward +// dimensions), then the heuristic is called to find the best model. +LayoutChoice genLayout(int secWidth, int secHeight, double modelLength, double modelDepth, double modelHeight, std::pair ambientDims); + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/TODO b/src/gtools/gist/TODO new file mode 100644 index 00000000000..1bbf82e1df9 --- /dev/null +++ b/src/gtools/gist/TODO @@ -0,0 +1,61 @@ +Soon +---- + +* Instead of total projected surface area, projected surface area for + front/back, left/right, and top/bottom would be more meaningful. + +* Compute mass data (lots of requests, need density data) + +* Showing axes vs showing "z up". Or give user options + +* Include hashing method on Checksum (SHA1): 120EAB... + +* Classification markings (overall with normal declass + instructions). _GLOBAL attribute. Use RED box if classified + +* Possibly include model filesize + +* Bounding box information in gray area + + +Future +------ + +* Would be great if material data can be displayed in another + page. List out the different materials used in the models, perhaps + even broken down by percentage of total + +* There will often be more than one top level assembly in each file + and specifying which assembly may need to be an option. + +* Geometry Type should breakdown the numbers of primitives (types of + solids) - CSG, BOT, NURBS, NMG, DSP with CSG being all + + +* Option to display location of Ground_Plane_Offset attribute if not + at the bottom of the target. For example, a small boat in the + water. + +* physically based rendering + +* colors and shaders set automatically based on naming patterns + +* a second page that goes into more detail – e.g., exploded hierarchy + diagram. (Would be great if a bigger hierarchy can be displayed in + another page. More subassemblies (hierarchy)) + +* ability to add my agency/organization’s logo in the bottom + right-hand corner + +* show model origin? + +* both metric and imperial units + +NOTE: + +When running this command: + +rtwizard -s 1024 -a 35 -e 25 -i sample_models/shipping_container.g -c container_air.r -g shipping_container -G 10 -o "output/test.png" + +The command does not throw an error although container_air.r is void +air. Instead, it just generates a black image diff --git a/src/gtools/gist/main.cpp b/src/gtools/gist/main.cpp new file mode 100644 index 00000000000..d020002ab6a --- /dev/null +++ b/src/gtools/gist/main.cpp @@ -0,0 +1,266 @@ +/* M A I N . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "pch.h" + + +/** + * Takes in a list of parameters and updates program variables accordingly + * + * @argc the number of parameters + * @argv the list of parameters + * @opt options to be used in report generation + * @h flag for help + * @f flag for filepath specification + * + * @returns if the given parameters are valid. + */ +static bool +readParameters(int argc, char** argv, Options &opt) +{ + /* + * A list of parameters is as follows: + * p = filepath + * w = width of output and window + * l = length of output and window + * F = path specified is a folder of models + * g = GUI output + * f = filename of png export + * E = folder name of png export + */ + + bool h = false; // user requested help + bool hasFile = 0; // user specified filepath + bool hasFolder = false; // user specified filepath + + int opts; + + + while ((opts = bu_getopt(argc, argv, "g?Oop:F:P:f:n:T:E:N:l:m:c:t:Z")) != -1) { + + switch (opts) { + case 'p': + hasFile = true; + opt.setFilepath(bu_optarg); + break; + case 'P': + opt.setPPI(atoi(bu_optarg)); + break; + case 'F': + hasFolder = true; + opt.setIsFolder(); + opt.setFolder(bu_optarg); + break; + case 'E': + opt.setExportFolder(bu_optarg); + break; + case 'g': + opt.setOpenGUI(); + break; + case 'f': + opt.setExportToFile(); + opt.setFileName(bu_optarg); + break; + case 'n': + opt.setName(bu_optarg); + break; + case 'T': + opt.setTemppath(bu_optarg); + break; + case 'c': + opt.setClassification(bu_optarg); + break; + case 'o': + opt.setOrientationRightLeft(true); + break; + case 'O': + opt.setOrientationZYUp(true); + break; + case 'N': + opt.setNotes(bu_optarg); + break; + case 'Z': + opt.setOverrideImages(); + break; + case 't': + opt.setTopComp(bu_optarg); + std::cout << "Top component: " << opt.getTopComp() << std::endl; + break; + case 'l': + opt.setUnitLength(bu_optarg); + break; + case 'm': + opt.setUnitMass(bu_optarg); + break; + case '?': + h = true; + break; + default: + std::cerr << "Unknown option\n"; + break; + } + } + + if (h) { + bu_log("\nUsage: %s [options] -p path/to/model.g\n", argv[0]); + bu_log("\nOptions:\n"); + bu_log(" p = filepath\n"); + bu_log(" P = pixels per inch, default is 300ppi\n"); + bu_log(" F = path specified is a folder of models\n"); + bu_log(" E = path to folder to export reports. Used for processing folder of models\n"); + bu_log(" g = GUI output\n"); + bu_log(" f = filepath of png export, MUST end in .png\n"); + bu_log(" n = name of preparer, to be used in report\n"); + bu_log(" T = directory where rt and rtwizard executables are stored\n"); + bu_log(" c = classification of a file, to be displayed in uppercase on top and bottom of report. If the classification is \"confidential\", the header and footer will be red.\n"); + bu_log(" o = orientation of the file, default is right hand, flag will change orientation output to left hand"); + bu_log(" O = orientation of the file, default is +Z-up, flag will change orientation output to +Y-up"); + bu_log(" N = notes that a user would like to add to be specified in the report"); + bu_log(" Z = option to re-use pre-made renders in the output folder. Should only be used when running on the same model multiple times."); + bu_log(" t = option to specify the top component of the report. Useful when there are multiple tops"); + bu_log(" l = override the default length units in a file."); + bu_log(" m = override the default mass units in a file."); + return false; + } + //If user has no arguments or did not specify filepath, give shortened help + else if (argc < 2 || (hasFolder == hasFile)) { + bu_log("\nUsage: %s [options] -p path/to/model.g\n", argv[0]); + bu_log("\nPlease specify the path to the file for report generation, use flag \"-?\" to see all options\n"); + return false; + } else if (!bu_file_exists(opt.getFilepath().c_str(), NULL)) { + bu_log("ERROR: %s doesn't exist\n", opt.getFilepath().c_str()); + bu_exit(BRLCAD_ERROR, "No input, aborting.\n"); + } else if (bu_file_exists(opt.getFileName().c_str(), NULL)) { + std::cout << "File already exists: " << opt.getFileName() << std::endl; + std::cout << "Overwrite? (y/n): "; + char token; std::cin >> token; + if (token != 'y' && token != 'Y') + return false; + } + + return true; +} + + +/** + * Calls the necessary functions to generate the reports. + * + * @opt options to be used in report generation + */ +static void +generateReport(Options opt) +{ + // create image frame + IFPainter img(opt.getLength(), opt.getWidth()); + + // create information gatherer + InformationGatherer info(&opt); + + // read in all information from model file + if (!info.gatherInformation(opt.getName())) { + std::cerr << "Error on Information Gathering. Report Generation skipped..." << std::endl; + return; + } + + // Define commonly used ratio variables + int margin = opt.getWidth() / 150; + int header_footer_height = opt.getLength() / 25; + int padding = opt.getLength() / 250; + int vvHeight = (opt.getLength() - 2*header_footer_height - 2*margin) / 3; + + + // Has same height and width as V&V Checks, offset X by V&V checks width + // makeHeirarchySection(img, info, XY_margin + vvSectionWidth + (opt.getLength() / 250), vvOffsetY, vvSectionWidth, vvSectionHeight, opt); + + // define the position of all sections in the report + Position imagePosition(0, 0, opt.getWidth(), opt.getLength()); + Position topSection(margin, margin, imagePosition.width() - 2*margin, header_footer_height); + Position bottomSection(margin, imagePosition.bottom() - header_footer_height - margin, imagePosition.width() - 2*margin, header_footer_height); + Position hierarchySection(imagePosition.right() - imagePosition.thirdWidth() - margin, imagePosition.height() - margin - header_footer_height - padding - vvHeight, imagePosition.thirdWidth(), vvHeight); + Position fileSection(imagePosition.right() - imagePosition.sixthWidth() - margin, topSection.bottom() + padding, imagePosition.sixthWidth(), hierarchySection.top() - topSection.bottom() - padding); + Position renderSection(margin, topSection.bottom() + padding, fileSection.left() - margin - padding, bottomSection.top() - topSection.bottom() - 2*padding); + + // draw all sections + makeTopSection(img, info, topSection.x(), topSection.y(), topSection.width(), topSection.height()); + makeBottomSection(img, info, bottomSection.x(), bottomSection.y(), bottomSection.width(), bottomSection.height()); + makeFileInfoSection(img, info, fileSection.x(), fileSection.y(), fileSection.width(), fileSection.height(), opt); + makeRenderSection(img, info, renderSection.x(), renderSection.y(), renderSection.width(), renderSection.height(), opt); + makeHeirarchySection(img, info, hierarchySection.x(), hierarchySection.y(), hierarchySection.width(), hierarchySection.height(), opt); + + // paint renderings + + // optionally, display the scene + if (opt.getOpenGUI()) { + img.openInGUI(); + } + + // optionally, export the image + if (opt.getExportToFile()) { + img.exportToFile(opt.getFileName()); + } +} + + +/** + * Checks if we are processing a folder of models + */ +static void +handleFolder(Options& options) +{ + int cnt = 1; + + for (const auto & entry : std::filesystem::directory_iterator(options.getFolder())) { + options.setFilepath(entry.path().string()); + options.setExportToFile(); + std::string filename = options.getFilepath(); + filename = filename.substr(filename.find_last_of("/\\") + 1); + filename = filename.substr(0, filename.find_last_of(".")); + std::cout << "Processing: " << filename << std::endl; + std::string exportPath = options.getExportFolder() + "/" + filename + "_report.png"; + options.setFileName(exportPath); + generateReport(options); + std::cout << "Finished Processing: " << cnt++ << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + Options options; + + if (readParameters(argc, argv, options)) { + if (options.getIsFolder()) { + handleFolder(options); + } else { + generateReport(options); + } + } +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/gtools/gist/pch.h b/src/gtools/gist/pch.h new file mode 100644 index 00000000000..6e708766b46 --- /dev/null +++ b/src/gtools/gist/pch.h @@ -0,0 +1,69 @@ +/* P C H . H + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#pragma once + +#include "common.h" + +// OpenCV header files +#include +#include +#include "opencv2/highgui/highgui.hpp" + +// Necessary C++ header files +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "picohash.h" + +// BRL-CAD header files +#include "bu/getopt.h" +#include "bu/log.h" +#include "bu/units.h" +#include "ged.h" + +// Visualization project header files +#include "Options.h" +#include "IFPainter.h" +#include "InformationGatherer.h" +#include "PerspectiveGatherer.h" +#include "RenderHandler.h" +#include "FactsHandler.h" +#include "Position.h" + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/gtools/gist/picohash.h b/src/gtools/gist/picohash.h new file mode 100644 index 00000000000..abd79c83ed0 --- /dev/null +++ b/src/gtools/gist/picohash.h @@ -0,0 +1,754 @@ +/* + * The code is placed under public domain by Kazuho Oku . + * + * The MD5 implementation is based on a public domain implementation written by + * Solar Designer in 2001, which is used by Dovecot. + * + * The SHA1 implementation is based on a public domain implementation written + * by Wei Dai and other contributors for libcrypt, used also in liboauth. + * + * The SHA224/SHA256 implementation is based on a public domain implementation + * by Sam Hocevar for LibTomCrypt. + */ +#ifndef _picohash_h_ +#define _picohash_h_ + +#include +#include +#include + +#ifdef __BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#elif defined __LITTLE_ENDIAN__ +/* override */ +#elif defined __BYTE_ORDER +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#endif +#elif !defined(_WIN32) +#include // machine/endian.h +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define _PICOHASH_BIG_ENDIAN +#endif +#endif + +#define PICOHASH_MD5_BLOCK_LENGTH 64 +#define PICOHASH_MD5_DIGEST_LENGTH 16 + +typedef struct _picohash_md5_ctx_t { + uint_fast32_t lo, hi; + uint_fast32_t a, b, c, d; + unsigned char buffer[64]; + uint_fast32_t block[PICOHASH_MD5_DIGEST_LENGTH]; + const void *(*_body)(struct _picohash_md5_ctx_t *ctx, const void *data, size_t size); +} _picohash_md5_ctx_t; + +static void _picohash_md5_init(_picohash_md5_ctx_t *ctx); +static void _picohash_md5_update(_picohash_md5_ctx_t *ctx, const void *data, size_t size); +static void _picohash_md5_final(_picohash_md5_ctx_t *ctx, void *digest); + +#define PICOHASH_SHA1_BLOCK_LENGTH 64 +#define PICOHASH_SHA1_DIGEST_LENGTH 20 + +typedef struct { + uint32_t buffer[PICOHASH_SHA1_BLOCK_LENGTH / 4]; + uint32_t state[PICOHASH_SHA1_DIGEST_LENGTH / 4]; + uint64_t byteCount; + uint8_t bufferOffset; +} _picohash_sha1_ctx_t; + +static void _picohash_sha1_init(_picohash_sha1_ctx_t *ctx); +static void _picohash_sha1_update(_picohash_sha1_ctx_t *ctx, const void *input, size_t len); +static void _picohash_sha1_final(_picohash_sha1_ctx_t *ctx, void *digest); + +#define PICOHASH_SHA256_BLOCK_LENGTH 64 +#define PICOHASH_SHA256_DIGEST_LENGTH 32 +#define PICOHASH_SHA224_BLOCK_LENGTH PICOHASH_SHA256_BLOCK_LENGTH +#define PICOHASH_SHA224_DIGEST_LENGTH 28 + +typedef struct { + uint64_t length; + uint32_t state[PICOHASH_SHA256_DIGEST_LENGTH / 4]; + uint32_t curlen; + unsigned char buf[PICOHASH_SHA256_BLOCK_LENGTH]; +} _picohash_sha256_ctx_t; + +static void _picohash_sha256_init(_picohash_sha256_ctx_t *ctx); +static void _picohash_sha256_update(_picohash_sha256_ctx_t *ctx, const void *data, size_t len); +static void _picohash_sha256_final(_picohash_sha256_ctx_t *ctx, void *digest); +static void _picohash_sha224_init(_picohash_sha256_ctx_t *ctx); +static void _picohash_sha224_final(_picohash_sha256_ctx_t *ctx, void *digest); + +#define PICOHASH_MAX_BLOCK_LENGTH 64 +#define PICOHASH_MAX_DIGEST_LENGTH 32 + +typedef struct { + union { + _picohash_md5_ctx_t _md5; + _picohash_sha1_ctx_t _sha1; + _picohash_sha256_ctx_t _sha256; + }; + size_t block_length; + size_t digest_length; + void (*_reset)(void *ctx); + void (*_update)(void *ctx, const void *input, size_t len); + void (*_final)(void *ctx, void *digest); + struct { + unsigned char key[PICOHASH_MAX_BLOCK_LENGTH]; + void (*hash_reset)(void *ctx); + void (*hash_final)(void *ctx, void *digest); + } _hmac; +} picohash_ctx_t; + +static void picohash_init_md5(picohash_ctx_t *ctx); +static void picohash_init_sha1(picohash_ctx_t *ctx); +static void picohash_init_sha224(picohash_ctx_t *ctx); +static void picohash_init_sha256(picohash_ctx_t *ctx); +static void picohash_update(picohash_ctx_t *ctx, const void *input, size_t len); +static void picohash_final(picohash_ctx_t *ctx, void *digest); +static void picohash_reset(picohash_ctx_t *ctx); + +static void picohash_init_hmac(picohash_ctx_t *ctx, void (*initf)(picohash_ctx_t *), const void *key, size_t key_len); + +/* following are private definitions */ + +/* + * The basic MD5 functions. + * + * F is optimized compared to its RFC 1321 definition just like in Colin + * Plumb's implementation. + */ +#define _PICOHASH_MD5_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define _PICOHASH_MD5_G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define _PICOHASH_MD5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _PICOHASH_MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define _PICOHASH_MD5_STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures which tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define _PICOHASH_MD5_SET(n) (*(const uint32_t *)&ptr[(n)*4]) +#define _PICOHASH_MD5_GET(n) _PICOHASH_MD5_SET(n) +#else +#define _PICOHASH_MD5_SET(n) \ + (ctx->block[(n)] = (uint_fast32_t)ptr[(n)*4] | ((uint_fast32_t)ptr[(n)*4 + 1] << 8) | ((uint_fast32_t)ptr[(n)*4 + 2] << 16) | \ + ((uint_fast32_t)ptr[(n)*4 + 3] << 24)) +#define _PICOHASH_MD5_GET(n) (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There're no alignment requirements. + */ +static const void *_picohash_md5_body(_picohash_md5_ctx_t *ctx, const void *data, size_t size) +{ + const unsigned char *ptr; + uint_fast32_t a, b, c, d; + uint_fast32_t saved_a, saved_b, saved_c, saved_d; + + ptr = reinterpret_cast(data); + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + /* Round 1 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(0), 0xd76aa478, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(1), 0xe8c7b756, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(2), 0x242070db, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(3), 0xc1bdceee, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(4), 0xf57c0faf, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(5), 0x4787c62a, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(6), 0xa8304613, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(7), 0xfd469501, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(8), 0x698098d8, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(9), 0x8b44f7af, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(10), 0xffff5bb1, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(11), 0x895cd7be, 22) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, a, b, c, d, _PICOHASH_MD5_SET(12), 0x6b901122, 7) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, d, a, b, c, _PICOHASH_MD5_SET(13), 0xfd987193, 12) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, c, d, a, b, _PICOHASH_MD5_SET(14), 0xa679438e, 17) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_F, b, c, d, a, _PICOHASH_MD5_SET(15), 0x49b40821, 22) + + /* Round 2 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(1), 0xf61e2562, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(6), 0xc040b340, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(11), 0x265e5a51, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(0), 0xe9b6c7aa, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(5), 0xd62f105d, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(10), 0x02441453, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(15), 0xd8a1e681, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(4), 0xe7d3fbc8, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(9), 0x21e1cde6, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(14), 0xc33707d6, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(3), 0xf4d50d87, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(8), 0x455a14ed, 20) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, a, b, c, d, _PICOHASH_MD5_GET(13), 0xa9e3e905, 5) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, d, a, b, c, _PICOHASH_MD5_GET(2), 0xfcefa3f8, 9) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, c, d, a, b, _PICOHASH_MD5_GET(7), 0x676f02d9, 14) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_G, b, c, d, a, _PICOHASH_MD5_GET(12), 0x8d2a4c8a, 20) + + /* Round 3 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(5), 0xfffa3942, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(8), 0x8771f681, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(11), 0x6d9d6122, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(14), 0xfde5380c, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(1), 0xa4beea44, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(4), 0x4bdecfa9, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(7), 0xf6bb4b60, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(10), 0xbebfbc70, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(13), 0x289b7ec6, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(0), 0xeaa127fa, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(3), 0xd4ef3085, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(6), 0x04881d05, 23) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, a, b, c, d, _PICOHASH_MD5_GET(9), 0xd9d4d039, 4) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, d, a, b, c, _PICOHASH_MD5_GET(12), 0xe6db99e5, 11) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, c, d, a, b, _PICOHASH_MD5_GET(15), 0x1fa27cf8, 16) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_H, b, c, d, a, _PICOHASH_MD5_GET(2), 0xc4ac5665, 23) + + /* Round 4 */ + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(0), 0xf4292244, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(7), 0x432aff97, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(14), 0xab9423a7, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(5), 0xfc93a039, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(12), 0x655b59c3, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(3), 0x8f0ccc92, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(10), 0xffeff47d, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(1), 0x85845dd1, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(8), 0x6fa87e4f, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(15), 0xfe2ce6e0, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(6), 0xa3014314, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(13), 0x4e0811a1, 21) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, a, b, c, d, _PICOHASH_MD5_GET(4), 0xf7537e82, 6) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, d, a, b, c, _PICOHASH_MD5_GET(11), 0xbd3af235, 10) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, c, d, a, b, _PICOHASH_MD5_GET(2), 0x2ad7d2bb, 15) + _PICOHASH_MD5_STEP(_PICOHASH_MD5_I, b, c, d, a, _PICOHASH_MD5_GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +inline void _picohash_md5_init(_picohash_md5_ctx_t *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; + + ctx->_body = _picohash_md5_body; +} + +inline void _picohash_md5_update(_picohash_md5_ctx_t *ctx, const void *data, size_t size) +{ + uint_fast32_t saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (const unsigned char *)data + free; + size -= free; + ctx->_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = ctx->_body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +inline void _picohash_md5_final(_picohash_md5_ctx_t *ctx, void *_digest) +{ + unsigned char *digest = reinterpret_cast(_digest); + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + ctx->_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + ctx->_body(ctx, ctx->buffer, 64); + + digest[0] = ctx->a; + digest[1] = ctx->a >> 8; + digest[2] = ctx->a >> 16; + digest[3] = ctx->a >> 24; + digest[4] = ctx->b; + digest[5] = ctx->b >> 8; + digest[6] = ctx->b >> 16; + digest[7] = ctx->b >> 24; + digest[8] = ctx->c; + digest[9] = ctx->c >> 8; + digest[10] = ctx->c >> 16; + digest[11] = ctx->c >> 24; + digest[12] = ctx->d; + digest[13] = ctx->d >> 8; + digest[14] = ctx->d >> 16; + digest[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(*ctx)); +} + +#define _PICOHASH_SHA1_K0 0x5a827999 +#define _PICOHASH_SHA1_K20 0x6ed9eba1 +#define _PICOHASH_SHA1_K40 0x8f1bbcdc +#define _PICOHASH_SHA1_K60 0xca62c1d6 + +static inline uint32_t _picohash_sha1_rol32(uint32_t number, uint8_t bits) +{ + return ((number << bits) | (number >> (32 - bits))); +} + +static inline void _picohash_sha1_hash_block(_picohash_sha1_ctx_t *s) +{ + uint8_t i; + uint32_t a, b, c, d, e, t; + + a = s->state[0]; + b = s->state[1]; + c = s->state[2]; + d = s->state[3]; + e = s->state[4]; + for (i = 0; i < 80; i++) { + if (i >= 16) { + t = s->buffer[(i + 13) & 15] ^ s->buffer[(i + 8) & 15] ^ s->buffer[(i + 2) & 15] ^ s->buffer[i & 15]; + s->buffer[i & 15] = _picohash_sha1_rol32(t, 1); + } + if (i < 20) { + t = (d ^ (b & (c ^ d))) + _PICOHASH_SHA1_K0; + } else if (i < 40) { + t = (b ^ c ^ d) + _PICOHASH_SHA1_K20; + } else if (i < 60) { + t = ((b & c) | (d & (b | c))) + _PICOHASH_SHA1_K40; + } else { + t = (b ^ c ^ d) + _PICOHASH_SHA1_K60; + } + t += _picohash_sha1_rol32(a, 5) + e + s->buffer[i & 15]; + e = d; + d = c; + c = _picohash_sha1_rol32(b, 30); + b = a; + a = t; + } + s->state[0] += a; + s->state[1] += b; + s->state[2] += c; + s->state[3] += d; + s->state[4] += e; +} + +static inline void _picohash_sha1_add_uncounted(_picohash_sha1_ctx_t *s, uint8_t data) +{ + uint8_t *const b = (uint8_t *)s->buffer; +#ifdef _PICOHASH_BIG_ENDIAN + b[s->bufferOffset] = data; +#else + b[s->bufferOffset ^ 3] = data; +#endif + s->bufferOffset++; + if (s->bufferOffset == PICOHASH_SHA1_BLOCK_LENGTH) { + _picohash_sha1_hash_block(s); + s->bufferOffset = 0; + } +} + +inline void _picohash_sha1_init(_picohash_sha1_ctx_t *s) +{ + s->state[0] = 0x67452301; + s->state[1] = 0xefcdab89; + s->state[2] = 0x98badcfe; + s->state[3] = 0x10325476; + s->state[4] = 0xc3d2e1f0; + s->byteCount = 0; + s->bufferOffset = 0; +} + +inline void _picohash_sha1_update(_picohash_sha1_ctx_t *s, const void *_data, size_t len) +{ + const uint8_t *data = (uint8_t*) _data; + for (; len != 0; --len) { + ++s->byteCount; + _picohash_sha1_add_uncounted(s, *data++); + } +} + +inline void _picohash_sha1_final(_picohash_sha1_ctx_t *s, void *digest) +{ + // Pad with 0x80 followed by 0x00 until the end of the block + _picohash_sha1_add_uncounted(s, 0x80); + while (s->bufferOffset != 56) + _picohash_sha1_add_uncounted(s, 0x00); + + // Append length in the last 8 bytes + _picohash_sha1_add_uncounted(s, s->byteCount >> 53); // Shifting to multiply by 8 + _picohash_sha1_add_uncounted(s, s->byteCount >> 45); // as SHA-1 supports bitstreams as well as + _picohash_sha1_add_uncounted(s, s->byteCount >> 37); // byte. + _picohash_sha1_add_uncounted(s, s->byteCount >> 29); + _picohash_sha1_add_uncounted(s, s->byteCount >> 21); + _picohash_sha1_add_uncounted(s, s->byteCount >> 13); + _picohash_sha1_add_uncounted(s, s->byteCount >> 5); + _picohash_sha1_add_uncounted(s, s->byteCount << 3); + +#ifndef SHA_BIG_ENDIAN + { // Swap byte order back + int i; + for (i = 0; i < 5; i++) { + s->state[i] = (((s->state[i]) << 24) & 0xff000000) | (((s->state[i]) << 8) & 0x00ff0000) | + (((s->state[i]) >> 8) & 0x0000ff00) | (((s->state[i]) >> 24) & 0x000000ff); + } + } +#endif + + memcpy(digest, s->state, sizeof(s->state)); +} + +#define _picohash_sha256_ch(x, y, z) (z ^ (x & (y ^ z))) +#define _picohash_sha256_maj(x, y, z) (((x | y) & z) | (x & y)) +#define _picohash_sha256_s(x, y) \ + (((((uint32_t)(x)&0xFFFFFFFFUL) >> (uint32_t)((y)&31)) | ((uint32_t)(x) << (uint32_t)(32 - ((y)&31)))) & 0xFFFFFFFFUL) +#define _picohash_sha256_r(x, n) (((x)&0xFFFFFFFFUL) >> (n)) +#define _picohash_sha256_sigma0(x) (_picohash_sha256_s(x, 2) ^ _picohash_sha256_s(x, 13) ^ _picohash_sha256_s(x, 22)) +#define _picohash_sha256_sigma1(x) (_picohash_sha256_s(x, 6) ^ _picohash_sha256_s(x, 11) ^ _picohash_sha256_s(x, 25)) +#define _picohash_sha256_gamma0(x) (_picohash_sha256_s(x, 7) ^ _picohash_sha256_s(x, 18) ^ _picohash_sha256_r(x, 3)) +#define _picohash_sha256_gamma1(x) (_picohash_sha256_s(x, 17) ^ _picohash_sha256_s(x, 19) ^ _picohash_sha256_r(x, 10)) +#define _picohash_sha256_rnd(a, b, c, d, e, f, g, h, i) \ + t0 = h + _picohash_sha256_sigma1(e) + _picohash_sha256_ch(e, f, g) + K[i] + W[i]; \ + t1 = _picohash_sha256_sigma0(a) + _picohash_sha256_maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +static inline void _picohash_sha256_compress(_picohash_sha256_ctx_t *ctx, unsigned char *buf) +{ + static const uint32_t K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; + uint32_t S[8], W[64], t, t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) + S[i] = ctx->state[i]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = + (uint32_t)buf[4 * i] << 24 | (uint32_t)buf[4 * i + 1] << 16 | (uint32_t)buf[4 * i + 2] << 8 | (uint32_t)buf[4 * i + 3]; + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) + W[i] = _picohash_sha256_gamma1(W[i - 2]) + W[i - 7] + _picohash_sha256_gamma0(W[i - 15]) + W[i - 16]; + + /* Compress */ + for (i = 0; i < 64; ++i) { + _picohash_sha256_rnd(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3]; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) + ctx->state[i] = ctx->state[i] + S[i]; +} + +static inline void _picohash_sha256_do_final(_picohash_sha256_ctx_t *ctx, void *digest, size_t len) +{ + unsigned char *out = reinterpret_cast(digest); + size_t i; + + /* increase the length of the message */ + ctx->length += ctx->curlen * 8; + + /* append the '1' bit */ + ctx->buf[ctx->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (ctx->curlen > 56) { + while (ctx->curlen < 64) { + ctx->buf[ctx->curlen++] = (unsigned char)0; + } + _picohash_sha256_compress(ctx, ctx->buf); + ctx->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (ctx->curlen < 56) { + ctx->buf[ctx->curlen++] = (unsigned char)0; + } + + /* store length */ + for (i = 0; i != 8; ++i) + ctx->buf[56 + i] = ctx->length >> (56 - 8 * i); + _picohash_sha256_compress(ctx, ctx->buf); + + /* copy output */ + for (i = 0; i != len / 4; ++i) { + out[i * 4] = ctx->state[i] >> 24; + out[i * 4 + 1] = ctx->state[i] >> 16; + out[i * 4 + 2] = ctx->state[i] >> 8; + out[i * 4 + 3] = ctx->state[i]; + } +} + +inline void _picohash_sha256_init(_picohash_sha256_ctx_t *ctx) +{ + ctx->curlen = 0; + ctx->length = 0; + ctx->state[0] = 0x6A09E667UL; + ctx->state[1] = 0xBB67AE85UL; + ctx->state[2] = 0x3C6EF372UL; + ctx->state[3] = 0xA54FF53AUL; + ctx->state[4] = 0x510E527FUL; + ctx->state[5] = 0x9B05688CUL; + ctx->state[6] = 0x1F83D9ABUL; + ctx->state[7] = 0x5BE0CD19UL; +} + +inline void _picohash_sha256_update(_picohash_sha256_ctx_t *ctx, const void *data, size_t len) +{ + const unsigned char *in = reinterpret_cast(data); + size_t n; + + while (len > 0) { + if (ctx->curlen == 0 && len >= PICOHASH_SHA256_BLOCK_LENGTH) { + _picohash_sha256_compress(ctx, (unsigned char *)in); + ctx->length += PICOHASH_SHA256_BLOCK_LENGTH * 8; + in += PICOHASH_SHA256_BLOCK_LENGTH; + len -= PICOHASH_SHA256_BLOCK_LENGTH; + } else { + n = PICOHASH_SHA256_BLOCK_LENGTH - ctx->curlen; + if (n > len) + n = len; + memcpy(ctx->buf + ctx->curlen, in, (size_t)n); + ctx->curlen += n; + in += n; + len -= n; + if (ctx->curlen == 64) { + _picohash_sha256_compress(ctx, ctx->buf); + ctx->length += 8 * PICOHASH_SHA256_BLOCK_LENGTH; + ctx->curlen = 0; + } + } + } +} + +inline void _picohash_sha256_final(_picohash_sha256_ctx_t *ctx, void *digest) +{ + _picohash_sha256_do_final(ctx, digest, PICOHASH_SHA256_DIGEST_LENGTH); +} + +inline void _picohash_sha224_init(_picohash_sha256_ctx_t *ctx) +{ + ctx->curlen = 0; + ctx->length = 0; + ctx->state[0] = 0xc1059ed8UL; + ctx->state[1] = 0x367cd507UL; + ctx->state[2] = 0x3070dd17UL; + ctx->state[3] = 0xf70e5939UL; + ctx->state[4] = 0xffc00b31UL; + ctx->state[5] = 0x68581511UL; + ctx->state[6] = 0x64f98fa7UL; + ctx->state[7] = 0xbefa4fa4UL; +} + +inline void _picohash_sha224_final(_picohash_sha256_ctx_t *ctx, void *digest) +{ + _picohash_sha256_do_final(ctx, digest, PICOHASH_SHA224_DIGEST_LENGTH); +} + +inline void picohash_init_md5(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_MD5_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_MD5_DIGEST_LENGTH; + ctx->_reset = reinterpret_cast(_picohash_md5_init); + ctx->_update = reinterpret_cast(_picohash_md5_update); + ctx->_final = reinterpret_cast(_picohash_md5_final); + + _picohash_md5_init(&ctx->_md5); +} + +inline void picohash_init_sha1(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA1_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA1_DIGEST_LENGTH; + ctx->_reset = reinterpret_cast(_picohash_sha1_init); + ctx->_update = reinterpret_cast(_picohash_sha1_update); + ctx->_final = reinterpret_cast(_picohash_sha1_final); + _picohash_sha1_init(&ctx->_sha1); +} + +inline void picohash_init_sha224(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA224_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA224_DIGEST_LENGTH; + ctx->_reset = reinterpret_cast(_picohash_sha224_init); + ctx->_update = reinterpret_cast(_picohash_sha256_update); + ctx->_final = reinterpret_cast(_picohash_sha224_final); + _picohash_sha224_init(&ctx->_sha256); +} + +inline void picohash_init_sha256(picohash_ctx_t *ctx) +{ + ctx->block_length = PICOHASH_SHA256_BLOCK_LENGTH; + ctx->digest_length = PICOHASH_SHA256_DIGEST_LENGTH; + ctx->_reset = (void (*)(void*))_picohash_sha256_init; + ctx->_update = (void (*)(void*, const void*, size_t))_picohash_sha256_update; + ctx->_final = (void (*)(void*, void*))_picohash_sha256_final; + _picohash_sha256_init(&ctx->_sha256); +} + +inline void picohash_update(picohash_ctx_t *ctx, const void *input, size_t len) +{ + ctx->_update(ctx, input, len); +} + +inline void picohash_final(picohash_ctx_t *ctx, void *digest) +{ + ctx->_final(ctx, digest); +} + +inline void picohash_reset(picohash_ctx_t *ctx) +{ + ctx->_reset(ctx); +} + +static inline void _picohash_hmac_apply_key(picohash_ctx_t *ctx, unsigned char delta) +{ + size_t i; + for (i = 0; i != ctx->block_length; ++i) + ctx->_hmac.key[i] ^= delta; + picohash_update(ctx, ctx->_hmac.key, ctx->block_length); + for (i = 0; i != ctx->block_length; ++i) + ctx->_hmac.key[i] ^= delta; +} + +static void _picohash_hmac_final(picohash_ctx_t *ctx, void *digest) +{ + unsigned char inner_digest[PICOHASH_MAX_DIGEST_LENGTH]; + + ctx->_hmac.hash_final(ctx, inner_digest); + + ctx->_hmac.hash_reset(ctx); + _picohash_hmac_apply_key(ctx, 0x5c); + picohash_update(ctx, inner_digest, ctx->digest_length); + memset(inner_digest, 0, ctx->digest_length); + + ctx->_hmac.hash_final(ctx, digest); +} + +static inline void _picohash_hmac_reset(picohash_ctx_t *ctx) +{ + ctx->_hmac.hash_reset(ctx); + _picohash_hmac_apply_key(ctx, 0x36); +} + +inline void picohash_init_hmac(picohash_ctx_t *ctx, void (*initf)(picohash_ctx_t *), const void *key, size_t key_len) +{ + initf(ctx); + + memset(ctx->_hmac.key, 0, ctx->block_length); + if (key_len > ctx->block_length) { + /* hash the key if it is too long */ + picohash_update(ctx, key, key_len); + picohash_final(ctx, ctx->_hmac.key); + ctx->_hmac.hash_reset(ctx); + } else { + memcpy(ctx->_hmac.key, key, key_len); + } + + /* replace reset and final function */ + ctx->_hmac.hash_reset = ctx->_reset; + ctx->_hmac.hash_final = ctx->_final; + ctx->_reset = reinterpret_cast(_picohash_hmac_reset); + ctx->_final = reinterpret_cast(_picohash_hmac_final); + + /* start calculating the inner hash */ + _picohash_hmac_apply_key(ctx, 0x36); +} + +#endif diff --git a/src/gtools/gsh.cpp b/src/gtools/gsh.cpp index 0fd971b1031..00f6cb18daf 100644 --- a/src/gtools/gsh.cpp +++ b/src/gtools/gsh.cpp @@ -95,7 +95,12 @@ view_checkpoint(struct gsh_state *s) struct dm *dmp = (struct dm *)s->gedp->ged_gvp->dmp; s->prev_dhash = (dmp) ? dm_hash(dmp) : 0; s->prev_vhash = bv_hash(s->gedp->ged_gvp); - s->prev_lhash = dl_name_hash(s->gedp); + const char *ncmd = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(ncmd, "1")) { + s->prev_lhash = 0; + } else { + s->prev_lhash = dl_name_hash(s->gedp); + } s->prev_ghash = ged_dl_hash((struct display_list *)s->gedp->ged_gdp->gd_headDisplay); } } @@ -103,7 +108,7 @@ view_checkpoint(struct gsh_state *s) void view_update(struct gsh_state *s) { - if (!s || !s->gedp || !s->gedp->dbip) + if (!s || !s->gedp || !s->gedp->ged_gvp) return; struct ged *gedp = s->gedp; @@ -112,13 +117,29 @@ view_update(struct gsh_state *s) if (!v) return; - struct dm *dmp = (struct dm *)gedp->ged_gvp->dmp; + struct dm *dmp = (struct dm *)v->dmp; if (!dmp) return; unsigned long long dhash = dm_hash(dmp); - unsigned long long vhash = bv_hash(gedp->ged_gvp); - unsigned long long lhash = dl_name_hash(gedp); + unsigned long long vhash = bv_hash(v); + unsigned long long lhash; + const char *ncmd = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(ncmd, "1")) { + if (gedp->dbi_state) { + unsigned long long updated = gedp->dbi_state->update(); + lhash = (updated) ? s->prev_lhash + 1 : 0; + if (v->gv_s->gv_cleared) { + lhash = 1; + v->gv_s->gv_cleared = 0; + } + } else { + lhash = 0; + } + } else { + lhash = dl_name_hash(s->gedp); + } + unsigned long long ghash = ged_dl_hash((struct display_list *)gedp->ged_gdp->gd_headDisplay); unsigned long long lhash_edit = lhash; if (dhash != s->prev_dhash) { @@ -134,19 +155,35 @@ view_update(struct gsh_state *s) dm_set_dirty(dmp, 1); } if (dm_get_dirty(dmp)) { - matp_t mat = gedp->ged_gvp->gv_model2view; - dm_loadmatrix(dmp, mat, 0); - unsigned char geometry_default_color[] = { 255, 0, 0 }; - dm_draw_begin(dmp); - dm_draw_head_dl(dmp, gedp->ged_gdp->gd_headDisplay, - 1.0, gedp->ged_gvp->gv_isize, -1, -1, -1, 1, - 0, 0, geometry_default_color, 1, 0); - - // Faceplate drawing - struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - dm_draw_viewobjs(wdbp, v, NULL, gedp->dbip->dbi_base2local, gedp->dbip->dbi_local2base); - - dm_draw_end(dmp); + ncmd = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(ncmd, "1")) { + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + dm_set_dirty(dmp, 0); + dm_draw_objs(v, NULL, NULL); + dm_draw_end(dmp); + } else { + matp_t mat = gedp->ged_gvp->gv_model2view; + dm_loadmatrix(dmp, mat, 0); + unsigned char geometry_default_color[] = { 255, 0, 0 }; + dm_draw_begin(dmp); + dm_draw_head_dl(dmp, gedp->ged_gdp->gd_headDisplay, + 1.0, gedp->ged_gvp->gv_isize, -1, -1, -1, 1, + 0, 0, geometry_default_color, 1, 0); + + // Faceplate drawing + if (gedp->dbip) { + struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + v->gv_base2local = gedp->dbip->dbi_base2local; + v->gv_local2base = gedp->dbip->dbi_local2base; + dm_draw_viewobjs(wdbp, v, NULL); + } else { + dm_draw_viewobjs(NULL, v, NULL); + } + dm_draw_end(dmp); + } } } #endif @@ -165,8 +202,10 @@ gsh_state_init(struct gsh_state *s) /* We will need a view to support commands like draw */ BU_GET(s->gedp->ged_gvp, struct bview); bv_init(s->gedp->ged_gvp, &s->gedp->ged_views); + bv_set_add_view(&s->gedp->ged_views, s->gedp->ged_gvp); bu_vls_sprintf(&s->gedp->ged_gvp->gv_name, "default"); bv_set_add_view(&s->gedp->ged_views, s->gedp->ged_gvp); + bu_ptbl_ins(&s->gedp->ged_free_views, (long *)s->gedp->ged_gvp); #ifdef USE_DM view_checkpoint(s); #endif @@ -315,6 +354,9 @@ main(int argc, const char **argv) /* Done with program name */ argv++; argc--; + // Prepare the dbi_state container for running with GED_TEST_NEW_CMD_FORMS + bu_setenv("LIBGED_DBI_STATE", "1", 1); + /* Parse options, fail if anything goes wrong */ if ((argc = bu_opt_parse(&msg, argc, argv, d)) == -1) { fputs(bu_vls_addr(&msg), stderr); diff --git a/src/isst/gfile.cpp b/src/isst/gfile.cpp index 3b3f9c35c9a..c91f4c7e2f7 100644 --- a/src/isst/gfile.cpp +++ b/src/isst/gfile.cpp @@ -58,7 +58,6 @@ nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s * { struct model *m; struct shell *s; - int region_polys=0; NMG_CK_REGION(r); @@ -114,7 +113,6 @@ nmg_to_adrt_internal(TIE_3 **tribuf, struct tie_s *cur_tie, struct adrt_mesh_s * continue; TIE_VAL(tie_push)(cur_tie, tribuf, 1, mesh, 0); - region_polys++; } } } @@ -311,7 +309,7 @@ GFile::load_g(const char *filename, int argc, const char *argv[]) &tree_state, /* initial tree state */ nmg_to_adrt_regstart, /* region start function */ gcv_region_end, /* region end function */ - nmg_booltree_leaf_tess, /* leaf func */ + rt_booltree_leaf_tess, /* leaf func */ (void *)&gcvwriter); /* client data */ /* Release dynamic storage */ diff --git a/src/isst/isstgl.cpp b/src/isst/isstgl.cpp index 08ad66858c1..29d2a6cf16c 100644 --- a/src/isst/isstgl.cpp +++ b/src/isst/isstgl.cpp @@ -29,6 +29,7 @@ #include #include #include // for qGuiApp +#include #include "bu/parallel.h" #include "isstgl.h" @@ -339,20 +340,20 @@ void isstGL::keyPressEvent(QKeyEvent *k) { void isstGL::mouseMoveEvent(QMouseEvent *e) { -#ifdef USE_QT6 - bu_log("(%f,%f)\n", e->position().x(), e->position().y()); - if (x_prev > -INT_MAX && y_prev > -INT_MAX) { - bu_log("Delta: (%f,%f)\n", e->position().x() - x_prev, e->position().y() - y_prev); - } - x_prev = e->position().x(); - y_prev = e->position().y(); -#else +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) bu_log("(%d,%d)\n", e->x(), e->y()); if (x_prev > -INT_MAX && y_prev > -INT_MAX) { bu_log("Delta: (%d,%d)\n", e->x() - x_prev, e->y() - y_prev); } x_prev = e->x(); y_prev = e->y(); +#else + bu_log("(%f,%f)\n", e->position().x(), e->position().y()); + if (x_prev > -INT_MAX && y_prev > -INT_MAX) { + bu_log("Delta: (%f,%f)\n", e->position().x() - x_prev, e->position().y() - y_prev); + } + x_prev = e->position().x(); + y_prev = e->position().y(); #endif QOpenGLWidget::mouseMoveEvent(e); diff --git a/src/isst/main_window.h b/src/isst/main_window.h index acfeed64879..8b1335d78dc 100644 --- a/src/isst/main_window.h +++ b/src/isst/main_window.h @@ -30,10 +30,11 @@ #include "common.h" #include -#ifdef USE_QT6 -#include -#else +#include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include +#else +#include #endif #include #include diff --git a/src/libanalyze/CMakeLists.txt b/src/libanalyze/CMakeLists.txt index 35035c2080f..71137072739 100644 --- a/src/libanalyze/CMakeLists.txt +++ b/src/libanalyze/CMakeLists.txt @@ -5,7 +5,6 @@ set(ANALYZE_INCLUDE_DIRS ${BRLCAD_SOURCE_DIR}/include ${BU_INCLUDE_DIRS} ${RT_INCLUDE_DIRS} - ${TCL_INCLUDE_PATH} ) BRLCAD_LIB_INCLUDE_DIRS(analyze ANALYZE_INCLUDE_DIRS "") @@ -72,7 +71,7 @@ set(libanalyze_ignored_files ) CMAKEFILES(${libanalyze_ignored_files}) -BRLCAD_ADDLIB(libanalyze "${LIBANALYZE_SOURCES}" "librt;libbu") +BRLCAD_ADDLIB(libanalyze "${LIBANALYZE_SOURCES}" "${libanalyze_deps}") set_target_properties(libanalyze PROPERTIES VERSION 20.0.1 SOVERSION 20) add_subdirectory(tests) diff --git a/src/libbg/CMakeLists.txt b/src/libbg/CMakeLists.txt index 7ecdc2c50c5..f08f61101d6 100644 --- a/src/libbg/CMakeLists.txt +++ b/src/libbg/CMakeLists.txt @@ -7,9 +7,11 @@ set(BG_INCLUDE_DIRS ${POLY2TRI_INCLUDE_DIRS} ${SPSR_INCLUDE_DIR} ${LMDB_INCLUDE_DIR} - ${BRLCAD_SOURCE_DIR}/src/other/ext/Eigen + ${EIGEN3_INCLUDE_DIRS} ) - +if (EXISTS ${BRLCAD_SOURCE_DIR}/src/other/Eigen) + set(BG_INCLUDE_DIRS ${BG_INCLUDE_DIRS} ${BRLCAD_SOURCE_DIR}/src/other/Eigen) +endif (EXISTS ${BRLCAD_SOURCE_DIR}/src/other/Eigen) BRLCAD_LIB_INCLUDE_DIRS(bg BG_INCLUDE_DIRS "") set(SPSR_srcs @@ -60,19 +62,15 @@ set(LIBBG_SOURCES chull3d.cpp clip.c clipper.cpp - lod.cpp lseg_lseg.c lseg_pt.c obr.c plane.cpp polygon.c - polygon_bview.c - polygon_fill.cpp polygon_op.cpp polygon_triangulate.cpp polygon_point_in.c sat.c - snap.c spsr.c ${SPSR_srcs} tri_pt.c @@ -87,7 +85,7 @@ set(LIBBG_SOURCES util.c ) -BRLCAD_ADDLIB(libbg "${LIBBG_SOURCES}" "libbv;libbn;libbu;${POLY2TRI_LIBRARIES};${LMDB_LIBRARIES}") +BRLCAD_ADDLIB(libbg "${LIBBG_SOURCES}" "${libbg_deps};${POLY2TRI_LIBRARIES};${LMDB_LIBRARIES}") set_target_properties(libbg PROPERTIES VERSION 20.0.1 SOVERSION 20) if (HIDE_INTERNAL_SYMBOLS) if (TARGET poly2tri OR HIDE_INTERNAL_SYMBOLS_EXT) @@ -108,6 +106,15 @@ if (TARGET libbg-obj) set_property(TARGET libbg-obj APPEND PROPERTY COMPILE_DEFINITIONS "EIGEN_DONT_VECTORIZE") endif (TARGET libbg-obj) +# With newer GCC, optimized linking of SPSR triggers a compiler warning about a +# new allocation potentially exceeding maximum object size. +if(${BRLCAD_OPTIMIZED} MATCHES "ON") + check_c_compiler_flag(-Wno-error=alloc-size-larger-than= HAVE_NO_ALLOC_SIZE_LARGER_THAN) + if (HAVE_NO_ALLOC_SIZE_LARGER_THAN) + target_link_options(libbg PRIVATE -Wno-error=alloc-size-larger-than=) + endif (HAVE_NO_ALLOC_SIZE_LARGER_THAN) +endif(${BRLCAD_OPTIMIZED} MATCHES "ON") + add_subdirectory(tests) set(bg_ignore diff --git a/src/libbg/lod.cpp b/src/libbg/lod.cpp deleted file mode 100644 index 67f257f4ac0..00000000000 --- a/src/libbg/lod.cpp +++ /dev/null @@ -1,2266 +0,0 @@ -/* L O D . C P P - * BRL-CAD - * - * Copyright (c) 2022-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * Based off of code from https://github.com/bhaettasch/pop-buffer-demo - * Copyright (c) 2016 Benjamin Hättasch and X3DOM - * The MIT License (MIT) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/** @file lod.cpp - * - * This file implements level-of-detail routines. Eventually it may have libbg - * wrappers around more sophisticated algorithms... - * - * The POP Buffer: Rapid Progressive Clustering by Geometry Quantization - * https://x3dom.org/pop/files/popbuffer2013.pdf - * - * Useful discussion of applying POP buffers here: - * https://medium.com/@petroskataras/the-ayotzinapa-case-447a72d89e58 - * - * Notes on caching: - * - * Management of LoD cached data is actually a bit of a challenge. A full - * content hash of the original ver/tri arrays is the most reliable approach - * but is a potentially expensive operation, which also requires reading the - * entire original geometry to get the hash value to do lookups. Ideally, we'd - * like for the application to never have to access more of the data than is - * needed for display purposes. However, object names are not unique across .g - * files and so are not useful for this purpose. Also, at this level of the - * logic we (deliberately) are separated from any notion of .g objects. - * - * What we do is generate a hash value of the data on initialization, when we - * need the full data set to perform the initial LoD setup. We then provide - * that value back to the caller for them to manage at a higher level. - */ - -#include "common.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_STAT_H -# include /* for mkdir */ -#endif - -extern "C" { -#define XXH_STATIC_LINKING_ONLY -#define XXH_IMPLEMENTATION -#include "xxhash.h" - -#include "lmdb.h" -} - -#include "bio.h" - -#include "bu/app.h" -#include "bu/bitv.h" -#include "bu/color.h" -#include "bu/malloc.h" -#include "bu/parallel.h" -#include "bu/path.h" -#include "bu/str.h" -#include "bu/time.h" -#include "bv/plot3.h" -#include "bg/lod.h" -#include "bg/plane.h" -#include "bg/sat.h" -#include "bg/trimesh.h" - -// Number of levels of detail to define -#define POP_MAXLEVEL 16 - -// Subdirectory in BRL-CAD cache to hold this type of LoD data -#define POP_CACHEDIR ".POPLoD" - -// Factor by which to bump out bounds to avoid points on box edges -#define MBUMP 1.01 - -// Maximum database size. For detailed views we fall back on just -// displaying the full data set, and we need to be able to memory map the -// file, so go with a 4Gb per file limit. -#define CACHE_MAX_DB_SIZE 4294967296 - -// Define what format of the cache is current - if it doesn't match, we need -// to wipe and redo. -#define CACHE_CURRENT_FORMAT 1 - -/* There are various individual pieces of data in the cache associated with - * each object key. For lookup they use short suffix strings to distinguish - * them - we define those strings here to have consistent definitions for use - * in multiple functions. - * - * Changing any of these requires incrementing CACHE_CURRENT_FORMAT. */ -#define CACHE_POP_MAX_LEVEL "th" -#define CACHE_POP_SWITCH_LEVEL "sw" -#define CACHE_VERTEX_COUNT "vc" -#define CACHE_TRI_COUNT "tc" -#define CACHE_OBJ_BOUNDS "bb" -#define CACHE_VERT_LEVEL "v" -#define CACHE_VERTNORM_LEVEL "vn" -#define CACHE_TRI_LEVEL "t" - -typedef int (*full_detail_clbk_t)(struct bv_mesh_lod *, void *); - -static void -lod_dir(char *dir) -{ -#ifdef HAVE_WINDOWS_H - CreateDirectory(dir, NULL); -#else - /* mode: 775 */ - mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); -#endif -} - -static void -obj_bb(int *have_objs, vect_t *min, vect_t *max, struct bv_scene_obj *s, struct bview *v) -{ - vect_t minus, plus; - if (bv_scene_obj_bound(s, v)) { - *have_objs = 1; - minus[X] = s->s_center[X] - s->s_size; - minus[Y] = s->s_center[Y] - s->s_size; - minus[Z] = s->s_center[Z] - s->s_size; - VMIN(*min, minus); - plus[X] = s->s_center[X] + s->s_size; - plus[Y] = s->s_center[Y] + s->s_size; - plus[Z] = s->s_center[Z] + s->s_size; - VMAX(*max, plus); - } - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *sc = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - obj_bb(have_objs, min, max, sc, v); - } -} - -// Debugging function to see constructed arb -void -obb_arb(vect_t obb_center, vect_t obb_extent1, vect_t obb_extent2, vect_t obb_extent3) -{ - // For debugging purposes, construct an arb - point_t arb[8]; - // 1 - c - e1 - e2 - e3 - VSUB2(arb[0], obb_center, obb_extent1); - VSUB2(arb[0], arb[0], obb_extent2); - VSUB2(arb[0], arb[0], obb_extent3); - // 2 - c - e1 - e2 + e3 - VSUB2(arb[1], obb_center, obb_extent1); - VSUB2(arb[1], arb[1], obb_extent2); - VADD2(arb[1], arb[1], obb_extent3); - // 3 - c - e1 + e2 + e3 - VSUB2(arb[2], obb_center, obb_extent1); - VADD2(arb[2], arb[2], obb_extent2); - VADD2(arb[2], arb[2], obb_extent3); - // 4 - c - e1 + e2 - e3 - VSUB2(arb[3], obb_center, obb_extent1); - VADD2(arb[3], arb[3], obb_extent2); - VSUB2(arb[3], arb[3], obb_extent3); - // 1 - c + e1 - e2 - e3 - VADD2(arb[4], obb_center, obb_extent1); - VSUB2(arb[4], arb[4], obb_extent2); - VSUB2(arb[4], arb[4], obb_extent3); - // 2 - c + e1 - e2 + e3 - VADD2(arb[5], obb_center, obb_extent1); - VSUB2(arb[5], arb[5], obb_extent2); - VADD2(arb[5], arb[5], obb_extent3); - // 3 - c + e1 + e2 + e3 - VADD2(arb[6], obb_center, obb_extent1); - VADD2(arb[6], arb[6], obb_extent2); - VADD2(arb[6], arb[6], obb_extent3); - // 4 - c + e1 + e2 - e3 - VADD2(arb[7], obb_center, obb_extent1); - VADD2(arb[7], arb[7], obb_extent2); - VSUB2(arb[7], arb[7], obb_extent3); - - bu_log("center: %f %f %f\n", V3ARGS(obb_center)); - bu_log("e1: %f %f %f\n", V3ARGS(obb_extent1)); - bu_log("e2: %f %f %f\n", V3ARGS(obb_extent2)); - bu_log("e3: %f %f %f\n", V3ARGS(obb_extent3)); - - bu_log("in obb.s arb8 %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", - V3ARGS(arb[0]), V3ARGS(arb[1]), V3ARGS(arb[2]), V3ARGS(arb[3]), V3ARGS(arb[4]), V3ARGS(arb[5]), V3ARGS(arb [6]), V3ARGS(arb[7])); -} - -static void -view_obb(struct bview *v, - point_t sbbc, fastf_t radius, - vect_t dir, - point_t ec, point_t ep1, point_t ep2) -{ - - // Box center is the closest point to the view center on the plane defined - // by the scene's center and the view dir - plane_t p; - bg_plane_pt_nrml(&p, sbbc, dir); - fastf_t pu, pv; - bg_plane_closest_pt(&pu, &pv, p, ec); - bg_plane_pt_at(&v->obb_center, p, pu, pv); - - // The first extent is just the scene radius in the lookat direction - VSCALE(dir, dir, radius); - VMOVE(v->obb_extent1, dir); - - // The other two extents we find by subtracting the view center from the edge points - VSUB2(v->obb_extent2, ep1, ec); - VSUB2(v->obb_extent3, ep2, ec); - -#if 0 - obb_arb(v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3); -#endif -} - -static void -_scene_radius(point_t *sbbc, fastf_t *radius, struct bview *v) -{ - if (!sbbc || !radius || !v) - return; - VSET(*sbbc, 0, 0, 0); - *radius = 1.0; - vect_t min, max, work; - VSETALL(min, INFINITY); - VSETALL(max, -INFINITY); - int have_objs = 0; - struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { - struct bv_scene_obj *g = (struct bv_scene_obj *)BU_PTBL_GET(so, i); - obj_bb(&have_objs, &min, &max, g, v); - } - struct bu_ptbl *sol = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); - if (so != sol) { - for (size_t i = 0; i < BU_PTBL_LEN(sol); i++) { - struct bv_scene_obj *g = (struct bv_scene_obj *)BU_PTBL_GET(sol, i); - obj_bb(&have_objs, &min, &max, g, v); - } - } - if (have_objs) { - VADD2SCALE(*sbbc, max, min, 0.5); - VSUB2SCALE(work, max, min, 0.5); - (*radius) = MAGNITUDE(work); - } -} - -void -bg_view_bounds(struct bview *v) -{ - if (!v || !v->gv_width || !v->gv_height) - return; - - // Get the radius of the scene. - point_t sbbc = VINIT_ZERO; - fastf_t radius = 1.0; - _scene_radius(&sbbc, &radius, v); - - // Using the pixel width and height of the current "window", construct some - // view space dimensions related to that window - int w = v->gv_width; - int h = v->gv_height; - int x = (int)(w * 0.5); - int y = (int)(h * 0.5); - //bu_log("w,h,x,y: %d %d %d %d\n", w,h, x, y); - fastf_t x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, xc = 0.0, yc = 0.0; - bv_screen_to_view(v, &x1, &y1, x, h); - bv_screen_to_view(v, &x2, &y2, w, y); - bv_screen_to_view(v, &xc, &yc, x, y); - - // Also stash the window's view space bbox - fastf_t w0, w1, w2, w3; - bv_screen_to_view(v, &w0, &w1, 0, 0); - bv_screen_to_view(v, &w2, &w3, w, h); - v->gv_wmin[0] = (w0 < w2) ? w0 : w2; - v->gv_wmin[1] = (w1 < w3) ? w1 : w3; - v->gv_wmax[0] = (w0 > w2) ? w0 : w2; - v->gv_wmax[1] = (w1 > w3) ? w1 : w3; - //bu_log("vbbmin: %f %f\n", v->gv_wmin[0], v->gv_wmin[1]); - //bu_log("vbbmax: %f %f\n", v->gv_wmax[0], v->gv_wmax[1]); - - // Get the model space points for the mid points of the top and right edges - // of the view. If we don't have a width or height, we will use the - // existing min and max since we don't have a "screen" to base the box on - //bu_log("x1,y1: %f %f\n", x1, y1); - //bu_log("x2,y2: %f %f\n", x2, y2); - //bu_log("xc,yc: %f %f\n", xc, yc); - point_t vp1, vp2, vc, ep1, ep2, ec; - VSET(vp1, x1, y1, 0); - VSET(vp2, x2, y2, 0); - VSET(vc, xc, yc, 0); - MAT4X3PNT(ep1, v->gv_view2model, vp1); - MAT4X3PNT(ep2, v->gv_view2model, vp2); - MAT4X3PNT(ec, v->gv_view2model, vc); - //bu_log("view center: %f %f %f\n", V3ARGS(ec)); - //bu_log("edge point 1: %f %f %f\n", V3ARGS(ep1)); - //bu_log("edge point 2: %f %f %f\n", V3ARGS(ep2)); - - // Need the direction vector - i.e., where the camera is looking. Got this - // trick from the libged nirt code... - vect_t dir; - VMOVEN(dir, v->gv_rotation + 8, 3); - VUNITIZE(dir); - VSCALE(dir, dir, -1.0); - - // If perspective mode is not enabled, update the oriented bounding box. - if (!(SMALL_FASTF < v->gv_perspective)) { - view_obb(v, sbbc, radius, dir, ec, ep1, ep2); - } - - - // While we have the info, construct the "backed out" point that will let - // us construct the "backed out" view plane, and save that point and the - // lookat direction to the view - VMOVE(v->gv_lookat, dir); - VSCALE(dir, dir, -radius); - VADD2(v->gv_vc_backout, sbbc, dir); - v->radius = radius; -} - -static void -_find_active_objs(std::set &active, struct bv_scene_obj *s, struct bview *v, point_t obb_c, point_t obb_e1, point_t obb_e2, point_t obb_e3) -{ - if (BU_PTBL_LEN(&s->children)) { - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *sc = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - _find_active_objs(active, sc, v, obb_c, obb_e1, obb_e2, obb_e3); - } - } else { - bv_scene_obj_bound(s, v); - if (bg_sat_aabb_obb(s->bmin, s->bmax, obb_c, obb_e1, obb_e2, obb_e3)) - active.insert(s); - } -} - -int -bg_view_objs_select(struct bv_scene_obj ***sset, struct bview *v, int x, int y) -{ - if (!v || !sset || !v->gv_width || !v->gv_height) - return 0; - - if (x < 0 || y < 0 || x > v->gv_width || y > v->gv_height) - return 0; - - - // Get the radius of the scene. - point_t sbbc = VINIT_ZERO; - fastf_t radius = 1.0; - _scene_radius(&sbbc, &radius, v); - - // Using the pixel width and height of the current "window", construct some - // view space dimensions related to that window - fastf_t x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, xc = 0.0, yc = 0.0; - bv_screen_to_view(v, &x1, &y1, x, y+1); - bv_screen_to_view(v, &x2, &y2, x+1, y); - bv_screen_to_view(v, &xc, &yc, x, y); - - // Get the model space points for the mid points of the top and right edges - // of the "pixel + 1" box. - //bu_log("x1,y1: %f %f\n", x1, y1); - //bu_log("x2,y2: %f %f\n", x2, y2); - //bu_log("xc,yc: %f %f\n", xc, yc); - point_t vp1, vp2, vc, ep1, ep2, ec; - VSET(vp1, x1, y1, 0); - VSET(vp2, x2, y2, 0); - VSET(vc, xc, yc, 0); - MAT4X3PNT(ep1, v->gv_view2model, vp1); - MAT4X3PNT(ep2, v->gv_view2model, vp2); - MAT4X3PNT(ec, v->gv_view2model, vc); - - // Need the direction vector - i.e., where the camera is looking. Got this - // trick from the libged nirt code... - vect_t dir; - VMOVEN(dir, v->gv_rotation + 8, 3); - VUNITIZE(dir); - VSCALE(dir, dir, -1.0); - - - // Construct the box values needed for the SAT test - point_t obb_c, obb_e1, obb_e2, obb_e3; - - // Box center is the closest point to the view center on the plane defined - // by the scene's center and the view dir - plane_t p; - bg_plane_pt_nrml(&p, sbbc, dir); - fastf_t pu, pv; - bg_plane_closest_pt(&pu, &pv, p, ec); - bg_plane_pt_at(&obb_c, p, pu, pv); - - - // The first extent is just the scene radius in the lookat direction - VSCALE(dir, dir, radius); - VMOVE(obb_e1, dir); - - // The other two extents we find by subtracting the view center from the edge points - VSUB2(obb_e2, ep1, ec); - VSUB2(obb_e3, ep2, ec); - - // Having constructed the box, test the scene objects against it. Any that intersect, - // add them to the set - std::set active; - struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(so, i); - _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); - } - if (active.size()) { - std::set::iterator a_it; - (*sset) = (struct bv_scene_obj **)bu_calloc(active.size(), sizeof(struct bv_scene_obj *), "objs"); - int i = 0; - for (a_it = active.begin(); a_it != active.end(); a_it++) { - (*sset)[i] = *a_it; - i++; - } - } - - return active.size(); -} - -int -bg_view_objs_rect_select(struct bv_scene_obj ***sset, struct bview *v, int x1, int y1, int x2, int y2) -{ - if (!v || !sset || !v->gv_width || !v->gv_height) - return 0; - - if (x1 < 0 || y1 < 0 || x1 > v->gv_width || y1 > v->gv_height) - return 0; - - if (x2 < 0 || y2 < 0 || x2 > v->gv_width || y2 > v->gv_height) - return 0; - - // Get the radius of the scene. - point_t sbbc = VINIT_ZERO; - fastf_t radius = 1.0; - _scene_radius(&sbbc, &radius, v); - - // Using the pixel width and height of the current "window", construct some - // view space dimensions related to that window - fastf_t fx1 = 0.0, fy1 = 0.0, fx2 = 0.0, fy2 = 0.0, fxc = 0.0, fyc = 0.0; - bv_screen_to_view(v, &fx1, &fy1, (int)(0.5*(x1+x2)), y2); - bv_screen_to_view(v, &fx2, &fy2, x2, (int)(0.5*(y1+y2))); - bv_screen_to_view(v, &fxc, &fyc, (int)(0.5*(x1+x2)), (int)(0.5*(y1+y2))); - - // Get the model space points for the mid points of the top and right edges - // of the box. - point_t vp1, vp2, vc, ep1, ep2, ec; - VSET(vp1, fx1, fy1, 0); - VSET(vp2, fx2, fy2, 0); - VSET(vc, fxc, fyc, 0); - MAT4X3PNT(ep1, v->gv_view2model, vp1); - MAT4X3PNT(ep2, v->gv_view2model, vp2); - MAT4X3PNT(ec, v->gv_view2model, vc); - //bu_log("in sph1.s sph %f %f %f 1\n", V3ARGS(ep1)); - //bu_log("in sph2.s sph %f %f %f 2\n", V3ARGS(ep2)); - //bu_log("in sphc.s sph %f %f %f 3\n", V3ARGS(ec)); - - // Need the direction vector - i.e., where the camera is looking. Got this - // trick from the libged nirt code... - vect_t dir; - VMOVEN(dir, v->gv_rotation + 8, 3); - VUNITIZE(dir); - VSCALE(dir, dir, -1.0); - - - // Construct the box values needed for the SAT test - point_t obb_c, obb_e1, obb_e2, obb_e3; - - // Box center is the closest point to the view center on the plane defined - // by the scene's center and the view dir - plane_t p; - bg_plane_pt_nrml(&p, sbbc, dir); - fastf_t pu, pv; - bg_plane_closest_pt(&pu, &pv, p, ec); - bg_plane_pt_at(&obb_c, p, pu, pv); - - - // The first extent is just the scene radius in the lookat direction - VSCALE(dir, dir, radius); - VMOVE(obb_e1, dir); - - // The other two extents we find by subtracting the view center from the edge points - VSUB2(obb_e2, ep1, ec); - VSUB2(obb_e3, ep2, ec); - -#if 0 - obb_arb(obb_c, obb_e1, obb_e2, obb_e3); -#endif - - // Having constructed the box, test the scene objects against it. Any that intersect, - // add them to the set - std::set active; - struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(so, i); - _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); - } - if (active.size()) { - std::set::iterator a_it; - (*sset) = (struct bv_scene_obj **)bu_calloc(active.size(), sizeof(struct bv_scene_obj *), "objs"); - int i = 0; - for (a_it = active.begin(); a_it != active.end(); a_it++) { - (*sset)[i] = *a_it; - i++; - } - } - - return active.size(); -} - -static int -_obj_visible(struct bv_scene_obj *s, struct bview *v) -{ - if (bg_sat_aabb_obb(s->bmin, s->bmax, v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)) - return 1; - - if (SMALL_FASTF < v->gv_perspective) { - // For perspective mode, project the vertices of the distorted bounding - // box into the view plane, bound them, and see if the box overlaps with - // the view screen's box. - point_t arb[8]; - VSET(arb[0], s->bmin[0], s->bmin[1], s->bmin[2]); - VSET(arb[1], s->bmin[0], s->bmin[1], s->bmax[2]); - VSET(arb[2], s->bmin[0], s->bmax[1], s->bmin[2]); - VSET(arb[3], s->bmin[0], s->bmax[1], s->bmax[2]); - VSET(arb[4], s->bmax[0], s->bmin[1], s->bmin[2]); - VSET(arb[5], s->bmax[0], s->bmin[1], s->bmax[2]); - VSET(arb[6], s->bmax[0], s->bmax[1], s->bmin[2]); - VSET(arb[7], s->bmax[0], s->bmax[1], s->bmax[2]); - point2d_t omin = {INFINITY, INFINITY}; - point2d_t omax = {-INFINITY, -INFINITY}; - for (int i = 0; i < 8; i++) { - point_t pp, ppnt; - point2d_t pxy; - MAT4X3PNT(pp, v->gv_pmat, arb[i]); - MAT4X3PNT(ppnt, v->gv_model2view, pp); - V2SET(pxy, ppnt[0], ppnt[1]); - V2MINMAX(omin, omax, pxy); - } - // IFF the omin/omax box and the corresponding view box overlap, this - // object may be visible in the current view and needs to be updated - for (int i = 0; i < 2; i++) { - if (omax[i] < v->gv_wmin[i] || omin[i] > v->gv_wmax[i]) - return 0; - } - return 1; - } - - return 0; -} - -struct bg_mesh_lod_context_internal { - MDB_env *lod_env; - MDB_txn *lod_txn; - MDB_dbi lod_dbi; - - MDB_env *name_env; - MDB_txn *name_txn; - MDB_dbi name_dbi; - - struct bu_vls *fname; -}; - -struct bg_mesh_lod_context * -bg_mesh_lod_context_create(const char *name) -{ - size_t mreaders = 0; - int ncpus = 0; - if (!name) - return NULL; - - // Hash the input filename to generate a key for uniqueness - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - struct bu_vls fname = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&fname, "%s", bu_path_normalize(name)); - // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... - if (bu_vls_strlen(&fname) < 10) { - bu_vls_printf(&fname, "GGGGGGGGGGGGG"); - } - XXH64_update(&h_state, bu_vls_cstr(&fname), bu_vls_strlen(&fname)*sizeof(char)); - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - bu_path_component(&fname, bu_path_normalize(name), BU_PATH_BASENAME_EXTLESS); - bu_vls_printf(&fname, "_%llu", hash); - - // Create the context - struct bg_mesh_lod_context *c; - BU_GET(c, struct bg_mesh_lod_context); - BU_GET(c->i, struct bg_mesh_lod_context_internal); - struct bg_mesh_lod_context_internal *i = c->i; - BU_GET(i->fname, struct bu_vls); - bu_vls_init(i->fname); - bu_vls_sprintf(i->fname, "%s", bu_vls_cstr(&fname)); - - // Base maximum readers on an estimate of how many threads - // we might want to fire off - mreaders = std::thread::hardware_concurrency(); - if (!mreaders) - mreaders = 1; - ncpus = bu_avail_cpus(); - if (ncpus > 0 && (size_t)ncpus > mreaders) - mreaders = (size_t)ncpus + 2; - - - // Set up LMDB environments - if (mdb_env_create(&i->lod_env)) - goto lod_context_fail; - if (mdb_env_create(&i->name_env)) - goto lod_context_close_lod_fail; - - if (mdb_env_set_maxreaders(i->lod_env, mreaders)) - goto lod_context_close_fail; - if (mdb_env_set_maxreaders(i->name_env, mreaders)) - goto lod_context_close_fail; - - // TODO - the "failure" mode if this limit is ever hit is to back down - // the maximum stored LoD on larger objects, but that will take some - // doing to implement... - if (mdb_env_set_mapsize(i->lod_env, CACHE_MAX_DB_SIZE)) - goto lod_context_close_fail; - - if (mdb_env_set_mapsize(i->name_env, CACHE_MAX_DB_SIZE)) - goto lod_context_close_fail; - - - // Ensure the necessary top level dirs are present - char dir[MAXPATHLEN]; - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, NULL); - if (!bu_file_exists(dir, NULL)) - lod_dir(dir); - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, NULL); - if (!bu_file_exists(dir, NULL)) { - lod_dir(dir); - } - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, "format", NULL); - if (!bu_file_exists(dir, NULL)) { - // Note a format, so we can detect if what's there isn't compatible - // with what this logic expects (in anticipation of future changes - // to the on-disk format). - FILE *fp = fopen(dir, "w"); - if (!fp) - goto lod_context_close_fail; - fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); - fclose(fp); - } else { - std::ifstream format_file(dir); - size_t disk_format_version = 0; - format_file >> disk_format_version; - format_file.close(); - if (disk_format_version != CACHE_CURRENT_FORMAT) { - bu_log("Old mesh lod cache (%zd) found - clearing\n", disk_format_version); - bg_mesh_lod_clear_cache(NULL, 0); - } - FILE *fp = fopen(dir, "w"); - if (!fp) - goto lod_context_close_fail; - fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); - fclose(fp); - } - - // Create the specific LoD LMDB cache dir, if not already present - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, bu_vls_cstr(&fname), NULL); - if (!bu_file_exists(dir, NULL)) - lod_dir(dir); - - // Need to call mdb_env_sync() at appropriate points. - if (mdb_env_open(i->lod_env, dir, MDB_NOSYNC, 0664)) - goto lod_context_close_fail; - - // Create the specific name/key LMDB mapping dir, if not already present - bu_vls_printf(&fname, "_namekey"); - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, bu_vls_cstr(&fname), NULL); - if (!bu_file_exists(dir, NULL)) - lod_dir(dir); - - // Need to call mdb_env_sync() at appropriate points. - if (mdb_env_open(i->name_env, dir, MDB_NOSYNC, 0664)) - goto lod_context_close_fail; - - // Success - return the context - return c; - - // If something went wrong, clean up and return NULL -lod_context_close_fail: - mdb_env_close(i->name_env); -lod_context_close_lod_fail: - mdb_env_close(i->lod_env); -lod_context_fail: - bu_vls_free(&fname); - BU_PUT(c->i, struct bg_mesh_lod_context_internal); - BU_PUT(c, struct bg_mesh_lod_context); - return NULL; -} - -void -bg_mesh_lod_context_destroy(struct bg_mesh_lod_context *c) -{ - if (!c) - return; - mdb_env_close(c->i->name_env); - mdb_env_close(c->i->lod_env); - bu_vls_free(c->i->fname); - BU_PUT(c->i->fname, struct bu_vls); - BU_PUT(c->i, struct bg_mesh_lod_context_internal); - BU_PUT(c, struct bg_mesh_lod_context); -} - -unsigned long long -bg_mesh_lod_key_get(struct bg_mesh_lod_context *c, const char *name) -{ - MDB_val mdb_key, mdb_data; - - // Database object names may be of arbitrary length - hash - // to get the lookup key - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - struct bu_vls keystr = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&keystr, "%s", name); - // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... - if (bu_vls_strlen(&keystr) < 10) { - bu_vls_printf(&keystr, "GGGGGGGGGGGGG"); - } - XXH64_update(&h_state, bu_vls_cstr(&keystr), bu_vls_strlen(&keystr)*sizeof(char)); - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - bu_vls_sprintf(&keystr, "%llu", hash); - - mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); - mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); - mdb_key.mv_size = bu_vls_strlen(&keystr)*sizeof(char); - mdb_key.mv_data = (void *)bu_vls_cstr(&keystr); - int rc = mdb_get(c->i->name_txn, c->i->name_dbi, &mdb_key, &mdb_data); - if (rc) { - mdb_txn_commit(c->i->name_txn); - return 0; - } - unsigned long long *fkeyp = (unsigned long long *)mdb_data.mv_data; - unsigned long long fkey = *fkeyp; - mdb_txn_commit(c->i->name_txn); - - bu_vls_free(&keystr); - //bu_log("GOT %s: %llu\n", name, fkey); - return fkey; -} - -int -bg_mesh_lod_key_put(struct bg_mesh_lod_context *c, const char *name, unsigned long long key) -{ - // Database object names may be of arbitrary length - hash - // to get something appropriate for a lookup key - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - struct bu_vls keystr = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&keystr, "%s", name); - // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... - if (bu_vls_strlen(&keystr) < 10) { - bu_vls_printf(&keystr, "GGGGGGGGGGGGG"); - } - XXH64_update(&h_state, bu_vls_cstr(&keystr), bu_vls_strlen(&keystr)*sizeof(char)); - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - bu_vls_sprintf(&keystr, "%llu", hash); - - MDB_val mdb_key; - MDB_val mdb_data[2]; - mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); - mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); - mdb_key.mv_size = bu_vls_strlen(&keystr)*sizeof(char); - mdb_key.mv_data = (void *)bu_vls_cstr(&keystr); - mdb_data[0].mv_size = sizeof(key); - mdb_data[0].mv_data = (void *)&key; - mdb_data[1].mv_size = 0; - mdb_data[1].mv_data = NULL; - int rc = mdb_put(c->i->name_txn, c->i->name_dbi, &mdb_key, mdb_data, 0); - mdb_txn_commit(c->i->name_txn); - - bu_vls_free(&keystr); - //bu_log("PUT %s: %llu\n", name, key); - return rc; -} - -// Output record -class rec { - public: - unsigned short x = 0, y = 0, z = 0; -}; - - -class POPState; -struct bg_mesh_lod_internal { - POPState *s; -}; - -class POPState { - public: - - // Create cached data (doesn't create a usable container) - POPState(struct bg_mesh_lod_context *ctx, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, fastf_t pop_face_cnt_threshold_ratio); - - // Load cached data (DOES create a usable container) - POPState(struct bg_mesh_lod_context *ctx, unsigned long long key); - - // Cleanup - ~POPState(); - - // Based on a view size, recommend a level - int get_level(fastf_t len); - - // Load/unload data level - void set_level(int level); - - // Shrink memory usage (level set routines will have to do more work - // after this is run, but the POPState is still viable). Used after a - // client code has done all that is needed with the level data, such as - // generating an OpenGL display list, but isn't done with the object. - void shrink_memory(); - - // Get the "current" position of a point, given its level - void level_pnt(point_t *o, const point_t *p, int level); - - // Debugging - void plot(const char *root); - - // Active faces needed by the current LoD (indexes into lod_tri_pnts). - std::vector lod_tris; - - // This is where we store the active points - i.e., those needed for - // the current LoD. When initially creating the breakout from BoT data - // we calculate all levels, but the goal is to not hold in memory any - // more than we need to support the LoD drawing. lod_tris will index - // into lod_tri_pnts. - std::vector lod_tri_pnts; - std::vector lod_tri_pnts_snapped; - std::vector lod_tri_norms; - - // Current level of detail information loaded into nfaces/npnts - int curr_level = -1; - - // Force a data reload even if the level hasn't changed (i.e. undo a - // shrink memory operation when level is set.) - bool force_update = false; - - // Maximum level for which POP info is defined. Above that level, - // need to shift to full rendering - int max_pop_threshold_level = 0; - - // Used by calling functions to detect initialization errors - bool is_valid = false; - - // Content based hash key - unsigned long long hash; - - // Methods for full detail - full_detail_clbk_t full_detail_setup_clbk = NULL; - full_detail_clbk_t full_detail_clear_clbk = NULL; - full_detail_clbk_t full_detail_free_clbk = NULL; - void *detail_clbk_data = NULL; - - // Bounding box of original mesh - point_t bbmin, bbmax; - - // Info for drawing - struct bv_mesh_lod *lod = NULL; - - private: - - void tri_process(); - - float minx = FLT_MAX, miny = FLT_MAX, minz = FLT_MAX; - float maxx = -FLT_MAX, maxy = -FLT_MAX, maxz = -FLT_MAX; - - fastf_t max_face_ratio = 0.66; - - // Clamping of points to various detail levels - int to_level(int val, int level); - - // Snap value to level value - fastf_t snap(fastf_t val, fastf_t min, fastf_t max, int level); - - // Check if two points are equal at a clamped level - bool is_equal(rec r1, rec r2, int level); - - // Degeneracy test for triangles - bool tri_degenerate(rec r0, rec r1, rec r2, int level); - - std::vector PRECOMPUTED_MASKS; - - // Write data out to cache (only used during initialization from - // external data) - void cache(); - bool cache_tri(); - bool cache_write(const char *component, std::stringstream &s); - size_t cache_get(void **data, const char *component); - void cache_done(); - void cache_del(const char *component); - MDB_val mdb_key, mdb_data[2]; - - // Specific loading and unloading methods - void tri_pop_load(int start_level, int level); - void tri_pop_trim(int level); - size_t level_vcnt[POP_MAXLEVEL+1] = {0}; - size_t level_tricnt[POP_MAXLEVEL+1] = {0}; - - // Processing containers used for initial triangle data characterization - std::vector tri_ind_map; - std::vector vert_tri_minlevel; - std::map> level_tri_verts; - std::vector> level_tris; - - // Pointers to original input data - size_t vert_cnt = 0; - const point_t *verts_array = NULL; - const vect_t *vnorms_array = NULL; - size_t faces_cnt = 0; - int *faces_array = NULL; - - // Context - struct bg_mesh_lod_context *c; -}; - -void -POPState::tri_process() -{ - // Until we prove otherwise, all edges are assumed to appear only at the - // last level (and consequently, their vertices are only needed then). Set - // the level accordingly. - vert_tri_minlevel.reserve(vert_cnt); - for (size_t i = 0; i < vert_cnt; i++) { - vert_tri_minlevel.push_back(POP_MAXLEVEL - 1); - } - - // Reserve memory for level containers - level_tris.reserve(POP_MAXLEVEL); - for (size_t i = 0; i < POP_MAXLEVEL; i++) { - level_tris.push_back(std::vector(0)); - } - - // Walk the triangles and perform the LoD characterization - for (size_t i = 0; i < faces_cnt; i++) { - rec triangle[3]; - // Transform triangle vertices - bool bad_face = false; - for (size_t j = 0; j < 3; j++) { - int f_ind = faces_array[3*i+j]; - if ((size_t)f_ind >= vert_cnt || f_ind < 0) { - bu_log("bad face %zd - skipping\n", i); - bad_face = true; - break; - } - triangle[j].x = floor((verts_array[f_ind][X] - minx) / (maxx - minx) * USHRT_MAX); - triangle[j].y = floor((verts_array[f_ind][Y] - miny) / (maxy - miny) * USHRT_MAX); - triangle[j].z = floor((verts_array[f_ind][Z] - minz) / (maxz - minz) * USHRT_MAX); - } - if (bad_face) - continue; - - // Find the pop up level for this triangle (i.e., when it will first - // appear as we step up the zoom levels.) - size_t level = POP_MAXLEVEL - 1; - for (int j = 0; j < POP_MAXLEVEL; j++) { - if (!tri_degenerate(triangle[0], triangle[1], triangle[2], j)) { - level = j; - break; - } - } - // Add this triangle to its "pop" level - level_tris[level].push_back(i); - - // Let the vertices know they will be needed at this level, if another - // triangle doesn't already need them sooner - for (size_t j = 0; j < 3; j++) { - if (vert_tri_minlevel[faces_array[3*i+j]] > level) { - vert_tri_minlevel[faces_array[3*i+j]] = level; - } - } - } - - // The vertices now know when they will first need to appear. Build level - // sets of vertices - for (size_t i = 0; i < vert_tri_minlevel.size(); i++) { - level_tri_verts[vert_tri_minlevel[i]].insert(i); - } - - // Having sorted the vertices into level sets, we may now define a new global - // vertex ordering that respects the needs of the levels. - tri_ind_map.reserve(vert_cnt); - for (size_t i = 0; i < vert_cnt; i++) { - tri_ind_map.push_back(i); - } - size_t vind = 0; - std::map>::iterator l_it; - std::unordered_set::iterator s_it; - for (l_it = level_tri_verts.begin(); l_it != level_tri_verts.end(); l_it++) { - for (s_it = l_it->second.begin(); s_it != l_it->second.end(); s_it++) { - tri_ind_map[*s_it] = vind; - vind++; - } - } - - // Beyond a certain depth, there is little benefit to the POP process. If - // we check the count of level_tris, we will find a level at which most of - // the triangles are active. - // TODO: Not clear yet when the tradeoff between memory and the work of LoD - // point snapping trades off - 0.66 is just a guess. We also need to - // calculate this maximum size ratio as a function of the overall database - // mesh data size, which will need to be passed in as a parameter - if the - // original is too large, we may not be able to fit higher LoD levels in - // the database and need to make this ratio smaller - probably a maximum of - // 0.66(?) and drop it lower of the original database is very large (i.e. - // we need to hold a lot of mesh data). - size_t trisum = 0; - if (max_face_ratio > 0.99 || max_face_ratio < 0) { - max_pop_threshold_level = level_tris.size() - 1; - } else { - size_t faces_array_cnt2 = (size_t)((fastf_t)faces_cnt * max_face_ratio); - for (size_t i = 0; i < level_tris.size(); i++) { - trisum += level_tris[i].size(); - if (trisum > faces_array_cnt2) { - // If we're using two thirds of the triangles, this is our - // threshold level. If we've got ALL the triangles, back - // down one level. - if (trisum < (size_t)faces_cnt) { - max_pop_threshold_level = i; - } else { - // Handle the case where we get i == 0 - max_pop_threshold_level = (i) ? i - 1 : 0; - } - break; - } - } - } - //bu_log("Max LoD POP level: %zd\n", max_pop_threshold_level); -} - -POPState::POPState(struct bg_mesh_lod_context *ctx, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, fastf_t pop_facecnt_threshold_ratio) -{ - // Store the context - c = ctx; - - // Caller set parameter telling us when to switch from POP data - // to just drawing the full mesh - max_face_ratio = pop_facecnt_threshold_ratio; - - // Hash the data to generate a key, if the user didn't supply us with one - if (!user_key) { - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - XXH64_update(&h_state, v, vcnt*sizeof(point_t)); - XXH64_update(&h_state, faces, 3*fcnt*sizeof(int)); - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - hash = (unsigned long long)hash_val; - } else { - hash = user_key; - } - - // Make sure there's no cache before performing the full initializing from - // the original data. In this mode the POPState creation is used to - // initialize the cache, not to create a workable data state from that - // data. The hash is set, which is all we really need - loading data from - // the cache is handled elsewhere. - void *cdata = NULL; - size_t csize = cache_get(&cdata, CACHE_POP_MAX_LEVEL); - if (csize && cdata) { - cache_done(); - is_valid = true; - return; - } - - // Cache isn't already populated - go to work. - cache_done(); - - curr_level = POP_MAXLEVEL - 1; - - // Precompute precision masks for each level - for (int i = 0; i < POP_MAXLEVEL; i++) { - PRECOMPUTED_MASKS.push_back(pow(2, (POP_MAXLEVEL - i - 1))); - } - - // Store source data info - vert_cnt = vcnt; - verts_array = v; - vnorms_array = vn; - faces_cnt = fcnt; - faces_array = faces; - - // Calculate the full mesh bounding box for later use - bg_trimesh_aabb(&bbmin, &bbmax, faces_array, faces_cnt, verts_array, vert_cnt); - - // Find our min and max values, initialize levels - for (size_t i = 0; i < vcnt; i++) { - minx = (v[i][X] < minx) ? v[i][X] : minx; - miny = (v[i][Y] < miny) ? v[i][Y] : miny; - minz = (v[i][Z] < minz) ? v[i][Z] : minz; - maxx = (v[i][X] > maxx) ? v[i][X] : maxx; - maxy = (v[i][Y] > maxy) ? v[i][Y] : maxy; - maxz = (v[i][Z] > maxz) ? v[i][Z] : maxz; - } - - // Bump out the min and max bounds slightly so none of our actual - // points are too close to these limits - minx = minx-fabs(MBUMP*minx); - miny = miny-fabs(MBUMP*miny); - minz = minz-fabs(MBUMP*minz); - maxx = maxx+fabs(MBUMP*maxx); - maxy = maxy+fabs(MBUMP*maxy); - maxz = maxz+fabs(MBUMP*maxz); - - // Characterize triangle faces - tri_process(); - - // We're now ready to write out the data - is_valid = true; - cache(); - - if (!is_valid) - return; - -#if 0 - for (size_t i = 0; i < POP_MAXLEVEL; i++) { - bu_log("bucket %zu count: %zu\n", i, level_tris[i].size()); - } - - for (size_t i = 0; i < POP_MAXLEVEL; i++) { - bu_log("vert %zu count: %zu\n", i, level_tri_verts[i].size()); - } -#endif -} - -POPState::POPState(struct bg_mesh_lod_context *ctx, unsigned long long key) -{ - // Store the context - c = ctx; - - if (!key) - return; - - // Initialize so set_level will read in the first level of triangles - curr_level = - 1; - - // Precompute precision masks for each level - for (int i = 0; i < POP_MAXLEVEL; i++) { - PRECOMPUTED_MASKS.push_back(pow(2, (POP_MAXLEVEL - i - 1))); - } - - hash = key; - - // Find the maximum POP level - { - const char *b = NULL; - size_t bsize = cache_get((void **)&b, CACHE_POP_MAX_LEVEL); - if (!bsize) { - cache_done(); - return; - } - if (bsize != sizeof(max_pop_threshold_level)) { - bu_log("Incorrect data size found loading max LoD POP threshold\n"); - cache_done(); - return; - } - memcpy(&max_pop_threshold_level, b, sizeof(max_pop_threshold_level)); - cache_done(); - } - - // Load the POP level where we switch from POP to full - { - const char *b = NULL; - size_t bsize = cache_get((void **)&b, CACHE_POP_SWITCH_LEVEL); - if (bsize && bsize != sizeof(max_face_ratio)) { - bu_log("Incorrect data size found loading LoD POP switch threshold\n"); - cache_done(); - return; - } - if (bsize) { - memcpy(&max_face_ratio, b, sizeof(max_face_ratio)); - } else { - max_face_ratio = 0.66; - } - cache_done(); - } - - // Load level counts for vectors and tris - { - const char *b = NULL; - size_t bsize = cache_get((void **)&b, CACHE_VERTEX_COUNT); - if (bsize != sizeof(level_vcnt)) { - bu_log("Incorrect data size found loading level vertex counts\n"); - cache_done(); - return; - } - memcpy(&level_vcnt, b, sizeof(level_vcnt)); - cache_done(); - } - { - const char *b = NULL; - size_t bsize = cache_get((void **)&b, CACHE_TRI_COUNT); - if (bsize != sizeof(level_tricnt)) { - bu_log("Incorrect data size found loading level triangle counts\n"); - cache_done(); - return; - } - memcpy(&level_tricnt, b, sizeof(level_tricnt)); - cache_done(); - } - - // Read in min/max bounds - { - float minmax[6]; - const char *b = NULL; - size_t bsize = cache_get((void **)&b, CACHE_OBJ_BOUNDS); - if (bsize != (sizeof(bbmin) + sizeof(bbmax) + sizeof(minmax))) { - bu_log("Incorrect data size found loading cached bounds data\n"); - cache_done(); - return; - } - memcpy(&bbmin, b, sizeof(bbmin)); - b += sizeof(bbmin); - memcpy(&bbmax, b, sizeof(bbmax)); - b += sizeof(bbmax); - //bu_log("bbmin: %f %f %f bbmax: %f %f %f\n", V3ARGS(bbmin), V3ARGS(bbmax)); - memcpy(&minmax, b, sizeof(minmax)); - minx = minmax[0]; - miny = minmax[1]; - minz = minmax[2]; - maxx = minmax[3]; - maxy = minmax[4]; - maxz = minmax[5]; - cache_done(); - } - - // Read in the zero level vertices, vertex normals (if defined) and triangles - set_level(0); - - // All set - ready for LoD - is_valid = 1; -} - -POPState::~POPState() -{ - if (full_detail_free_clbk) { - (*full_detail_free_clbk)(lod, detail_clbk_data); - detail_clbk_data = NULL; - } -} - -void -POPState::tri_pop_load(int start_level, int level) -{ - struct bu_vls kbuf = BU_VLS_INIT_ZERO; - - // Read in the level vertices - for (int i = start_level+1; i <= level; i++) { - if (!level_vcnt[i]) - continue; - bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERT_LEVEL, i); - fastf_t *b = NULL; - size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); - if (bsize != level_vcnt[i]*sizeof(point_t)) { - bu_log("Incorrect data size found loading level %d point data\n", i); - return; - } - lod_tri_pnts.insert(lod_tri_pnts.end(), &b[0], &b[level_vcnt[i]*3]); - cache_done(); - } - // Re-snap all vertices currently loaded at the new level - lod_tri_pnts_snapped.clear(); - lod_tri_pnts_snapped.reserve(lod_tri_pnts.size()); - for (size_t i = 0; i < lod_tri_pnts.size()/3; i++) { - point_t p, sp; - VSET(p, lod_tri_pnts[3*i+0], lod_tri_pnts[3*i+1], lod_tri_pnts[3*i+2]); - level_pnt(&sp, &p, level); - for (int k = 0; k < 3; k++) { - lod_tri_pnts_snapped.push_back(sp[k]); - } - } - - // Read in the level triangles - for (int i = start_level+1; i <= level; i++) { - if (!level_tricnt[i]) - continue; - bu_vls_sprintf(&kbuf, "%s%d", CACHE_TRI_LEVEL, i); - int *b = NULL; - size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); - if (bsize != level_tricnt[i]*3*sizeof(int)) { - bu_log("Incorrect data size found loading level %d tri data\n", i); - return; - } - lod_tris.insert(lod_tris.end(), &b[0], &b[level_tricnt[i]*3]); - cache_done(); - } - - // Read in the vertex normals, if we have them - for (int i = start_level+1; i <= level; i++) { - if (!level_tricnt[i]) - continue; - bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERTNORM_LEVEL, i); - fastf_t *b = NULL; - size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); - if (bsize > 0 && bsize != level_tricnt[i]*sizeof(vect_t)*3) { - bu_log("Incorrect data size found loading level %d normal data\n", i); - return; - } - if (bsize) { - lod_tri_norms.insert(lod_tri_norms.end(), &b[0], &b[level_tricnt[i]*3*3]); - } - cache_done(); - } -} - -void -POPState::shrink_memory() -{ - lod_tri_pnts.clear(); - lod_tri_pnts.shrink_to_fit(); - lod_tri_norms.clear(); - lod_tri_norms.shrink_to_fit(); - lod_tris.clear(); - lod_tris.shrink_to_fit(); - lod_tri_pnts_snapped.clear(); - lod_tri_pnts_snapped.shrink_to_fit(); -} - -void -POPState::tri_pop_trim(int level) -{ - // Tally all the lower level verts and tris - those are the ones we need to keep - size_t vkeep_cnt = 0; - size_t fkeep_cnt = 0; - for (size_t i = 0; i <= (size_t)level; i++) { - vkeep_cnt += level_vcnt[i]; - fkeep_cnt += level_tricnt[i]; - } - - // Shrink the main arrays (note that in C++11 shrink_to_fit may or may - // not actually shrink memory usage on any given call.) - lod_tri_pnts.resize(vkeep_cnt*3); - lod_tri_pnts.shrink_to_fit(); - lod_tri_norms.resize(fkeep_cnt*3*3); - lod_tri_norms.shrink_to_fit(); - lod_tris.resize(fkeep_cnt*3); - lod_tris.shrink_to_fit(); - - // Re-snap all vertices loaded at the new level - lod_tri_pnts_snapped.clear(); - lod_tri_pnts_snapped.reserve(lod_tri_pnts.size()); - for (size_t i = 0; i < lod_tri_pnts.size()/3; i++) { - point_t p, sp; - VSET(p, lod_tri_pnts[3*i+0], lod_tri_pnts[3*i+1], lod_tri_pnts[3*i+2]); - level_pnt(&sp, &p, level); - for (int k = 0; k < 3; k++) { - lod_tri_pnts_snapped.push_back(sp[k]); - } - } -} - -int -POPState::get_level(fastf_t vlen) -{ - fastf_t delta = 0.01*vlen; - point_t bmin, bmax; - fastf_t bdiag = 0; - VSET(bmin, minx, miny, minz); - VSET(bmax, maxx, maxy, maxz); - bdiag = DIST_PNT_PNT(bmin, bmax); - - // If all views are orthogonal we just need the diagonal of the bbox, but - // if we have any active perspective matrices that may change the answer. - // We need to provide as much detail as is required by the most demanding - // view. In principle we might also be able to back the LoD down further - // for very distant objects, but a quick test with that resulted in too much - // loss of detail so for now just look at the "need more" case. - struct bu_ptbl *vsets = (lod && lod->s) ? bv_set_views(lod->s->s_v->vset) : NULL; - if (!vsets) { - struct bview *v = (lod && lod->s) ? lod->s->s_v : NULL; - if (v && SMALL_FASTF < v->gv_perspective) { - fastf_t cdist = 0; - point_t pbmin, pbmax; - MAT4X3PNT(pbmin, v->gv_pmat, bmin); - MAT4X3PNT(pbmax, v->gv_pmat, bmax); - bdiag = DIST_PNT_PNT(pbmin, pbmax); - if (cdist > bdiag) - bdiag = cdist; - } - } else { - for (size_t i = 0; i < BU_PTBL_LEN(vsets); i++) { - fastf_t cdist = 0; - struct bview *cv = (struct bview *)BU_PTBL_GET(vsets, i); - if (!_obj_visible(lod->s, cv)) - continue; - if (SMALL_FASTF < cv->gv_perspective) { - point_t pbmin, pbmax; - MAT4X3PNT(pbmin, cv->gv_pmat, bmin); - MAT4X3PNT(pbmax, cv->gv_pmat, bmax); - cdist = DIST_PNT_PNT(pbmin, pbmax); - if (cdist > bdiag) - bdiag = cdist; - } - } - } - - for (int lev = 0; lev < POP_MAXLEVEL; lev++) { - fastf_t diag_slice = bdiag/pow(2,lev); - if (diag_slice < delta) { - return lev; - } - } - return POP_MAXLEVEL - 1; -} - -void -POPState::set_level(int level) -{ - // If we're already there and we're not undoing a memshrink, no work to do - if (level == curr_level && !force_update) - return; - - // If we're doing a forced update, it's like starting from - // scratch - reset to 0 - if (force_update) { - force_update = false; - set_level(0); - set_level(level); - } - - // int64_t start, elapsed; - // fastf_t seconds; - // start = bu_gettime(); - - // Triangles - - // If we need to pull more data, do so - if (level > curr_level && level <= max_pop_threshold_level) { - if (!lod_tri_pnts.size()) { - tri_pop_load(-1, level); - } else { - tri_pop_load(curr_level, level); - } - } - - // If we need to trim back the POP data, do that - if (level < curr_level && level <= max_pop_threshold_level && curr_level <= max_pop_threshold_level) { - if (!lod_tri_pnts.size()) { - tri_pop_load(-1, level); - } else { - tri_pop_trim(level); - } - } - - // If we were operating beyond POP detail levels (i.e. using RTree - // management) we need to reset our POP data and clear the more detailed - // info from the containers to free up memory. - if (level < curr_level && level <= max_pop_threshold_level && curr_level > max_pop_threshold_level) { - // We're (re)entering the POP range - clear the high detail data and start over - if (full_detail_clear_clbk) - (*full_detail_clear_clbk)(lod, detail_clbk_data); - - // Full reset, not an incremental load. - tri_pop_load(-1, level); - } - - // If we're jumping into details levels beyond POP range, clear the POP containers - // and load the more detailed data management info - if (level > curr_level && level > max_pop_threshold_level && curr_level <= max_pop_threshold_level) { - - // Clear the LoD data - we need the full set now - lod_tri_pnts_snapped.clear(); - lod_tri_pnts_snapped.shrink_to_fit(); - lod_tri_pnts.clear(); - lod_tri_pnts.shrink_to_fit(); - lod_tri_norms.clear(); - lod_tri_norms.shrink_to_fit(); - lod_tris.clear(); - lod_tris.shrink_to_fit(); - - // Use the callback to set up the full data pointers - if (full_detail_setup_clbk) - (*full_detail_setup_clbk)(lod, detail_clbk_data); - } - - //elapsed = bu_gettime() - start; - //seconds = elapsed / 1000000.0; - //bu_log("lod set_level(%d): %f sec\n", level, seconds); - - curr_level = level; -} - -// Rather than committing all data to LMDB in one transaction, use keys with -// appended strings to the hash to denote the individual pieces - basically -// what we were doing with files, but in the db instead -// -// This will also allow easier removal of larger subcomponents if we need to -// back off on saved LoD. -bool -POPState::cache_write(const char *component, std::stringstream &s) -{ - // Prepare inputs for writing - std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); - std::string buffer = s.str(); - - // As implemented this shouldn't be necessary, since all our keys are below - // the default size limit (511) - //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->i->lod_env)) - // return false; - - // Write out key/value to LMDB database, where the key is the hash - // and the value is the serialized LoD data - char *keycstr = bu_strdup(keystr.c_str()); - void *bdata = bu_calloc(buffer.length()+1, sizeof(char), "bdata"); - memcpy(bdata, buffer.data(), buffer.length()*sizeof(char)); - mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); - mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); - mdb_key.mv_size = keystr.length()*sizeof(char); - mdb_key.mv_data = (void *)keycstr; - mdb_data[0].mv_size = buffer.length()*sizeof(char); - mdb_data[0].mv_data = bdata; - mdb_data[1].mv_size = 0; - mdb_data[1].mv_data = NULL; - int rc = mdb_put(c->i->lod_txn, c->i->lod_dbi, &mdb_key, mdb_data, 0); - mdb_txn_commit(c->i->lod_txn); - bu_free(keycstr, "keycstr"); - bu_free(bdata, "buffer data"); - - return (!rc) ? true : false; -} - -// This pulls the data, but doesn't close the transaction because the -// calling code will want to manipulate the data. After that process -// is complete, cache_done() should be called to prepare for subsequent -// operations. -size_t -POPState::cache_get(void **data, const char *component) -{ - // Construct lookup key - std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); - - // As implemented this shouldn't be necessary, since all our keys are below - // the default size limit (511) - //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->i->lod_env)) - // return 0; - char *keycstr = bu_strdup(keystr.c_str()); - mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); - mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); - mdb_key.mv_size = keystr.length()*sizeof(char); - mdb_key.mv_data = (void *)keycstr; - int rc = mdb_get(c->i->lod_txn, c->i->lod_dbi, &mdb_key, &mdb_data[0]); - if (rc) { - bu_free(keycstr, "keycstr"); - (*data) = NULL; - return 0; - } - bu_free(keycstr, "keycstr"); - (*data) = mdb_data[0].mv_data; - - return mdb_data[0].mv_size; -} - -void -POPState::cache_done() -{ - mdb_txn_commit(c->i->lod_txn); -} - -bool -POPState::cache_tri() -{ - // Write out the threshold level - above this level, - // we need to switch to full-detail drawing - { - std::stringstream s; - s.write(reinterpret_cast(&max_pop_threshold_level), sizeof(max_pop_threshold_level)); - if (!cache_write(CACHE_POP_MAX_LEVEL, s)) - return false; - } - - // Write out the switch level - { - std::stringstream s; - s.write(reinterpret_cast(&max_face_ratio), sizeof(max_face_ratio)); - if (!cache_write(CACHE_POP_SWITCH_LEVEL, s)) - return false; - } - - // Write out the vertex counts for all active levels - { - std::stringstream s; - for (size_t i = 0; i <= POP_MAXLEVEL; i++) { - size_t icnt = 0; - if (level_tri_verts.find(i) == level_tri_verts.end()) { - s.write(reinterpret_cast(&icnt), sizeof(icnt)); - continue; - } - if ((int)i > max_pop_threshold_level || !level_tri_verts[i].size()) { - s.write(reinterpret_cast(&icnt), sizeof(icnt)); - continue; - } - icnt = level_tri_verts[i].size(); - s.write(reinterpret_cast(&icnt), sizeof(icnt)); - } - if (!cache_write(CACHE_VERTEX_COUNT, s)) - return false; - } - - // Write out the triangle counts for all active levels - { - std::stringstream s; - for (size_t i = 0; i <= POP_MAXLEVEL; i++) { - size_t tcnt = 0; - if ((int)i > max_pop_threshold_level || !level_tris[i].size()) { - s.write(reinterpret_cast(&tcnt), sizeof(tcnt)); - continue; - } - // Store the size of the level tri vector - tcnt = level_tris[i].size(); - s.write(reinterpret_cast(&tcnt), sizeof(tcnt)); - } - if (!cache_write(CACHE_TRI_COUNT, s)) - return false; - } - - struct bu_vls kbuf = BU_VLS_INIT_ZERO; - - // Write out the vertices in LoD order for each level - { - for (int i = 0; i <= max_pop_threshold_level; i++) { - std::stringstream s; - if (level_tri_verts.find(i) == level_tri_verts.end()) - continue; - if (!level_tri_verts[i].size()) - continue; - // Write out the vertex points - std::unordered_set::iterator s_it; - for (s_it = level_tri_verts[i].begin(); s_it != level_tri_verts[i].end(); s_it++) { - point_t v; - VMOVE(v, verts_array[*s_it]); - s.write(reinterpret_cast(&v[0]), sizeof(point_t)); - } - bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERT_LEVEL, i); - if (!cache_write(bu_vls_cstr(&kbuf), s)) - return false; - } - } - - // Write out the triangles in LoD order for each level - { - for (int i = 0; i <= max_pop_threshold_level; i++) { - std::stringstream s; - if (!level_tris[i].size()) - continue; - // Write out the mapped triangle indices - std::vector::iterator s_it; - for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { - int vt[3]; - vt[0] = (int)tri_ind_map[faces_array[3*(*s_it)+0]]; - vt[1] = (int)tri_ind_map[faces_array[3*(*s_it)+1]]; - vt[2] = (int)tri_ind_map[faces_array[3*(*s_it)+2]]; - s.write(reinterpret_cast(&vt[0]), sizeof(vt)); - } - bu_vls_sprintf(&kbuf, "%s%d", CACHE_TRI_LEVEL, i); - if (!cache_write(bu_vls_cstr(&kbuf), s)) - return false; - } - } - - // Write out the vertex normals in LoD order for each level, if we have them - { - if (vnorms_array) { - for (int i = 0; i <= max_pop_threshold_level; i++) { - std::stringstream s; - if (!level_tris[i].size()) - continue; - // Write out the normals associated with the triangle indices - std::vector::iterator s_it; - for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { - vect_t v; - int tind; - tind = 3*(*s_it)+0; - VMOVE(v, vnorms_array[tind]); - s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); - tind = 3*(*s_it)+1; - VMOVE(v, vnorms_array[tind]); - s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); - tind = 3*(*s_it)+2; - VMOVE(v, vnorms_array[tind]); - s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); - } - bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERTNORM_LEVEL, i); - if (!cache_write(bu_vls_cstr(&kbuf), s)) - return false; - } - } - } - - - return true; -} - -// Write out the generated LoD data to the BRL-CAD cache -void -POPState::cache() -{ - if (!hash) { - is_valid = false; - return; - } - - // Stash the original mesh bbox and the min and max bounds, which will be used in decoding - { - std::stringstream s; - s.write(reinterpret_cast(&bbmin), sizeof(bbmin)); - s.write(reinterpret_cast(&bbmax), sizeof(bbmax)); - s.write(reinterpret_cast(&minx), sizeof(minx)); - s.write(reinterpret_cast(&miny), sizeof(miny)); - s.write(reinterpret_cast(&minz), sizeof(minz)); - s.write(reinterpret_cast(&maxx), sizeof(maxx)); - s.write(reinterpret_cast(&maxy), sizeof(maxy)); - s.write(reinterpret_cast(&maxz), sizeof(maxz)); - is_valid = cache_write(CACHE_OBJ_BOUNDS, s); - } - - if (!is_valid) - return; - - // Serialize triangle-specific data - is_valid = cache_tri(); -} - -// Transfer coordinate into level precision -int -POPState::to_level(int val, int level) -{ - int ret = floor(val/double(PRECOMPUTED_MASKS[level])); - //bu_log("to_level: %d, %d : %d\n", val, level, ret); - return ret; -} - -fastf_t -POPState::snap(fastf_t val, fastf_t min, fastf_t max, int level) -{ - unsigned int vf = floor((val - min) / (max - min) * USHRT_MAX); - int lv = floor(vf/double(PRECOMPUTED_MASKS[level])); - unsigned int vc = ceil((val - min) / (max - min) * USHRT_MAX); - int hc = ceil(vc/double(PRECOMPUTED_MASKS[level])); - fastf_t v = ((fastf_t)lv + (fastf_t)hc)*0.5 * double(PRECOMPUTED_MASKS[level]); - fastf_t vs = ((v / USHRT_MAX) * (max - min)) + min; - return vs; -} - -// Transfer coordinate into level-appropriate value -void -POPState::level_pnt(point_t *o, const point_t *p, int level) -{ - fastf_t nx = snap((*p)[X], minx, maxx, level); - fastf_t ny = snap((*p)[Y], miny, maxy, level); - fastf_t nz = snap((*p)[Z], minz, maxz, level); - VSET(*o, nx, ny, nz); -#if 0 - double poffset = DIST_PNT_PNT(*o, *p); - if (poffset > (maxx - minx) && poffset > (maxy - miny) && poffset > (maxz - minz)) { - bu_log("Error: %f %f %f -> %f %f %f\n", V3ARGS(*p), V3ARGS(*o)); - bu_log("bound: %f %f %f -> %f %f %f\n", minx, miny, minz, maxx, maxy, maxz); - } -#endif -} - -// Compares two coordinates for equality (on a given precision level) -bool -POPState::is_equal(rec r1, rec r2, int level) -{ - bool tl_x = (to_level(r1.x, level) == to_level(r2.x, level)); - bool tl_y = (to_level(r1.y, level) == to_level(r2.y, level)); - bool tl_z = (to_level(r1.z, level) == to_level(r2.z, level)); - return (tl_x && tl_y && tl_z); -} - -// Checks whether a triangle is degenerate (at least two coordinates are the -// same on the given precision level) -bool -POPState::tri_degenerate(rec r0, rec r1, rec r2, int level) -{ - return is_equal(r0, r1, level) || is_equal(r1, r2, level) || is_equal(r0, r2, level); -} - -void -POPState::plot(const char *root) -{ - if (curr_level < 0) - return; - - struct bu_vls name = BU_VLS_INIT_ZERO; - FILE *plot_file = NULL; - bu_vls_init(&name); - if (!root) { - bu_vls_sprintf(&name, "init_tris_level_%.2d.plot3", curr_level); - } else { - bu_vls_sprintf(&name, "%s_tris_level_%.2d.plot3", root, curr_level); - } - plot_file = fopen(bu_vls_addr(&name), "wb"); - - if (curr_level <= max_pop_threshold_level) { - pl_color(plot_file, 0, 255, 0); - - for (int i = 0; i <= curr_level; i++) { - std::vector::iterator s_it; - for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { - size_t f_ind = *s_it; - int v1ind, v2ind, v3ind; - if (faces_array) { - v1ind = faces_array[3*f_ind+0]; - v2ind = faces_array[3*f_ind+1]; - v3ind = faces_array[3*f_ind+2]; - } else { - v1ind = lod_tris[3*f_ind+0]; - v2ind = lod_tris[3*f_ind+1]; - v3ind = lod_tris[3*f_ind+2]; - } - point_t p1, p2, p3, o1, o2, o3; - if (verts_array) { - VMOVE(p1, verts_array[v1ind]); - VMOVE(p2, verts_array[v2ind]); - VMOVE(p3, verts_array[v3ind]); - } else { - VSET(p1, lod_tri_pnts[3*v1ind+0], lod_tri_pnts[3*v1ind+1], lod_tri_pnts[3*v1ind+2]); - VSET(p2, lod_tri_pnts[3*v2ind+0], lod_tri_pnts[3*v2ind+1], lod_tri_pnts[3*v2ind+2]); - VSET(p3, lod_tri_pnts[3*v3ind+0], lod_tri_pnts[3*v3ind+1], lod_tri_pnts[3*v3ind+2]); - } - // We iterate over the level i triangles, but our target level is - // curr_level so we "decode" the points to that level, NOT level i - level_pnt(&o1, &p1, curr_level); - level_pnt(&o2, &p2, curr_level); - level_pnt(&o3, &p3, curr_level); - pdv_3move(plot_file, o1); - pdv_3cont(plot_file, o2); - pdv_3cont(plot_file, o3); - pdv_3cont(plot_file, o1); - } - } - - } else { - for (size_t i = 0; i < lod_tris.size() / 3; i++) { - int v1ind, v2ind, v3ind; - point_t p1, p2, p3; - v1ind = lod_tris[3*i+0]; - v2ind = lod_tris[3*i+1]; - v3ind = lod_tris[3*i+2]; - VSET(p1, lod_tri_pnts[3*v1ind+0], lod_tri_pnts[3*v1ind+1], lod_tri_pnts[3*v1ind+2]); - VSET(p2, lod_tri_pnts[3*v2ind+0], lod_tri_pnts[3*v2ind+1], lod_tri_pnts[3*v2ind+2]); - VSET(p3, lod_tri_pnts[3*v3ind+0], lod_tri_pnts[3*v3ind+1], lod_tri_pnts[3*v3ind+2]); - pdv_3move(plot_file, p1); - pdv_3cont(plot_file, p2); - pdv_3cont(plot_file, p3); - pdv_3cont(plot_file, p1); - } - } - - fclose(plot_file); - - bu_vls_free(&name); -} - - -extern "C" unsigned long long -bg_mesh_lod_cache(struct bg_mesh_lod_context *c, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, double fratio) -{ - unsigned long long key = 0; - - if (!v || !vcnt || !faces || !fcnt) - return 0; - - POPState p(c, v, vcnt, vn, faces, fcnt, user_key, fratio); - if (!p.is_valid) - return 0; - - key = p.hash; - - return key; -} - - -extern "C" unsigned long long -bg_mesh_lod_custom_key(void *data, size_t data_size) -{ - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - XXH64_update(&h_state, data, data_size); - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - return hash; -} - - -extern "C" struct bv_mesh_lod * -bg_mesh_lod_create(struct bg_mesh_lod_context *c, unsigned long long key) -{ - if (!key) - return NULL; - - POPState *p = new POPState(c, key); - if (!p) - return NULL; - - if (!p->is_valid) { - delete p; - return NULL; - } - - // Set up info container - struct bv_mesh_lod *lod; - BU_GET(lod, struct bv_mesh_lod); - BU_GET(lod->i, struct bg_mesh_lod_internal); - ((struct bg_mesh_lod_internal *)lod->i)->s = p; - lod->c = (void *)c; - p->lod = lod; - - // Important - parent codes need to have a sense of the size of - // the object, and we want that size to be consistent regardless - // of the LoD actually in use. Set the bbox dimensions at a level - // where external codes can see and use them. - VMOVE(lod->bmin, p->bbmin); - VMOVE(lod->bmax, p->bbmax); - - return lod; -} - -extern "C" void -bg_mesh_lod_destroy(struct bv_mesh_lod *lod) -{ - if (!lod) - return; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)lod->i; - delete i->s; - i->s = NULL; - BU_PUT(i, struct bg_mesh_lod_internal); - lod->i = NULL; - BU_PUT(lod, struct bv_mesh_lod); -} - -static void -dlist_stale(struct bv_scene_obj *s) -{ - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(&s->children, i); - dlist_stale(cg); - } - s->s_dlist_stale = 1; -} - -extern "C" int -bg_mesh_lod_level(struct bv_scene_obj *s, int level, int reset) -{ - if (!s) - return -1; - - struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)l->i; - POPState *sp = i->s; - if (level < 0) - return sp->curr_level; - - - int old_level = sp->curr_level; - - sp->force_update = (reset) ? true : false; - sp->set_level(level); - - // If we're in POP territory use the local arrays - otherwise, they - // were already set by the full detail callback. - if (sp->curr_level <= sp->max_pop_threshold_level) { - l->fcnt = (int)sp->lod_tris.size()/3; - l->faces = sp->lod_tris.data(); - l->points_orig = (const point_t *)sp->lod_tri_pnts.data(); - l->porig_cnt = (int)sp->lod_tri_pnts.size(); -#if 0 - // TODO - there's still some error with normals - they seem to work, - // but when zooming way out and back in (at least on Windows) we're - // getting an access violation with some geometry... - if (sp->lod_tri_norms.size() >= sp->lod_tris.size()) { - l->normals = (const vect_t *)sp->lod_tri_norms.data(); - } else { - l->normals = NULL; - } -#else - l->normals = NULL; -#endif - l->points = (const point_t *)sp->lod_tri_pnts_snapped.data(); - l->pcnt = (int)sp->lod_tri_pnts_snapped.size(); - } - - // If the data changed, any Display List we may have previously generated - // is now obsolete - if (old_level != sp->curr_level) - dlist_stale(s); - - return sp->curr_level; -} - - -extern "C" int -bg_mesh_lod_view(struct bv_scene_obj *s, struct bview *v, int reset) -{ - if (!s || !v) - return -1; - struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; - if (!l) - return -1; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)l->i; - POPState *sp = i->s; - int ret = sp->curr_level; - int vscale = (int)((double)sp->get_level(v->gv_size) * v->gv_s->lod_scale); - vscale = (vscale < 0) ? 0 : vscale; - vscale = (vscale >= POP_MAXLEVEL) ? POP_MAXLEVEL-1 : vscale; - - // If the object is not visible in the scene, don't change the data - //bu_log("min: %f %f %f max: %f %f %f\n", V3ARGS(s->bmin), V3ARGS(s->bmax)); - if (_obj_visible(s, v)) - ret = bg_mesh_lod_level(s, vscale, reset); - - return ret; -} - -extern "C" void -bg_mesh_lod_memshrink(struct bv_scene_obj *s) -{ - if (!s) - return; - struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; - if (!l) - return; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)l->i; - POPState *sp = i->s; - sp->shrink_memory(); - bu_log("memshrink\n"); -} - -static void -bg_clear(const char *d) -{ - if (bu_file_directory(d)) { - char **filenames; - size_t nfiles = bu_file_list(d, "*", &filenames); - for (size_t i = 0; i < nfiles; i++) { - if (BU_STR_EQUAL(filenames[i], ".")) - continue; - if (BU_STR_EQUAL(filenames[i], "..")) - continue; - char cdir[MAXPATHLEN] = {0}; - bu_dir(cdir, MAXPATHLEN, d, filenames[i], NULL); - bg_clear((const char *)cdir); - } - bu_argv_free(nfiles, filenames); - } - bu_file_delete(d); -} - -static void -cache_del(struct bg_mesh_lod_context *c, unsigned long long hash, const char *component) -{ - // Construct lookup key - MDB_val mdb_key; - std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); - - mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); - mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); - mdb_key.mv_size = keystr.length()*sizeof(char); - mdb_key.mv_data = (void *)keystr.c_str(); - mdb_del(c->i->lod_txn, c->i->lod_dbi, &mdb_key, NULL); - mdb_txn_commit(c->i->lod_txn); -} - - -extern "C" void -bg_mesh_lod_clear_cache(struct bg_mesh_lod_context *c, unsigned long long key) -{ - char dir[MAXPATHLEN]; - - if (c && key) { - // For this case, we're clearing the data associated with a - // specific key (for example, if we're about to edit a BoT but - // don't want to redo the whole database's cache. - cache_del(c, key, CACHE_POP_MAX_LEVEL); - cache_del(c, key, CACHE_POP_SWITCH_LEVEL); - cache_del(c, key, CACHE_VERTEX_COUNT); - cache_del(c, key, CACHE_TRI_COUNT); - cache_del(c, key, CACHE_OBJ_BOUNDS); - cache_del(c, key, CACHE_VERT_LEVEL); - cache_del(c, key, CACHE_VERTNORM_LEVEL); - cache_del(c, key, CACHE_TRI_LEVEL); - - // Iterate over the name/key mapper, removing anything with a value - // of key - MDB_val mdb_key, mdb_data; - unsigned long long *fkeyp = NULL; - unsigned long long fkey = 0; - mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); - mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); - MDB_cursor *cursor; - int rc = mdb_cursor_open(c->i->name_txn, c->i->name_dbi, &cursor); - if (rc) { - mdb_txn_commit(c->i->name_txn); - return; - } - rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); - if (rc) { - mdb_txn_commit(c->i->name_txn); - return; - } - fkeyp = (unsigned long long *)mdb_data.mv_data; - fkey = *fkeyp; - if (fkey == key) - mdb_cursor_del(cursor, 0); - while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) { - fkeyp = (unsigned long long *)mdb_data.mv_data; - fkey = *fkeyp; - if (fkey == key) - mdb_cursor_del(cursor, 0); - } - mdb_txn_commit(c->i->name_txn); - return; - } - - if (c && !key) { - - MDB_val mdb_key, mdb_data; - MDB_cursor *cursor; - int rc; - - // Clear the actual LoD data - mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); - mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); - rc = mdb_cursor_open(c->i->lod_txn, c->i->lod_dbi, &cursor); - if (rc) { - mdb_txn_commit(c->i->lod_txn); - return; - } - rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); - if (rc) { - mdb_txn_commit(c->i->lod_txn); - return; - } - mdb_cursor_del(cursor, 0); - while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) - mdb_cursor_del(cursor, 0); - mdb_txn_commit(c->i->lod_txn); - - // Iterate over the name/key mapper, removing anything with a value - // of key - mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); - mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); - rc = mdb_cursor_open(c->i->name_txn, c->i->name_dbi, &cursor); - if (rc) { - mdb_txn_commit(c->i->name_txn); - return; - } - rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); - if (rc) { - mdb_txn_commit(c->i->name_txn); - return; - } - mdb_cursor_del(cursor, 0); - while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) - mdb_cursor_del(cursor, 0); - mdb_txn_commit(c->i->name_txn); - - return; - } - - // Clear everything - bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, NULL); - bg_clear((const char *)dir); -} - -extern "C" void -bg_mesh_lod_detail_setup_clbk( - struct bv_mesh_lod *lod, - int (*clbk)(struct bv_mesh_lod *, void *), - void *clbk_data - ) -{ - if (!lod || !clbk) - return; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)lod->i; - POPState *s = i->s; - s->full_detail_setup_clbk = clbk; - s->detail_clbk_data = clbk_data; -} - -extern "C" void -bg_mesh_lod_detail_clear_clbk( - struct bv_mesh_lod *lod, - int (*clbk)(struct bv_mesh_lod *, void *) - ) -{ - if (!lod || !clbk) - return; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)lod->i; - POPState *s = i->s; - s->full_detail_clear_clbk = clbk; -} - -extern "C" void -bg_mesh_lod_detail_free_clbk( - struct bv_mesh_lod *lod, - int (*clbk)(struct bv_mesh_lod *, void *) - ) -{ - if (!lod || !clbk) - return; - - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)lod->i; - POPState *s = i->s; - s->full_detail_free_clbk = clbk; -} - -void -bg_mesh_lod_free(struct bv_scene_obj *s) -{ - if (!s || !s->draw_data) - return; - struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; - struct bg_mesh_lod_internal *i = (struct bg_mesh_lod_internal *)l->i; - delete i->s; - s->draw_data = NULL; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libbg/polygon.c b/src/libbg/polygon.c index 7159aa6b349..9e34bbecd94 100644 --- a/src/libbg/polygon.c +++ b/src/libbg/polygon.c @@ -25,6 +25,7 @@ #include "bu/malloc.h" #include "bu/sort.h" #include "bg/plane.h" +#define PLOT3_IMPLEMENTATION #include "bv/plot3.h" #include "bn/tol.h" #include "bg/polygon.h" @@ -61,6 +62,36 @@ bg_polygons_free(struct bg_polygons *gpp) gpp->num_polygons = 0; } +void +bg_polygon_view_bbox(point2d_t *bmin, point2d_t *bmax, struct bg_polygon *p, matp_t model2view) +{ + if (!bmin || !bmax || !p) + return; + + // Initialize + V2SET(*bmin, INFINITY, INFINITY); + V2SET(*bmax, -INFINITY, -INFINITY); + + if (!p->num_contours || !p->contour) + return; + + // NOTE: Holes don't define positive area, so their points are not + // considered for the bbox dimensions even if they are outside the positive + // contours. ONLY considering positive contour points. + for (size_t i = 0; i < p->num_contours; i++) { + struct bg_poly_contour *c = &p->contour[i]; + if (!c->num_points) + continue; + for (size_t j = 0; j < c->num_points; j++) { + point_t vpoint; + MAT4X3PNT(vpoint, model2view, c->point[j]); + point2d_t v2d; + v2d[0] = vpoint[0]; + v2d[1] = vpoint[1]; + V2MINMAX(*bmin, *bmax, v2d); + } + } +} int bg_3d_polygon_area(fastf_t *area, size_t npts, const point_t *pts) diff --git a/src/libbg/polygon_bview.c b/src/libbg/polygon_bview.c deleted file mode 100644 index bc85d2bce42..00000000000 --- a/src/libbg/polygon_bview.c +++ /dev/null @@ -1,900 +0,0 @@ -/* P O L Y G O N _ B V I E W . C - * BRL-CAD - * - * Copyright (c) 2020-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file polygons.c - * - * Utility functions for working with polygons in a bv context. - * - */ - -#include "common.h" -#include -#include "vmath.h" -#include "bu/log.h" -#include "bu/malloc.h" -#include "bu/str.h" -#include "bn/mat.h" -#include "bn/tol.h" -#include "bv/vlist.h" -#include "bv/defines.h" -#include "bv/util.h" -#include "bg/lseg.h" -#include "bg/plane.h" -#include "bg/polygon.h" - -void -bv_polygon_contour(struct bv_scene_obj *s, struct bg_poly_contour *c, int curr_c, int curr_i, int do_pnt) -{ - if (!s || !c || !s->s_v) - return; - - if (do_pnt) { - BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[0], BV_VLIST_POINT_DRAW); - return; - } - - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, c->point[0], BV_VLIST_LINE_MOVE); - for (size_t i = 0; i < c->num_points; i++) { - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, c->point[i], BV_VLIST_LINE_DRAW); - } - if (!c->open) - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, c->point[0], BV_VLIST_LINE_DRAW); - - if (curr_c && curr_i >= 0) { - point_t psize; - VSET(psize, 10, 0, 0); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, c->point[curr_i], BV_VLIST_LINE_MOVE); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, psize, BV_VLIST_POINT_SIZE); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, c->point[curr_i], BV_VLIST_POINT_DRAW); - } -} - -void -bv_fill_polygon(struct bv_scene_obj *s) -{ - if (!s) - return; - - // free old fill, if present - struct bv_scene_obj *fobj = bv_find_child(s, "*fill*"); - if (fobj) - bv_obj_put(fobj); - - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - if (p->polygon.contour[0].open) { - return; - } - if (p->fill_delta < BN_TOL_DIST) { - return; - } - - struct bg_polygon *fill = bg_polygon_fill_segments(&p->polygon, p->fill_dir, p->fill_delta); - if (!fill) - return; - - // Got fill, create lines - fobj = bv_obj_get_child(s); - bu_vls_printf(&fobj->s_uuid, ":fill"); - fobj->s_os->s_line_width = 1; - fobj->s_soldash = 0; - bu_color_to_rgb_chars(&p->fill_color, fobj->s_color); - for (size_t i = 0; i < fill->num_contours; i++) { - bv_polygon_contour(fobj, &fill->contour[i], 0, -1, 0); - } -} - -void -bv_polygon_vlist(struct bv_scene_obj *s) -{ - if (!s) - return; - - // Reset obj drawing data, but keep view - struct bview *v = s->s_v; - bv_obj_reset(s); - s->s_v = v; - - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - int type = p->type; - - for (size_t i = 0; i < p->polygon.num_contours; ++i) { - /* Draw holes using segmented lines. Since vlists don't have a style - * command for that, we make child scene objects for the holes. */ - size_t pcnt = p->polygon.contour[i].num_points; - int do_pnt = 0; - if (pcnt == 1) - do_pnt = 1; - if (type == BV_POLYGON_CIRCLE && pcnt == 3) - do_pnt = 1; - if (type == BV_POLYGON_ELLIPSE && pcnt == 4) - do_pnt = 1; - if (type == BV_POLYGON_RECTANGLE) { - if (NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[1]), SMALL_FASTF) && - NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[2]), SMALL_FASTF)) - do_pnt = 1; - } - if (type == BV_POLYGON_SQUARE) { - if (NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[1]), SMALL_FASTF) && - NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[2]), SMALL_FASTF)) - do_pnt = 1; - } - - if (p->polygon.hole[i]) { - struct bv_scene_obj *s_c = bv_obj_get_child(s); - s_c->s_soldash = 1; - s_c->s_color[0] = s->s_color[0]; - s_c->s_color[1] = s->s_color[1]; - s_c->s_color[2] = s->s_color[2]; - s_c->s_v = s->s_v; - bv_polygon_contour(s_c, &p->polygon.contour[i], ((int)i == p->curr_contour_i), p->curr_point_i, do_pnt); - bu_ptbl_ins(&s->children, (long *)s_c); - continue; - } - - bv_polygon_contour(s, &p->polygon.contour[i], ((int)i == p->curr_contour_i), p->curr_point_i, do_pnt); - } - - if (p->fill_flag) { - bv_fill_polygon(s); - } - -} - -struct bv_scene_obj * -bv_create_polygon_obj(struct bview *v, struct bv_polygon *p) -{ - struct bv_scene_obj *s = bv_obj_get(v, BV_VIEW_OBJS); - s->s_type_flags |= BV_POLYGONS; - - // Save the current view for later processing - bv_sync(&p->v, s->s_v); - - s->s_os->s_line_width = 1; - s->s_color[0] = 255; - s->s_color[1] = 255; - s->s_color[2] = 0; - s->s_i_data = (void *)p; - s->s_update_callback = &bv_update_polygon; - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* updated */ - s->s_changed++; - - return s; -} - -struct bv_scene_obj * -bv_create_polygon(struct bview *v, int type, int x, int y) -{ - - struct bv_polygon *p; - BU_GET(p, struct bv_polygon); - p->type = type; - p->curr_contour_i = -1; - p->curr_point_i = -1; - - // Set default fill color to blue - unsigned char frgb[3] = {0, 0, 255}; - bu_color_from_rgb_chars(&p->fill_color, frgb); - - // Let the view know these are now the previous x,y points - v->gv_prevMouseX = x; - v->gv_prevMouseY = y; - - // If snapping is active, handle it - fastf_t fx, fy; - if (bv_screen_to_view(v, &fx, &fy, x, y) < 0) { - BU_PUT(p, struct bv_polygon); - return NULL; - } - int snapped = 0; - if (v->gv_s) { - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - } - - point_t v_pt, m_pt; - if (v->gv_s) { - VSET(v_pt, fx, fy, v->gv_data_vZ); - } else { - VSET(v_pt, fx, fy, 0); - } - MAT4X3PNT(m_pt, v->gv_view2model, v_pt); - VMOVE(p->prev_point, v_pt); - - int pcnt = 1; - if (type == BV_POLYGON_CIRCLE) - pcnt = 3; - if (type == BV_POLYGON_ELLIPSE) - pcnt = 4; - if (type == BV_POLYGON_RECTANGLE) - pcnt = 4; - if (type == BV_POLYGON_SQUARE) - pcnt = 4; - - p->polygon.num_contours = 1; - p->polygon.hole = (int *)bu_calloc(1, sizeof(int), "hole"); - p->polygon.contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); - p->polygon.contour[0].num_points = pcnt; - p->polygon.contour[0].open = 0; - p->polygon.contour[0].point = (point_t *)bu_calloc(pcnt, sizeof(point_t), "point"); - p->polygon.hole[0] = 0; - for (int i = 0; i < pcnt; i++) { - VMOVE(p->polygon.contour[0].point[i], m_pt); - } - - // Only the general polygon isn't closed out of the gate - if (type == BV_POLYGON_GENERAL) - p->polygon.contour[0].open = 1; - - // Have polygon, now make scene object - struct bv_scene_obj *s = bv_create_polygon_obj(v, p); - if (!s) - BU_PUT(p, struct bv_polygon); - return s; -} - -int -bv_append_polygon_pt(struct bv_scene_obj *s) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - if (p->type != BV_POLYGON_GENERAL) - return -1; - - if (p->curr_contour_i < 0) - return -1; - - fastf_t fx, fy; - - struct bview *v = s->s_v; - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - point_t v_pt; - VSET(v_pt, fx, fy, v->gv_data_vZ); - - struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; - c->num_points++; - c->point = (point_t *)bu_realloc(c->point,c->num_points * sizeof(point_t), "realloc contour points"); - // Use the polygon's view context for actually adding the point - MAT4X3PNT(c->point[c->num_points-1], p->v.gv_view2model, v_pt); - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 0; -} - -// NOTE: This is a naive brute force search for the closest edge at the -// moment... Would be better for repeated sampling of relatively static -// scenes to build an RTree first... -struct bv_scene_obj * -bv_select_polygon(struct bu_ptbl *objs, struct bview *v) -{ - if (!objs) - return NULL; - - fastf_t fx, fy; - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - point_t v_pt, m_pt; - VSET(v_pt, fx, fy, v->gv_data_vZ); - MAT4X3PNT(m_pt, v->gv_view2model, v_pt); - - struct bv_scene_obj *closest = NULL; - double dist_min_sq = DBL_MAX; - - for (size_t i = 0; i < BU_PTBL_LEN(objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(objs, i); - if (s->s_type_flags & BV_POLYGONS) { - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - for (size_t j = 0; j < p->polygon.num_contours; j++) { - struct bg_poly_contour *c = &p->polygon.contour[j]; - for (size_t k = 0; k < c->num_points; k++) { - double dcand; - if (k < c->num_points - 1) { - dcand = bg_distsq_lseg3_pt(NULL, c->point[k], c->point[k+1], m_pt); - } else { - dcand = bg_distsq_lseg3_pt(NULL, c->point[k], c->point[0], m_pt); - } - if (dcand < dist_min_sq) { - dist_min_sq = dcand; - closest = s; - } - } - } - } - } - - return closest; -} - -int -bv_select_polygon_pt(struct bv_scene_obj *s) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - if (p->type != BV_POLYGON_GENERAL) - return -1; - - fastf_t fx, fy; - - struct bview *v = s->s_v; - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - point_t v_pt, m_pt; - VSET(v_pt, fx, fy, v->gv_data_vZ); - MAT4X3PNT(m_pt, v->gv_view2model, v_pt); - - - // If a contour is selected, restrict our closest point candidates to - // that contour's points - double dist_min_sq = DBL_MAX; - long closest_ind = -1; - long closest_contour = -1; - if (p->curr_contour_i >= 0) { - struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; - closest_contour = p->curr_contour_i; - for (size_t i = 0; i < c->num_points; i++) { - double dcand = DIST_PNT_PNT_SQ(c->point[i], m_pt); - if (dcand < dist_min_sq) { - closest_ind = (long)i; - dist_min_sq = dcand; - } - } - } else { - for (size_t j = 0; j < p->polygon.num_contours; j++) { - struct bg_poly_contour *c = &p->polygon.contour[j]; - for (size_t i = 0; i < c->num_points; i++) { - double dcand = DIST_PNT_PNT_SQ(c->point[i], m_pt); - if (dcand < dist_min_sq) { - closest_ind = (long)i; - closest_contour = (long)j; - dist_min_sq = dcand; - } - } - } - } - - p->curr_point_i = closest_ind; - p->curr_contour_i = closest_contour; - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 0; -} - -int -bv_move_polygon(struct bv_scene_obj *s) -{ - fastf_t pfx, pfy, fx, fy; - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - struct bview *v = s->s_v; - if (bv_screen_to_view(v, &pfx, &pfy, v->gv_prevMouseX, v->gv_prevMouseY) < 0) - return 0; - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - fastf_t dx = fx - pfx; - fastf_t dy = fy - pfy; - - point_t v_pt, m_pt; - VSET(v_pt, dx, dy, v->gv_data_vZ); - // Use the polygon's view context for actually moving the point - MAT4X3PNT(m_pt, p->v.gv_view2model, v_pt); - - for (size_t j = 0; j < p->polygon.num_contours; j++) { - struct bg_poly_contour *c = &p->polygon.contour[j]; - for (size_t i = 0; i < c->num_points; i++) { - VADD2(c->point[i], c->point[i], m_pt); - } - } - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - // Shift the previous point so updates will start from the - // correct point. - p->prev_point[0] = p->prev_point[0]+dx; - p->prev_point[1] = p->prev_point[1]+dy; - - /* Updated */ - s->s_changed++; - - return 0; -} - -int -bv_move_polygon_pt(struct bv_scene_obj *s) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - if (p->type != BV_POLYGON_GENERAL) - return -1; - - // Need to have a point selected before we can move - if (p->curr_point_i < 0 || p->curr_contour_i < 0) - return -1; - - fastf_t fx, fy; - - struct bview *v = s->s_v; - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - point_t v_pt, m_pt; - VSET(v_pt, fx, fy, v->gv_data_vZ); - // Use the polygon's view context for actually moving the point - MAT4X3PNT(m_pt, p->v.gv_view2model, v_pt); - - struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; - VMOVE(c->point[p->curr_point_i], m_pt); - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 0; -} - -/* Oof. Followed the logic down the chain to_poly_circ_mode_func -> - * to_data_polygons_func -> to_extract_contours_av to get what are hopefully - * all the pieces needed to seed a circle at an XY point. */ - -int -bv_update_polygon_circle(struct bv_scene_obj *s, struct bview *v) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - fastf_t curr_fx, curr_fy; - fastf_t fx, fy; - fastf_t r, arc; - int nsegs, n; - point_t v_pt; - vect_t vdiff; - - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - VSET(v_pt, fx, fy, v->gv_data_vZ); - VSUB2(vdiff, v_pt, p->prev_point); - r = MAGNITUDE(vdiff); - - /* use a variable number of segments based on the size of the - * circle being created so small circles have few segments and - * large ones are nice and smooth. select a chord length that - * results in segments approximately 4 pixels in length. - * - * circumference / 4 = PI * diameter / 4 - */ - nsegs = M_PI_2 * r * v->gv_scale; - - if (nsegs < 32) - nsegs = 32; - - struct bg_polygon gp; - struct bg_polygon *gpp = &gp; - gpp->num_contours = 1; - gpp->hole = (int *)bu_calloc(1, sizeof(int), "hole");; - gpp->contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); - gpp->contour[0].num_points = nsegs; - gpp->contour[0].open = 0; - gpp->contour[0].point = (point_t *)bu_calloc(nsegs, sizeof(point_t), "point"); - - arc = 360.0 / nsegs; - for (n = 0; n < nsegs; ++n) { - fastf_t ang = n * arc; - - curr_fx = cos(ang*DEG2RAD) * r + p->prev_point[X]; - curr_fy = sin(ang*DEG2RAD) * r + p->prev_point[Y]; - VSET(v_pt, curr_fx, curr_fy, v->gv_data_vZ); - // Use the polygon's view context for actually adding the points - MAT4X3PNT(gpp->contour[0].point[n], p->v.gv_view2model, v_pt); - } - - bg_polygon_free(&p->polygon); - - /* Not doing a struct copy to avoid overwriting other properties. */ - p->polygon.num_contours = gp.num_contours; - p->polygon.hole = gp.hole; - p->polygon.contour = gp.contour; - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 1; -} - -int -bv_update_polygon_ellipse(struct bv_scene_obj *s, struct bview *v) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - fastf_t fx, fy; - - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - - fastf_t a, b, arc; - point_t ellout; - point_t A, B; - int nsegs, n; - - a = fx - p->prev_point[X]; - b = fy - p->prev_point[Y]; - - /* - * For angle alpha, compute surface point as - * - * V + cos(alpha) * A + sin(alpha) * B - * - * note that sin(alpha) is cos(90-alpha). - */ - - VSET(A, a, 0, 0); - VSET(B, 0, b, 0); - - /* use a variable number of segments based on the size of the - * circle being created so small circles have few segments and - * large ones are nice and smooth. select a chord length that - * results in segments approximately 4 pixels in length. - * - * circumference / 4 = PI * diameter / 4 - * - */ - nsegs = M_PI_2 * FMAX(a, b) * v->gv_scale; - - if (nsegs < 32) - nsegs = 32; - - struct bg_polygon gp; - struct bg_polygon *gpp = &gp; - gpp->num_contours = 1; - gpp->hole = (int *)bu_calloc(1, sizeof(int), "hole");; - gpp->contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); - gpp->contour[0].num_points = nsegs; - gpp->contour[0].open = 0; - gpp->contour[0].point = (point_t *)bu_calloc(nsegs, sizeof(point_t), "point"); - - arc = 360.0 / nsegs; - for (n = 0; n < nsegs; ++n) { - fastf_t cosa = cos(n * arc * DEG2RAD); - fastf_t sina = sin(n * arc * DEG2RAD); - - VJOIN2(ellout, p->prev_point, cosa, A, sina, B); - - // Note - don't set Z until after elliptical point is calculated - - // if we set it beforehand we get ellipses not in the view plane. - ellout[Z] = v->gv_data_vZ; - - // Use the polygon's view context for actually adding the points - MAT4X3PNT(gpp->contour[0].point[n], p->v.gv_view2model, ellout); - } - - bg_polygon_free(&p->polygon); - - /* Not doing a struct copy to avoid overwriting other properties. */ - p->polygon.num_contours = gp.num_contours; - p->polygon.hole = gp.hole; - p->polygon.contour = gp.contour; - - /* Have new polygon, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 1; -} - -int -bv_update_polygon_rectangle(struct bv_scene_obj *s, struct bview *v) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - fastf_t fx, fy; - - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - // Use the polygon's view context for actually adjusting the points - point_t v_pt; - MAT4X3PNT(p->polygon.contour[0].point[0], p->v.gv_view2model, p->prev_point); - VSET(v_pt, p->prev_point[X], fy, v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[1], p->v.gv_view2model, v_pt); - VSET(v_pt, fx, fy, v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[2], p->v.gv_view2model, v_pt); - VSET(v_pt, fx, p->prev_point[Y], v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[3], p->v.gv_view2model, v_pt); - p->polygon.contour[0].open = 0; - - /* Polygon updated, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 1; -} - -int -bv_update_polygon_square(struct bv_scene_obj *s, struct bview *v) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - fastf_t fx, fy; - - if (bv_screen_to_view(v, &fx, &fy, v->gv_mouse_x, v->gv_mouse_y) < 0) - return 0; - - int snapped = 0; - if (v->gv_s->gv_snap_lines) { - snapped = bv_snap_lines_2d(v, &fx, &fy); - } - if (!snapped && v->gv_s->gv_grid.snap) { - bv_snap_grid_2d(v, &fx, &fy); - } - - fastf_t dx = fx - p->prev_point[X]; - fastf_t dy = fy - p->prev_point[Y]; - - if (fabs(dx) > fabs(dy)) { - if (dy < 0.0) - fy = p->prev_point[Y] - fabs(dx); - else - fy = p->prev_point[Y] + fabs(dx); - } else { - if (dx < 0.0) - fx = p->prev_point[X] - fabs(dy); - else - fx = p->prev_point[X] + fabs(dy); - } - - // Use the polygon's view context for actually adjusting the points - point_t v_pt; - MAT4X3PNT(p->polygon.contour[0].point[0], p->v.gv_view2model, p->prev_point); - VSET(v_pt, p->prev_point[X], fy, v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[1], p->v.gv_view2model, v_pt); - VSET(v_pt, fx, fy, v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[2], p->v.gv_view2model, v_pt); - VSET(v_pt, fx, p->prev_point[Y], v->gv_data_vZ); - MAT4X3PNT(p->polygon.contour[0].point[3], p->v.gv_view2model, v_pt); - p->polygon.contour[0].open = 0; - - /* Polygon updated, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 1; -} - -int -bv_update_general_polygon(struct bv_scene_obj *s, int utype) -{ - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - if (p->type != BV_POLYGON_GENERAL) - return 0; - - if (utype == BV_POLYGON_UPDATE_PT_APPEND) { - return bv_append_polygon_pt(s); - } - - if (utype == BV_POLYGON_UPDATE_PT_SELECT) { - return bv_select_polygon_pt(s); - } - - if (utype == BV_POLYGON_UPDATE_PT_MOVE) { - return bv_move_polygon_pt(s); - } - - /* Polygon updated, now update view object vlist */ - bv_polygon_vlist(s); - - /* Updated */ - s->s_changed++; - - return 0; -} - -int -bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype) -{ - if (!s) - return 0; - - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - - // Regardless of type, sync fill color - struct bv_scene_obj *fobj = NULL; - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - if (BU_STR_EQUAL(bu_vls_cstr(&s_c->s_uuid), "fill")) { - fobj = s_c; - break; - } - } - if (fobj) { - bu_color_to_rgb_chars(&p->fill_color, fobj->s_color); - } - - if (utype == BV_POLYGON_UPDATE_PROPS_ONLY) { - - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - if (!s_c) - continue; - s_c->s_color[0] = s->s_color[0]; - s_c->s_color[1] = s->s_color[1]; - s_c->s_color[2] = s->s_color[2]; - } - - if (p->fill_flag) { - bv_fill_polygon(s); - } else { - // Clear old fill - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - if (!s_c) - continue; - if (BU_STR_EQUAL(bu_vls_cstr(&s_c->s_uuid), "fill")) { - BV_FREE_VLIST(&s->s_v->gv_objs.gv_vlfree, &s_c->s_vlist); - break; - } - } - } - - return 0; - } - - if (p->type == BV_POLYGON_CIRCLE) - return bv_update_polygon_circle(s, v); - if (p->type == BV_POLYGON_ELLIPSE) - return bv_update_polygon_ellipse(s, v); - if (p->type == BV_POLYGON_RECTANGLE) - return bv_update_polygon_rectangle(s, v); - if (p->type == BV_POLYGON_SQUARE) - return bv_update_polygon_square(s, v); - if (p->type != BV_POLYGON_GENERAL) - return 0; - return bv_update_general_polygon(s, utype); -} - -struct bv_scene_obj * -bg_dup_view_polygon(const char *nname, struct bv_scene_obj *s) -{ - if (!nname || !s) - return NULL; - - struct bv_polygon *ip = (struct bv_polygon *)s->s_i_data; - - // Since we want to create our copy using s's original creation frame and - // not (necessarily) the current s_v, make sure the s_v's vlfree list is - // set in the internal polygon's stored view. - // - // TODO - fix this... - // ip->v.gv_objs.vlfree = &s->s_v->vset->vlfree; - - struct bv_scene_obj *np = bv_create_polygon(&ip->v, ip->type, ip->v.gv_prevMouseX, ip->v.gv_prevMouseY); - - // Internal "creation" view is defined - now set the working view that s is - // using for normal operations. - np->s_v = s->s_v; - - // Copy polygon geometry - struct bv_polygon *dp = (struct bv_polygon *)np->s_i_data; - bg_polygon_free(&dp->polygon); - bg_polygon_cpy(&dp->polygon, &ip->polygon); - - // Have geometry, now copy visual settings - VMOVE(np->s_color, s->s_color); - BU_COLOR_CPY(&dp->fill_color, &ip->fill_color); - V2MOVE(dp->fill_dir, ip->fill_dir); - dp->fill_delta = ip->fill_delta; - dp->fill_flag = ip->fill_flag; - - // Update scene obj vlist - bv_polygon_vlist(np); - - // Set new name - bu_vls_init(&np->s_uuid); - bu_vls_sprintf(&np->s_uuid, "%s", nname); - - // Return new object - return np; -} - - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libbg/polygon_op.cpp b/src/libbg/polygon_op.cpp index 80190171832..4024e92416e 100644 --- a/src/libbg/polygon_op.cpp +++ b/src/libbg/polygon_op.cpp @@ -25,6 +25,10 @@ #include "common.h" +#include +#include + +#include "RTree.h" #include "clipper.hpp" #include "vmath.h" @@ -33,13 +37,12 @@ #include "bn/mat.h" #include "bg/plane.h" #include "bg/defines.h" +extern "C" { #include "bg/polygon.h" - -#define FREE_BV_SCENE_OBJ(p, fp) { \ - BU_LIST_APPEND(fp, &((p)->l)); } +} fastf_t -bg_find_polygon_area(struct bg_polygon *gpoly, fastf_t sf, matp_t model2view, fastf_t size) +bg_find_polygon_area(struct bg_polygon *gpoly, fastf_t sf, plane_t *vp, fastf_t size) { size_t j, k, n; ClipperLib::Path poly; @@ -52,13 +55,11 @@ bg_find_polygon_area(struct bg_polygon *gpoly, fastf_t sf, matp_t model2view, fa n = gpoly->contour[j].num_points; poly.resize(n); for (k = 0; k < n; k++) { - point_t vpoint; - - /* Convert to view coordinates */ - MAT4X3PNT(vpoint, model2view, gpoly->contour[j].point[k]); + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, *vp, gpoly->contour[j].point[k]); - poly[k].X = (ClipperLib::long64)(vpoint[X] * sf); - poly[k].Y = (ClipperLib::long64)(vpoint[Y] * sf); + poly[k].X = (ClipperLib::long64)(fx * sf); + poly[k].Y = (ClipperLib::long64)(fy * sf); } area += (fastf_t)ClipperLib::Area(poly); @@ -81,27 +82,19 @@ typedef struct { poly_contour_2d *p_contour; } polygon_2d; -int -bg_polygons_overlap(struct bg_polygon *polyA, struct bg_polygon *polyB, matp_t model2view, const struct bn_tol *tol, fastf_t iscale) +extern "C" int +bg_polygons_overlap(struct bg_polygon *polyA, struct bg_polygon *polyB, plane_t *vp, const struct bn_tol *tol, fastf_t iscale) { - size_t i, j; size_t beginA, endA, beginB, endB; - fastf_t tol_dist; - fastf_t tol_dist_sq; fastf_t scale; polygon_2d polyA_2d; polygon_2d polyB_2d; - point2d_t pt_2d; - point_t A; - size_t winding = 0; int ret = 0; if (polyA->num_contours < 1 || polyA->contour[0].num_points < 1 || polyB->num_contours < 1 || polyB->contour[0].num_points < 1) return 0; - tol_dist = (tol->dist > 0.0) ? tol->dist : BN_TOL_DIST; - tol_dist_sq = (tol->dist_sq > 0.0) ? tol->dist_sq : tol_dist * tol_dist; scale = (iscale > (fastf_t)UINT16_MAX) ? iscale : (fastf_t)UINT16_MAX; /* Project polyA and polyB onto the view plane */ @@ -109,16 +102,16 @@ bg_polygons_overlap(struct bg_polygon *polyA, struct bg_polygon *polyB, matp_t m polyA_2d.p_hole = (int *)bu_calloc(polyA->num_contours, sizeof(int), "p_hole"); polyA_2d.p_contour = (poly_contour_2d *)bu_calloc(polyA->num_contours, sizeof(poly_contour_2d), "p_contour"); - for (i = 0; i < polyA->num_contours; ++i) { + for (size_t i = 0; i < polyA->num_contours; ++i) { polyA_2d.p_hole[i] = polyA->hole[i]; polyA_2d.p_contour[i].pc_num_points = polyA->contour[i].num_points; polyA_2d.p_contour[i].pc_point = (point2d_t *)bu_calloc(polyA->contour[i].num_points, sizeof(point2d_t), "pc_point"); - for (j = 0; j < polyA->contour[i].num_points; ++j) { + for (size_t j = 0; j < polyA->contour[i].num_points; ++j) { point_t vpoint; - - MAT4X3PNT(vpoint, model2view, polyA->contour[i].point[j]); - VSCALE(vpoint, vpoint, scale); + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, *vp, polyA->contour[i].point[j]); + VSET(vpoint, fx * scale, fy * scale, 0); V2MOVE(polyA_2d.p_contour[i].pc_point[j], vpoint); } } @@ -127,306 +120,178 @@ bg_polygons_overlap(struct bg_polygon *polyA, struct bg_polygon *polyB, matp_t m polyB_2d.p_hole = (int *)bu_calloc(polyB->num_contours, sizeof(int), "p_hole"); polyB_2d.p_contour = (poly_contour_2d *)bu_calloc(polyB->num_contours, sizeof(poly_contour_2d), "p_contour"); - for (i = 0; i < polyB->num_contours; ++i) { + for (size_t i = 0; i < polyB->num_contours; ++i) { polyB_2d.p_hole[i] = polyB->hole[i]; polyB_2d.p_contour[i].pc_num_points = polyB->contour[i].num_points; polyB_2d.p_contour[i].pc_point = (point2d_t *)bu_calloc(polyB->contour[i].num_points, sizeof(point2d_t), "pc_point"); - for (j = 0; j < polyB->contour[i].num_points; ++j) { + for (size_t j = 0; j < polyB->contour[i].num_points; ++j) { point_t vpoint; - - MAT4X3PNT(vpoint, model2view, polyB->contour[i].point[j]); - VSCALE(vpoint, vpoint, scale); + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, *vp, polyB->contour[i].point[j]); + VSET(vpoint, fx * scale, fy * scale, 0); V2MOVE(polyB_2d.p_contour[i].pc_point[j], vpoint); } } - /* - * Check every line segment of polyA against every line segment of polyB. - * If there are any intersecting line segments, there exists an overlap. - */ - for (i = 0; i < polyA_2d.p_num_contours; ++i) { + // Next, assemble RTrees of the polygon lines so we can quickly identify + // which pairs we need to check for intersection. In order to provide a + // single index for the RTree to identify each segment, we map a count of + // segments to a contour/point number pair + RTree rtree_2d_A; + std::unordered_map> s_indA; + int s_cnt_A = 0; + for (size_t i = 0; i < polyA_2d.p_num_contours; ++i) { for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points; ++beginA) { - vect2d_t dirA; - - if (beginA == polyA_2d.p_contour[i].pc_num_points-1) - endA = 0; - else - endA = beginA + 1; - - V2SUB2(dirA, polyA_2d.p_contour[i].pc_point[endA], polyA_2d.p_contour[i].pc_point[beginA]); - - for (j = 0; j < polyB_2d.p_num_contours; ++j) { - for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points; ++beginB) { - vect2d_t distvec; - vect2d_t dirB; - - if (beginB == polyB_2d.p_contour[j].pc_num_points-1) - endB = 0; - else - endB = beginB + 1; - - V2SUB2(dirB, polyB_2d.p_contour[j].pc_point[endB], polyB_2d.p_contour[j].pc_point[beginB]); - - if (bg_isect_lseg2_lseg2(distvec, - polyA_2d.p_contour[i].pc_point[beginA], dirA, - polyB_2d.p_contour[j].pc_point[beginB], dirB, - tol) == 1) { - /* Check to see if intersection is near an end point */ - if (!NEAR_EQUAL(distvec[0], 0.0, tol_dist_sq) && - !NEAR_EQUAL(distvec[0], 1.0, tol_dist_sq) && - !NEAR_EQUAL(distvec[1], 0.0, tol_dist_sq) && - !NEAR_EQUAL(distvec[1], 1.0, tol_dist_sq)) { - ret = 1; - goto end; - } - } - } - } + point2d_t p1, p2; + endA = (beginA == polyA_2d.p_contour[i].pc_num_points-1) ? 0 : beginA + 1; + V2MOVE(p1, polyA_2d.p_contour[i].pc_point[beginA]); + V2MOVE(p2, polyA_2d.p_contour[i].pc_point[endA]); + s_indA[s_cnt_A] = std::make_pair(i, beginA); + double tMin[2], tMax[2]; + tMin[0] = (p1[X] < p2[X]) ? p1[X] : p2[X]; + tMin[1] = (p1[Y] < p2[Y]) ? p1[Y] : p2[Y]; + tMax[0] = (p1[X] > p2[X]) ? p1[X] : p2[X]; + tMax[1] = (p1[Y] > p2[Y]) ? p1[Y] : p2[Y]; + rtree_2d_A.Insert(tMin, tMax, s_cnt_A); + s_cnt_A++; + } + } + RTree rtree_2d_B; + std::unordered_map> s_indB; + int s_cnt_B = 0; + for (size_t i = 0; i < polyB_2d.p_num_contours; ++i) { + for (beginB = 0; beginB < polyB_2d.p_contour[i].pc_num_points; ++beginB) { + point2d_t p1, p2; + endB = (beginB == polyB_2d.p_contour[i].pc_num_points-1) ? 0 : beginB + 1; + V2MOVE(p1, polyB_2d.p_contour[i].pc_point[beginB]); + V2MOVE(p2, polyB_2d.p_contour[i].pc_point[endB]); + s_indB[s_cnt_B] = std::make_pair(i, beginB); + double tMin[2], tMax[2]; + tMin[0] = (p1[X] < p2[X]) ? p1[X] : p2[X]; + tMin[1] = (p1[Y] < p2[Y]) ? p1[Y] : p2[Y]; + tMax[0] = (p1[X] > p2[X]) ? p1[X] : p2[X]; + tMax[1] = (p1[Y] > p2[Y]) ? p1[Y] : p2[Y]; + rtree_2d_B.Insert(tMin, tMax, s_cnt_B); + s_cnt_B++; } } - for (i = 0; i < polyB_2d.p_num_contours; ++i) { - size_t npts_on_contour = 0; - size_t npts_outside = 0; - - /* Skip holes */ - if (polyB_2d.p_hole[i]) - continue; + std::set> test_segs; + size_t ovlp_cnt = rtree_2d_A.Overlaps(rtree_2d_B, &test_segs); + //bu_log("ovlp_cnt: %zd\n", ovlp_cnt); + //rtree_2d_A.plot2d("TreeA.plot3"); + //rtree_2d_B.plot2d("TreeB.plot3"); - /* Check if all points in the current polygon B contour are inside A */ - for (beginB = 0; beginB < polyB_2d.p_contour[i].pc_num_points; ++beginB) { - winding = 0; - V2MOVE(pt_2d, polyB_2d.p_contour[i].pc_point[beginB]); - V2MOVE(A, pt_2d); - A[2] = 0.0; - - for (j = 0; j < polyA_2d.p_num_contours; ++j) { - point_t B, C; - vect_t BmA, CmA; - vect_t vcross; - - for (beginA = 0; beginA < polyA_2d.p_contour[j].pc_num_points; ++beginA) { - fastf_t dot; - - if (beginA == polyA_2d.p_contour[j].pc_num_points-1) - endA = 0; - else - endA = beginA + 1; - - if (V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA], pt_2d, tol_dist_sq) || - V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[endA], pt_2d, tol_dist_sq)) { - /* pt_2d is the same as one of the end points, so count it */ - ++npts_on_contour; - - if (polyA_2d.p_hole[j]) - winding = 0; - else - winding = 1; - - goto endA; - } - - if ((polyA_2d.p_contour[j].pc_point[beginA][1] <= pt_2d[1] && - polyA_2d.p_contour[j].pc_point[endA][1] > pt_2d[1])) { - V2MOVE(B, polyA_2d.p_contour[j].pc_point[endA]); - B[2] = 0.0; - V2MOVE(C, polyA_2d.p_contour[j].pc_point[beginA]); - C[2] = 0.0; - } else if ((polyA_2d.p_contour[j].pc_point[endA][1] <= pt_2d[1] && - polyA_2d.p_contour[j].pc_point[beginA][1] > pt_2d[1])) { - V2MOVE(B, polyA_2d.p_contour[j].pc_point[beginA]); - B[2] = 0.0; - V2MOVE(C, polyA_2d.p_contour[j].pc_point[endA]); - C[2] = 0.0; - } else { - /* check if the point is on a horizontal edge */ - if (NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1], - polyA_2d.p_contour[j].pc_point[endA][1], tol_dist_sq) && - NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1], pt_2d[1], tol_dist_sq) && - ((polyA_2d.p_contour[j].pc_point[beginA][0] <= pt_2d[0] && - polyA_2d.p_contour[j].pc_point[endA][0] >= pt_2d[0]) || - (polyA_2d.p_contour[j].pc_point[endA][0] <= pt_2d[0] && - polyA_2d.p_contour[j].pc_point[beginA][0] >= pt_2d[0]))) { - ++npts_on_contour; - - if (polyA_2d.p_hole[j]) - winding = 0; - else - winding = 1; - - goto endA; - } - - continue; - } - - VSUB2(BmA, B, A); - VSUB2(CmA, C, A); - VUNITIZE(BmA); - VUNITIZE(CmA); - dot = VDOT(BmA, CmA); - - if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot, 1.0, tol_dist_sq)) { - ++npts_on_contour; - - if (polyA_2d.p_hole[j]) - winding = 0; - else - winding = 0; - - goto endA; - } - - VCROSS(vcross, BmA, CmA); - - if (vcross[2] > 0) - ++winding; - } + /* + * Check every line segment pairing from polyA & polyB where the bounding + * boxes overlapped. If there are any intersecting line segments, there + * exists an overlap. + */ + if (ovlp_cnt) { + std::set>::iterator ts_it; + for (ts_it = test_segs.begin(); ts_it != test_segs.end(); ts_it++) { + vect2d_t dirA, dirB; + size_t iA = s_indA[ts_it->first].first; + beginA = s_indA[ts_it->first].second; + endA = (beginA == polyA_2d.p_contour[iA].pc_num_points-1) ? 0 : beginA + 1; + V2SUB2(dirA, polyA_2d.p_contour[iA].pc_point[endA], polyA_2d.p_contour[iA].pc_point[beginA]); + + size_t iB = s_indB[ts_it->second].first; + beginB = s_indB[ts_it->second].second; + endB = (beginB == polyB_2d.p_contour[iB].pc_num_points-1) ? 0 : beginB + 1; + V2SUB2(dirB, polyB_2d.p_contour[iB].pc_point[endB], polyB_2d.p_contour[iB].pc_point[beginB]); + + vect2d_t distvec; + if (bg_isect_lseg2_lseg2(distvec, + polyA_2d.p_contour[iA].pc_point[beginA], dirA, + polyB_2d.p_contour[iB].pc_point[beginB], dirB, + tol) == 1) { + ret = 1; + goto end; } - - endA: - /* found a point on a polygon B contour that's outside of polygon A */ - if (!(winding%2)) { - ++npts_outside; - if (npts_outside != npts_on_contour) { - break; - } + } + } + + /* If there aren't any overlapping segments, then it boils down to whether + * one of the polygons is fully inside the other but NOT fully inside a + * hole. Since we have ruled out segment intersections, we can simply + * check one point on each contour against the other polygon's contours. + * If it's inside a hole, it's not an overlap. If it's not inside a hole + * but IS inside a contour, it's an overlap. This doesn't cover multiply + * nested contours, but that's not currently a use case of interest - in the + * event that use case does come up, we'll have to sort out in the original + * polygon which positive contours are fully inside holes and establish a + * hierarchy. */ + for (size_t i = 0; i < polyA_2d.p_num_contours; ++i) { + bool in_hole = false; + // No points, no work to do + if (!polyA_2d.p_contour[i].pc_num_points) + continue; + const point2d_t *tp = &polyA_2d.p_contour[i].pc_point[0]; + for (size_t j = 0; j < polyB_2d.p_num_contours; ++j) { + if (!polyB_2d.p_contour[j].pc_num_points || !polyB_2d.p_hole[j]) + continue; + int is_in = bg_pnt_in_polygon(polyB_2d.p_contour[j].pc_num_points, polyB_2d.p_contour[j].pc_point, tp); + if (is_in) { + in_hole = true; + // If we assume non-nested contour, we now know the answer for this contour + break; } } + if (in_hole) + continue; - /* found a B polygon contour that's completely inside polygon A */ - if (winding%2 || (npts_outside != 0 && - npts_outside != polyB_2d.p_contour[i].pc_num_points && - npts_outside == npts_on_contour)) { - ret = 1; - goto end; + // Not inside a hole, see if we're inside a positive contour + for (size_t j = 0; j < polyB_2d.p_num_contours; ++j) { + if (!polyB_2d.p_contour[j].pc_num_points || polyB_2d.p_hole[j]) + continue; + int is_in = bg_pnt_in_polygon(polyB_2d.p_contour[j].pc_num_points, polyB_2d.p_contour[j].pc_point, tp); + if (is_in) { + // If we assume non-nested contour, we now know the answer + ret = 1; + goto end; + } } } - for (i = 0; i < polyA_2d.p_num_contours; ++i) { - size_t npts_on_contour = 0; - size_t npts_outside = 0; - - /* Skip holes */ - if (polyA_2d.p_hole[i]) + // Check B points against a contours + for (size_t i = 0; i < polyB_2d.p_num_contours; ++i) { + bool in_hole = false; + // No points, no work to do + if (!polyB_2d.p_contour[i].pc_num_points) continue; - - /* Check if all points in the current polygon A contour are inside B */ - for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points; ++beginA) { - winding = 0; - V2MOVE(pt_2d, polyA_2d.p_contour[i].pc_point[beginA]); - V2MOVE(A, pt_2d); - A[2] = 0.0; - - for (j = 0; j < polyB_2d.p_num_contours; ++j) { - point_t B, C; - vect_t BmA, CmA; - vect_t vcross; - - for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points; ++beginB) { - fastf_t dot; - - if (beginB == polyB_2d.p_contour[j].pc_num_points-1) - endB = 0; - else - endB = beginB + 1; - - if (V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB], pt_2d, tol_dist_sq) || - V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[endB], pt_2d, tol_dist_sq)) { - /* pt_2d is the same as one of the end points, so count it */ - - if (polyB_2d.p_hole[j]) - winding = 0; - else - winding = 1; - - ++npts_on_contour; - goto endB; - } - - if ((polyB_2d.p_contour[j].pc_point[beginB][1] <= pt_2d[1] && - polyB_2d.p_contour[j].pc_point[endB][1] > pt_2d[1])) { - V2MOVE(B, polyB_2d.p_contour[j].pc_point[endB]); - B[2] = 0.0; - V2MOVE(C, polyB_2d.p_contour[j].pc_point[beginB]); - C[2] = 0.0; - } else if ((polyB_2d.p_contour[j].pc_point[endB][1] <= pt_2d[1] && - polyB_2d.p_contour[j].pc_point[beginB][1] > pt_2d[1])) { - V2MOVE(B, polyB_2d.p_contour[j].pc_point[beginB]); - B[2] = 0.0; - V2MOVE(C, polyB_2d.p_contour[j].pc_point[endB]); - C[2] = 0.0; - } else { - /* check if the point is on a horizontal edge */ - if (NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1], - polyB_2d.p_contour[j].pc_point[endB][1], tol_dist_sq) && - NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1], pt_2d[1], tol_dist_sq) && - ((polyB_2d.p_contour[j].pc_point[beginB][0] <= pt_2d[0] && - polyB_2d.p_contour[j].pc_point[endB][0] >= pt_2d[0]) || - (polyB_2d.p_contour[j].pc_point[endB][0] <= pt_2d[0] && - polyB_2d.p_contour[j].pc_point[beginB][0] >= pt_2d[0]))) { - if (polyB_2d.p_hole[j]) - winding = 0; - else - winding = 1; - - ++npts_on_contour; - - goto endB; - } - - continue; - } - - VSUB2(BmA, B, A); - VSUB2(CmA, C, A); - VUNITIZE(BmA); - VUNITIZE(CmA); - dot = VDOT(BmA, CmA); - - if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot, 1.0, tol_dist_sq)) { - if (polyB_2d.p_hole[j]) - winding = 0; - else - winding = 1; - - ++npts_on_contour; - goto endB; - } - - VCROSS(vcross, BmA, CmA); - - if (vcross[2] > 0) - ++winding; - } + const point2d_t *tp = &polyB_2d.p_contour[i].pc_point[0]; + for (size_t j = 0; j < polyA_2d.p_num_contours; ++j) { + if (!polyA_2d.p_contour[j].pc_num_points || !polyA_2d.p_hole[j]) + continue; + int is_in = bg_pnt_in_polygon(polyA_2d.p_contour[j].pc_num_points, polyA_2d.p_contour[j].pc_point, tp); + if (is_in) { + in_hole = true; + // If we assume non-nested contour, we now know the answer for this contour + break; } + } + if (in_hole) + continue; - endB: - /* found a point on a polygon A contour that's outside of polygon B */ - if (!(winding%2)) { - ++npts_outside; - if (npts_outside != npts_on_contour) { - break; - } + // Not inside a hole, see if we're inside a positive contour + for (size_t j = 0; j < polyA_2d.p_num_contours; ++j) { + if (!polyA_2d.p_contour[j].pc_num_points || polyA_2d.p_hole[j]) + continue; + int is_in = bg_pnt_in_polygon(polyA_2d.p_contour[j].pc_num_points, polyA_2d.p_contour[j].pc_point, tp); + if (is_in) { + // If we assume non-nested contour, we now know the answer + ret = 1; + goto end; } } - - /* found an A polygon contour that's completely inside polygon B */ - if (winding%2 || (npts_outside != 0 && - npts_outside != polyA_2d.p_contour[i].pc_num_points && - npts_outside == npts_on_contour)) { - ret = 1; - break; - } else - ret = 0; } end: - - for (i = 0; i < polyA->num_contours; ++i) + for (size_t i = 0; i < polyA->num_contours; ++i) bu_free((void *)polyA_2d.p_contour[i].pc_point, "pc_point"); - for (i = 0; i < polyB->num_contours; ++i) + for (size_t i = 0; i < polyB->num_contours; ++i) bu_free((void *)polyB_2d.p_contour[i].pc_point, "pc_point"); bu_free((void *)polyA_2d.p_hole, "p_hole"); @@ -445,29 +310,23 @@ typedef struct { static fastf_t -load_polygon(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct bg_polygon *gpoly, fastf_t sf, matp_t mat) +load_polygon(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct bg_polygon *gpoly, fastf_t sf, plane_t *vp) { size_t j, k, n; ClipperLib::Path curr_poly; fastf_t vZ = 1.0; - mat_t idmat = MAT_INIT_IDN; for (j = 0; j < gpoly->num_contours; ++j) { n = gpoly->contour[j].num_points; curr_poly.resize(n); for (k = 0; k < n; k++) { - point_t vpoint; - - /* Convert to view coordinates */ - if (mat) { - MAT4X3PNT(vpoint, mat, gpoly->contour[j].point[k]); - } else { - MAT4X3PNT(vpoint, idmat, gpoly->contour[j].point[k]); - } - vZ = vpoint[Z]; + fastf_t fx = gpoly->contour[j].point[k][0]; + fastf_t fy = gpoly->contour[j].point[k][1]; + if (vp) + bg_plane_closest_pt(&fx, &fy, *vp, gpoly->contour[j].point[k]); - curr_poly[k].X = (ClipperLib::long64)(vpoint[X] * sf); - curr_poly[k].Y = (ClipperLib::long64)(vpoint[Y] * sf); + curr_poly[k].X = (ClipperLib::long64)(fx * sf); + curr_poly[k].Y = (ClipperLib::long64)(fy * sf); } try { @@ -481,13 +340,13 @@ load_polygon(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct bg } static fastf_t -load_polygons(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct bg_polygons *subj, fastf_t sf, matp_t mat) +load_polygons(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct bg_polygons *subj, fastf_t sf, plane_t *vp) { size_t i; fastf_t vZ = 1.0; for (i = 0; i < subj->num_polygons; ++i) - vZ = load_polygon(clipper, ptype, &subj->polygon[i], sf, mat); + vZ = load_polygon(clipper, ptype, &subj->polygon[i], sf, vp); return vZ; } @@ -496,12 +355,11 @@ load_polygons(ClipperLib::Clipper &clipper, ClipperLib::PolyType ptype, struct b * Process/extract the clipper_polys into a struct bg_polygon. */ static struct bg_polygon * -extract(ClipperLib::PolyTree &clipper_polytree, fastf_t sf, matp_t mat, fastf_t vZ) +extract(ClipperLib::PolyTree &clipper_polytree, fastf_t sf, plane_t *vp) { size_t j, n; size_t num_contours = clipper_polytree.Total(); struct bg_polygon *outp; - mat_t idmat = MAT_INIT_IDN; BU_ALLOC(outp, struct bg_polygon); outp->num_contours = num_contours; @@ -515,7 +373,6 @@ extract(ClipperLib::PolyTree &clipper_polytree, fastf_t sf, matp_t mat, fastf_t ClipperLib::PolyNode *polynode = clipper_polytree.GetFirst(); n = 0; while (polynode) { - point_t vpoint; ClipperLib::Path &path = polynode->Contour; outp->hole[n] = polynode->IsHole(); @@ -524,13 +381,10 @@ extract(ClipperLib::PolyTree &clipper_polytree, fastf_t sf, matp_t mat, fastf_t outp->contour[n].point = (point_t *)bu_calloc(outp->contour[n].num_points, sizeof(point_t), "point"); for (j = 0; j < outp->contour[n].num_points; ++j) { - VSET(vpoint, (fastf_t)(path[j].X) * sf, (fastf_t)(path[j].Y) * sf, vZ); - - /* Convert to model coordinates */ - if (mat) { - MAT4X3PNT(outp->contour[n].point[j], mat, vpoint); + if (vp) { + bg_plane_pt_at(&outp->contour[n].point[j], *vp, (fastf_t)(path[j].X) * sf, (fastf_t)(path[j].Y) * sf); } else { - MAT4X3PNT(outp->contour[n].point[j], idmat, vpoint); + VSET(outp->contour[n].point[j], (fastf_t)(path[j].X) * sf, (fastf_t)(path[j].Y) * sf, 0); } } @@ -546,10 +400,9 @@ extract(ClipperLib::PolyTree &clipper_polytree, fastf_t sf, matp_t mat, fastf_t struct bg_polygon * -bg_clip_polygon(bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, fastf_t sf, matp_t model2view, matp_t view2model) +bg_clip_polygon(bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, fastf_t sf, plane_t *vp) { fastf_t inv_sf; - fastf_t vZ; ClipperLib::Clipper clipper; ClipperLib::PolyTree result_clipper_polys; ClipperLib::ClipType ctOp; @@ -559,10 +412,10 @@ bg_clip_polygon(bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, /* need the inverse of the matrix above to put things back after clipping */ /* Load subject polygon into clipper */ - load_polygon(clipper, ClipperLib::ptSubject, subj, sf, model2view); + load_polygon(clipper, ClipperLib::ptSubject, subj, sf, vp); /* Load clip polygon into clipper */ - vZ = load_polygon(clipper, ClipperLib::ptClip, clip, sf, model2view); + load_polygon(clipper, ClipperLib::ptClip, clip, sf, vp); /* Convert op from BRL-CAD to Clipper */ switch (op) { @@ -584,15 +437,14 @@ bg_clip_polygon(bg_clip_t op, struct bg_polygon *subj, struct bg_polygon *clip, clipper.Execute(ctOp, result_clipper_polys, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); inv_sf = 1.0/sf; - return extract(result_clipper_polys, inv_sf, view2model, vZ); + return extract(result_clipper_polys, inv_sf, vp); } struct bg_polygon * -bg_clip_polygons(bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *clip, fastf_t sf, matp_t model2view, matp_t view2model) +bg_clip_polygons(bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *clip, fastf_t sf, plane_t *vp) { fastf_t inv_sf; - fastf_t vZ; ClipperLib::Clipper clipper; ClipperLib::PolyTree result_clipper_polys; ClipperLib::ClipType ctOp; @@ -602,10 +454,10 @@ bg_clip_polygons(bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *cli /* need the inverse of the matrix above to put things back after clipping */ /* Load subject polygons into clipper */ - load_polygons(clipper, ClipperLib::ptSubject, subj, sf, model2view); + load_polygons(clipper, ClipperLib::ptSubject, subj, sf, vp); /* Load clip polygons into clipper */ - vZ = load_polygons(clipper, ClipperLib::ptClip, clip, sf, model2view); + load_polygons(clipper, ClipperLib::ptClip, clip, sf, vp); /* Convert op from BRL-CAD to Clipper */ switch (op) { @@ -627,87 +479,9 @@ bg_clip_polygons(bg_clip_t op, struct bg_polygons *subj, struct bg_polygons *cli clipper.Execute(ctOp, result_clipper_polys, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); inv_sf = 1.0/sf; - return extract(result_clipper_polys, inv_sf, view2model, vZ); + return extract(result_clipper_polys, inv_sf, vp); } - -int -bv_polygon_csg(struct bu_ptbl *objs, struct bv_scene_obj *p, bg_clip_t op, int merge) -{ - if (!objs || !p) - return -1; - - struct bu_ptbl null_polys = BU_PTBL_INIT_ZERO; - int pcnt = 0; - struct bv_scene_obj *bp = p; - struct bv_scene_obj *free_scene_obj = p->free_scene_obj; - - for (size_t i = 0; i < BU_PTBL_LEN(objs); i++) { - struct bv_scene_obj *vp = (struct bv_scene_obj *)BU_PTBL_GET(objs, i); - if (!(vp->s_type_flags & BV_POLYGONS)) - continue; - if (p == vp) - continue; - struct bv_polygon *polyA = (struct bv_polygon *)vp->s_i_data; - struct bv_polygon *polyB = (struct bv_polygon *)bp->s_i_data; - - // Make sure the polygons overlap before we operate, since clipper results are - // always general polygons. We don't want to perform a no-op clip and lose our - // type info. - const struct bn_tol poly_tol = BN_TOL_INIT_TOL; - int ovlp = bg_polygons_overlap(&polyA->polygon, &polyB->polygon, polyA->v.gv_model2view, &poly_tol, polyA->v.gv_scale); - if (!ovlp) - continue; - - // Perform the specified operation - struct bg_polygon *cp = bg_clip_polygon(op, &polyA->polygon, &polyB->polygon, CLIPPER_MAX, polyA->v.gv_model2view, polyA->v.gv_view2model); - bg_polygon_free(&polyA->polygon); - polyA->polygon.num_contours = cp->num_contours; - polyA->polygon.hole = cp->hole; - polyA->polygon.contour = cp->contour; - - // clipper results are always general polygons - polyA->type = BV_POLYGON_GENERAL; - - if (op != bg_Difference && merge && polyA->polygon.num_contours) { - - // The seed polygon is handled elsewhere, but if we're - // consolidating other view polygons into polyA we need to log the - // consolidated polys for removal here. - if (bp != p) { - bu_ptbl_ins_unique(&null_polys, (long *)bp); - } - - // If we're merging results, subsequent operations will be done - // using the results of this operation, not the original polygon - bp = vp; - } - - if (!polyA->polygon.num_contours) { - // operation eliminated polyA - stash for removal from view - bu_ptbl_ins_unique(&null_polys, (long *)vp); - } else { - bv_update_polygon(vp, p->s_v, BV_POLYGON_UPDATE_DEFAULT); - } - - BU_PUT(cp, struct bg_polygon); - pcnt++; - } - - // If we're eliminating any polygons from the view as a result of the operations, do it now - for (size_t i = 0; i < BU_PTBL_LEN(&null_polys); i++) { - struct bv_scene_obj *np = (struct bv_scene_obj *)BU_PTBL_GET(&null_polys, i); - struct bv_polygon *ip = (struct bv_polygon *)np->s_i_data; - bg_polygon_free(&ip->polygon); - BU_PUT(ip, struct bv_polygon); - bu_ptbl_rm(objs, (long *)np); - FREE_BV_SCENE_OBJ(np, &free_scene_obj->l); - } - - return pcnt; -} - - // Local Variables: // tab-width: 8 // mode: C++ diff --git a/src/libbg/polygon_triangulate.cpp b/src/libbg/polygon_triangulate.cpp index bfbb1e374e1..9eeba8111d6 100644 --- a/src/libbg/polygon_triangulate.cpp +++ b/src/libbg/polygon_triangulate.cpp @@ -62,6 +62,7 @@ #include "bn/rand.h" #include "bv/plot3.h" #include "bg/polygon.h" +#include "bg/plane.h" extern int polyline_2d_plot3(const char *fname, std::vector> &xy, fastf_t scale, struct bu_color *c); @@ -830,7 +831,7 @@ bg_poly2tri(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, extern "C" int -bg_nested_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, +bg_nested_poly_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, const int *poly, const size_t poly_pnts, const int **holes_array, const size_t *holes_npts, const size_t nholes, const int *steiner, const size_t steiner_npts, @@ -924,7 +925,7 @@ bg_nested_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, } extern "C" int -bg_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, +bg_poly_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *num_outpts, const int *steiner, const size_t steiner_pnts, const point2d_t *pts, const size_t npts, triangulation_t type) { @@ -938,13 +939,12 @@ bg_polygon_triangulate(int **faces, int *num_faces, point2d_t **out_pts, int *nu verts_ind[i] = (int)i; } - ret = bg_nested_polygon_triangulate(faces, num_faces, out_pts, num_outpts, verts_ind, npts, NULL, NULL, 0, steiner, steiner_pnts, pts, npts, type); + ret = bg_nested_poly_triangulate(faces, num_faces, out_pts, num_outpts, verts_ind, npts, NULL, NULL, 0, steiner, steiner_pnts, pts, npts, type); bu_free(verts_ind, "vert indices"); return ret; } - extern "C" void bg_tri_plot_2d(const char *filename, const int *faces, int num_faces, const point2d_t *pnts, int r, int g, int b) { @@ -967,7 +967,82 @@ bg_tri_plot_2d(const char *filename, const int *faces, int num_faces, const poin fclose(plot_file); } +extern "C" int +bg_polygon_triangulate(int **faces, int *num_faces, point_t **out_pts, int *num_outpts, + struct bg_polygon *p, triangulation_t type) +{ + if (!faces || !num_faces || !out_pts || !num_outpts || !p) + return -1; + + // Fit the outer contour to get a 2D plane (bg_polygon is in principle a 3D data structure) + point_t pcenter; + vect_t pnorm; + plane_t pl; + if (bg_fit_plane(&pcenter, &pnorm, p->contour[0].num_points, p->contour[0].point)) { + return -1; + } + bg_plane_pt_nrml(&pl, pcenter, pnorm); + + // Count all points + int pnt_cnt = 0; + for (size_t i = 0; i < p->num_contours; ++i) { + pnt_cnt += p->contour[i].num_points; + } + + // Translate the bg_polygon into bg_nested_poly_triangulate inputs + point2d_t *pnts_2d = (point2d_t *)bu_calloc(pnt_cnt, sizeof(point2d_t), "projected points"); + int *ocontour = NULL; + int ocontour_cnt = 0; + int **holes_array = (int **)bu_calloc(p->num_contours - 1, sizeof(int *), "holes"); + size_t *holes_npts = (size_t *)bu_calloc(p->num_contours - 1, sizeof(size_t), "holes_cnt"); + int curr_pnt = 0; + for (size_t i = 0; i < p->num_contours; ++i) { + int *cpnts = (int *)bu_calloc(p->contour[i].num_points, sizeof(int), "point indices"); + if (i > 0) { + holes_array[i-1] = cpnts; + holes_npts[i-1] = p->contour[i].num_points; + } else { + ocontour = cpnts; + ocontour_cnt = p->contour[i].num_points; + } + for (size_t j = 0; j < p->contour[i].num_points; ++j) { + vect2d_t p2d; + bg_plane_closest_pt(&p2d[0], &p2d[1], pl, p->contour[i].point[j]); + V2MOVE(pnts_2d[curr_pnt], p2d); + cpnts[j] = curr_pnt; + curr_pnt++; + } + } + + int *tri_faces = NULL; + int tri_num_faces = 0; + point2d_t *tri_out_pts = NULL; + int tri_num_outpts = 0; + int ret = bg_nested_poly_triangulate(&tri_faces, &tri_num_faces, &tri_out_pts, &tri_num_outpts, ocontour, ocontour_cnt, (const int **)holes_array, (const size_t *)holes_npts, p->num_contours - 1, NULL, 0, pnts_2d, pnt_cnt, type); + + + // Translate 2D plane points into 3D points + point_t *pnts_3d = (point_t *)bu_calloc(pnt_cnt, sizeof(point_t), "3D points"); + for (int i = 0; i < pnt_cnt; i++) { + bg_plane_pt_at(&pnts_3d[i], pl, pnts_2d[i][0], pnts_2d[i][1]); + } + + // Assign outputs + *faces = tri_faces; + *num_faces = tri_num_faces; + *out_pts = pnts_3d; + *num_outpts = tri_num_outpts; + + // Clean up 2D and translation arrays + bu_free(ocontour, "free ocontour"); + for (size_t i = 0; i < p->num_contours - 1; i++) { + bu_free(holes_array[i], "free holes array"); + } + bu_free(holes_npts, "hole cnts"); + bu_free(pnts_2d, "2d pnts"); + return ret; +} // Local Variables: // tab-width: 8 diff --git a/src/libbg/snap.c b/src/libbg/snap.c deleted file mode 100644 index 7f2ba47f0e5..00000000000 --- a/src/libbg/snap.c +++ /dev/null @@ -1,312 +0,0 @@ -/* S N A P . C - * BRL-CAD - * - * Copyright (c) 2008-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libbv/snap.c - * - * Logic for snapping points to visual elements. - * - */ - -#include "common.h" - -#include -#include -#include -#include - -#include "bu/opt.h" -#include "bu/vls.h" -#include "bg/lseg.h" -#include "bv.h" - -struct bv_cp_info { - double ctol_sq; // square of the distance that defines "close to a line" - - struct bv_data_line_state *c_lset; // container holding closest line - point_t cp; // closest point on closest line - int c_l; // index of closest line - double dsq; // squared distance to closest line - - struct bv_data_line_state *c_lset2; // container holding 2nd closest line - point_t cp2; // closest point on closest line - int c_l2; // index of 2nd closest line - double dsq2; // squared distance to 2nd closest line -}; -#define BV_CP_INFO_INIT {BN_TOL_DIST, NULL, VINIT_ZERO, -1, DBL_MAX, NULL, VINIT_ZERO, -1, DBL_MAX} - -static -int -_find_closest_point(struct bv_cp_info *s, point_t *p, struct bv_data_line_state *lines) -{ - int ret = 0; - point_t P0, P1; - - if (lines->gdls_num_points < 2) { - return ret; - } - - // TODO - if we have a large number of lines drawn, we could really benefit - // from an acceleration structure such as the RTree to localize these tests - // rather than checking everything... - for (int i = 0; i < lines->gdls_num_points; i+=2) { - if (s->c_l == i && s->c_lset == lines) { - continue; - } - point_t c; - VMOVE(P0, lines->gdls_points[i]); - VMOVE(P1, lines->gdls_points[i+1]); - double dsq = bg_distsq_lseg3_pt(&c, P0, P1, *p); - // If we're outside tolerance, continue - if (dsq > s->ctol_sq) { - continue; - } - // If this is the closest we've seen, record it - if (s->dsq > dsq) { - // Closest is now second closest - VMOVE(s->cp2, s->cp); - s->dsq2 = s->dsq; - s->c_l2 = s->c_l; - s->c_lset2 = s->c_lset; - - // set new closest - VMOVE(s->cp, c); - s->dsq = dsq; - s->c_l = i; - s->c_lset = lines; - ret = 1; - continue; - } - // Not the closest - is it closer than the second closest? - if (s->dsq2 > dsq) { - VMOVE(s->cp2, c); - s->dsq2 = dsq; - s->c_l2 = i; - s->c_lset2 = lines; - ret = 2; - continue; - } - } - - return ret; -} - -void -_find_close_isect(struct bv_cp_info *s, point_t *p) -{ - point_t P0, P1, Q0, Q1; - point_t c1, c2; - - if (!s || !s->c_lset || !p) - return; - - VMOVE(P0, s->c_lset->gdls_points[s->c_l]); - VMOVE(P1, s->c_lset->gdls_points[s->c_l+1]); - - VMOVE(Q0, s->c_lset2->gdls_points[s->c_l2]); - VMOVE(Q1, s->c_lset2->gdls_points[s->c_l2+1]); - - double csdist_sq = bg_distsq_lseg3_lseg3(&c1, &c2, P0, P1, Q0, Q1); - if (csdist_sq > s->ctol_sq) { - // Line segments are too far away to use both of them to override the - // original answer - return; - } - - // If either closest segment point is too far from the test point, go with - // the original answer rather than changing it - double d1_sq = DIST_PNT_PNT_SQ(*p, c1); - if (d1_sq > s->ctol_sq) { - // Too far away to work - return; - } - - double d2_sq = DIST_PNT_PNT_SQ(*p, c2); - if (d2_sq > s->ctol_sq) { - // Too far away to work - return; - } - - // Go with the closest segment point to the original point. If - // the segments intersect the two points should be the same and - // it won't matter which is chosen, but if they don't then the - // intuitive behavior is to prefer the closest point that attempts - // to satisfy both line segments - if (d1_sq < d2_sq) { - VMOVE(s->cp, c1); - } else { - VMOVE(s->cp, c2); - } -} - -static double -line_tol_sq(struct bview *v, struct bv_data_line_state *gdlsp) -{ - if (!v || !gdlsp) - return 100*100; - - // NOTE - make sure calling applications update these values from - // the display manager info before command execution. - int width = v->gv_width; - int height = v->gv_height; - - if (!width || !height) - return 100*100; - - double lavg = ((double)width + (double)height) * 0.5; - double lwidth = (gdlsp->gdls_line_width) ? gdlsp->gdls_line_width : 1; - double lratio = lwidth/lavg; - double lrsize = v->gv_size * lratio * v->gv_s->gv_snap_tol_factor; - return lrsize*lrsize; -} - -int -bv_snap_lines_3d(point_t *out_pt, struct bview *v, point_t *p) -{ - struct bv_cp_info cpinfo = BV_CP_INFO_INIT; - - if (!p || !v) return BRLCAD_ERROR; - - // There are some issues with line snapping that don't come up with grid - // snapping - in particular, when are we "close enough" to a line to snap, - // and how do we handle snapping when close enough to multiple lines? We - // probably want to prefer intersections between lines to closest line - // point if we are close to multiple lines... - int ret = 0; - cpinfo.ctol_sq = line_tol_sq(v, &v->gv_tcl.gv_data_lines); - ret += _find_closest_point(&cpinfo, p, &v->gv_tcl.gv_data_lines); - cpinfo.ctol_sq = line_tol_sq(v, &v->gv_tcl.gv_sdata_lines); - ret += _find_closest_point(&cpinfo, p, &v->gv_tcl.gv_sdata_lines); - - // Check if we are close enough to two line segments to warrant using the - // closest approach point. The intersection may not be close enough to - // use, but if it is prefer it as it satisfies two lines instead of one. - if (ret > 1) { - _find_close_isect(&cpinfo, p); - } - - // If we found something, we can snap - if (ret) { - VMOVE(*out_pt, cpinfo.cp); - return 1; - } - - return 0; -} - -int -bv_snap_lines_2d(struct bview *v, fastf_t *vx, fastf_t *vy) -{ - if (!v || !vx || !vy) return 0; - - point2d_t p2d = {0.0, 0.0}; - V2SET(p2d, *vx, *vy); - point_t vp = VINIT_ZERO; - VSET(vp, p2d[0], p2d[1], 0); - point_t p = VINIT_ZERO; - MAT4X3PNT(p, v->gv_view2model, vp); - point_t out_pt = VINIT_ZERO; - if (bv_snap_lines_3d(&out_pt, v, &p) == BRLCAD_OK) { - MAT4X3PNT(vp, v->gv_model2view, out_pt); - (*vx) = vp[0]; - (*vy) = vp[1]; - return 1; - } - - return 0; -} - -void -bv_view_center_linesnap(struct bview *v) -{ - point_t view_pt; - point_t model_pt; - - MAT_DELTAS_GET_NEG(model_pt, v->gv_center); - MAT4X3PNT(view_pt, v->gv_model2view, model_pt); - bv_snap_lines_2d(v, &view_pt[X], &view_pt[Y]); - MAT4X3PNT(model_pt, v->gv_view2model, view_pt); - MAT_DELTAS_VEC_NEG(v->gv_center, model_pt); - bv_update(v); -} - -int -bv_snap_grid_2d(struct bview *v, fastf_t *vx, fastf_t *vy) -{ - int nh, nv; /* whole grid units */ - point_t view_pt; - point_t view_grid_anchor; - fastf_t grid_units_h; /* eventually holds only fractional horizontal grid units */ - fastf_t grid_units_v; /* eventually holds only fractional vertical grid units */ - fastf_t sf; - fastf_t inv_sf; - - if (!v || !vx || !vy) - return 0; - - if (ZERO(v->gv_s->gv_grid.res_h) || - ZERO(v->gv_s->gv_grid.res_v)) - return 0; - - sf = v->gv_base2local; - inv_sf = 1 / sf; - - VSET(view_pt, *vx, *vy, 0.0); - VSCALE(view_pt, view_pt, sf); /* view_pt now in local units */ - - MAT4X3PNT(view_grid_anchor, v->gv_model2view, v->gv_s->gv_grid.anchor); - VSCALE(view_grid_anchor, view_grid_anchor, sf); /* view_grid_anchor now in local units */ - - grid_units_h = (view_grid_anchor[X] - view_pt[X]) / (v->gv_s->gv_grid.res_h * v->gv_base2local); - grid_units_v = (view_grid_anchor[Y] - view_pt[Y]) / (v->gv_s->gv_grid.res_v * v->gv_base2local); - nh = grid_units_h; - nv = grid_units_v; - - grid_units_h -= nh; /* now contains only the fraction part */ - grid_units_v -= nv; /* now contains only the fraction part */ - - if (grid_units_h <= -0.5) - *vx = view_grid_anchor[X] - ((nh - 1) * v->gv_s->gv_grid.res_h * v->gv_base2local); - else if (0.5 <= grid_units_h) - *vx = view_grid_anchor[X] - ((nh + 1) * v->gv_s->gv_grid.res_h * v->gv_base2local); - else - *vx = view_grid_anchor[X] - (nh * v->gv_s->gv_grid.res_h * v->gv_base2local); - - if (grid_units_v <= -0.5) - *vy = view_grid_anchor[Y] - ((nv - 1) * v->gv_s->gv_grid.res_v * v->gv_base2local); - else if (0.5 <= grid_units_v) - *vy = view_grid_anchor[Y] - ((nv + 1) * v->gv_s->gv_grid.res_v * v->gv_base2local); - else - *vy = view_grid_anchor[Y] - (nv * v->gv_s->gv_grid.res_v * v->gv_base2local); - - *vx *= inv_sf; - *vy *= inv_sf; - - return 1; -} - - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libbg/tests/chull.c b/src/libbg/tests/chull.c index c22c3a1d2c6..dcd2d42f64d 100644 --- a/src/libbg/tests/chull.c +++ b/src/libbg/tests/chull.c @@ -27,6 +27,7 @@ #include "bu.h" #include "vmath.h" #include "bg.h" +#define PLOT3_IMPLEMENTATION #include "bv/plot3.h" static diff --git a/src/libbg/tests/obr.c b/src/libbg/tests/obr.c index 607cda785d0..81c9145e9a4 100644 --- a/src/libbg/tests/obr.c +++ b/src/libbg/tests/obr.c @@ -27,6 +27,7 @@ #include "bu.h" #include "vmath.h" #include "bg.h" +#define PLOT3_IMPLEMENTATION #include "bv/plot3.h" static @@ -71,7 +72,6 @@ main(int argc, const char **argv) point2d_t pnts[4+1] = {{0}}; point2d_t expected[4+1] = {{0}}; point2d_t output_pnts[4+1] = {{0}}; - point_t output_3d_pnts[4+1] = {{0}}; int n = 4; V2SET(pnts[0], 1.5, 1.5); @@ -109,6 +109,7 @@ main(int argc, const char **argv) } if (retval) {return -1;} else {bu_log("Test #001 Passed!\n");} if (do_plotting) { + point_t output_3d_pnts[4+1] = {{0}}; VSET(output_3d_pnts[0], output_pnts[0][0], output_pnts[0][1], 0); VSET(output_3d_pnts[1], output_pnts[1][0], output_pnts[1][1], 0); VSET(output_3d_pnts[2], output_pnts[2][0], output_pnts[2][1], 0); @@ -127,7 +128,6 @@ main(int argc, const char **argv) point2d_t pnts[3+1] = {{0}}; point2d_t expected[4+1] = {{0}}; point2d_t output_pnts[4+1] = {{0}}; - point_t output_3d_pnts[4+1] = {{0}}; int n = 3; V2SET(pnts[0], 1.0, 0.0); @@ -163,6 +163,7 @@ main(int argc, const char **argv) } } if (do_plotting) { + point_t output_3d_pnts[4+1] = {{0}}; VSET(output_3d_pnts[0], output_pnts[0][0], output_pnts[0][1], 0); VSET(output_3d_pnts[1], output_pnts[1][0], output_pnts[1][1], 0); VSET(output_3d_pnts[2], output_pnts[2][0], output_pnts[2][1], 0); diff --git a/src/libbg/tests/poly2tri.c b/src/libbg/tests/poly2tri.c index e996bf06774..5504617f494 100644 --- a/src/libbg/tests/poly2tri.c +++ b/src/libbg/tests/poly2tri.c @@ -224,7 +224,7 @@ main(int argc, const char **argv) bg_polygon_plot_2d("test_3_polygon_hole.plot3", (const point2d_t *)(points+12), 4, 0, 0, 255); } - ret = bg_nested_polygon_triangulate(&faces, &num_faces, NULL, NULL, + ret = bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, (const int *)poly, 12, (const int **)hole_array, (const size_t *)&hole_cnt, 1, NULL, 0, (const point2d_t *)points, 16, TRI_EAR_CLIPPING); bu_free(hole_array, "free hole array"); @@ -266,7 +266,7 @@ main(int argc, const char **argv) bg_polygon_plot_2d("test_4_polygon_hole.plot3", (const point2d_t *)(points+8), 4, 0, 0, 255); } - ret = bg_nested_polygon_triangulate(&faces, &num_faces, NULL, NULL, + ret = bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, (const int *)poly, 8, (const int **)hole_array, (const size_t *)&hole_cnt, 1, NULL, 0, (const point2d_t *)points, 12, TRI_EAR_CLIPPING); bu_free(hole_array, "free hole array"); @@ -296,7 +296,7 @@ main(int argc, const char **argv) } num_points = sizeof(points) / sizeof(point2d_t); - ret = bg_polygon_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); + ret = bg_poly_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); if (ret) { bu_log("4 point triangle failure!\n"); return 1; diff --git a/src/libbg/tests/polygon_op.c b/src/libbg/tests/polygon_op.c index 39585773aeb..105b18675ad 100644 --- a/src/libbg/tests/polygon_op.c +++ b/src/libbg/tests/polygon_op.c @@ -139,7 +139,7 @@ main(int argc, const char **argv) VSET(union_expected.contour[0].point[7], 3, -3, 0); /* Calculate union and compare it with the expected result */ - struct bg_polygon *ur = bg_clip_polygon(bg_Union, &p1, &p2, 1.0, NULL, NULL); + struct bg_polygon *ur = bg_clip_polygon(bg_Union, &p1, &p2, 1.0, NULL); if (plot_files) { bg_polygon_plot("ur.plot3", (const point_t *)ur->contour[0].point, ur->contour[0].num_points, 0, 0, 255); } @@ -160,7 +160,7 @@ main(int argc, const char **argv) VSET(difference_expected.contour[0].point[5], 3, -3, 0); /* Calculate difference and compare it with the expected result */ - struct bg_polygon *dr = bg_clip_polygon(bg_Difference, &p1, &p2, 1.0, NULL, NULL); + struct bg_polygon *dr = bg_clip_polygon(bg_Difference, &p1, &p2, 1.0, NULL); if (plot_files) { bg_polygon_plot("dr.plot3", (const point_t *)dr->contour[0].point, dr->contour[0].num_points, 0, 0, 255); } @@ -178,7 +178,7 @@ main(int argc, const char **argv) VSET(intersection_expected.contour[0].point[3], 3, 0, 0); /* Calculate intersection and compare it with the expected result */ - struct bg_polygon *ir = bg_clip_polygon(bg_Intersection, &p1, &p2, 1.0, NULL, NULL); + struct bg_polygon *ir = bg_clip_polygon(bg_Intersection, &p1, &p2, 1.0, NULL); if (plot_files) { bg_polygon_plot("ir.plot3", (const point_t *)ir->contour[0].point, ir->contour[0].num_points, 0, 0, 255); } @@ -219,14 +219,14 @@ main(int argc, const char **argv) } /* Calculate union and compare it with the expected result */ - struct bg_polygon *ucr = bg_clip_polygon(bg_Union, &p3, &p4, 1.0, NULL, NULL); + struct bg_polygon *ucr = bg_clip_polygon(bg_Union, &p3, &p4, 1.0, NULL); if (plot_files) { bg_polygon_plot("ucr.plot3", (const point_t *)ucr->contour[0].point, ucr->contour[0].num_points, 0, 0, 255); } ret += _bg_polygon_diff(ucr, &p3); /* Calculate intersection and compare it with the expected result */ - struct bg_polygon *icr = bg_clip_polygon(bg_Intersection, &p3, &p4, 1.0, NULL, NULL); + struct bg_polygon *icr = bg_clip_polygon(bg_Intersection, &p3, &p4, 1.0, NULL); if (plot_files) { bg_polygon_plot("icr.plot3", (const point_t *)icr->contour[0].point, icr->contour[0].num_points, 0, 0, 255); } @@ -255,7 +255,7 @@ main(int argc, const char **argv) VSET(de2.contour[1].point[3], 2, -2, 0); /* Calculate difference and compare it with the expected result */ - struct bg_polygon *dcr = bg_clip_polygon(bg_Difference, &p3, &p4, 1.0, NULL, NULL); + struct bg_polygon *dcr = bg_clip_polygon(bg_Difference, &p3, &p4, 1.0, NULL); if (plot_files) { bg_polygon_plot("dcr_1.plot3", (const point_t *)dcr->contour[0].point, dcr->contour[0].num_points, 0, 0, 255); bg_polygon_plot("dcr_2.plot3", (const point_t *)dcr->contour[1].point, dcr->contour[0].num_points, 0, 0, 255); @@ -264,7 +264,7 @@ main(int argc, const char **argv) /* Calculate difference the opposite way - this should be a null return, as * p4 is inside p3 so subtracting p3 from it leaves no geometry */ - struct bg_polygon *dcr2 = bg_clip_polygon(bg_Difference, &p4, &p3, 1.0, NULL, NULL); + struct bg_polygon *dcr2 = bg_clip_polygon(bg_Difference, &p4, &p3, 1.0, NULL); ret += (dcr2->num_contours) ? 1 : 0; return ret; diff --git a/src/libbg/tests/polygon_triangulate.c b/src/libbg/tests/polygon_triangulate.c index 4dad715e92e..de3c6cf2b4f 100644 --- a/src/libbg/tests/polygon_triangulate.c +++ b/src/libbg/tests/polygon_triangulate.c @@ -130,7 +130,7 @@ main(int argc, const char **argv) if (plot_files) { bg_polygon_plot_2d("test_1_polygon.plot3", (const point2d_t *)points, num_points, 255, 0, 0); } - ret = bg_polygon_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); + ret = bg_poly_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); if (ret) { bu_log("test 1 ear clipping failure!\n"); return 1; @@ -138,7 +138,7 @@ main(int argc, const char **argv) _tess_report(faces, num_faces, (const point2d_t *)points, 1, 1); } - ret = bg_polygon_triangulate(&faces2, &num_faces2, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_CONSTRAINED_DELAUNAY); + ret = bg_poly_triangulate(&faces2, &num_faces2, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_CONSTRAINED_DELAUNAY); if (ret) { bu_log("test 1 constrained delaunay failure!\n"); return 1; @@ -175,7 +175,7 @@ main(int argc, const char **argv) if (plot_files) { bg_polygon_plot_2d("test_2_polygon.plot3", (const point2d_t *)points, num_points, 255, 0, 0); } - ret = bg_polygon_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); + ret = bg_poly_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); if (ret) { bu_log("test 2 failure!\n"); return 1; @@ -218,7 +218,7 @@ main(int argc, const char **argv) bg_polygon_plot_2d("test_3_polygon_hole.plot3", (const point2d_t *)(points+12), 4, 0, 0, 255); } - ret = bg_nested_polygon_triangulate(&faces, &num_faces, NULL, NULL, + ret = bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, (const int *)poly, 12, (const int **)hole_array, (const size_t *)&hole_cnt, 1, NULL, 0, (const point2d_t *)points, 16, TRI_EAR_CLIPPING); bu_free(hole_array, "free hole array"); @@ -260,7 +260,7 @@ main(int argc, const char **argv) bg_polygon_plot_2d("test_4_polygon_hole.plot3", (const point2d_t *)(points+8), 4, 0, 0, 255); } - ret = bg_nested_polygon_triangulate(&faces, &num_faces, NULL, NULL, + ret = bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, (const int *)poly, 8, (const int **)hole_array, (const size_t *)&hole_cnt, 1, NULL, 0, (const point2d_t *)points, 12, TRI_EAR_CLIPPING); bu_free(hole_array, "free hole array"); @@ -290,7 +290,7 @@ main(int argc, const char **argv) } num_points = sizeof(points) / sizeof(point2d_t); - ret = bg_polygon_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); + ret = bg_poly_triangulate(&faces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)points, num_points, TRI_EAR_CLIPPING); if (ret) { bu_log("4 point triangle failure!\n"); return 1; diff --git a/src/libbg/tests/sat.c b/src/libbg/tests/sat.c index af0aa7c1608..71c9ee2da69 100644 --- a/src/libbg/tests/sat.c +++ b/src/libbg/tests/sat.c @@ -23,6 +23,7 @@ #include #include "bu.h" +#include "bn.h" #include "bg.h" void diff --git a/src/libbg/trimesh.cpp b/src/libbg/trimesh.cpp index 62c2f8ae211..21e5f1dd283 100644 --- a/src/libbg/trimesh.cpp +++ b/src/libbg/trimesh.cpp @@ -381,7 +381,8 @@ bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges) bedge_cnt = bg_trimesh_solid2(vcnt, fcnt, v, f, NULL); } - return bedge_cnt; + /* returns true when not solid */ + return (bedge_cnt > 0) ? 1 : 0; } int diff --git a/src/libbg/trimesh_plot3.cpp b/src/libbg/trimesh_plot3.cpp index 54350983904..2d31eabea9f 100644 --- a/src/libbg/trimesh_plot3.cpp +++ b/src/libbg/trimesh_plot3.cpp @@ -30,6 +30,7 @@ #include "bu/log.h" #include "bu/list.h" #include "bu/malloc.h" +#include "bu/color.h" #include "bu/sort.h" #include "bv/plot3.h" #include "bg/trimesh.h" diff --git a/src/libbn/CMakeLists.txt b/src/libbn/CMakeLists.txt index 16d00b64610..7c319d32e47 100644 --- a/src/libbn/CMakeLists.txt +++ b/src/libbn/CMakeLists.txt @@ -34,7 +34,7 @@ set(LIBBN_SOURCES ) -BRLCAD_ADDLIB(libbn "${LIBBN_SOURCES}" "libbu") +BRLCAD_ADDLIB(libbn "${LIBBN_SOURCES}" "${libbn_deps}") set_target_properties(libbn PROPERTIES VERSION 20.0.1 SOVERSION 20) add_subdirectory(tests) diff --git a/src/libbn/tests/CMakeLists.txt b/src/libbn/tests/CMakeLists.txt index dc4d2e81360..1c12824deb3 100644 --- a/src/libbn/tests/CMakeLists.txt +++ b/src/libbn/tests/CMakeLists.txt @@ -39,6 +39,14 @@ VALIDATE_STYLE("${bn_test_srcs}" bn_test) # WIP - needs to become real test BRLCAD_ADDEXEC(bn_randsph randsph.c "libbu;libbn" TEST) +# Testing with Eigen +BRLCAD_ADDEXEC(bn_eigen eigen.cpp "libbu;libbn" TEST) +if (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other/Eigen") + target_include_directories(bn_eigen SYSTEM PRIVATE "${EIGEN3_INCLUDE_DIRS}") +else (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other/Eigen") + target_include_directories(bn_eigen SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/other/Eigen") +endif (NOT EXISTS "${CMAKE_SOURCE_DIR}/src/other/Eigen") + # # *********** poly.c tests ************* # @@ -363,8 +371,33 @@ BRLCAD_ADD_TEST(NAME bn_ae_vec_2 COMMAND bn_test mat 15 -23.78,42,3. # The value of the returned vector seems to always have the same z value # irrespective of the input. -BRLCAD_ADD_TEST(NAME bn_vec_ae_1 COMMAND bn_test mat 16 1 1 0.291926581820,0.454648713558,0.841470984697) -BRLCAD_ADD_TEST(NAME bn_vec_ae_2 COMMAND bn_test mat 16 0.5 1.2 0.317998846662,0.173723561699,0.932039085893) +BRLCAD_ADD_TEST(NAME bn_vec_ae_00 COMMAND bn_test mat 16 0 0 1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_01 COMMAND bn_test mat 16 0 1.57079632679 0,0,1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_02 COMMAND bn_test mat 16 0 -1.57079632679 0,0,-1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_03 COMMAND bn_test mat 16 0 3.14159265359 -1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_04 COMMAND bn_test mat 16 0 -3.14159265359 -1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_05 COMMAND bn_test mat 16 1.57079632679 0 0,1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_06 COMMAND bn_test mat 16 1.57079632679 1.57079632679 0,0,1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_07 COMMAND bn_test mat 16 1.57079632679 -1.57079632679 0,0,-1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_08 COMMAND bn_test mat 16 1.57079632679 3.14159265359 0,-1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_09 COMMAND bn_test mat 16 1.57079632679 -3.14159265359 0,-1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_10 COMMAND bn_test mat 16 -1.57079632679 0 0,-1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_11 COMMAND bn_test mat 16 -1.57079632679 1.57079632679 0,0,1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_12 COMMAND bn_test mat 16 -1.57079632679 -1.57079632679 0,0,-1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_13 COMMAND bn_test mat 16 -1.57079632679 3.14159265359 0,1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_14 COMMAND bn_test mat 16 -1.57079632679 -3.14159265359 0,1,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_15 COMMAND bn_test mat 16 3.14159265359 0 -1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_16 COMMAND bn_test mat 16 3.14159265359 1.57079632679 0,0,1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_17 COMMAND bn_test mat 16 3.14159265359 -1.57079632679 0,0,-1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_18 COMMAND bn_test mat 16 3.14159265359 3.14159265359 1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_19 COMMAND bn_test mat 16 3.14159265359 -3.14159265359 1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_20 COMMAND bn_test mat 16 -3.14159265359 0 -1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_21 COMMAND bn_test mat 16 -3.14159265359 1.5707963267 0,0,1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_22 COMMAND bn_test mat 16 -3.14159265359 -1.5707963267 0,0,-1) +BRLCAD_ADD_TEST(NAME bn_vec_ae_23 COMMAND bn_test mat 16 -3.14159265359 3.14159265359 1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_24 COMMAND bn_test mat 16 -3.14159265359 -3.14159265359 1,0,0) +BRLCAD_ADD_TEST(NAME bn_vec_ae_25 COMMAND bn_test mat 16 1 1 0.291926581820,0.454648713558,0.841470984697) +BRLCAD_ADD_TEST(NAME bn_vec_ae_26 COMMAND bn_test mat 16 0.5 1.2 0.317998846662,0.173723561699,0.932039085893) # For function #17 (bn_vec_aed), the format is as follows: # @@ -394,7 +427,7 @@ BRLCAD_ADD_TEST(NAME bn_mat_angles_2 COMMAND bn_test mat 18 84.23 19.5 3 # For function #19 (bn_mat_angles_rad), the format is as follows: # # x y z -# +## # where x, y, z are the angles to rotate about their respective axes # x, y, z are floating point numbers and are in radians. diff --git a/src/libbn/tests/eigen.cpp b/src/libbn/tests/eigen.cpp new file mode 100644 index 00000000000..13fcd6df9f2 --- /dev/null +++ b/src/libbn/tests/eigen.cpp @@ -0,0 +1,92 @@ +/* E I G E N . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file eigen.cpp + * + * The primary purpose of this test is to use Eigen's Map capability + * to work with libbn/vmath data. + */ + +#include "common.h" +#include +#include +#include +#include +#include +#include "bu/app.h" +#include "bu/exit.h" +#include "bu/log.h" +#include "bn/mat.h" + +int main(int UNUSED(ac), const char **av) +{ + bu_setprogname(av[0]); + + // Set up a vmath zero matrix without reference to Eigen + mat_t bn_mat; + MAT_ZERO(bn_mat); + bn_mat_print("Initial Zero Matrix", bn_mat); + + // Establish an Eigen map to the vmath mat_t storage + Eigen::Map> emat(bn_mat); + + // Set the matrix to identity in Eigen + emat = Eigen::Matrix::Identity(); + + // Verify (independent of Eigen) that the libbn data received the update + if (!bn_mat_is_identity(bn_mat)) + bu_exit(BRLCAD_ERROR, "Identity matrix assignment failed\n"); + bn_mat_print("Identity Matrix", bn_mat); + + // Set up a vmath vector + vect_t bn_vec = VINIT_ZERO; + + // Establish an Eigen map to the vmath vect_t storage + Eigen::Map> evec(bn_vec); + bu_log("Initial Vector: %g %g %g\n", V3ARGS(bn_vec)); + + // Copy new vector values into evec + evec = Eigen::Vector(3,2,5); + + // Verify the assigned vector contents + vect_t cmp_vec; + VSET(cmp_vec, 3, 2, 5); + if (!VNEAR_EQUAL(cmp_vec, bn_vec, SMALL_FASTF)) + bu_exit(BRLCAD_ERROR, "Vector assignment failed\n"); + bu_log("Updated Vector: %g %g %g\n", V3ARGS(bn_vec)); + + // Unitize both the comparison vector (with libbn) and the original + // vector (with Eigen). Make sure the results are the same. + VUNITIZE(cmp_vec); + evec.normalize(); + if (!VNEAR_EQUAL(cmp_vec, bn_vec, SMALL_FASTF)) + bu_exit(BRLCAD_ERROR, "Vector unitization failed\n"); + bu_log("Normalized Vector: %g %g %g\n", V3ARGS(bn_vec)); + + return 0; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libbrep/CMakeLists.txt b/src/libbrep/CMakeLists.txt index def02224944..2e916ed0fd7 100644 --- a/src/libbrep/CMakeLists.txt +++ b/src/libbrep/CMakeLists.txt @@ -49,7 +49,7 @@ set(LIBBREP_SOURCES tools/util.cpp ) -BRLCAD_ADDLIB(libbrep "${LIBBREP_SOURCES}" "libbv;libbg;libbn;libbu;${OPENNURBS_LIBRARIES};${POLY2TRI_LIBRARIES};${WINSOCK_LIB};${RPCRT_LIB};${STDCXX_LIBRARIES}") +BRLCAD_ADDLIB(libbrep "${LIBBREP_SOURCES}" "${libbrep_deps};${OPENNURBS_LIBRARIES};${POLY2TRI_LIBRARIES};${WINSOCK_LIB};${RPCRT_LIB};${STDCXX_LIBRARIES}") set_target_properties(libbrep PROPERTIES VERSION 20.0.1 SOVERSION 20) if(HIDE_INTERNAL_SYMBOLS) @@ -58,6 +58,15 @@ if(HIDE_INTERNAL_SYMBOLS) set_property(TARGET libbrep APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "OPENNURBS_IMPORTS") endif(HIDE_INTERNAL_SYMBOLS) +# With newer GCC, optimized linking of poly2tri_CDT triggers a compiler warning about a +# new allocation potentially exceeding maximum object size. +if(${BRLCAD_OPTIMIZED} MATCHES "ON") + check_c_compiler_flag(-Wno-error=alloc-size-larger-than= HAVE_NO_ALLOC_SIZE_LARGER_THAN) + if (HAVE_NO_ALLOC_SIZE_LARGER_THAN) + target_link_options(libbrep PRIVATE -Wno-error=alloc-size-larger-than=) + endif (HAVE_NO_ALLOC_SIZE_LARGER_THAN) +endif(${BRLCAD_OPTIMIZED} MATCHES "ON") + add_subdirectory(tests) CMAKEFILES( diff --git a/src/libbrep/PullbackCurve.cpp b/src/libbrep/PullbackCurve.cpp index 14c0a4b8c25..aaa8433a04b 100644 --- a/src/libbrep/PullbackCurve.cpp +++ b/src/libbrep/PullbackCurve.cpp @@ -351,7 +351,10 @@ face_GetBoundingBox( // may be a smaller trimmed subset of surface so worth getting // face boundary bool growcurrent = bGrowBox != 0; - ON_3dPoint min, max; + // ON_Geometry::GetBoundingBox treats an invalid box input as + // empty, which is what we want for the initial calculation + ON_3dPoint min(DBL_MAX, DBL_MAX, DBL_MAX); + ON_3dPoint max(-DBL_MAX, -DBL_MAX, -DBL_MAX); for (int li = 0; li < face.LoopCount(); li++) { for (int ti = 0; ti < face.Loop(li)->TrimCount(); ti++) { ON_BrepTrim *trim = face.Loop(li)->Trim(ti); diff --git a/src/libbrep/boolean.cpp b/src/libbrep/boolean.cpp index 3598838c230..e87c6e3850e 100644 --- a/src/libbrep/boolean.cpp +++ b/src/libbrep/boolean.cpp @@ -50,7 +50,7 @@ #include "brep_except.h" #include "brep_defines.h" -DebugPlot *dplot = NULL; +//DebugPlot *dplot = NULL; // Whether to output the debug messages about b-rep booleans. #define DEBUG_BREP_BOOLEAN 0 @@ -3595,8 +3595,8 @@ get_face_intersection_curves( continue; } - dplot->SSX(events, brep1, brep1->m_F[i].m_si, brep2, brep2->m_F[j].m_si); - dplot->WriteLog(); + //dplot->SSX(events, brep1, brep1->m_F[i].m_si, brep2, brep2->m_F[j].m_si); + //dplot->WriteLog(); ON_SimpleArray face1_curves, face2_curves; for (int k = 0; k < events.Count(); k++) { @@ -3625,8 +3625,8 @@ get_face_intersection_curves( } } } - dplot->ClippedFaceCurves(surf1, surf2, face1_curves, face2_curves); - dplot->WriteLog(); + //dplot->ClippedFaceCurves(surf1, surf2, face1_curves, face2_curves); + //dplot->WriteLog(); if (DEBUG_BREP_BOOLEAN) { // Look for coplanar faces @@ -3851,8 +3851,8 @@ get_evaluated_faces(const ON_Brep *brep1, const ON_Brep *brep2, op_type operatio for (int i = 0; i < original_faces.Count(); i++) { TrimmedFace *first = original_faces[i]; ON_ClassArray linked_curves = link_curves(curves_array[i]); - dplot->LinkedCurves(first->m_face->SurfaceOf(), linked_curves); - dplot->WriteLog(); + //dplot->LinkedCurves(first->m_face->SurfaceOf(), linked_curves); + //dplot->WriteLog(); ON_SimpleArray splitted = split_trimmed_face(first, linked_curves); trimmed_faces.Append(splitted); @@ -3881,8 +3881,8 @@ get_evaluated_faces(const ON_Brep *brep1, const ON_Brep *brep2, op_type operatio categorize_trimmed_faces(trimmed_faces, brep1, brep2, surf_tree1, surf_tree2, operation); - dplot->SplitFaces(trimmed_faces); - dplot->WriteLog(); + //dplot->SplitFaces(trimmed_faces); + //dplot->WriteLog(); for (int i = 0; i < surf_tree1.Count(); i++) { delete surf_tree1[i]; @@ -3976,9 +3976,9 @@ ON_Boolean(ON_Brep *evaluated_brep, const ON_Brep *brep1, const ON_Brep *brep2, ++calls; std::ostringstream prefix; prefix << "bool" << calls; - dplot = new DebugPlot(prefix.str().c_str()); - dplot->Surfaces(brep1, brep2); - dplot->WriteLog(); + //dplot = new DebugPlot(prefix.str().c_str()); + //dplot->Surfaces(brep1, brep2); + //dplot->WriteLog(); ON_ClassArray > trimmed_faces; try { @@ -4000,17 +4000,17 @@ ON_Boolean(ON_Brep *evaluated_brep, const ON_Brep *brep1, const ON_Brep *brep2, } evaluated_brep->ShrinkSurfaces(); evaluated_brep->Compact(); - dplot->WriteLog(); + //dplot->WriteLog(); return 0; } trimmed_faces = get_evaluated_faces(brep1, brep2, operation); } catch (InvalidBooleanOperation &e) { bu_log("%s", e.what()); - dplot->WriteLog(); + //dplot->WriteLog(); return -1; } catch (GeometryGenerationError &e) { bu_log("%s", e.what()); - dplot->WriteLog(); + //dplot->WriteLog(); return -1; } @@ -4073,9 +4073,9 @@ ON_Boolean(ON_Brep *evaluated_brep, const ON_Brep *brep1, const ON_Brep *brep2, bu_log("%s", ON_String(ws).Array()); } - dplot->WriteLog(); - delete dplot; - dplot = NULL; + //dplot->WriteLog(); + //delete dplot; + //dplot = NULL; return 0; } diff --git a/src/libbrep/cdt/fast.cpp b/src/libbrep/cdt/fast.cpp index 6ab963541ce..4d5c6b9b22b 100644 --- a/src/libbrep/cdt/fast.cpp +++ b/src/libbrep/cdt/fast.cpp @@ -517,6 +517,10 @@ getSurfacePoints(const ON_BrepFace &face, } } + // Sanity + if (!bGrowBox) + return; + ON_BoundingBox tight_bbox; if (brep->GetTightBoundingBox(tight_bbox)) { dist = DIST_PNT_PNT(tight_bbox.m_min, tight_bbox.m_max); diff --git a/src/libbrep/cdt/mesh.cpp b/src/libbrep/cdt/mesh.cpp index 2c61c75579a..8799b1c20a4 100644 --- a/src/libbrep/cdt/mesh.cpp +++ b/src/libbrep/cdt/mesh.cpp @@ -1102,7 +1102,7 @@ void cpolygon_t::cdt_inputs_print(const char *filename) } - sfile << "int result = !bg_nested_polygon_triangulate(&faces, &num_faces,\n"; + sfile << "int result = !bg_nested_poly_triangulate(&faces, &num_faces,\n"; sfile << " NULL, NULL, opoly, " << poly.size()+1 << ", NULL, NULL, 0,\n"; sfile << " steiner, " << interior_points.size() << ", pnts_2d, " << pnts_2d.size() << ", TRI_CONSTRAINED_DELAUNAY);\n"; sfile << "if (result) printf(\"success\\n\");\n"; @@ -1177,7 +1177,7 @@ cpolygon_t::cdt(triangulation_t ttype) } } - bool result = (bool)!bg_nested_polygon_triangulate(&faces, &num_faces, + bool result = (bool)!bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, opoly, poly.size()+1, NULL, NULL, 0, steiner, steiner_cnt, bgp_2d, pnts_2d.size(), ttype); @@ -3192,7 +3192,7 @@ cdt_mesh_t::cdt() } } - bool result = (bool)!bg_nested_polygon_triangulate(&faces, &num_faces, + bool result = (bool)!bg_nested_poly_triangulate(&faces, &num_faces, NULL, NULL, opoly, outer_loop.poly.size()+1, holes_array, holes_npts, holes_cnt, steiner, m_interior_pnts.size(), bgp_2d, m_pnts_2d.size(), TRI_CONSTRAINED_DELAUNAY); @@ -5111,7 +5111,7 @@ void cdt_mesh_t::cdt_inputs_print(const char *filename) } } - sfile << "int result = !bg_nested_polygon_triangulate(&faces, &num_faces,\n"; + sfile << "int result = !bg_nested_poly_triangulate(&faces, &num_faces,\n"; sfile << " NULL, NULL, opoly, " << outer_loop.poly.size()+1 << ", holes_array, holes_npts, holes_cnt,\n"; sfile << " steiner, " << m_interior_pnts.size() << ", pnts_2d, " << m_pnts_2d.size() << ", TRI_CONSTRAINED_DELAUNAY);\n"; sfile << "if (result) printf(\"success\\n\");\n"; diff --git a/src/libbrep/debug_plot.cpp b/src/libbrep/debug_plot.cpp index 44587166d19..0123493d889 100644 --- a/src/libbrep/debug_plot.cpp +++ b/src/libbrep/debug_plot.cpp @@ -749,8 +749,8 @@ DebugPlot::SplitFaces( for (int j = 0; j < split_faces[i].Count(); ++j) { TrimmedFace *face = split_faces[i][j]; - unsigned char *outerloop_color = unknown_outerloop_color; - unsigned char *innerloop_color = unknown_innerloop_color; + unsigned char *outerloop_color = NULL; + unsigned char *innerloop_color = NULL; switch (face->m_belong_to_final) { case TrimmedFace::NOT_BELONG: outerloop_color = rejected_outerloop_color; diff --git a/src/libbrep/edit.cpp b/src/libbrep/edit.cpp index af6cac1bb25..5568576f5f5 100644 --- a/src/libbrep/edit.cpp +++ b/src/libbrep/edit.cpp @@ -34,6 +34,41 @@ void *brep_create() return (void *)brep; } +int brep_vertex_create(ON_Brep *brep, ON_3dPoint point) +{ + ON_BrepVertex& v = brep->NewVertex(point); + v.m_tolerance = 0.0; + return brep->m_V.Count() - 1; +} + +bool brep_vertex_remove(ON_Brep *brep, int v_id) +{ + if (v_id < 0 || v_id >= brep->m_V.Count()) { + bu_log("v_id is out of range\n"); + return false; + } + brep->m_V.Remove(v_id); + return true; +} + +int brep_curve2d_make_line(ON_Brep *brep, const ON_2dPoint &from, const ON_2dPoint &to) +{ + ON_Curve* c2 = new ON_LineCurve(from, to); + c2->SetDomain(0.0, 1.0); + brep->m_C2.Append(c2); + return brep->m_C2.Count() - 1; +} + +bool brep_curve2d_remove(ON_Brep *brep, int curve_id) +{ + if (curve_id < 0 || curve_id >= brep->m_C2.Count()) { + bu_log("curve_id is out of range\n"); + return false; + } + brep->m_C2.Remove(curve_id); + return true; +} + int brep_curve_make(ON_Brep *brep, const ON_3dPoint &position) { ON_NurbsCurve *curve = ON_NurbsCurve::New(3, true, 3, 4); @@ -82,7 +117,7 @@ ON_NurbsCurve *brep_get_nurbs_curve(ON_Brep *brep, int curve_id) ON_NurbsSurface *brep_get_nurbs_surface(ON_Brep *brep, int surface_id) { - if (surface_id < 0 || surface_id >= brep->m_C3.Count()) { + if (surface_id < 0 || surface_id >= brep->m_S.Count()) { bu_log("surface_id is out of range\n"); return NULL; } @@ -122,6 +157,30 @@ int brep_curve_interpCrv(ON_Brep *brep, std::vector points) return brep->AddEdgeCurve(curve); } +int brep_curve_copy(ON_Brep *brep, int curve_id) +{ + if (curve_id < 0 || curve_id >= brep->m_C3.Count()) { + bu_log("curve_id is out of range\n"); + return -1; + } + ON_Curve *curve = brep->m_C3[curve_id]; + if (!curve) { + return -1; + } + ON_Curve *curve_copy = curve->DuplicateCurve(); + return brep->AddEdgeCurve(curve_copy); +} + +bool brep_curve_remove(ON_Brep *brep, int curve_id) +{ + if (curve_id < 0 || curve_id >= brep->m_C3.Count()) { + bu_log("curve_id is out of range\n"); + return false; + } + brep->m_C3.Remove(curve_id); + return true; +} + bool brep_curve_move(ON_Brep *brep, int curve_id, const ON_3dVector &point) { /// the curve could be a NURBS curve or not @@ -173,6 +232,24 @@ bool brep_curve_trim(ON_Brep *brep, int curve_id, double t0, double t1) return curve->Trim(interval); } +bool brep_curve_split(ON_Brep *brep, int curve_id, double t) +{ + ON_NurbsCurve *curve = brep_get_nurbs_curve(brep, curve_id); + if (!curve) { + return false; + } + ON_Curve *curve1 = NULL; + ON_Curve *curve2 = NULL; + bool flag = curve->Split(t, curve1, curve2); + if (flag) { + brep->m_C3.Remove(curve_id); + brep->AddEdgeCurve(curve1); + brep->AddEdgeCurve(curve2); + bu_log("old curve removed, id: %d, new curve id: %d, %d\n", curve_id, brep->m_C3.Count() - 2, brep->m_C3.Count() - 1); + } + return flag; +} + int brep_curve_join(ON_Brep *brep, int curve_id_1, int curve_id_2) { ON_NurbsCurve *curve1 = brep_get_nurbs_curve(brep, curve_id_1); @@ -232,6 +309,128 @@ int brep_surface_make(ON_Brep *brep, const ON_3dPoint &position) return brep->AddSurface(surface); } +int brep_surface_extract_vertex(ON_Brep *brep, int surface_id, double u, double v) +{ + ON_NurbsSurface *surface = brep_get_nurbs_surface(brep, surface_id); + if (!surface) { + return -1; + } + ON_3dPoint point; + bool res = surface->Evaluate(u, v, 0, 3, point); + if(!res) { + return -1; + } + ON_BrepVertex& vertex = brep->NewVertex(point); + vertex.m_tolerance = 0.0; + return brep->m_V.Count() - 1; +} + +int brep_surface_extract_curve(ON_Brep *brep, int surface_id, int dir, double t) +{ + ON_NurbsSurface *surface = brep_get_nurbs_surface(brep, surface_id); + if (!surface) { + return -1; + } + ON_Curve *curve = surface->IsoCurve(dir, t); + if(!curve) { + return -1; + } + return brep->AddEdgeCurve(curve); +} + +int brep_surface_copy(ON_Brep *brep, int surface_id) +{ + if (surface_id < 0 || surface_id >= brep->m_S.Count()) { + bu_log("surface_id is out of range\n"); + return -1; + } + ON_Surface *surface = brep->m_S[surface_id]; + if (!surface) { + return -1; + } + ON_Surface *surface_copy = surface->DuplicateSurface(); + return brep->AddSurface(surface_copy); +} + +/** + * caculate parameter values of each point + */ +int SurfMeshParams(int n, int m, std::vector points, std::vector &uk, std::vector &ul); + +/** + * global cubic curve interpolation with C2 continuity + * input: n, knots, Q + * output: P + * reference: The NURBS Book (2nd Edition), chapter 9.2.3 + * TODO: while n <= 3, the special case should be considered + */ +void globalCurveInterp(int n, std::vector &knots, const std::vector &Q, std::vector &P); + +int brep_surface_interpCrv(ON_Brep *brep, int cv_count_x, int cv_count_y, std::vector points) +{ + cv_count_x = cv_count_x < 2 ? 2 : cv_count_x; + cv_count_y = cv_count_y < 2 ? 2 : cv_count_y; + if (points.size() != (size_t)(cv_count_x * cv_count_y)) { + return -1; + } + int n = cv_count_x - 1; + int m = cv_count_y - 1; + + /// calculate parameter values of each point + std::vector uk, ul; + SurfMeshParams(n, m, points, uk, ul); + + /// calculate knots of the cubic B-spline surface + std::vector knots_u, knots_v; + for (size_t i = 0; i < 4; i++) { + knots_u.push_back(0); + knots_v.push_back(0); + } + for (size_t i = 1; i < uk.size() - 1; i++) { + knots_u.push_back(uk[i]); + } + for (size_t i = 1; i < ul.size() - 1; i++) { + knots_v.push_back(ul[i]); + } + for (int i = 0; i < 4; i++) { + knots_u.push_back(1); + knots_v.push_back(1); + } + + /// curve interpolation in v direction + // temporary control points + std::vector> R(n + 1, std::vector(m + 3)); + + for (int l = 0; l <= n; l++) { + std::vector Q(m + 1); + for (int k = 0; k <= m; k++) { + Q[k] = points[l * (m + 1) + k]; + } + globalCurveInterp(m, knots_v, Q, R[l]); + } + + ON_NurbsSurface *surface = ON_NurbsSurface::New(3, false, 4, 4, n + 3, m + 3); + for (int i = 0; i < m + 3; i++) { + std::vector Q(n + 1); + for (int j = 0; j < n + 1; j++) { + Q[j] = R[j][i]; + } + std::vector P(n + 3); + globalCurveInterp(n, knots_u, Q, P); + for (int j = 0; j < n + 3; j++) { + surface->SetCV(j, i, P[j]); + } + } + /// the knot vector of openNURBS is different from the NURBS book + for (size_t i = 1; i < knots_u.size() - 1; i++) { + surface->SetKnot(0, i - 1, knots_u[i]); + } + for (size_t i = 1; i < knots_v.size() - 1; i++) { + surface->SetKnot(1, i - 1, knots_v[i]); + } + return brep->AddSurface(surface); +} + bool brep_surface_move(ON_Brep *brep, int surface_id, const ON_3dVector &point) { /// the surface could be a NURBS surface or not @@ -265,6 +464,23 @@ bool brep_surface_trim(ON_Brep *brep, int surface_id, int dir, double t0, double return surface->Trim(dir, interval); } +bool brep_surface_split(ON_Brep *brep, int surface_id, int dir, double t) +{ + ON_NurbsSurface *surface = brep_get_nurbs_surface(brep, surface_id); + if (!surface) { + return false; + } + ON_Surface *surf1=NULL, *surf2=NULL; + bool flag = surface->Split(dir, t, surf1, surf2); + if (flag) { + brep->m_S.Remove(surface_id); + brep->AddSurface(surf1); + brep->AddSurface(surf2); + bu_log("brep_surface_split: split surface %d into %d and %d\n", surface_id, brep->m_S.Count()-2, brep->m_S.Count()-1); + } + return flag; +} + int brep_surface_create_ruled(ON_Brep *brep, int curve_id0, int curve_id1) { ON_NurbsCurve *curve0 = brep_get_nurbs_curve(brep, curve_id0); @@ -280,6 +496,161 @@ int brep_surface_create_ruled(ON_Brep *brep, int curve_id0, int curve_id1) return brep->AddSurface(surface); } +int brep_surface_tensor_product(ON_Brep *brep, int curve_id0, int curve_id1) +{ + ON_NurbsCurve *curve0 = brep_get_nurbs_curve(brep, curve_id0); + ON_NurbsCurve *curve1 = brep_get_nurbs_curve(brep, curve_id1); + if (!curve0 || !curve1) { + return -1; + } + ON_SumSurface *surface = ON_SumSurface::New(); + if(!surface->Create(*curve0, *curve1)) { + delete surface; + return -1; + } + ON_NurbsSurface *nurbs_surface = surface->NurbsSurface(); + delete surface; + if(nurbs_surface == NULL) { + return -1; + } + return brep->AddSurface(nurbs_surface); +} + +int brep_surface_revolution(ON_Brep *brep, int curve_id0, ON_3dPoint line_start, ON_3dPoint line_end, double angle) +{ + + ON_NurbsCurve *curve0 = brep_get_nurbs_curve(brep, curve_id0); + if(!curve0) { + return -1; + } + ON_RevSurface* rev_surf = ON_RevSurface::New(); + ON_Line line = ON_Line(line_start, line_end); + if(angle < ON_ZERO_TOLERANCE) { + angle = -angle; + line.Reverse(); + } + if (angle > 2 * ON_PI) { + angle = 2 * ON_PI; + } + rev_surf->m_curve = curve0; + rev_surf->m_axis = line; + rev_surf->m_angle = ON_Interval(0, angle); + + // Get the NURBS form of the surface + ON_NurbsSurface *nurbs_surface = ON_NurbsSurface::New(); + rev_surf->GetNurbForm(*nurbs_surface, 0.0); + delete rev_surf; + return brep->AddSurface(nurbs_surface); +} + +bool brep_surface_remove(ON_Brep *brep, int surface_id) +{ + if (surface_id < 0 || surface_id >= brep->m_S.Count()) { + bu_log("surface_id is out of range\n"); + return false; + } + brep->m_S.Remove(surface_id); + return true; +} + +int brep_edge_create(ON_Brep *brep, int from, int to, int curve) +{ + ON_BrepVertex& v0 = brep->m_V[from]; + ON_BrepVertex& v1 = brep->m_V[to]; + ON_BrepEdge& edge = brep->NewEdge(v0, v1, curve); + edge.m_tolerance = 0.0; + return brep->m_E.Count() - 1; +} + +int brep_face_create(ON_Brep *brep, int surface) +{ + if(surface < 0 || surface >= brep->m_S.Count()) { + bu_log("surface is out of range\n"); + return -1; + } + brep->NewFace(surface); + return brep->m_F.Count() - 1; +} + +bool brep_face_reverse(ON_Brep *brep, int face) +{ + if(face < 0 || face >= brep->m_F.Count()) { + bu_log("face is out of range\n"); + return false; + } + ON_BrepFace& f = brep->m_F[face]; + f.m_bRev = !f.m_bRev; + return true; +} + +ON_Curve* getEdgeCurve(const ON_Surface& s, int side) +{ + ON_2dPoint from, to; + double u0, u1, v0, v1; + s.GetDomain(0, &u0, &u1); + s.GetDomain(1, &v0, &v1); + + switch (side) { + case 0: + from.x = u0; from.y = v0; + to.x = u1; to.y = v0; + break; + case 1: + from.x = u1; from.y = v0; + to.x = u1; to.y = v1; + break; + case 2: + from.x = u1; from.y = v1; + to.x = u0; to.y = v1; + break; + case 3: + from.x = u0; from.y = v1; + to.x = u0; to.y = v0; + break; + default: + return NULL; + } + ON_Curve* c2d = new ON_LineCurve(from, to); + c2d->SetDomain(0.0, 1.0); + return c2d; +} + +int brep_loop_create(ON_Brep *brep, int face_id) +{ + if(face_id < 0 || face_id >= brep->m_F.Count()) { + bu_log("face_id is out of range\n"); + return -1; + } + ON_BrepFace& face = brep->m_F[face_id]; + ON_BrepLoop& loop = brep->NewLoop(ON_BrepLoop::outer, face); + return loop.m_loop_index; +} + +int brep_trim_create(ON_Brep *brep, int loop_id, int edge_id, int orientation, int para_curve_id) +{ + if(loop_id < 0 || loop_id >= brep->m_L.Count()) { + bu_log("loop_id is out of range\n"); + return -1; + } + if(edge_id < 0 || edge_id >= brep->m_E.Count()) { + bu_log("edge_id is out of range\n"); + return -1; + } + if(para_curve_id < 0 || para_curve_id >= brep->m_C2.Count()) { + bu_log("para_curve_id is out of range\n"); + return -1; + } + ON_BrepLoop& loop = brep->m_L[loop_id]; + ON_BrepTrim& trim = brep->NewTrim(brep->m_E[edge_id], orientation, loop, para_curve_id); + trim.m_type = ON_BrepTrim::mated; + const ON_Curve* c2 = brep->m_C2[trim.m_c2i]; + const ON_Surface* s = loop.SurfaceOf(); + ON_Interval PD = trim.ProxyCurveDomain(); + trim.m_iso = s->IsIsoparametric(*c2, &PD); + trim.m_tolerance[0] = 0.0; + trim.m_tolerance[1] = 0.0; + return trim.m_trim_index; +} std::vector calculateTangentVectors(const std::vector &points) { @@ -377,6 +748,154 @@ void calcuBsplineCVsKnots(std::vector &cvs, std::vector &kno knots.push_back(1); } +// caculate parameters of the surface +// input: n, m, points +// output: uk, ul +int SurfMeshParams(int n, int m, std::vector points, std::vector &uk, std::vector &ul) +{ + std::vector cds; + n > m ? cds.resize(n + 1) : cds.resize(m + 1); + int num = m + 1; // number of nondegenerate rows + uk.resize(n + 1); + uk[0] = 0.0f; + uk[n] = 1.0f; + for (int i = 1; i < n; i++) + uk[i] = 0; + for (int i = 0; i <= m; i++) { + double sum = 0; + for (int j = 1; j <= n; j++) { + cds[j] = points[i * (n + 1) + j].DistanceTo(points[i * (n + 1) + j - 1]); + sum += cds[j]; + } + if (sum <= 0) + num--; + else + { + double d = 0.0f; + for (int j = 1; j < n; j++) + { + d += cds[j]; + uk[j] += d / sum; + } + } + } + if (num == 0) + return -1; + for (int i = 1; i < n; i++) + uk[i] /= num; + + num = n + 1; + ul.resize(m + 1); + ul[0] = 0.0f; + ul[m] = 1.0f; + for (int i = 1; i < m; i++) + ul[i] = 0; + for (int i = 0; i <= n; i++) { + double sum = 0; + for (int j = 1; j <= m; j++) { + cds[j] = points[j * (n + 1) + i].DistanceTo(points[(j - 1) * (n + 1) + i]); + sum += cds[j]; + } + if (sum <= 0) + num--; + else + { + double d = 0.0f; + for (int j = 1; j < m; j++) + { + d += cds[j]; + ul[j] += d / sum; + } + } + } + if (num == 0) + return -1; + for (int i = 1; i < m; i++) + ul[i] /= num; + return 0; +} + +void bsplineBasisFuns(int i, double u, int p, std::vector U, std::vector &N) +{ + double *left = (double *)bu_calloc(p + 1, sizeof(double), "left"); + double *right = (double *)bu_calloc(p + 1, sizeof(double), "right"); + double saved, temp; + int j, r; + N[0] = 1.0; + + for (j = 1; j <= p; j++) { + left[j] = u - U[i + 1 - j]; + right[j] = U[i + j] - u; + saved = 0.0; + + for (r = 0; r < j; r++) { + temp = N[r] / (right[r + 1] + left[j - r]); + N[r] = saved + right[r + 1] * temp; + saved = left[j - r] * temp; + } + N[j] = saved; + } + bu_free(left, "left"); + bu_free(right, "right"); +} + +/** + * solve tridiagonal equation for cubic spline interpolation + */ +int solveTridiagonalint(int n, std::vector Q, std::vector U, std::vector& P) +{ + std::vector abc(4); + std::vector R(n + 1); + std::vector dd(n + 1); + double den; + int i; + + for (i = 3; i < n; i++) { + R[i] = Q[i - 1]; + } + + bsplineBasisFuns(4, U[4], 3, U, abc); + den = abc[1]; + + /* P[2] */ + P[2] = (Q[1] - abc[0] * P[1]) / den; + + for (i = 3; i < n; i++) { + dd[i] = abc[2] / den; + + bsplineBasisFuns(i + 2, U[i + 2], 3, U, abc); + den = abc[1] - abc[0] * dd[i]; + P[i] = (R[i] - abc[0] * P[i - 1]) / den; + } + + dd[n] = abc[2] / den; + + bsplineBasisFuns(n + 2, U[n + 2], 3, U, abc); + den = abc[1] - abc[0] * dd[n]; + + P[n] = (Q[n - 1] - abc[2] * P[n + 1] - abc[0] * P[n - 1]) / den; + + for (i = (n - 1); i >= 2; i--) { + P[i] = P[i] - dd[i + 1] * P[i + 1]; + } + + if (n == 2) { + P[2] /= 4.0f / 3.0f; + } + return 1; +} + +void globalCurveInterp(int n, std::vector &knots, const std::vector &Q, std::vector &P) +{ + /// initialize control points of P[0], P[1], P[n+1], P[n+2] + P.resize(n + 3); + P[0] = Q[0]; + P[1] = Q[0] + (Q[1] - Q[0]) / 3.0f * knots[4]; + P[n + 2] = Q[n]; + P[n + 1] = Q[n] - (Q[n] - Q[n - 1]) / 3.0f * (1.0f - knots[n + 2]); + + solveTridiagonalint(n, Q, knots, P); +} // Local Variables: // tab-width: 8 // mode: C++ diff --git a/src/libbrep/intersect.cpp b/src/libbrep/intersect.cpp index 16c0d699d89..0e7404a9111 100644 --- a/src/libbrep/intersect.cpp +++ b/src/libbrep/intersect.cpp @@ -44,7 +44,7 @@ #include "brep_except.h" #include "brep_defines.h" -extern DebugPlot *dplot; +//extern DebugPlot *dplot; // Whether to output the debug messages about b-rep intersections. static int DEBUG_BREP_INTERSECT = 0; @@ -3579,8 +3579,8 @@ find_overlap_boundary_curves( ON_Intersect(surf1_isocurve, surf2, events, isect_tol, overlap_tol, 0, 0, 0, &overlap2d); - dplot->IsoCSX(events, surf1_isocurve, is_surfA_iso); - dplot->WriteLog(); + //dplot->IsoCSX(events, surf1_isocurve, is_surfA_iso); + //dplot->WriteLog(); append_csx_event_points(isocurve_3d, isocurve2_2d, events); diff --git a/src/libbrep/shape_recognition/planar.cpp b/src/libbrep/shape_recognition/planar.cpp index 74ef4c5b162..578e8c9f8e9 100644 --- a/src/libbrep/shape_recognition/planar.cpp +++ b/src/libbrep/shape_recognition/planar.cpp @@ -117,7 +117,7 @@ triangulate_array(ON_2dPointArray &on2dpts, int *verts_map, int **ffaces, int lo for (int i = 0; i < on2dpts.Count(); i++) verts_map[i] = vert_map[i]; } - if (bg_polygon_triangulate(ffaces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)verts2d, on2dpts.Count(), TRI_EAR_CLIPPING)) { + if (bg_poly_triangulate(ffaces, &num_faces, NULL, NULL, NULL, 0, (const point2d_t *)verts2d, on2dpts.Count(), TRI_EAR_CLIPPING)) { bu_free(verts2d, "free verts2d"); bu_free(pt_ind, "free verts2d"); return 0; @@ -216,7 +216,7 @@ triangulate_array_with_holes(ON_2dPointArray &on2dpts, int *verts_map, int loop_ h_npts[i] = holes_npts[i]; } - bg_nested_polygon_triangulate(ffaces, &num_faces, NULL, NULL, outer_pt_ind, outer_npts, (const int **)h_arrays, h_npts, nholes, NULL, 0, (const point2d_t *)verts2d, on2dpts.Count(), TRI_EAR_CLIPPING); + bg_nested_poly_triangulate(ffaces, &num_faces, NULL, NULL, outer_pt_ind, outer_npts, (const int **)h_arrays, h_npts, nholes, NULL, 0, (const point2d_t *)verts2d, on2dpts.Count(), TRI_EAR_CLIPPING); // fix up vertex indices for (int i = 0; i < num_faces*3; i++) { diff --git a/src/libbu/CMakeLists.txt b/src/libbu/CMakeLists.txt index 9f323d592ba..fdec57824e2 100644 --- a/src/libbu/CMakeLists.txt +++ b/src/libbu/CMakeLists.txt @@ -15,6 +15,7 @@ endif(BRLCAD_ENABLE_BINARY_ATTRIBUTES) # locally used but not needed by users of the library set(BU_LOCAL_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/y2038 + ${LMDB_INCLUDE_DIR} ) if (UUID_INCLUDE_DIR) set(BU_LOCAL_INCLUDE_DIRS ${BU_LOCAL_INCLUDE_DIRS} ${UUID_INCLUDE_DIR}) @@ -58,6 +59,7 @@ set(LIBBU_SOURCES booleanize.c brlcad_path.c bu_init.cpp + cache.cpp cmd.c color.cpp convert.c @@ -148,9 +150,18 @@ else(NOT CMAKE_CXX_STANDARD EQUAL 98) CMAKEFILES(parallel_cpp11thread.cpp) endif(NOT CMAKE_CXX_STANDARD EQUAL 98) -BRLCAD_ADDLIB(libbu "${LIBBU_SOURCES}" "${Foundation_LIBRARIES};Threads::Threads;${DL_LIBRARY};${WINSOCK_LIB};${PSAPI_LIB};${BSON_LIBRARIES};${UUID_LIBRARIES};${M_LIBRARY}") +BRLCAD_ADDLIB(libbu "${LIBBU_SOURCES}" "${Foundation_LIBRARIES};Threads::Threads;${libbu_deps};${DL_LIBRARY};${WINSOCK_LIB};${PSAPI_LIB};${BSON_LIBRARIES};${LMDB_LIBRARIES};${UUID_LIBRARIES};${M_LIBRARY}") set_target_properties(libbu PROPERTIES VERSION 20.0.1 SOVERSION 20) +# With newer GCC, our bitv structure triggers a compiler +# warning about writing 1 byte into a region of size 0. +if(${BRLCAD_OPTIMIZED} MATCHES "ON") + check_c_compiler_flag(-Wno-error=stringop-overflow= HAVE_NO_STRINGOP_OVERFLOW) + if (HAVE_NO_STRINGOP_OVERFLOW) + target_link_options(libbu PRIVATE -Wno-error=stringop-overflow=) + endif (HAVE_NO_STRINGOP_OVERFLOW) +endif(${BRLCAD_OPTIMIZED} MATCHES "ON") + # Define a pre-build test for libbu to check the semaphores in BRL-CAD's headers for # ordering issues #set(BCAD_HDRS_FILE "${CMAKE_CURRENT_BINARY_DIR}/brlcad_headers.txt") diff --git a/src/libbu/cache.cpp b/src/libbu/cache.cpp new file mode 100644 index 00000000000..661d2b33fb4 --- /dev/null +++ b/src/libbu/cache.cpp @@ -0,0 +1,294 @@ +/* C A C H E . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file cache.c + * + * Routines for creating and manipulating a key/value cache database. + * + */ + +#include "common.h" + +#include +#include +#include +#include + +#ifdef HAVE_SYS_STAT_H +# include /* for mkdir */ +#endif + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#include "lmdb.h" + +#include "bio.h" +#include "bu/app.h" +#include "bu/cache.h" +#include "bu/file.h" +#include "bu/malloc.h" +#include "bu/parallel.h" +#include "bu/path.h" +#include "bu/str.h" +#include "bu/vls.h" + +// Maximum database size. +#define CACHE_MAX_DB_SIZE 4294967296 + +struct bu_cache_impl { + MDB_env *env; + MDB_txn *txn; // TODO - do we need to support more than one of these for parallel reading... + MDB_dbi dbi; + MDB_txn *write_txn; // Blocking, only need one + MDB_dbi write_dbi; + struct bu_vls *fname; +}; + +static void +_mk_cache_dir(char *dir) { +#ifdef HAVE_WINDOWS_H + CreateDirectory(dir, NULL); +#else + /* mode: 775 */ + mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif +} + +struct bu_cache * +bu_cache_open(const char *cache_db, int create) +{ + if (!cache_db) + return NULL; + + char cdb[MAXPATHLEN]; + bu_dir(cdb, MAXPATHLEN, BU_DIR_CACHE, cache_db, NULL); + + if (!bu_file_exists(cdb, NULL)) { + // If the cache isn't already present and we're not being told to create it + // in that situation, we need to bail + if (!create) + return NULL; + + // Ensure the necessary top level dirs are present + bu_dir(cdb, MAXPATHLEN, BU_DIR_CACHE, NULL); + if (!bu_file_exists(cdb, NULL)) + _mk_cache_dir(cdb); + + // Break cache_db up into component directories with bu_path_component, + // making sure each one exists + std::vector dirs; + struct bu_vls cdbd = BU_VLS_INIT_ZERO; + struct bu_vls ctmp = BU_VLS_INIT_ZERO; + bu_path_component(&cdbd, cache_db, BU_PATH_DIRNAME); + while (bu_vls_strlen(&cdbd)) { + bu_path_component(&ctmp, bu_vls_cstr(&cdbd), BU_PATH_BASENAME); + dirs.push_back(std::string(bu_vls_cstr(&cdbd))); + bu_vls_sprintf(&ctmp, "%s", bu_vls_cstr(&cdbd)); + bu_path_component(&cdbd, bu_vls_cstr(&ctmp), BU_PATH_DIRNAME); + } + bu_dir(cdb, MAXPATHLEN, BU_DIR_CACHE, NULL); + bu_vls_sprintf(&ctmp, "%s", cdb); + for (long long i = dirs.size() - 1; i >= 0; i--) { + bu_vls_printf(&ctmp, "/%s", dirs[i].c_str()); + if (!bu_file_exists(bu_vls_cstr(&ctmp), NULL)) + _mk_cache_dir((char *)bu_vls_cstr(&ctmp)); + } + + bu_dir(cdb, MAXPATHLEN, BU_DIR_CACHE, cache_db, NULL); + } + + struct bu_cache *c = NULL; + BU_GET(c, struct bu_cache); + BU_GET(c->i, struct bu_cache_impl); + BU_GET(c->i->fname, struct bu_vls); + bu_vls_init(c->i->fname); + bu_vls_sprintf(c->i->fname, "%s", cdb); + + // Base maximum readers on an estimate of how many threads + // we might want to fire off + size_t mreaders = std::thread::hardware_concurrency(); + if (!mreaders) + mreaders = 1; + int ncpus = bu_avail_cpus(); + if (ncpus > 0 && (size_t)ncpus > mreaders) + mreaders = (size_t)ncpus + 2; + + // Set up LMDB environments + if (mdb_env_create(&c->i->env)) + goto bu_context_fail; + if (mdb_env_set_maxreaders(c->i->env, mreaders)) + goto bu_context_close_fail; + if (mdb_env_set_mapsize(c->i->env, CACHE_MAX_DB_SIZE)) + goto bu_context_close_fail; + + // Need to call mdb_env_sync() at appropriate points. + if (mdb_env_open(c->i->env, cdb, MDB_NOSYNC, 0664)) + goto bu_context_close_fail; + + // Success - return the context + return c; + +bu_context_close_fail: + mdb_env_close(c->i->env); +bu_context_fail: + bu_vls_free(c->i->fname); + BU_PUT(c->i->fname, struct bu_vls); + BU_PUT(c->i, struct bu_cache_impl); + BU_PUT(c, struct bu_cache); + return NULL; +} + +void +bu_cache_close(struct bu_cache *c) +{ + if (!c) + return; + + mdb_env_close(c->i->env); + bu_vls_free(c->i->fname); + BU_PUT(c->i->fname, struct bu_vls); + BU_PUT(c->i, struct bu_cache_impl); + BU_PUT(c, struct bu_cache); +} + +static void +_cache_dirclear(const char *d) +{ + if (bu_file_directory(d)) { + char **filenames; + size_t nfiles = bu_file_list(d, "*", &filenames); + for (size_t i = 0; i < nfiles; i++) { + if (BU_STR_EQUAL(filenames[i], ".")) + continue; + if (BU_STR_EQUAL(filenames[i], "..")) + continue; + char cdir[MAXPATHLEN] = {0}; + bu_dir(cdir, MAXPATHLEN, d, filenames[i], NULL); + _cache_dirclear((const char *)cdir); + } + bu_argv_free(nfiles, filenames); + } + bu_file_delete(d); +} + +void +bu_cache_erase(const char *cache_db) +{ + if (!cache_db) + return; + + char cdb[MAXPATHLEN]; + bu_dir(cdb, MAXPATHLEN, BU_DIR_CACHE, cache_db, NULL); + _cache_dirclear(cdb); +} + +size_t +bu_cache_get(void **data, const char *key, struct bu_cache *c) +{ + if (!data || !c || !key) + return 0; + + int mkeysize = mdb_env_get_maxkeysize(c->i->env); + if (mkeysize <= 0 || strlen(key) > (size_t)mkeysize) + return 0; + + MDB_val mdb_key; + MDB_val mdb_data[2]; + + if (!c->i->txn) { + mdb_txn_begin(c->i->env, NULL, 0, &c->i->txn); + mdb_dbi_open(c->i->txn, NULL, 0, &c->i->dbi); + } + mdb_key.mv_size = strlen(key)*sizeof(char); + mdb_key.mv_data = (void *)key; + int rc = mdb_get(c->i->txn, c->i->dbi, &mdb_key, &mdb_data[0]); + if (rc) { + (*data) = NULL; + return 0; + } + (*data) = mdb_data[0].mv_data; + + return mdb_data[0].mv_size; +} + +void +bu_cache_get_done(const char *key, struct bu_cache *c) +{ + if (!key || !c) + return; + + mdb_txn_commit(c->i->txn); + c->i->txn = NULL; +} + +size_t +bu_cache_write(void *data, size_t dsize, char *key, struct bu_cache *c) +{ + if (!data || !key || !c) + return 0; + + int mkeysize = mdb_env_get_maxkeysize(c->i->env); + if (mkeysize <= 0 || strlen(key) > (size_t)mkeysize) + return 0; + + // Prepare inputs for writing + MDB_val mdb_key; + MDB_val mdb_data[2]; + + // Write out key/value to LMDB database, where the key is the hash + // and the value is the serialized LoD data + mdb_txn_begin(c->i->env, NULL, 0, &c->i->write_txn); + mdb_dbi_open(c->i->write_txn, NULL, 0, &c->i->write_dbi); + mdb_key.mv_size = strlen(key)*sizeof(char); + mdb_key.mv_data = (void *)key; + mdb_data[0].mv_size = dsize; + mdb_data[0].mv_data = data; + mdb_data[1].mv_size = 0; + mdb_data[1].mv_data = NULL; + mdb_put(c->i->write_txn, c->i->write_dbi, &mdb_key, mdb_data, 0); + mdb_txn_commit(c->i->write_txn); + return dsize; +} + +void +bu_cache_clear(const char *key, struct bu_cache *c) +{ + if (!key || !c) + return; + + // Construct lookup key + MDB_val mdb_key; + + mdb_txn_begin(c->i->env, NULL, 0, &c->i->write_txn); + mdb_dbi_open(c->i->write_txn, NULL, 0, &c->i->write_dbi); + mdb_key.mv_size = strlen(key)*sizeof(char); + mdb_key.mv_data = (void *)key; + mdb_del(c->i->write_txn, c->i->write_dbi, &mdb_key, NULL); + mdb_txn_commit(c->i->write_txn); +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libbu/dir.c b/src/libbu/dir.c index ed61481fade..0df6b33426a 100644 --- a/src/libbu/dir.c +++ b/src/libbu/dir.c @@ -214,7 +214,15 @@ dir_cache(char *buf, size_t len) if (!buf || !len) return buf; - /* method #1a: platform standard (linux) */ + /* method #1: BRL-CAD environment variable */ + if (BU_STR_EMPTY(path)) { + env = getenv("BU_DIR_CACHE"); + if (env && env[0] != '\0' && !BU_STR_EMPTY(env) && bu_file_writable(env) && bu_file_executable(env)) { + bu_strlcpy(path, env, MAXPATHLEN); + } + } + + /* method #2a: platform standard (linux) */ if (BU_STR_EMPTY(path)) { env = getenv("XDG_CACHE_HOME"); if (!BU_STR_EMPTY(env)) { @@ -222,14 +230,14 @@ dir_cache(char *buf, size_t len) } } - /* method #1b: platform standard (macosx) */ + /* method #2b: platform standard (macosx) */ #if defined(HAVE_CONFSTR) && defined(_CS_DARWIN_CACHE_DIR) if (BU_STR_EMPTY(path)) { confstr(_CS_DARWIN_CACHE_DIR, path, len); } #endif - /* method #1c: platform standard (windows) */ + /* method #2c: platform standard (windows) */ #ifdef HAVE_WINDOWS_H if (BU_STR_EMPTY(path)) { PWSTR wpath; @@ -240,7 +248,7 @@ dir_cache(char *buf, size_t len) } #endif - /* method 2: fallback to home directory subdir */ + /* method 3: fallback to home directory subdir */ if (BU_STR_EMPTY(path)) { dir_home(temp, MAXPATHLEN); bu_strlcat(path, temp, MAXPATHLEN); @@ -248,7 +256,7 @@ dir_cache(char *buf, size_t len) bu_strlcat(path, ".cache", MAXPATHLEN); } - /* method 3: fallback to temp directory subdir */ + /* method 4: fallback to temp directory subdir */ if (BU_STR_EMPTY(path)) { dir_temp(temp, MAXPATHLEN); bu_strlcat(path, temp, MAXPATHLEN); diff --git a/src/libbu/parallel.c b/src/libbu/parallel.c index edec6766124..af007630ab0 100644 --- a/src/libbu/parallel.c +++ b/src/libbu/parallel.c @@ -34,6 +34,10 @@ # include #endif +#ifdef HAVE_SYS_SYSCALL_H +# include +#endif + #ifdef linux # include #endif @@ -44,6 +48,13 @@ # include #endif +#if defined(__FreeBSD__) +# include // for thr_self +#endif +#if defined(__NetBSD__) +# include // for _lwp_self +#endif + #ifdef __APPLE__ # include # include @@ -137,6 +148,26 @@ struct thread_data { struct parallel_info *parent; }; +int +bu_thread_id(void) +{ + #if defined(HAVE_SYS_SYSCALL_H) + return syscall(SYS_gettid); + #elif defined(_WIN32) + return GetCurrentThreadId(); + #elif defined(__FreeBSD__) + long tid; + thr_self(&tid); + return (int)tid; + #elif defined(__NetBSD__) + return _lwp_self(); + #elif defined(__OpenBSD__) + return getthrid(); + #else + return -1; + #endif +} + int bu_parallel_id(void) diff --git a/src/libbu/temp.c b/src/libbu/temp.c index 477ec6ec6f0..8f575ebad1d 100644 --- a/src/libbu/temp.c +++ b/src/libbu/temp.c @@ -40,6 +40,9 @@ #include "bu/malloc.h" #include "bu/time.h" #include "bu/vls.h" +#include "bu/str.h" +#include "bu/parallel.h" +#include "bu/process.h" #define _TF_FAIL "WARNING: Unable to create a temporary file\n" @@ -147,6 +150,29 @@ temp_add_to_list(const char *fn, int fd) all_temp_files.size++; } +#define MAX_FILELEN 25 /* arbitrary len */ +const char* +bu_temp_file_name(char* filename, size_t len) +{ + static char buf[MAX_FILELEN] = {0}; + + memset(buf, 0, MAX_FILELEN); + + /* create name in form of prefix_procID_threadID */ + char* prefix = (filename && filename[0]) ? filename : PACKAGE_NAME; + int procID = bu_process_id(); + int threadID = bu_thread_id(); + snprintf(buf, MAX_FILELEN, "%s_%d_%d", prefix, procID, threadID); + + /* if user supplied buffer, copy over */ + if (len > 0 && strlen(buf) > 0) { + int maxlen = len > MAX_FILELEN ? MAX_FILELEN : len; /* cap len at MAX_FILELEN */ + bu_strlcpy(filename, buf, maxlen); + return filename; + } + + return buf; +} #ifndef HAVE_MKSTEMP static int diff --git a/src/libbu/tests/CMakeLists.txt b/src/libbu/tests/CMakeLists.txt index 1d9f9a4e270..fd72fd12da4 100644 --- a/src/libbu/tests/CMakeLists.txt +++ b/src/libbu/tests/CMakeLists.txt @@ -36,6 +36,7 @@ set(bu_test_srcs sort.c str.c str_isprint.c + temp_filename.c vls.c vls_vprintf.c ) @@ -138,6 +139,12 @@ BRLCAD_ADD_TEST(NAME bu_file_mime_png COMMAND bu_test file_mime png 3 BU_MIME_ #BRLCAD_ADD_TEST(NAME bu_file_glob COMMAND bu_test file_glob) # runs a series of built-in unit tests +#################################### +# bu_temp_filename testing # +#################################### +BRLCAD_ADD_TEST(NAME bu_temp_filename COMMAND bu_test temp_filename "single") +#BRLCAD_ADD_TEST(NAME bu_temp_filename COMMAND bu_test temp_filename "parallel") + # # ************ bitv.c tests ************* # diff --git a/src/libbu/tests/temp_filename.c b/src/libbu/tests/temp_filename.c new file mode 100644 index 00000000000..0ad10850cdd --- /dev/null +++ b/src/libbu/tests/temp_filename.c @@ -0,0 +1,126 @@ +/* T E M P _ F I L E N A M E . C + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "common.h" + +void +temp_filename_thread(int cpu, void* ptr) +{ + // unroll ptr into names arr + char** names = (char**)ptr; + + // generate name + const char* buf = bu_temp_file_name(NULL, 0); + + // add to arr + size_t len = strlen(buf); + names[cpu - 1] = (char*)bu_malloc(len * sizeof(char), "alloc name"); + bu_strlcpy(names[cpu - 1], buf, len); +} + +int +main(int argc, char *argv[]) +{ + // Normally this file is part of bu_test, so only set this if it looks like + // the program name is still unset. + if (bu_getprogname()[0] == '\0') + bu_setprogname(argv[0]); + + /* group tests so failures are easier to pinpoint */ + char* curr = NULL; + for (int test = 1; test < argc; test++) { + curr = argv[test]; + + if (!bu_strcmp(curr, "single")) { + // test with different configurations - all thread and proc ID's should be the same + + // no prefix - buffer + no-buffer should match + char plain[25] = {0}; + bu_temp_file_name(plain, 25); + const char* non_alloc = bu_temp_file_name(NULL, 0); + // validate + if (bu_strncmp(plain, non_alloc, strlen(plain))) /* should match */ + bu_exit(EXIT_FAILURE, "temp_filename failure: expected match, got [%s] | [%s]\n", plain, non_alloc); + + // prefix - buffer + no-buffer should match + char prefix[25] = "prefix"; + bu_temp_file_name(prefix, 25); + const char* prefix_non_alloc = bu_temp_file_name(prefix, 0); + // validate + if (bu_strncmp(prefix, prefix_non_alloc, strlen(prefix))) /* should match */ + bu_exit(EXIT_FAILURE, "temp_filename failure: expected match, got [%s] | [%s]\n", prefix, prefix_non_alloc); + + // validate prefix != generic + if (!bu_strncmp(plain, prefix, strlen(plain))) /* should not match */ + bu_exit(EXIT_FAILURE, "temp_filename failure: expected non-matching names\n"); + + // undersized buffer - should create 4 chars + null termination + char under_size[5] = {0}; + bu_temp_file_name(under_size, 5); + // validate + if (strlen(under_size) != 4) /* buffer size -1 */ + bu_exit(EXIT_FAILURE, "temp_filename failure: expected size [%d], got [%ld]]\n", 4, strlen(under_size)); + + } else if (!bu_strcmp(curr, "parallel")) { + // test parallel / threaded - + uint8_t threads = bu_avail_cpus(); + + /* create names array. passed to each thread to ensure each name is created uniquely */ + char** names = (char**)bu_malloc(threads * sizeof(char*), "alloc names arr"); + /* individual names are allocated in each thread */ + /*for (int i = 0; i < threads; i++) + names[i] = (char*)bu_malloc(25 * sizeof(char), "zero alloc name");*/ + + bu_parallel(temp_filename_thread, threads, &names); + + // check names are all unique, free memory as we go + int failed = 0; + for (int i = 0; i < threads; i++) { + for (int j = i + 1; j < threads; j++) { + /* keep going even if we've failed to make sure memory is released */ + if (failed || !bu_strncmp(names[i], names[j], 25)) + failed = 1; + } + bu_free(names[i], "free name"); + } + + /* cleanup */ + bu_free(names, "free names"); + + if (failed) + bu_exit(EXIT_FAILURE, "temp_filename failure: parallel did not create unique names\n"); + } else { + bu_exit(EXIT_FAILURE, "temp_filename failure: unknown test mode [%s]\n", curr); + } + } + + return 0; +} + + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libbv/CMakeLists.txt b/src/libbv/CMakeLists.txt index 80b5987d362..2038d4d4dd8 100644 --- a/src/libbv/CMakeLists.txt +++ b/src/libbv/CMakeLists.txt @@ -18,7 +18,11 @@ set(LIBBV_SRCS diff.c font.c hash.c - plot3.c + lod.cpp + polygon.c + polygon_op.cpp + polygon_fill.cpp + snap.c tig/axis.c tig/list.c tig/marker.c @@ -32,8 +36,14 @@ set(LIBBV_SRCS view_sets.cpp ) -BRLCAD_ADDLIB(libbv "${LIBBV_SRCS}" "libbn;libbu") +BRLCAD_ADDLIB(libbv "${LIBBV_SRCS}" "${libbv_deps}") set_target_properties(libbv PROPERTIES VERSION 20.0.1 SOVERSION 20) +if(HIDE_INTERNAL_SYMBOLS) + set_property(TARGET libbv APPEND PROPERTY COMPILE_DEFINITIONS "PLOT3_DLL_EXPORTS") + if (TARGET libbv-obj) + set_property(TARGET libbv-obj APPEND PROPERTY COMPILE_DEFINITIONS "PLOT3_DLL_EXPORTS") + endif (TARGET libbv-obj) +endif(HIDE_INTERNAL_SYMBOLS) add_subdirectory(tests) diff --git a/src/libbv/diff.c b/src/libbv/diff.c index 6b0e0de4a3c..b140b9bde44 100644 --- a/src/libbv/diff.c +++ b/src/libbv/diff.c @@ -331,6 +331,7 @@ _bv_grid_state_differ(struct bv_grid_state *v1, struct bv_grid_state *v2) BV_NDIFF(1,rc); BV_NDIFF(1,draw); + BV_NDIFF(1,adaptive); BV_NDIFF(1,snap); BV_VDIFF(1,anchor); BV_NDIFF(1,res_h); @@ -341,6 +342,27 @@ _bv_grid_state_differ(struct bv_grid_state *v1, struct bv_grid_state *v2) return 0; } +static int +_bv_params_state_differ(struct bv_params_state *v1, struct bv_params_state *v2) +{ + /* First, do sanity checks */ + if (!v1 && !v2) + return -1; + if ((v1 && !v2) || (!v1 && v2)) + return -1; + + BV_NDIFF(1,draw); + BV_NDIFF(1,draw_size); + BV_NDIFF(1,draw_center); + BV_NDIFF(1,draw_az); + BV_NDIFF(1,draw_el); + BV_NDIFF(1,draw_tw); + BV_NDIFF(1,draw_fps); + BV_IVDIFF(1,color); + BV_NDIFF(1,font_size); + return 0; +} + static int _bv_other_state_differ(struct bv_other_state *v1, struct bv_other_state *v2) { @@ -408,7 +430,7 @@ _bv_settings_differ(struct bview_settings *v1, struct bview_settings *v2) BV_CDIFF(1, _bv_axes_differ, gv_view_axes); BV_CDIFF(1, _bv_grid_state_differ, gv_grid); BV_CDIFF(1, _bv_other_state_differ, gv_center_dot); - BV_CDIFF(1, _bv_other_state_differ, gv_view_params); + BV_CDIFF(1, _bv_params_state_differ, gv_view_params); BV_CDIFF(1, _bv_other_state_differ, gv_view_scale); BV_CDIFF(1, _bv_interactive_rect_state_differ, gv_rect); @@ -467,7 +489,7 @@ bv_differ(struct bview *v1, struct bview *v2) BV_NDIFF(1,gv_rscale); BV_NDIFF(1,gv_sscale); - BV_NDIFF(1,gv_data_vZ); + BV_NDIFF(1, gv_tcl.gv_data_vZ); BV_CDIFF(1, _bv_data_arrow_state_differ, gv_tcl.gv_data_arrows); BV_CDIFF(1, _bv_data_axes_state_differ, gv_tcl.gv_data_axes); diff --git a/src/libbv/hash.c b/src/libbv/hash.c index 66248fd496c..d5174948b38 100644 --- a/src/libbv/hash.c +++ b/src/libbv/hash.c @@ -171,6 +171,16 @@ _bv_grid_state_hash(XXH64_state_t *state, struct bv_grid_state *v) XXH64_update(state, v, sizeof(struct bv_grid_state)); } +static void +_bv_params_state_hash(XXH64_state_t *state, struct bv_params_state *v) +{ + /* First, do sanity checks */ + if (!v || !state) + return; + + XXH64_update(state, v, sizeof(struct bv_params_state)); +} + static void _bv_other_state_hash(XXH64_state_t *state, struct bv_other_state *v) { @@ -267,7 +277,7 @@ bv_settings_hash(XXH64_state_t *state, struct bview_settings *s) _bv_axes_hash(state, &s->gv_view_axes); _bv_grid_state_hash(state, &s->gv_grid); _bv_other_state_hash(state, &s->gv_center_dot); - _bv_other_state_hash(state, &s->gv_view_params); + _bv_params_state_hash(state, &s->gv_view_params); _bv_other_state_hash(state, &s->gv_view_scale); _bv_interactive_rect_state_hash(state, &s->gv_rect); @@ -318,6 +328,8 @@ bv_hash(struct bview *v) tbls[2] = bv_view_objs(v, BV_VIEW_OBJS); tbls[3] = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); for (int t = 0; t < 4; t++) { + if (!tbls[t]) + continue; for (size_t i = 0; i < BU_PTBL_LEN(tbls[t]); i++) { struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(tbls[t], i); if (BU_PTBL_IS_INITIALIZED(&g->children)) { diff --git a/src/libbv/lod.cpp b/src/libbv/lod.cpp new file mode 100644 index 00000000000..14b648b85ed --- /dev/null +++ b/src/libbv/lod.cpp @@ -0,0 +1,2306 @@ +/* L O D . C P P + * BRL-CAD + * + * Copyright (c) 2022-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * Based off of code from https://github.com/bhaettasch/pop-buffer-demo + * Copyright (c) 2016 Benjamin Hättasch and X3DOM + * The MIT License (MIT) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file lod.cpp + * + * This file implements level-of-detail routines. Eventually it may have libbg + * wrappers around more sophisticated algorithms... + * + * The POP Buffer: Rapid Progressive Clustering by Geometry Quantization + * https://x3dom.org/pop/files/popbuffer2013.pdf + * + * Useful discussion of applying POP buffers here: + * https://medium.com/@petroskataras/the-ayotzinapa-case-447a72d89e58 + * + * Notes on caching: + * + * Management of LoD cached data is actually a bit of a challenge. A full + * content hash of the original ver/tri arrays is the most reliable approach + * but is a potentially expensive operation, which also requires reading the + * entire original geometry to get the hash value to do lookups. Ideally, we'd + * like for the application to never have to access more of the data than is + * needed for display purposes. However, object names are not unique across .g + * files and so are not useful for this purpose. Also, at this level of the + * logic we (deliberately) are separated from any notion of .g objects. + * + * What we do is generate a hash value of the data on initialization, when we + * need the full data set to perform the initial LoD setup. We then provide + * that value back to the caller for them to manage at a higher level. + */ + +#include "common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_STAT_H +# include /* for mkdir */ +#endif + +extern "C" { +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#include "lmdb.h" +} + +#include "bio.h" + +#include "bu/app.h" +#include "bu/bitv.h" +#include "bu/color.h" +#include "bu/malloc.h" +#include "bu/parallel.h" +#include "bu/path.h" +#include "bu/str.h" +#include "bu/time.h" +#include "bg/plane.h" +#include "bg/sat.h" +#include "bg/trimesh.h" +#include "bv/plot3.h" +#include "bv/lod.h" +#include "bv/util.h" +#include "bv/view_sets.h" + +// Number of levels of detail to define +#define POP_MAXLEVEL 16 + +// Subdirectory in BRL-CAD cache to hold this type of LoD data +#define POP_CACHEDIR ".POPLoD" + +// Factor by which to bump out bounds to avoid points on box edges +#define MBUMP 1.01 + +// Maximum database size. For detailed views we fall back on just +// displaying the full data set, and we need to be able to memory map the +// file, so go with a 4Gb per file limit. +#define CACHE_MAX_DB_SIZE 4294967296 + +// Define what format of the cache is current - if it doesn't match, we need +// to wipe and redo. +#define CACHE_CURRENT_FORMAT 1 + +/* There are various individual pieces of data in the cache associated with + * each object key. For lookup they use short suffix strings to distinguish + * them - we define those strings here to have consistent definitions for use + * in multiple functions. + * + * Changing any of these requires incrementing CACHE_CURRENT_FORMAT. */ +#define CACHE_POP_MAX_LEVEL "th" +#define CACHE_POP_SWITCH_LEVEL "sw" +#define CACHE_VERTEX_COUNT "vc" +#define CACHE_TRI_COUNT "tc" +#define CACHE_OBJ_BOUNDS "bb" +#define CACHE_VERT_LEVEL "v" +#define CACHE_VERTNORM_LEVEL "vn" +#define CACHE_TRI_LEVEL "t" + +typedef int (*full_detail_clbk_t)(struct bv_mesh_lod *, void *); + +static void +lod_dir(char *dir) +{ +#ifdef HAVE_WINDOWS_H + CreateDirectory(dir, NULL); +#else + /* mode: 775 */ + mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif +} + +static void +obj_bb(int *have_objs, vect_t *min, vect_t *max, struct bv_scene_obj *s, struct bview *v) +{ + vect_t minus, plus; + if (bv_scene_obj_bound(s, v)) { + *have_objs = 1; + minus[X] = s->s_center[X] - s->s_size; + minus[Y] = s->s_center[Y] - s->s_size; + minus[Z] = s->s_center[Z] - s->s_size; + VMIN(*min, minus); + plus[X] = s->s_center[X] + s->s_size; + plus[Y] = s->s_center[Y] + s->s_size; + plus[Z] = s->s_center[Z] + s->s_size; + VMAX(*max, plus); + } + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_obj *sc = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); + obj_bb(have_objs, min, max, sc, v); + } +} + +// Debugging function to see constructed arb +#define ARB_MAX_STRLEN 400 +const char * +obb_arb(vect_t obb_center, vect_t obb_extent1, vect_t obb_extent2, vect_t obb_extent3) +{ + static char str[ARB_MAX_STRLEN+1]; + + // For debugging purposes, construct an arb + point_t arb[8]; + // 1 - c - e1 - e2 - e3 + VSUB2(arb[0], obb_center, obb_extent1); + VSUB2(arb[0], arb[0], obb_extent2); + VSUB2(arb[0], arb[0], obb_extent3); + // 2 - c - e1 - e2 + e3 + VSUB2(arb[1], obb_center, obb_extent1); + VSUB2(arb[1], arb[1], obb_extent2); + VADD2(arb[1], arb[1], obb_extent3); + // 3 - c - e1 + e2 + e3 + VSUB2(arb[2], obb_center, obb_extent1); + VADD2(arb[2], arb[2], obb_extent2); + VADD2(arb[2], arb[2], obb_extent3); + // 4 - c - e1 + e2 - e3 + VSUB2(arb[3], obb_center, obb_extent1); + VADD2(arb[3], arb[3], obb_extent2); + VSUB2(arb[3], arb[3], obb_extent3); + // 1 - c + e1 - e2 - e3 + VADD2(arb[4], obb_center, obb_extent1); + VSUB2(arb[4], arb[4], obb_extent2); + VSUB2(arb[4], arb[4], obb_extent3); + // 2 - c + e1 - e2 + e3 + VADD2(arb[5], obb_center, obb_extent1); + VSUB2(arb[5], arb[5], obb_extent2); + VADD2(arb[5], arb[5], obb_extent3); + // 3 - c + e1 + e2 + e3 + VADD2(arb[6], obb_center, obb_extent1); + VADD2(arb[6], arb[6], obb_extent2); + VADD2(arb[6], arb[6], obb_extent3); + // 4 - c + e1 + e2 - e3 + VADD2(arb[7], obb_center, obb_extent1); + VADD2(arb[7], arb[7], obb_extent2); + VSUB2(arb[7], arb[7], obb_extent3); + +#if 0 + bu_log("center: %f %f %f\n", V3ARGS(obb_center)); + bu_log("e1: %f %f %f\n", V3ARGS(obb_extent1)); + bu_log("e2: %f %f %f\n", V3ARGS(obb_extent2)); + bu_log("e3: %f %f %f\n", V3ARGS(obb_extent3)); +#endif + + snprintf(str, ARB_MAX_STRLEN, "in obb.s arb8 %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", + V3ARGS(arb[0]), V3ARGS(arb[1]), V3ARGS(arb[2]), V3ARGS(arb[3]), V3ARGS(arb[4]), V3ARGS(arb[5]), V3ARGS(arb [6]), V3ARGS(arb[7])); + return str; +} + +static void +view_obb(struct bview *v, + point_t sbbc, fastf_t radius, + vect_t dir, + point_t ec, point_t ep1, point_t ep2) +{ + + // Box center is the closest point to the view center on the plane defined + // by the scene's center and the view dir + plane_t p; + bg_plane_pt_nrml(&p, sbbc, dir); + fastf_t pu, pv; + bg_plane_closest_pt(&pu, &pv, p, ec); + bg_plane_pt_at(&v->obb_center, p, pu, pv); + + // The first extent is just the scene radius in the lookat direction + VSCALE(dir, dir, radius); + VMOVE(v->obb_extent1, dir); + + // The other two extents we find by subtracting the view center from the edge points + VSUB2(v->obb_extent2, ep1, ec); + VSUB2(v->obb_extent3, ep2, ec); + + bv_log(3, "view_obb inputs[%s]: sbbc(%f %f %f) radius(%f) dir(%f %f %f)", bu_vls_cstr(&v->gv_name), V3ARGS(sbbc), radius, V3ARGS(dir)); + bv_log(3, "view_obb[%s]: %f %f %f -> [%f %f %f] [%f %f %f] [%f %f %f]", bu_vls_cstr(&v->gv_name), V3ARGS(v->obb_center), V3ARGS(v->obb_extent1), V3ARGS(v->obb_extent2), V3ARGS(v->obb_extent3)); + bv_log(3, "%s", obb_arb(v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)); +} + +static void +_scene_radius(point_t *sbbc, fastf_t *radius, struct bview *v) +{ + if (!sbbc || !radius || !v) + return; + VSET(*sbbc, 0, 0, 0); + *radius = 1.0; + vect_t min, max, work; + VSETALL(min, INFINITY); + VSETALL(max, -INFINITY); + int have_objs = 0; + struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); + if (!so) + return; + for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { + struct bv_scene_obj *g = (struct bv_scene_obj *)BU_PTBL_GET(so, i); + obj_bb(&have_objs, &min, &max, g, v); + } + struct bu_ptbl *sol = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (sol) { + for (size_t i = 0; i < BU_PTBL_LEN(sol); i++) { + struct bv_scene_obj *g = (struct bv_scene_obj *)BU_PTBL_GET(sol, i); + obj_bb(&have_objs, &min, &max, g, v); + } + } + if (have_objs) { + VADD2SCALE(*sbbc, max, min, 0.5); + VSUB2SCALE(work, max, min, 0.5); + (*radius) = MAGNITUDE(work); + } +} + +void +bv_view_bounds(struct bview *v) +{ + if (!v || !v->gv_width || !v->gv_height) + return; + + // Get the radius of the scene. + point_t sbbc = VINIT_ZERO; + fastf_t radius = 1.0; + _scene_radius(&sbbc, &radius, v); + + // Using the pixel width and height of the current "window", construct some + // view space dimensions related to that window + int w = v->gv_width; + int h = v->gv_height; + int x = (int)(w * 0.5); + int y = (int)(h * 0.5); + //bu_log("w,h,x,y: %d %d %d %d\n", w,h, x, y); + fastf_t x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, xc = 0.0, yc = 0.0; + bv_screen_to_view(v, &x1, &y1, x, h); + bv_screen_to_view(v, &x2, &y2, w, y); + bv_screen_to_view(v, &xc, &yc, x, y); + + // Also stash the window's view space bbox + fastf_t w0, w1, w2, w3; + bv_screen_to_view(v, &w0, &w1, 0, 0); + bv_screen_to_view(v, &w2, &w3, w, h); + v->gv_wmin[0] = (w0 < w2) ? w0 : w2; + v->gv_wmin[1] = (w1 < w3) ? w1 : w3; + v->gv_wmax[0] = (w0 > w2) ? w0 : w2; + v->gv_wmax[1] = (w1 > w3) ? w1 : w3; + //bu_log("vbbmin: %f %f\n", v->gv_wmin[0], v->gv_wmin[1]); + //bu_log("vbbmax: %f %f\n", v->gv_wmax[0], v->gv_wmax[1]); + + // Get the model space points for the mid points of the top and right edges + // of the view. If we don't have a width or height, we will use the + // existing min and max since we don't have a "screen" to base the box on + //bu_log("x1,y1: %f %f\n", x1, y1); + //bu_log("x2,y2: %f %f\n", x2, y2); + //bu_log("xc,yc: %f %f\n", xc, yc); + point_t vp1, vp2, vc, ep1, ep2, ec; + VSET(vp1, x1, y1, 0); + VSET(vp2, x2, y2, 0); + VSET(vc, xc, yc, 0); + MAT4X3PNT(ep1, v->gv_view2model, vp1); + MAT4X3PNT(ep2, v->gv_view2model, vp2); + MAT4X3PNT(ec, v->gv_view2model, vc); + //bu_log("view center: %f %f %f\n", V3ARGS(ec)); + //bu_log("edge point 1: %f %f %f\n", V3ARGS(ep1)); + //bu_log("edge point 2: %f %f %f\n", V3ARGS(ep2)); + + // Need the direction vector - i.e., where the camera is looking. Got this + // trick from the libged nirt code... + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, -1.0); + + // If perspective mode is not enabled, update the oriented bounding box. + if (!(SMALL_FASTF < v->gv_perspective)) { + view_obb(v, sbbc, radius, dir, ec, ep1, ep2); + } + + + // While we have the info, construct the "backed out" point that will let + // us construct the "backed out" view plane, and save that point and the + // lookat direction to the view + VMOVE(v->gv_lookat, dir); + VSCALE(dir, dir, -radius); + VADD2(v->gv_vc_backout, sbbc, dir); + v->radius = radius; +} + +static void +_find_active_objs(std::set &active, struct bv_scene_obj *s, struct bview *v, point_t obb_c, point_t obb_e1, point_t obb_e2, point_t obb_e3) +{ + if (BU_PTBL_LEN(&s->children)) { + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_obj *sc = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); + _find_active_objs(active, sc, v, obb_c, obb_e1, obb_e2, obb_e3); + } + } else { + bv_scene_obj_bound(s, v); + if (bg_sat_aabb_obb(s->bmin, s->bmax, obb_c, obb_e1, obb_e2, obb_e3)) + active.insert(s); + } +} + +int +bv_view_objs_select(struct bu_ptbl *sset, struct bview *v, int x, int y) +{ + if (!v || !sset || !v->gv_width || !v->gv_height) + return 0; + + bu_ptbl_reset(sset); + + if (x < 0 || y < 0 || x > v->gv_width || y > v->gv_height) + return 0; + + + // Get the radius of the scene. + point_t sbbc = VINIT_ZERO; + fastf_t radius = 1.0; + _scene_radius(&sbbc, &radius, v); + + // Using the pixel width and height of the current "window", construct some + // view space dimensions related to that window + fastf_t x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, xc = 0.0, yc = 0.0; + bv_screen_to_view(v, &x1, &y1, x, y+1); + bv_screen_to_view(v, &x2, &y2, x+1, y); + bv_screen_to_view(v, &xc, &yc, x, y); + + // Get the model space points for the mid points of the top and right edges + // of the "pixel + 1" box. + //bu_log("x1,y1: %f %f\n", x1, y1); + //bu_log("x2,y2: %f %f\n", x2, y2); + //bu_log("xc,yc: %f %f\n", xc, yc); + point_t vp1, vp2, vc, ep1, ep2, ec; + VSET(vp1, x1, y1, 0); + VSET(vp2, x2, y2, 0); + VSET(vc, xc, yc, 0); + MAT4X3PNT(ep1, v->gv_view2model, vp1); + MAT4X3PNT(ep2, v->gv_view2model, vp2); + MAT4X3PNT(ec, v->gv_view2model, vc); + + // Need the direction vector - i.e., where the camera is looking. Got this + // trick from the libged nirt code... + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, -1.0); + + + // Construct the box values needed for the SAT test + point_t obb_c, obb_e1, obb_e2, obb_e3; + + // Box center is the closest point to the view center on the plane defined + // by the scene's center and the view dir + plane_t p; + bg_plane_pt_nrml(&p, sbbc, dir); + fastf_t pu, pv; + bg_plane_closest_pt(&pu, &pv, p, ec); + bg_plane_pt_at(&obb_c, p, pu, pv); + + + // The first extent is just the scene radius in the lookat direction + VSCALE(dir, dir, radius); + VMOVE(obb_e1, dir); + + // The other two extents we find by subtracting the view center from the edge points + VSUB2(obb_e2, ep1, ec); + VSUB2(obb_e3, ep2, ec); + + // Having constructed the box, test the scene objects against it. Any that intersect, + // add them to the set + std::set active; + struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); + if (so) { + for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(so, i); + _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); + } + } + struct bu_ptbl *sol = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (sol) { + for (size_t i = 0; i < BU_PTBL_LEN(sol); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(sol, i); + _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); + } + } + if (active.size()) { + std::set::iterator a_it; + for (a_it = active.begin(); a_it != active.end(); a_it++) { + bu_ptbl_ins(sset, (long *)*a_it); + } + } + + return active.size(); +} + +int +bv_view_objs_rect_select(struct bu_ptbl *sset, struct bview *v, int x1, int y1, int x2, int y2) +{ + if (!v || !sset || !v->gv_width || !v->gv_height) + return 0; + + bu_ptbl_reset(sset); + + if (x1 < 0 || y1 < 0 || x1 > v->gv_width || y1 > v->gv_height) + return 0; + + if (x2 < 0 || y2 < 0 || x2 > v->gv_width || y2 > v->gv_height) + return 0; + + // Get the radius of the scene. + point_t sbbc = VINIT_ZERO; + fastf_t radius = 1.0; + _scene_radius(&sbbc, &radius, v); + + // Using the pixel width and height of the current "window", construct some + // view space dimensions related to that window + fastf_t fx1 = 0.0, fy1 = 0.0, fx2 = 0.0, fy2 = 0.0, fxc = 0.0, fyc = 0.0; + bv_screen_to_view(v, &fx1, &fy1, (int)(0.5*(x1+x2)), y2); + bv_screen_to_view(v, &fx2, &fy2, x2, (int)(0.5*(y1+y2))); + bv_screen_to_view(v, &fxc, &fyc, (int)(0.5*(x1+x2)), (int)(0.5*(y1+y2))); + + // Get the model space points for the mid points of the top and right edges + // of the box. + point_t vp1, vp2, vc, ep1, ep2, ec; + VSET(vp1, fx1, fy1, 0); + VSET(vp2, fx2, fy2, 0); + VSET(vc, fxc, fyc, 0); + MAT4X3PNT(ep1, v->gv_view2model, vp1); + MAT4X3PNT(ep2, v->gv_view2model, vp2); + MAT4X3PNT(ec, v->gv_view2model, vc); + //bu_log("in sph1.s sph %f %f %f 1\n", V3ARGS(ep1)); + //bu_log("in sph2.s sph %f %f %f 2\n", V3ARGS(ep2)); + //bu_log("in sphc.s sph %f %f %f 3\n", V3ARGS(ec)); + + // Need the direction vector - i.e., where the camera is looking. Got this + // trick from the libged nirt code... + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, -1.0); + + + // Construct the box values needed for the SAT test + point_t obb_c, obb_e1, obb_e2, obb_e3; + + // Box center is the closest point to the view center on the plane defined + // by the scene's center and the view dir + plane_t p; + bg_plane_pt_nrml(&p, sbbc, dir); + fastf_t pu, pv; + bg_plane_closest_pt(&pu, &pv, p, ec); + bg_plane_pt_at(&obb_c, p, pu, pv); + + + // The first extent is just the scene radius in the lookat direction + VSCALE(dir, dir, radius); + VMOVE(obb_e1, dir); + + // The other two extents we find by subtracting the view center from the edge points + VSUB2(obb_e2, ep1, ec); + VSUB2(obb_e3, ep2, ec); + +#if 0 + bu_log("%s", obb_arb(obb_c, obb_e1, obb_e2, obb_e3)); +#endif + + // Having constructed the box, test the scene objects against it. Any that intersect, + // add them to the set + std::set active; + struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); + if (so) { + for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(so, i); + _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); + } + } + struct bu_ptbl *sol = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (sol) { + for (size_t i = 0; i < BU_PTBL_LEN(sol); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(sol, i); + _find_active_objs(active, s, v, obb_c, obb_e1, obb_e2, obb_e3); + } + } + if (active.size()) { + std::set::iterator a_it; + for (a_it = active.begin(); a_it != active.end(); a_it++) { + bu_ptbl_ins(sset, (long *)*a_it); + } + } + + return active.size(); +} + +static int +_obj_visible(struct bv_scene_obj *s, struct bview *v) +{ + if (bg_sat_aabb_obb(s->bmin, s->bmax, v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)) { + bv_log(3, "obj_visible[%s] - passed bg_sat_abb_obb: %f %f %f -> %f %f %f", bu_vls_cstr(&v->gv_name), V3ARGS(s->bmin), V3ARGS(s->bmax)); + bv_log(3, " view abb : %f %f %f -> [%f %f %f] [%f %f %f] [%f %f %f]", V3ARGS(v->obb_center), V3ARGS(v->obb_extent1), V3ARGS(v->obb_extent2), V3ARGS(v->obb_extent3)); + //bv_log(3, "%s", obb_arb(v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)); + + return 1; + } else { + bv_log(3, "obj_visible[%s] - FAILED bg_sat_abb_obb: %f %f %f -> %f %f %f", bu_vls_cstr(&v->gv_name),V3ARGS(s->bmin), V3ARGS(s->bmax)); + bv_log(3, " view abb : %f %f %f -> [%f %f %f] [%f %f %f] [%f %f %f]", V3ARGS(v->obb_center), V3ARGS(v->obb_extent1), V3ARGS(v->obb_extent2), V3ARGS(v->obb_extent3)); + //bv_log(3, "%s", obb_arb(v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)); + } + + if (SMALL_FASTF < v->gv_perspective) { + // For perspective mode, project the vertices of the distorted bounding + // box into the view plane, bound them, and see if the box overlaps with + // the view screen's box. + point_t arb[8]; + VSET(arb[0], s->bmin[0], s->bmin[1], s->bmin[2]); + VSET(arb[1], s->bmin[0], s->bmin[1], s->bmax[2]); + VSET(arb[2], s->bmin[0], s->bmax[1], s->bmin[2]); + VSET(arb[3], s->bmin[0], s->bmax[1], s->bmax[2]); + VSET(arb[4], s->bmax[0], s->bmin[1], s->bmin[2]); + VSET(arb[5], s->bmax[0], s->bmin[1], s->bmax[2]); + VSET(arb[6], s->bmax[0], s->bmax[1], s->bmin[2]); + VSET(arb[7], s->bmax[0], s->bmax[1], s->bmax[2]); + point2d_t omin = {INFINITY, INFINITY}; + point2d_t omax = {-INFINITY, -INFINITY}; + for (int i = 0; i < 8; i++) { + point_t pp, ppnt; + point2d_t pxy; + MAT4X3PNT(pp, v->gv_pmat, arb[i]); + MAT4X3PNT(ppnt, v->gv_model2view, pp); + V2SET(pxy, ppnt[0], ppnt[1]); + V2MINMAX(omin, omax, pxy); + } + // IFF the omin/omax box and the corresponding view box overlap, this + // object may be visible in the current view and needs to be updated + for (int i = 0; i < 2; i++) { + if (omax[i] < v->gv_wmin[i] || omin[i] > v->gv_wmax[i]) + return 0; + } + return 1; + } + + return 0; +} + +struct bv_mesh_lod_context_internal { + MDB_env *lod_env; + MDB_txn *lod_txn; + MDB_dbi lod_dbi; + + MDB_env *name_env; + MDB_txn *name_txn; + MDB_dbi name_dbi; + + struct bu_vls *fname; +}; + +struct bv_mesh_lod_context * +bv_mesh_lod_context_create(const char *name) +{ + size_t mreaders = 0; + int ncpus = 0; + if (!name) + return NULL; + + // Hash the input filename to generate a key for uniqueness + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + struct bu_vls fname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&fname, "%s", bu_path_normalize(name)); + // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... + if (bu_vls_strlen(&fname) < 10) { + bu_vls_printf(&fname, "GGGGGGGGGGGGG"); + } + XXH64_update(&h_state, bu_vls_cstr(&fname), bu_vls_strlen(&fname)*sizeof(char)); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + unsigned long long hash = (unsigned long long)hash_val; + bu_path_component(&fname, bu_path_normalize(name), BU_PATH_BASENAME_EXTLESS); + bu_vls_printf(&fname, "_%llu", hash); + + // Create the context + struct bv_mesh_lod_context *c; + BU_GET(c, struct bv_mesh_lod_context); + BU_GET(c->i, struct bv_mesh_lod_context_internal); + struct bv_mesh_lod_context_internal *i = c->i; + BU_GET(i->fname, struct bu_vls); + bu_vls_init(i->fname); + bu_vls_sprintf(i->fname, "%s", bu_vls_cstr(&fname)); + + // Base maximum readers on an estimate of how many threads + // we might want to fire off + mreaders = std::thread::hardware_concurrency(); + if (!mreaders) + mreaders = 1; + ncpus = bu_avail_cpus(); + if (ncpus > 0 && (size_t)ncpus > mreaders) + mreaders = (size_t)ncpus + 2; + + + // Set up LMDB environments + if (mdb_env_create(&i->lod_env)) + goto lod_context_fail; + if (mdb_env_create(&i->name_env)) + goto lod_context_close_lod_fail; + + if (mdb_env_set_maxreaders(i->lod_env, mreaders)) + goto lod_context_close_fail; + if (mdb_env_set_maxreaders(i->name_env, mreaders)) + goto lod_context_close_fail; + + // TODO - the "failure" mode if this limit is ever hit is to back down + // the maximum stored LoD on larger objects, but that will take some + // doing to implement... + if (mdb_env_set_mapsize(i->lod_env, CACHE_MAX_DB_SIZE)) + goto lod_context_close_fail; + + if (mdb_env_set_mapsize(i->name_env, CACHE_MAX_DB_SIZE)) + goto lod_context_close_fail; + + + // Ensure the necessary top level dirs are present + char dir[MAXPATHLEN]; + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, NULL); + if (!bu_file_exists(dir, NULL)) + lod_dir(dir); + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, NULL); + if (!bu_file_exists(dir, NULL)) { + lod_dir(dir); + } + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, "format", NULL); + if (!bu_file_exists(dir, NULL)) { + // Note a format, so we can detect if what's there isn't compatible + // with what this logic expects (in anticipation of future changes + // to the on-disk format). + FILE *fp = fopen(dir, "w"); + if (!fp) + goto lod_context_close_fail; + fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); + fclose(fp); + } else { + std::ifstream format_file(dir); + size_t disk_format_version = 0; + format_file >> disk_format_version; + format_file.close(); + if (disk_format_version != CACHE_CURRENT_FORMAT) { + bu_log("Old mesh lod cache (%zd) found - clearing\n", disk_format_version); + bv_mesh_lod_clear_cache(NULL, 0); + } + FILE *fp = fopen(dir, "w"); + if (!fp) + goto lod_context_close_fail; + fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); + fclose(fp); + } + + // Create the specific LoD LMDB cache dir, if not already present + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, bu_vls_cstr(&fname), NULL); + if (!bu_file_exists(dir, NULL)) + lod_dir(dir); + + // Need to call mdb_env_sync() at appropriate points. + if (mdb_env_open(i->lod_env, dir, MDB_NOSYNC, 0664)) + goto lod_context_close_fail; + + // Create the specific name/key LMDB mapping dir, if not already present + bu_vls_printf(&fname, "_namekey"); + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, bu_vls_cstr(&fname), NULL); + if (!bu_file_exists(dir, NULL)) + lod_dir(dir); + + // Need to call mdb_env_sync() at appropriate points. + if (mdb_env_open(i->name_env, dir, MDB_NOSYNC, 0664)) + goto lod_context_close_fail; + + // Success - return the context + return c; + + // If something went wrong, clean up and return NULL +lod_context_close_fail: + mdb_env_close(i->name_env); +lod_context_close_lod_fail: + mdb_env_close(i->lod_env); +lod_context_fail: + bu_vls_free(&fname); + BU_PUT(c->i, struct bv_mesh_lod_context_internal); + BU_PUT(c, struct bv_mesh_lod_context); + return NULL; +} + +void +bv_mesh_lod_context_destroy(struct bv_mesh_lod_context *c) +{ + if (!c) + return; + mdb_env_close(c->i->name_env); + mdb_env_close(c->i->lod_env); + bu_vls_free(c->i->fname); + BU_PUT(c->i->fname, struct bu_vls); + BU_PUT(c->i, struct bv_mesh_lod_context_internal); + BU_PUT(c, struct bv_mesh_lod_context); +} + +unsigned long long +bv_mesh_lod_key_get(struct bv_mesh_lod_context *c, const char *name) +{ + MDB_val mdb_key, mdb_data; + + // Database object names may be of arbitrary length - hash + // to get the lookup key + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + struct bu_vls keystr = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&keystr, "%s", name); + // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... + if (bu_vls_strlen(&keystr) < 10) { + bu_vls_printf(&keystr, "GGGGGGGGGGGGG"); + } + XXH64_update(&h_state, bu_vls_cstr(&keystr), bu_vls_strlen(&keystr)*sizeof(char)); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + unsigned long long hash = (unsigned long long)hash_val; + bu_vls_sprintf(&keystr, "%llu", hash); + + mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); + mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); + mdb_key.mv_size = bu_vls_strlen(&keystr)*sizeof(char); + mdb_key.mv_data = (void *)bu_vls_cstr(&keystr); + int rc = mdb_get(c->i->name_txn, c->i->name_dbi, &mdb_key, &mdb_data); + if (rc) { + mdb_txn_commit(c->i->name_txn); + return 0; + } + unsigned long long *fkeyp = (unsigned long long *)mdb_data.mv_data; + unsigned long long fkey = *fkeyp; + mdb_txn_commit(c->i->name_txn); + + bu_vls_free(&keystr); + //bu_log("GOT %s: %llu\n", name, fkey); + return fkey; +} + +int +bv_mesh_lod_key_put(struct bv_mesh_lod_context *c, const char *name, unsigned long long key) +{ + // Database object names may be of arbitrary length - hash + // to get something appropriate for a lookup key + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + struct bu_vls keystr = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&keystr, "%s", name); + // TODO - xxhash needs a minimum input size per Coverity - figure out what it is... + if (bu_vls_strlen(&keystr) < 10) { + bu_vls_printf(&keystr, "GGGGGGGGGGGGG"); + } + XXH64_update(&h_state, bu_vls_cstr(&keystr), bu_vls_strlen(&keystr)*sizeof(char)); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + unsigned long long hash = (unsigned long long)hash_val; + bu_vls_sprintf(&keystr, "%llu", hash); + + MDB_val mdb_key; + MDB_val mdb_data[2]; + mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); + mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); + mdb_key.mv_size = bu_vls_strlen(&keystr)*sizeof(char); + mdb_key.mv_data = (void *)bu_vls_cstr(&keystr); + mdb_data[0].mv_size = sizeof(key); + mdb_data[0].mv_data = (void *)&key; + mdb_data[1].mv_size = 0; + mdb_data[1].mv_data = NULL; + int rc = mdb_put(c->i->name_txn, c->i->name_dbi, &mdb_key, mdb_data, 0); + mdb_txn_commit(c->i->name_txn); + + bu_vls_free(&keystr); + //bu_log("PUT %s: %llu\n", name, key); + return rc; +} + +// Output record +class rec { + public: + unsigned short x = 0, y = 0, z = 0; +}; + + +class POPState; +struct bv_mesh_lod_internal { + POPState *s; +}; + +class POPState { + public: + + // Create cached data (doesn't create a usable container) + POPState(struct bv_mesh_lod_context *ctx, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, fastf_t pop_face_cnt_threshold_ratio); + + // Load cached data (DOES create a usable container) + POPState(struct bv_mesh_lod_context *ctx, unsigned long long key); + + // Cleanup + ~POPState(); + + // Based on a view size, recommend a level + int get_level(fastf_t len); + + // Load/unload data level + void set_level(int level); + + // Shrink memory usage (level set routines will have to do more work + // after this is run, but the POPState is still viable). Used after a + // client code has done all that is needed with the level data, such as + // generating an OpenGL display list, but isn't done with the object. + void shrink_memory(); + + // Get the "current" position of a point, given its level + void level_pnt(point_t *o, const point_t *p, int level); + + // Debugging + void plot(const char *root); + + // Active faces needed by the current LoD (indexes into lod_tri_pnts). + std::vector lod_tris; + + // This is where we store the active points - i.e., those needed for + // the current LoD. When initially creating the breakout from BoT data + // we calculate all levels, but the goal is to not hold in memory any + // more than we need to support the LoD drawing. lod_tris will index + // into lod_tri_pnts. + std::vector lod_tri_pnts; + std::vector lod_tri_pnts_snapped; + std::vector lod_tri_norms; + + // Current level of detail information loaded into nfaces/npnts + int curr_level = -1; + + // Force a data reload even if the level hasn't changed (i.e. undo a + // shrink memory operation when level is set.) + bool force_update = false; + + // Maximum level for which POP info is defined. Above that level, + // need to shift to full rendering + int max_pop_threshold_level = 0; + + // Used by calling functions to detect initialization errors + bool is_valid = false; + + // Content based hash key + unsigned long long hash; + + // Methods for full detail + full_detail_clbk_t full_detail_setup_clbk = NULL; + full_detail_clbk_t full_detail_clear_clbk = NULL; + full_detail_clbk_t full_detail_free_clbk = NULL; + void *detail_clbk_data = NULL; + + // Bounding box of original mesh + point_t bbmin, bbmax; + + // Info for drawing + struct bv_mesh_lod *lod = NULL; + + private: + + void tri_process(); + + float minx = FLT_MAX, miny = FLT_MAX, minz = FLT_MAX; + float maxx = -FLT_MAX, maxy = -FLT_MAX, maxz = -FLT_MAX; + + fastf_t max_face_ratio = 0.66; + + // Clamping of points to various detail levels + int to_level(int val, int level); + + // Snap value to level value + fastf_t snap(fastf_t val, fastf_t min, fastf_t max, int level); + + // Check if two points are equal at a clamped level + bool is_equal(rec r1, rec r2, int level); + + // Degeneracy test for triangles + bool tri_degenerate(rec r0, rec r1, rec r2, int level); + + std::vector PRECOMPUTED_MASKS; + + // Write data out to cache (only used during initialization from + // external data) + void cache(); + bool cache_tri(); + bool cache_write(const char *component, std::stringstream &s); + size_t cache_get(void **data, const char *component); + void cache_done(); + void cache_del(const char *component); + MDB_val mdb_key, mdb_data[2]; + + // Specific loading and unloading methods + void tri_pop_load(int start_level, int level); + void tri_pop_trim(int level); + size_t level_vcnt[POP_MAXLEVEL+1] = {0}; + size_t level_tricnt[POP_MAXLEVEL+1] = {0}; + + // Processing containers used for initial triangle data characterization + std::vector tri_ind_map; + std::vector vert_tri_minlevel; + std::map> level_tri_verts; + std::vector> level_tris; + + // Pointers to original input data + size_t vert_cnt = 0; + const point_t *verts_array = NULL; + const vect_t *vnorms_array = NULL; + size_t faces_cnt = 0; + int *faces_array = NULL; + + // Context + struct bv_mesh_lod_context *c; +}; + +void +POPState::tri_process() +{ + // Until we prove otherwise, all edges are assumed to appear only at the + // last level (and consequently, their vertices are only needed then). Set + // the level accordingly. + vert_tri_minlevel.reserve(vert_cnt); + for (size_t i = 0; i < vert_cnt; i++) { + vert_tri_minlevel.push_back(POP_MAXLEVEL - 1); + } + + // Reserve memory for level containers + level_tris.reserve(POP_MAXLEVEL); + for (size_t i = 0; i < POP_MAXLEVEL; i++) { + level_tris.push_back(std::vector(0)); + } + + // Walk the triangles and perform the LoD characterization + for (size_t i = 0; i < faces_cnt; i++) { + rec triangle[3]; + // Transform triangle vertices + bool bad_face = false; + for (size_t j = 0; j < 3; j++) { + int f_ind = faces_array[3*i+j]; + if ((size_t)f_ind >= vert_cnt || f_ind < 0) { + bu_log("bad face %zd - skipping\n", i); + bad_face = true; + break; + } + triangle[j].x = floor((verts_array[f_ind][X] - minx) / (maxx - minx) * USHRT_MAX); + triangle[j].y = floor((verts_array[f_ind][Y] - miny) / (maxy - miny) * USHRT_MAX); + triangle[j].z = floor((verts_array[f_ind][Z] - minz) / (maxz - minz) * USHRT_MAX); + } + if (bad_face) + continue; + + // Find the pop up level for this triangle (i.e., when it will first + // appear as we step up the zoom levels.) + size_t level = POP_MAXLEVEL - 1; + for (int j = 0; j < POP_MAXLEVEL; j++) { + if (!tri_degenerate(triangle[0], triangle[1], triangle[2], j)) { + level = j; + break; + } + } + // Add this triangle to its "pop" level + level_tris[level].push_back(i); + + // Let the vertices know they will be needed at this level, if another + // triangle doesn't already need them sooner + for (size_t j = 0; j < 3; j++) { + if (vert_tri_minlevel[faces_array[3*i+j]] > level) { + vert_tri_minlevel[faces_array[3*i+j]] = level; + } + } + } + + // The vertices now know when they will first need to appear. Build level + // sets of vertices + for (size_t i = 0; i < vert_tri_minlevel.size(); i++) { + level_tri_verts[vert_tri_minlevel[i]].insert(i); + } + + // Having sorted the vertices into level sets, we may now define a new global + // vertex ordering that respects the needs of the levels. + tri_ind_map.reserve(vert_cnt); + for (size_t i = 0; i < vert_cnt; i++) { + tri_ind_map.push_back(i); + } + size_t vind = 0; + std::map>::iterator l_it; + std::unordered_set::iterator s_it; + for (l_it = level_tri_verts.begin(); l_it != level_tri_verts.end(); l_it++) { + for (s_it = l_it->second.begin(); s_it != l_it->second.end(); s_it++) { + tri_ind_map[*s_it] = vind; + vind++; + } + } + + // Beyond a certain depth, there is little benefit to the POP process. If + // we check the count of level_tris, we will find a level at which most of + // the triangles are active. + // TODO: Not clear yet when the tradeoff between memory and the work of LoD + // point snapping trades off - 0.66 is just a guess. We also need to + // calculate this maximum size ratio as a function of the overall database + // mesh data size, which will need to be passed in as a parameter - if the + // original is too large, we may not be able to fit higher LoD levels in + // the database and need to make this ratio smaller - probably a maximum of + // 0.66(?) and drop it lower of the original database is very large (i.e. + // we need to hold a lot of mesh data). + size_t trisum = 0; + if (max_face_ratio > 0.99 || max_face_ratio < 0) { + max_pop_threshold_level = level_tris.size() - 1; + } else { + size_t faces_array_cnt2 = (size_t)((fastf_t)faces_cnt * max_face_ratio); + for (size_t i = 0; i < level_tris.size(); i++) { + trisum += level_tris[i].size(); + if (trisum > faces_array_cnt2) { + // If we're using two thirds of the triangles, this is our + // threshold level. If we've got ALL the triangles, back + // down one level. + if (trisum < (size_t)faces_cnt) { + max_pop_threshold_level = i; + } else { + // Handle the case where we get i == 0 + max_pop_threshold_level = (i) ? i - 1 : 0; + } + break; + } + } + } + //bu_log("Max LoD POP level: %zd\n", max_pop_threshold_level); +} + +POPState::POPState(struct bv_mesh_lod_context *ctx, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, fastf_t pop_facecnt_threshold_ratio) +{ + // Store the context + c = ctx; + + // Caller set parameter telling us when to switch from POP data + // to just drawing the full mesh + max_face_ratio = pop_facecnt_threshold_ratio; + + // Hash the data to generate a key, if the user didn't supply us with one + if (!user_key) { + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, v, vcnt*sizeof(point_t)); + XXH64_update(&h_state, faces, 3*fcnt*sizeof(int)); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + hash = (unsigned long long)hash_val; + } else { + hash = user_key; + } + + // Make sure there's no cache before performing the full initializing from + // the original data. In this mode the POPState creation is used to + // initialize the cache, not to create a workable data state from that + // data. The hash is set, which is all we really need - loading data from + // the cache is handled elsewhere. + void *cdata = NULL; + size_t csize = cache_get(&cdata, CACHE_POP_MAX_LEVEL); + if (csize && cdata) { + cache_done(); + is_valid = true; + return; + } + + // Cache isn't already populated - go to work. + cache_done(); + + curr_level = POP_MAXLEVEL - 1; + + // Precompute precision masks for each level + for (int i = 0; i < POP_MAXLEVEL; i++) { + PRECOMPUTED_MASKS.push_back(pow(2, (POP_MAXLEVEL - i - 1))); + } + + // Store source data info + vert_cnt = vcnt; + verts_array = v; + vnorms_array = vn; + faces_cnt = fcnt; + faces_array = faces; + + // Calculate the full mesh bounding box for later use + bg_trimesh_aabb(&bbmin, &bbmax, faces_array, faces_cnt, verts_array, vert_cnt); + + // Find our min and max values, initialize levels + for (size_t i = 0; i < vcnt; i++) { + minx = (v[i][X] < minx) ? v[i][X] : minx; + miny = (v[i][Y] < miny) ? v[i][Y] : miny; + minz = (v[i][Z] < minz) ? v[i][Z] : minz; + maxx = (v[i][X] > maxx) ? v[i][X] : maxx; + maxy = (v[i][Y] > maxy) ? v[i][Y] : maxy; + maxz = (v[i][Z] > maxz) ? v[i][Z] : maxz; + } + + // Bump out the min and max bounds slightly so none of our actual + // points are too close to these limits + minx = minx-fabs(MBUMP*minx); + miny = miny-fabs(MBUMP*miny); + minz = minz-fabs(MBUMP*minz); + maxx = maxx+fabs(MBUMP*maxx); + maxy = maxy+fabs(MBUMP*maxy); + maxz = maxz+fabs(MBUMP*maxz); + + // Characterize triangle faces + tri_process(); + + // We're now ready to write out the data + is_valid = true; + cache(); + + if (!is_valid) + return; + +#if 0 + for (size_t i = 0; i < POP_MAXLEVEL; i++) { + bu_log("bucket %zu count: %zu\n", i, level_tris[i].size()); + } + + for (size_t i = 0; i < POP_MAXLEVEL; i++) { + bu_log("vert %zu count: %zu\n", i, level_tri_verts[i].size()); + } +#endif +} + +POPState::POPState(struct bv_mesh_lod_context *ctx, unsigned long long key) +{ + // Store the context + c = ctx; + + if (!key) + return; + + // Initialize so set_level will read in the first level of triangles + curr_level = - 1; + + // Precompute precision masks for each level + for (int i = 0; i < POP_MAXLEVEL; i++) { + PRECOMPUTED_MASKS.push_back(pow(2, (POP_MAXLEVEL - i - 1))); + } + + hash = key; + + // Find the maximum POP level + { + const char *b = NULL; + size_t bsize = cache_get((void **)&b, CACHE_POP_MAX_LEVEL); + if (!bsize) { + cache_done(); + return; + } + if (bsize != sizeof(max_pop_threshold_level)) { + bu_log("Incorrect data size found loading max LoD POP threshold\n"); + cache_done(); + return; + } + memcpy(&max_pop_threshold_level, b, sizeof(max_pop_threshold_level)); + cache_done(); + } + + // Load the POP level where we switch from POP to full + { + const char *b = NULL; + size_t bsize = cache_get((void **)&b, CACHE_POP_SWITCH_LEVEL); + if (bsize && bsize != sizeof(max_face_ratio)) { + bu_log("Incorrect data size found loading LoD POP switch threshold\n"); + cache_done(); + return; + } + if (bsize) { + memcpy(&max_face_ratio, b, sizeof(max_face_ratio)); + } else { + max_face_ratio = 0.66; + } + cache_done(); + } + + // Load level counts for vectors and tris + { + const char *b = NULL; + size_t bsize = cache_get((void **)&b, CACHE_VERTEX_COUNT); + if (bsize != sizeof(level_vcnt)) { + bu_log("Incorrect data size found loading level vertex counts\n"); + cache_done(); + return; + } + memcpy(&level_vcnt, b, sizeof(level_vcnt)); + cache_done(); + } + { + const char *b = NULL; + size_t bsize = cache_get((void **)&b, CACHE_TRI_COUNT); + if (bsize != sizeof(level_tricnt)) { + bu_log("Incorrect data size found loading level triangle counts\n"); + cache_done(); + return; + } + memcpy(&level_tricnt, b, sizeof(level_tricnt)); + cache_done(); + } + + // Read in min/max bounds + { + float minmax[6]; + const char *b = NULL; + size_t bsize = cache_get((void **)&b, CACHE_OBJ_BOUNDS); + if (bsize != (sizeof(bbmin) + sizeof(bbmax) + sizeof(minmax))) { + bu_log("Incorrect data size found loading cached bounds data\n"); + cache_done(); + return; + } + memcpy(&bbmin, b, sizeof(bbmin)); + b += sizeof(bbmin); + memcpy(&bbmax, b, sizeof(bbmax)); + b += sizeof(bbmax); + //bu_log("bbmin: %f %f %f bbmax: %f %f %f\n", V3ARGS(bbmin), V3ARGS(bbmax)); + memcpy(&minmax, b, sizeof(minmax)); + minx = minmax[0]; + miny = minmax[1]; + minz = minmax[2]; + maxx = minmax[3]; + maxy = minmax[4]; + maxz = minmax[5]; + cache_done(); + } + + // Read in the zero level vertices, vertex normals (if defined) and triangles + set_level(0); + + // All set - ready for LoD + is_valid = 1; +} + +POPState::~POPState() +{ + if (full_detail_free_clbk) { + (*full_detail_free_clbk)(lod, detail_clbk_data); + detail_clbk_data = NULL; + } +} + +void +POPState::tri_pop_load(int start_level, int level) +{ + struct bu_vls kbuf = BU_VLS_INIT_ZERO; + + // Read in the level vertices + for (int i = start_level+1; i <= level; i++) { + if (!level_vcnt[i]) + continue; + bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERT_LEVEL, i); + fastf_t *b = NULL; + size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); + if (bsize != level_vcnt[i]*sizeof(point_t)) { + bu_log("Incorrect data size found loading level %d point data\n", i); + return; + } + lod_tri_pnts.insert(lod_tri_pnts.end(), &b[0], &b[level_vcnt[i]*3]); + cache_done(); + } + // Re-snap all vertices currently loaded at the new level + lod_tri_pnts_snapped.clear(); + lod_tri_pnts_snapped.reserve(lod_tri_pnts.size()); + for (size_t i = 0; i < lod_tri_pnts.size()/3; i++) { + point_t p, sp; + VSET(p, lod_tri_pnts[3*i+0], lod_tri_pnts[3*i+1], lod_tri_pnts[3*i+2]); + level_pnt(&sp, &p, level); + for (int k = 0; k < 3; k++) { + lod_tri_pnts_snapped.push_back(sp[k]); + } + } + + // Read in the level triangles + for (int i = start_level+1; i <= level; i++) { + if (!level_tricnt[i]) + continue; + bu_vls_sprintf(&kbuf, "%s%d", CACHE_TRI_LEVEL, i); + int *b = NULL; + size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); + if (bsize != level_tricnt[i]*3*sizeof(int)) { + bu_log("Incorrect data size found loading level %d tri data\n", i); + return; + } + lod_tris.insert(lod_tris.end(), &b[0], &b[level_tricnt[i]*3]); + cache_done(); + } + + // Read in the vertex normals, if we have them + for (int i = start_level+1; i <= level; i++) { + if (!level_tricnt[i]) + continue; + bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERTNORM_LEVEL, i); + fastf_t *b = NULL; + size_t bsize = cache_get((void **)&b, bu_vls_cstr(&kbuf)); + if (bsize > 0 && bsize != level_tricnt[i]*sizeof(vect_t)*3) { + bu_log("Incorrect data size found loading level %d normal data\n", i); + return; + } + if (bsize) { + lod_tri_norms.insert(lod_tri_norms.end(), &b[0], &b[level_tricnt[i]*3*3]); + } + cache_done(); + } +} + +void +POPState::shrink_memory() +{ + lod_tri_pnts.clear(); + lod_tri_pnts.shrink_to_fit(); + lod_tri_norms.clear(); + lod_tri_norms.shrink_to_fit(); + lod_tris.clear(); + lod_tris.shrink_to_fit(); + lod_tri_pnts_snapped.clear(); + lod_tri_pnts_snapped.shrink_to_fit(); +} + +void +POPState::tri_pop_trim(int level) +{ + // Tally all the lower level verts and tris - those are the ones we need to keep + size_t vkeep_cnt = 0; + size_t fkeep_cnt = 0; + for (size_t i = 0; i <= (size_t)level; i++) { + vkeep_cnt += level_vcnt[i]; + fkeep_cnt += level_tricnt[i]; + } + + // Shrink the main arrays (note that in C++11 shrink_to_fit may or may + // not actually shrink memory usage on any given call.) + lod_tri_pnts.resize(vkeep_cnt*3); + lod_tri_pnts.shrink_to_fit(); + lod_tri_norms.resize(fkeep_cnt*3*3); + lod_tri_norms.shrink_to_fit(); + lod_tris.resize(fkeep_cnt*3); + lod_tris.shrink_to_fit(); + + // Re-snap all vertices loaded at the new level + lod_tri_pnts_snapped.clear(); + lod_tri_pnts_snapped.reserve(lod_tri_pnts.size()); + for (size_t i = 0; i < lod_tri_pnts.size()/3; i++) { + point_t p, sp; + VSET(p, lod_tri_pnts[3*i+0], lod_tri_pnts[3*i+1], lod_tri_pnts[3*i+2]); + level_pnt(&sp, &p, level); + for (int k = 0; k < 3; k++) { + lod_tri_pnts_snapped.push_back(sp[k]); + } + } +} + +int +POPState::get_level(fastf_t vlen) +{ + fastf_t delta = 0.01*vlen; + point_t bmin, bmax; + fastf_t bdiag = 0; + VSET(bmin, minx, miny, minz); + VSET(bmax, maxx, maxy, maxz); + bdiag = DIST_PNT_PNT(bmin, bmax); + + // If all views are orthogonal we just need the diagonal of the bbox, but + // if we have any active perspective matrices that may change the answer. + // We need to provide as much detail as is required by the most demanding + // view. In principle we might also be able to back the LoD down further + // for very distant objects, but a quick test with that resulted in too much + // loss of detail so for now just look at the "need more" case. + struct bu_ptbl *vsets = (lod && lod->s) ? bv_set_views(lod->s->s_v->vset) : NULL; + if (!vsets) { + struct bview *v = (lod && lod->s) ? lod->s->s_v : NULL; + if (v && SMALL_FASTF < v->gv_perspective) { + fastf_t cdist = 0; + point_t pbmin, pbmax; + MAT4X3PNT(pbmin, v->gv_pmat, bmin); + MAT4X3PNT(pbmax, v->gv_pmat, bmax); + bdiag = DIST_PNT_PNT(pbmin, pbmax); + if (cdist > bdiag) + bdiag = cdist; + } + } else { + for (size_t i = 0; i < BU_PTBL_LEN(vsets); i++) { + fastf_t cdist = 0; + struct bview *cv = (struct bview *)BU_PTBL_GET(vsets, i); + if (!_obj_visible(lod->s, cv)) + continue; + if (SMALL_FASTF < cv->gv_perspective) { + point_t pbmin, pbmax; + MAT4X3PNT(pbmin, cv->gv_pmat, bmin); + MAT4X3PNT(pbmax, cv->gv_pmat, bmax); + cdist = DIST_PNT_PNT(pbmin, pbmax); + if (cdist > bdiag) + bdiag = cdist; + } + } + } + + for (int lev = 0; lev < POP_MAXLEVEL; lev++) { + fastf_t diag_slice = bdiag/pow(2,lev); + if (diag_slice < delta) { + bv_log(2, "POPState::get_level %g->%d", vlen, lev); + return lev; + } + } + bv_log(2, "POPState::get_level %g->%d", vlen, POP_MAXLEVEL - 1); + return POP_MAXLEVEL - 1; +} + +void +POPState::set_level(int level) +{ + // If we're already there and we're not undoing a memshrink, no work to do + if (level == curr_level && !force_update) + return; + + // If we're doing a forced update, it's like starting from + // scratch - reset to 0 + if (force_update) { + force_update = false; + set_level(0); + set_level(level); + } + + // int64_t start, elapsed; + // fastf_t seconds; + // start = bu_gettime(); + + // Triangles + + // If we need to pull more data, do so + if (level > curr_level && level <= max_pop_threshold_level) { + if (!lod_tri_pnts.size()) { + tri_pop_load(-1, level); + } else { + tri_pop_load(curr_level, level); + } + } + + // If we need to trim back the POP data, do that + if (level < curr_level && level <= max_pop_threshold_level && curr_level <= max_pop_threshold_level) { + if (!lod_tri_pnts.size()) { + tri_pop_load(-1, level); + } else { + tri_pop_trim(level); + } + } + + // If we were operating beyond POP detail levels (i.e. using RTree + // management) we need to reset our POP data and clear the more detailed + // info from the containers to free up memory. + if (level < curr_level && level <= max_pop_threshold_level && curr_level > max_pop_threshold_level) { + // We're (re)entering the POP range - clear the high detail data and start over + if (full_detail_clear_clbk) + (*full_detail_clear_clbk)(lod, detail_clbk_data); + + // Full reset, not an incremental load. + tri_pop_load(-1, level); + } + + // If we're jumping into details levels beyond POP range, clear the POP containers + // and load the more detailed data management info + if (level > curr_level && level > max_pop_threshold_level && curr_level <= max_pop_threshold_level) { + + // Clear the LoD data - we need the full set now + lod_tri_pnts_snapped.clear(); + lod_tri_pnts_snapped.shrink_to_fit(); + lod_tri_pnts.clear(); + lod_tri_pnts.shrink_to_fit(); + lod_tri_norms.clear(); + lod_tri_norms.shrink_to_fit(); + lod_tris.clear(); + lod_tris.shrink_to_fit(); + + // Use the callback to set up the full data pointers + if (full_detail_setup_clbk) + (*full_detail_setup_clbk)(lod, detail_clbk_data); + } + + //elapsed = bu_gettime() - start; + //seconds = elapsed / 1000000.0; + //bu_log("lod set_level(%d): %f sec\n", level, seconds); + + curr_level = level; +} + +// Rather than committing all data to LMDB in one transaction, use keys with +// appended strings to the hash to denote the individual pieces - basically +// what we were doing with files, but in the db instead +// +// This will also allow easier removal of larger subcomponents if we need to +// back off on saved LoD. +bool +POPState::cache_write(const char *component, std::stringstream &s) +{ + // Prepare inputs for writing + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + std::string buffer = s.str(); + + // As implemented this shouldn't be necessary, since all our keys are below + // the default size limit (511) + //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->i->lod_env)) + // return false; + + // Write out key/value to LMDB database, where the key is the hash + // and the value is the serialized LoD data + char *keycstr = bu_strdup(keystr.c_str()); + void *bdata = bu_calloc(buffer.length()+1, sizeof(char), "bdata"); + memcpy(bdata, buffer.data(), buffer.length()*sizeof(char)); + mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); + mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keycstr; + mdb_data[0].mv_size = buffer.length()*sizeof(char); + mdb_data[0].mv_data = bdata; + mdb_data[1].mv_size = 0; + mdb_data[1].mv_data = NULL; + int rc = mdb_put(c->i->lod_txn, c->i->lod_dbi, &mdb_key, mdb_data, 0); + mdb_txn_commit(c->i->lod_txn); + bu_free(keycstr, "keycstr"); + bu_free(bdata, "buffer data"); + + return (!rc) ? true : false; +} + +// This pulls the data, but doesn't close the transaction because the +// calling code will want to manipulate the data. After that process +// is complete, cache_done() should be called to prepare for subsequent +// operations. +size_t +POPState::cache_get(void **data, const char *component) +{ + // Construct lookup key + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + + // As implemented this shouldn't be necessary, since all our keys are below + // the default size limit (511) + //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->i->lod_env)) + // return 0; + char *keycstr = bu_strdup(keystr.c_str()); + mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); + mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keycstr; + int rc = mdb_get(c->i->lod_txn, c->i->lod_dbi, &mdb_key, &mdb_data[0]); + if (rc) { + bu_free(keycstr, "keycstr"); + (*data) = NULL; + return 0; + } + bu_free(keycstr, "keycstr"); + (*data) = mdb_data[0].mv_data; + + return mdb_data[0].mv_size; +} + +void +POPState::cache_done() +{ + mdb_txn_commit(c->i->lod_txn); +} + +bool +POPState::cache_tri() +{ + // Write out the threshold level - above this level, + // we need to switch to full-detail drawing + { + std::stringstream s; + s.write(reinterpret_cast(&max_pop_threshold_level), sizeof(max_pop_threshold_level)); + if (!cache_write(CACHE_POP_MAX_LEVEL, s)) + return false; + } + + // Write out the switch level + { + std::stringstream s; + s.write(reinterpret_cast(&max_face_ratio), sizeof(max_face_ratio)); + if (!cache_write(CACHE_POP_SWITCH_LEVEL, s)) + return false; + } + + // Write out the vertex counts for all active levels + { + std::stringstream s; + for (size_t i = 0; i <= POP_MAXLEVEL; i++) { + size_t icnt = 0; + if (level_tri_verts.find(i) == level_tri_verts.end()) { + s.write(reinterpret_cast(&icnt), sizeof(icnt)); + continue; + } + if ((int)i > max_pop_threshold_level || !level_tri_verts[i].size()) { + s.write(reinterpret_cast(&icnt), sizeof(icnt)); + continue; + } + icnt = level_tri_verts[i].size(); + s.write(reinterpret_cast(&icnt), sizeof(icnt)); + } + if (!cache_write(CACHE_VERTEX_COUNT, s)) + return false; + } + + // Write out the triangle counts for all active levels + { + std::stringstream s; + for (size_t i = 0; i <= POP_MAXLEVEL; i++) { + size_t tcnt = 0; + if ((int)i > max_pop_threshold_level || !level_tris[i].size()) { + s.write(reinterpret_cast(&tcnt), sizeof(tcnt)); + continue; + } + // Store the size of the level tri vector + tcnt = level_tris[i].size(); + s.write(reinterpret_cast(&tcnt), sizeof(tcnt)); + } + if (!cache_write(CACHE_TRI_COUNT, s)) + return false; + } + + struct bu_vls kbuf = BU_VLS_INIT_ZERO; + + // Write out the vertices in LoD order for each level + { + for (int i = 0; i <= max_pop_threshold_level; i++) { + std::stringstream s; + if (level_tri_verts.find(i) == level_tri_verts.end()) + continue; + if (!level_tri_verts[i].size()) + continue; + // Write out the vertex points + std::unordered_set::iterator s_it; + for (s_it = level_tri_verts[i].begin(); s_it != level_tri_verts[i].end(); s_it++) { + point_t v; + VMOVE(v, verts_array[*s_it]); + s.write(reinterpret_cast(&v[0]), sizeof(point_t)); + } + bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERT_LEVEL, i); + if (!cache_write(bu_vls_cstr(&kbuf), s)) + return false; + } + } + + // Write out the triangles in LoD order for each level + { + for (int i = 0; i <= max_pop_threshold_level; i++) { + std::stringstream s; + if (!level_tris[i].size()) + continue; + // Write out the mapped triangle indices + std::vector::iterator s_it; + for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { + int vt[3]; + vt[0] = (int)tri_ind_map[faces_array[3*(*s_it)+0]]; + vt[1] = (int)tri_ind_map[faces_array[3*(*s_it)+1]]; + vt[2] = (int)tri_ind_map[faces_array[3*(*s_it)+2]]; + s.write(reinterpret_cast(&vt[0]), sizeof(vt)); + } + bu_vls_sprintf(&kbuf, "%s%d", CACHE_TRI_LEVEL, i); + if (!cache_write(bu_vls_cstr(&kbuf), s)) + return false; + } + } + + // Write out the vertex normals in LoD order for each level, if we have them + { + if (vnorms_array) { + for (int i = 0; i <= max_pop_threshold_level; i++) { + std::stringstream s; + if (!level_tris[i].size()) + continue; + // Write out the normals associated with the triangle indices + std::vector::iterator s_it; + for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { + vect_t v; + int tind; + tind = 3*(*s_it)+0; + VMOVE(v, vnorms_array[tind]); + s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); + tind = 3*(*s_it)+1; + VMOVE(v, vnorms_array[tind]); + s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); + tind = 3*(*s_it)+2; + VMOVE(v, vnorms_array[tind]); + s.write(reinterpret_cast(&v[0]), sizeof(vect_t)); + } + bu_vls_sprintf(&kbuf, "%s%d", CACHE_VERTNORM_LEVEL, i); + if (!cache_write(bu_vls_cstr(&kbuf), s)) + return false; + } + } + } + + + return true; +} + +// Write out the generated LoD data to the BRL-CAD cache +void +POPState::cache() +{ + if (!hash) { + is_valid = false; + return; + } + + // Stash the original mesh bbox and the min and max bounds, which will be used in decoding + { + std::stringstream s; + s.write(reinterpret_cast(&bbmin), sizeof(bbmin)); + s.write(reinterpret_cast(&bbmax), sizeof(bbmax)); + s.write(reinterpret_cast(&minx), sizeof(minx)); + s.write(reinterpret_cast(&miny), sizeof(miny)); + s.write(reinterpret_cast(&minz), sizeof(minz)); + s.write(reinterpret_cast(&maxx), sizeof(maxx)); + s.write(reinterpret_cast(&maxy), sizeof(maxy)); + s.write(reinterpret_cast(&maxz), sizeof(maxz)); + is_valid = cache_write(CACHE_OBJ_BOUNDS, s); + } + + if (!is_valid) + return; + + // Serialize triangle-specific data + is_valid = cache_tri(); +} + +// Transfer coordinate into level precision +int +POPState::to_level(int val, int level) +{ + int ret = floor(val/double(PRECOMPUTED_MASKS[level])); + //bu_log("to_level: %d, %d : %d\n", val, level, ret); + return ret; +} + +fastf_t +POPState::snap(fastf_t val, fastf_t min, fastf_t max, int level) +{ + unsigned int vf = floor((val - min) / (max - min) * USHRT_MAX); + int lv = floor(vf/double(PRECOMPUTED_MASKS[level])); + unsigned int vc = ceil((val - min) / (max - min) * USHRT_MAX); + int hc = ceil(vc/double(PRECOMPUTED_MASKS[level])); + fastf_t v = ((fastf_t)lv + (fastf_t)hc)*0.5 * double(PRECOMPUTED_MASKS[level]); + fastf_t vs = ((v / USHRT_MAX) * (max - min)) + min; + return vs; +} + +// Transfer coordinate into level-appropriate value +void +POPState::level_pnt(point_t *o, const point_t *p, int level) +{ + fastf_t nx = snap((*p)[X], minx, maxx, level); + fastf_t ny = snap((*p)[Y], miny, maxy, level); + fastf_t nz = snap((*p)[Z], minz, maxz, level); + VSET(*o, nx, ny, nz); +#if 0 + double poffset = DIST_PNT_PNT(*o, *p); + if (poffset > (maxx - minx) && poffset > (maxy - miny) && poffset > (maxz - minz)) { + bu_log("Error: %f %f %f -> %f %f %f\n", V3ARGS(*p), V3ARGS(*o)); + bu_log("bound: %f %f %f -> %f %f %f\n", minx, miny, minz, maxx, maxy, maxz); + } +#endif +} + +// Compares two coordinates for equality (on a given precision level) +bool +POPState::is_equal(rec r1, rec r2, int level) +{ + bool tl_x = (to_level(r1.x, level) == to_level(r2.x, level)); + bool tl_y = (to_level(r1.y, level) == to_level(r2.y, level)); + bool tl_z = (to_level(r1.z, level) == to_level(r2.z, level)); + return (tl_x && tl_y && tl_z); +} + +// Checks whether a triangle is degenerate (at least two coordinates are the +// same on the given precision level) +bool +POPState::tri_degenerate(rec r0, rec r1, rec r2, int level) +{ + return is_equal(r0, r1, level) || is_equal(r1, r2, level) || is_equal(r0, r2, level); +} + +void +POPState::plot(const char *root) +{ + if (curr_level < 0) + return; + + struct bu_vls name = BU_VLS_INIT_ZERO; + FILE *plot_file = NULL; + bu_vls_init(&name); + if (!root) { + bu_vls_sprintf(&name, "init_tris_level_%.2d.plot3", curr_level); + } else { + bu_vls_sprintf(&name, "%s_tris_level_%.2d.plot3", root, curr_level); + } + plot_file = fopen(bu_vls_addr(&name), "wb"); + + if (curr_level <= max_pop_threshold_level) { + pl_color(plot_file, 0, 255, 0); + + for (int i = 0; i <= curr_level; i++) { + std::vector::iterator s_it; + for (s_it = level_tris[i].begin(); s_it != level_tris[i].end(); s_it++) { + size_t f_ind = *s_it; + int v1ind, v2ind, v3ind; + if (faces_array) { + v1ind = faces_array[3*f_ind+0]; + v2ind = faces_array[3*f_ind+1]; + v3ind = faces_array[3*f_ind+2]; + } else { + v1ind = lod_tris[3*f_ind+0]; + v2ind = lod_tris[3*f_ind+1]; + v3ind = lod_tris[3*f_ind+2]; + } + point_t p1, p2, p3, o1, o2, o3; + if (verts_array) { + VMOVE(p1, verts_array[v1ind]); + VMOVE(p2, verts_array[v2ind]); + VMOVE(p3, verts_array[v3ind]); + } else { + VSET(p1, lod_tri_pnts[3*v1ind+0], lod_tri_pnts[3*v1ind+1], lod_tri_pnts[3*v1ind+2]); + VSET(p2, lod_tri_pnts[3*v2ind+0], lod_tri_pnts[3*v2ind+1], lod_tri_pnts[3*v2ind+2]); + VSET(p3, lod_tri_pnts[3*v3ind+0], lod_tri_pnts[3*v3ind+1], lod_tri_pnts[3*v3ind+2]); + } + // We iterate over the level i triangles, but our target level is + // curr_level so we "decode" the points to that level, NOT level i + level_pnt(&o1, &p1, curr_level); + level_pnt(&o2, &p2, curr_level); + level_pnt(&o3, &p3, curr_level); + pdv_3move(plot_file, o1); + pdv_3cont(plot_file, o2); + pdv_3cont(plot_file, o3); + pdv_3cont(plot_file, o1); + } + } + + } else { + for (size_t i = 0; i < lod_tris.size() / 3; i++) { + int v1ind, v2ind, v3ind; + point_t p1, p2, p3; + v1ind = lod_tris[3*i+0]; + v2ind = lod_tris[3*i+1]; + v3ind = lod_tris[3*i+2]; + VSET(p1, lod_tri_pnts[3*v1ind+0], lod_tri_pnts[3*v1ind+1], lod_tri_pnts[3*v1ind+2]); + VSET(p2, lod_tri_pnts[3*v2ind+0], lod_tri_pnts[3*v2ind+1], lod_tri_pnts[3*v2ind+2]); + VSET(p3, lod_tri_pnts[3*v3ind+0], lod_tri_pnts[3*v3ind+1], lod_tri_pnts[3*v3ind+2]); + pdv_3move(plot_file, p1); + pdv_3cont(plot_file, p2); + pdv_3cont(plot_file, p3); + pdv_3cont(plot_file, p1); + } + } + + fclose(plot_file); + + bu_vls_free(&name); +} + + +extern "C" unsigned long long +bv_mesh_lod_cache(struct bv_mesh_lod_context *c, const point_t *v, size_t vcnt, const vect_t *vn, int *faces, size_t fcnt, unsigned long long user_key, double fratio) +{ + unsigned long long key = 0; + + if (!v || !vcnt || !faces || !fcnt) + return 0; + + POPState p(c, v, vcnt, vn, faces, fcnt, user_key, fratio); + if (!p.is_valid) + return 0; + + key = p.hash; + + return key; +} + + +extern "C" unsigned long long +bv_mesh_lod_custom_key(void *data, size_t data_size) +{ + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, data, data_size); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + unsigned long long hash = (unsigned long long)hash_val; + return hash; +} + + +extern "C" struct bv_mesh_lod * +bv_mesh_lod_create(struct bv_mesh_lod_context *c, unsigned long long key) +{ + if (!key) + return NULL; + + POPState *p = new POPState(c, key); + if (!p) + return NULL; + + if (!p->is_valid) { + delete p; + return NULL; + } + + // Set up info container + struct bv_mesh_lod *lod; + BU_GET(lod, struct bv_mesh_lod); + BU_GET(lod->i, struct bv_mesh_lod_internal); + ((struct bv_mesh_lod_internal *)lod->i)->s = p; + lod->c = (void *)c; + p->lod = lod; + + // Important - parent codes need to have a sense of the size of + // the object, and we want that size to be consistent regardless + // of the LoD actually in use. Set the bbox dimensions at a level + // where external codes can see and use them. + VMOVE(lod->bmin, p->bbmin); + VMOVE(lod->bmax, p->bbmax); + + return lod; +} + +extern "C" void +bv_mesh_lod_destroy(struct bv_mesh_lod *lod) +{ + if (!lod) + return; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)lod->i; + delete i->s; + i->s = NULL; + BU_PUT(i, struct bv_mesh_lod_internal); + lod->i = NULL; + BU_PUT(lod, struct bv_mesh_lod); +} + +static void +dlist_stale(struct bv_scene_obj *s) +{ + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(&s->children, i); + dlist_stale(cg); + } + s->s_dlist_stale = 1; +} + +extern "C" int +bv_mesh_lod_level(struct bv_scene_obj *s, int level, int reset) +{ + if (!s) + return -1; + + struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)l->i; + POPState *sp = i->s; + if (level < 0) + return sp->curr_level; + + int old_level = sp->curr_level; + + sp->force_update = (reset) ? true : false; + sp->set_level(level); + + // If we're in POP territory use the local arrays - otherwise, they + // were already set by the full detail callback. + if (sp->curr_level <= sp->max_pop_threshold_level) { + l->fcnt = (int)sp->lod_tris.size()/3; + l->faces = sp->lod_tris.data(); + l->points_orig = (const point_t *)sp->lod_tri_pnts.data(); + l->porig_cnt = (int)sp->lod_tri_pnts.size(); +#if 0 + // TODO - there's still some error with normals - they seem to work, + // but when zooming way out and back in (at least on Windows) we're + // getting an access violation with some geometry... + if (sp->lod_tri_norms.size() >= sp->lod_tris.size()) { + l->normals = (const vect_t *)sp->lod_tri_norms.data(); + } else { + l->normals = NULL; + } +#else + l->normals = NULL; +#endif + l->points = (const point_t *)sp->lod_tri_pnts_snapped.data(); + l->pcnt = (int)sp->lod_tri_pnts_snapped.size(); + } + + bv_log(2, "bv_mesh_lod_level %s[%d](%d): %d", bu_vls_cstr(&s->s_name), level, reset, l->fcnt); + + // If the data changed, any Display List we may have previously generated + // is now obsolete + if (old_level != sp->curr_level) + dlist_stale(s); + + return sp->curr_level; +} + + +extern "C" int +bv_mesh_lod_view(struct bv_scene_obj *s, struct bview *v, int reset) +{ + if (!s || !v) + return -1; + struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; + if (!l) + return -1; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)l->i; + POPState *sp = i->s; + int ret = sp->curr_level; + int vscale = (int)((double)sp->get_level(v->gv_size) * v->gv_s->lod_scale); + vscale = (vscale < 0) ? 0 : vscale; + vscale = (vscale >= POP_MAXLEVEL) ? POP_MAXLEVEL-1 : vscale; + + bv_log(2, "bv_mesh_lod_view %s[%s][%d]", bu_vls_cstr(&s->s_name), bu_vls_cstr(&v->gv_name), vscale); + + // If the object is not visible in the scene, don't change the data + //bu_log("min: %f %f %f max: %f %f %f\n", V3ARGS(s->bmin), V3ARGS(s->bmax)); + if (_obj_visible(s, v)) + ret = bv_mesh_lod_level(s, vscale, reset); + + return ret; +} + +extern "C" void +bv_mesh_lod_memshrink(struct bv_scene_obj *s) +{ + if (!s) + return; + struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; + if (!l) + return; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)l->i; + POPState *sp = i->s; + sp->shrink_memory(); + bu_log("memshrink\n"); +} + +static void +bv_clear(const char *d) +{ + if (bu_file_directory(d)) { + char **filenames; + size_t nfiles = bu_file_list(d, "*", &filenames); + for (size_t i = 0; i < nfiles; i++) { + if (BU_STR_EQUAL(filenames[i], ".")) + continue; + if (BU_STR_EQUAL(filenames[i], "..")) + continue; + char cdir[MAXPATHLEN] = {0}; + bu_dir(cdir, MAXPATHLEN, d, filenames[i], NULL); + bv_clear((const char *)cdir); + } + bu_argv_free(nfiles, filenames); + } + bu_file_delete(d); +} + +static void +cache_del(struct bv_mesh_lod_context *c, unsigned long long hash, const char *component) +{ + // Construct lookup key + MDB_val mdb_key; + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + + mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); + mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keystr.c_str(); + mdb_del(c->i->lod_txn, c->i->lod_dbi, &mdb_key, NULL); + mdb_txn_commit(c->i->lod_txn); +} + + +extern "C" void +bv_mesh_lod_clear_cache(struct bv_mesh_lod_context *c, unsigned long long key) +{ + char dir[MAXPATHLEN]; + + if (c && key) { + // For this case, we're clearing the data associated with a + // specific key (for example, if we're about to edit a BoT but + // don't want to redo the whole database's cache. + cache_del(c, key, CACHE_POP_MAX_LEVEL); + cache_del(c, key, CACHE_POP_SWITCH_LEVEL); + cache_del(c, key, CACHE_VERTEX_COUNT); + cache_del(c, key, CACHE_TRI_COUNT); + cache_del(c, key, CACHE_OBJ_BOUNDS); + cache_del(c, key, CACHE_VERT_LEVEL); + cache_del(c, key, CACHE_VERTNORM_LEVEL); + cache_del(c, key, CACHE_TRI_LEVEL); + + // Iterate over the name/key mapper, removing anything with a value + // of key + MDB_val mdb_key, mdb_data; + unsigned long long *fkeyp = NULL; + unsigned long long fkey = 0; + mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); + mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); + MDB_cursor *cursor; + int rc = mdb_cursor_open(c->i->name_txn, c->i->name_dbi, &cursor); + if (rc) { + mdb_txn_commit(c->i->name_txn); + return; + } + rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); + if (rc) { + mdb_txn_commit(c->i->name_txn); + return; + } + fkeyp = (unsigned long long *)mdb_data.mv_data; + fkey = *fkeyp; + if (fkey == key) + mdb_cursor_del(cursor, 0); + while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) { + fkeyp = (unsigned long long *)mdb_data.mv_data; + fkey = *fkeyp; + if (fkey == key) + mdb_cursor_del(cursor, 0); + } + mdb_txn_commit(c->i->name_txn); + return; + } + + if (c && !key) { + + MDB_val mdb_key, mdb_data; + MDB_cursor *cursor; + int rc; + + // Clear the actual LoD data + mdb_txn_begin(c->i->lod_env, NULL, 0, &c->i->lod_txn); + mdb_dbi_open(c->i->lod_txn, NULL, 0, &c->i->lod_dbi); + rc = mdb_cursor_open(c->i->lod_txn, c->i->lod_dbi, &cursor); + if (rc) { + mdb_txn_commit(c->i->lod_txn); + return; + } + rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); + if (rc) { + mdb_txn_commit(c->i->lod_txn); + return; + } + mdb_cursor_del(cursor, 0); + while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) + mdb_cursor_del(cursor, 0); + mdb_txn_commit(c->i->lod_txn); + + // Iterate over the name/key mapper, removing anything with a value + // of key + mdb_txn_begin(c->i->name_env, NULL, 0, &c->i->name_txn); + mdb_dbi_open(c->i->name_txn, NULL, 0, &c->i->name_dbi); + rc = mdb_cursor_open(c->i->name_txn, c->i->name_dbi, &cursor); + if (rc) { + mdb_txn_commit(c->i->name_txn); + return; + } + rc = mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_FIRST); + if (rc) { + mdb_txn_commit(c->i->name_txn); + return; + } + mdb_cursor_del(cursor, 0); + while (!mdb_cursor_get(cursor, &mdb_key, &mdb_data, MDB_NEXT)) + mdb_cursor_del(cursor, 0); + mdb_txn_commit(c->i->name_txn); + + return; + } + + // Clear everything + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, POP_CACHEDIR, NULL); + bv_clear((const char *)dir); +} + +extern "C" void +bv_mesh_lod_detail_setup_clbk( + struct bv_mesh_lod *lod, + int (*clbk)(struct bv_mesh_lod *, void *), + void *clbk_data + ) +{ + if (!lod || !clbk) + return; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)lod->i; + POPState *s = i->s; + s->full_detail_setup_clbk = clbk; + s->detail_clbk_data = clbk_data; +} + +extern "C" void +bv_mesh_lod_detail_clear_clbk( + struct bv_mesh_lod *lod, + int (*clbk)(struct bv_mesh_lod *, void *) + ) +{ + if (!lod || !clbk) + return; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)lod->i; + POPState *s = i->s; + s->full_detail_clear_clbk = clbk; +} + +extern "C" void +bv_mesh_lod_detail_free_clbk( + struct bv_mesh_lod *lod, + int (*clbk)(struct bv_mesh_lod *, void *) + ) +{ + if (!lod || !clbk) + return; + + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)lod->i; + POPState *s = i->s; + s->full_detail_free_clbk = clbk; +} + +void +bv_mesh_lod_free(struct bv_scene_obj *s) +{ + if (!s || !s->draw_data) + return; + struct bv_mesh_lod *l = (struct bv_mesh_lod *)s->draw_data; + struct bv_mesh_lod_internal *i = (struct bv_mesh_lod_internal *)l->i; + delete i->s; + s->draw_data = NULL; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libbv/plot3.c b/src/libbv/plot3.c deleted file mode 100644 index 071d9b9dcbe..00000000000 --- a/src/libbv/plot3.c +++ /dev/null @@ -1,1031 +0,0 @@ -/* P L O T 3 . C - * BRL-CAD - * - * Copyright (c) 2004-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @addtogroup plot */ -/** @{ */ -/** @file libbn/plot3.c - * - * @brief A public-domain UNIX plot library, for 2-D and 3-D plotting - * in 16-bit VAX signed integer spaces, or 64-bit IEEE floating point. - * - * These routines generate "UNIX plot" output (with the addition of - * 3-D commands). They behave almost exactly like the regular libplot - * routines, except: - * - * -# These all take a stdio file pointer, and can thus be used to - * create multiple plot files simultaneously. - * -# There are 3-D versions of most commands. - * -# There are IEEE floating point versions of the commands. - * -# The names have been changed. - * - * The 3-D extensions are those of Doug Gwyn, from his System V - * extensions. - * - * These are the ascii command letters allocated to various actions. - * Care has been taken to consistently match lowercase and uppercase - * letters. - * - * @code - 2d 3d 2df 3df - space s S w W - move m M o O - cont n N q Q - point p P x X - line l L v V - circle c i - arc a r - linmod f - label t - erase e - color C - flush F - - bd gh jk uyz - ABDEGHIJKRTUYZ - - @endcode - * - */ - -#include "common.h" - -#include - -#include "bu/cv.h" -#include "vmath.h" -#include "bv/plot3.h" - - -static int pl_outputMode = PL_OUTPUT_MODE_BINARY; - -/* For the sake of efficiency, we trust putc() to write only one byte */ -#define putsi(a) putc(a, plotfp); putc((a>>8), plotfp) - -/* Making a common pd_3 to be used in pd_3cont and pd_3move */ -void -pd_3(register FILE *plotfp, double x, double y, double z, char c) -{ - size_t ret; - double in[3]; - unsigned char out[3*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = x; - in[1] = y; - in[2] = z; - bu_cv_htond(&out[1], (unsigned char *)in, 3); - - out[0] = c; - ret = fwrite(out, 1, 3*8+1, plotfp); - if (ret != 3*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "%c %g %g %g\n", c, x, y, z); - } -} - -/* Making a common pdv_3 to be used in pdv_3cont and pdv_3move */ -void -pdv_3(register FILE *plotfp, const fastf_t *pt, char c) -{ - size_t ret; - unsigned char out[3*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - bu_cv_htond(&out[1], (unsigned char *)pt, 3); - - out[0] = c; - ret = fwrite(out, 1, 3*8+1, plotfp); - if (ret != 3*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "%c %g %g %g\n", c, V3ARGS(pt)); - } -} - -/* Making a common pd to be used in pd_cont and pd_move */ -void -pd(register FILE *plotfp, double x, double y, char c) -{ - size_t ret; - double in[2]; - unsigned char out[2*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = x; - in[1] = y; - bu_cv_htond(&out[1], (unsigned char *)in, 2); - - out[0] = c; - ret = fwrite(out, 1, 2*8+1, plotfp); - if (ret != 2*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "%c %g %g\n", c, x, y); - } -} - -/* Making a common pl_3 to be used in pl_3cont and pl_3move */ -void -pl_3(register FILE *plotfp, int x, int y, int z, char c) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc( c, plotfp); - putsi(x); - putsi(y); - putsi(z); - } else { - fprintf(plotfp, "%c %d %d %d\n", c, x, y, z); - } -} - -/* - * These interfaces provide the standard UNIX-Plot functionality - */ - -int -pl_getOutputMode(void) { - return pl_outputMode; -} - -void -pl_setOutputMode(int mode) { - pl_outputMode = mode; -} - -/** - * @brief - * plot a point - */ -void -pl_point(register FILE *plotfp, int x, int y) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('p', plotfp); - putsi(x); - putsi(y); - } else { - fprintf(plotfp, "p %d %d\n", x, y); - } -} - -void -pl_line(register FILE *plotfp, int px1, int py1, int px2, int py2) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('l', plotfp); - putsi(px1); - putsi(py1); - putsi(px2); - putsi(py2); - } else { - fprintf(plotfp, "l %d %d %d %d\n", px1, py1, px2, py2); - } -} - -void -pl_linmod(register FILE *plotfp, const char *s) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('f', plotfp); - while (*s) - putc(*s++, plotfp); - putc('\n', plotfp); - } else { - fprintf(plotfp, "f %s\n", s); - } -} - -void -pl_move(register FILE *plotfp, int x, int y) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('m', plotfp); - putsi(x); - putsi(y); - } else { - fprintf(plotfp, "m %d %d\n", x, y); - } -} - -void -pl_cont(register FILE *plotfp, int x, int y) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('n', plotfp); - putsi(x); - putsi(y); - } else { - fprintf(plotfp, "n %d %d\n", x, y); - } -} - -void -pl_label(register FILE *plotfp, const char *s) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('t', plotfp); - while (*s) - putc(*s++, plotfp); - putc('\n', plotfp); - } else { - fprintf(plotfp, "t %s\n", s); - } -} - -void -pl_space(register FILE *plotfp, int px1, int py1, int px2, int py2) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('s', plotfp); - putsi(px1); - putsi(py1); - putsi(px2); - putsi(py2); - } else { - fprintf(plotfp, "s %d %d %d %d\n", px1, py1, px2, py2); - } -} - -void -pl_erase(register FILE *plotfp) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) - putc('e', plotfp); - else - fprintf(plotfp, "e\n"); -} - -void -pl_circle(register FILE *plotfp, int x, int y, int r) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('c', plotfp); - putsi(x); - putsi(y); - putsi(r); - } else { - fprintf(plotfp, "c %d %d %d\n", x, y, r); - } -} - -void -pl_arc(register FILE *plotfp, int xc, int yc, int px1, int py1, int px2, int py2) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('a', plotfp); - putsi(xc); - putsi(yc); - putsi(px1); - putsi(py1); - putsi(px2); - putsi(py2); - } else { - fprintf(plotfp, "a %d %d %d %d %d %d\n", xc, yc, px1, py1, px2, py2); - } -} - -void -pl_box(register FILE *plotfp, int px1, int py1, int px2, int py2) -{ - pl_move(plotfp, px1, py1); - pl_cont(plotfp, px1, py2); - pl_cont(plotfp, px2, py2); - pl_cont(plotfp, px2, py1); - pl_cont(plotfp, px1, py1); - pl_move(plotfp, px2, py2); -} - -/* - * Here lie the BRL 3-D extensions. - */ - -/* Warning: r, g, b are ints. The output is chars. */ -void -pl_color(register FILE *plotfp, int r, int g, int b) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('C', plotfp); - putc(r, plotfp); - putc(g, plotfp); - putc(b, plotfp); - } else { - fprintf(plotfp, "C %d %d %d\n", r, g, b); - } -} - -void -pl_color_buc(register FILE *plotfp, struct bu_color *c) -{ - int r = 0; - int g = 0; - int b = 0; - (void)bu_color_to_rgb_ints(c, &r, &g, &b); - pl_color(plotfp, r, g, b); -} -void -pl_flush(register FILE *plotfp) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('F', plotfp); - } else { - fprintf(plotfp, "F\n"); - } - - fflush(plotfp); -} - -void -pl_3space(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('S', plotfp); - putsi(px1); - putsi(py1); - putsi(pz1); - putsi(px2); - putsi(py2); - putsi(pz2); - } else { - fprintf(plotfp, "S %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2); - } -} - -void -pl_3point(register FILE *plotfp, int x, int y, int z) -{ - pl_3(plotfp, x, y, z, 'P'); /* calling common function pl_3 */ -} - -void -pl_3move(register FILE *plotfp, int x, int y, int z) -{ - pl_3(plotfp, x, y, z, 'M'); /* calling common function pl_3 */ -} - -void -pl_3cont(register FILE *plotfp, int x, int y, int z) -{ - pl_3(plotfp, x, y, z, 'N'); /* calling common function pl_3 */ -} - -void -pl_3line(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) -{ - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - putc('L', plotfp); - putsi(px1); - putsi(py1); - putsi(pz1); - putsi(px2); - putsi(py2); - putsi(pz2); - } else { - fprintf(plotfp, "L %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2); - } -} - -void -pl_3box(register FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2) -{ - pl_3move(plotfp, px1, py1, pz1); - /* first side */ - pl_3cont(plotfp, px1, py2, pz1); - pl_3cont(plotfp, px1, py2, pz2); - pl_3cont(plotfp, px1, py1, pz2); - pl_3cont(plotfp, px1, py1, pz1); - /* across */ - pl_3cont(plotfp, px2, py1, pz1); - /* second side */ - pl_3cont(plotfp, px2, py2, pz1); - pl_3cont(plotfp, px2, py2, pz2); - pl_3cont(plotfp, px2, py1, pz2); - pl_3cont(plotfp, px2, py1, pz1); - /* front edge */ - pl_3move(plotfp, px1, py2, pz1); - pl_3cont(plotfp, px2, py2, pz1); - /* bottom back */ - pl_3move(plotfp, px1, py1, pz2); - pl_3cont(plotfp, px2, py1, pz2); - /* top back */ - pl_3move(plotfp, px1, py2, pz2); - pl_3cont(plotfp, px2, py2, pz2); -} - -/* - * Double floating point versions - */ - -void -pd_point(register FILE *plotfp, double x, double y) -{ - pd( plotfp, x, y, 'x'); /* calling common function pd */ -} - -void -pd_line(register FILE *plotfp, double px1, double py1, double px2, double py2) -{ - size_t ret; - double in[4]; - unsigned char out[4*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = px1; - in[1] = py1; - in[2] = px2; - in[3] = py2; - bu_cv_htond(&out[1], (unsigned char *)in, 4); - - out[0] = 'v'; - ret = fwrite(out, 1, 4*8+1, plotfp); - if (ret != 4*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "v %g %g %g %g\n", px1, py1, px2, py2); - } -} - -/* Note: no pd_linmod(), just use pl_linmod() */ - -void -pd_move(register FILE *plotfp, double x, double y) -{ - pd( plotfp, x, y, 'o'); /* calling common function pd */ -} - -void -pd_cont(register FILE *plotfp, double x, double y) -{ - pd( plotfp, x, y, 'q'); /* calling common function pd */ -} - -void -pd_space(register FILE *plotfp, double px1, double py1, double px2, double py2) -{ - size_t ret; - double in[4]; - unsigned char out[4*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = px1; - in[1] = py1; - in[2] = px2; - in[3] = py2; - bu_cv_htond(&out[1], (unsigned char *)in, 4); - - out[0] = 'w'; - ret = fwrite(out, 1, 4*8+1, plotfp); - if (ret != 4*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "w %g %g %g %g\n", px1, py1, px2, py2); - } -} - -void -pd_circle(register FILE *plotfp, double x, double y, double r) -{ - size_t ret; - double in[3]; - unsigned char out[3*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = x; - in[1] = y; - in[2] = r; - bu_cv_htond(&out[1], (unsigned char *)in, 3); - - out[0] = 'i'; - ret = fwrite(out, 1, 3*8+1, plotfp); - if (ret != 3*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "i %g %g %g\n", x, y, r); - } -} - -void -pd_arc(register FILE *plotfp, double xc, double yc, double px1, double py1, double px2, double py2) -{ - size_t ret; - double in[6]; - unsigned char out[6*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = xc; - in[1] = yc; - in[2] = px1; - in[3] = py1; - in[4] = px2; - in[5] = py2; - bu_cv_htond(&out[1], (unsigned char *)in, 6); - - out[0] = 'r'; - ret = fwrite(out, 1, 6*8+1, plotfp); - if (ret != 6*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "r %g %g %g %g %g %g\n", xc, yc, px1, py1, px2, py2); - } -} - -void -pd_box(register FILE *plotfp, double px1, double py1, double px2, double py2) -{ - pd_move(plotfp, px1, py1); - pd_cont(plotfp, px1, py2); - pd_cont(plotfp, px2, py2); - pd_cont(plotfp, px2, py1); - pd_cont(plotfp, px1, py1); - pd_move(plotfp, px2, py2); -} - -/* Double 3-D, both in vector and enumerated versions */ -void -pdv_3space(register FILE *plotfp, const vect_t min, const vect_t max) -{ - size_t ret; - unsigned char out[6*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - bu_cv_htond(&out[1], (unsigned char *)min, 3); - bu_cv_htond(&out[3*8+1], (unsigned char *)max, 3); - - out[0] = 'W'; - ret = fwrite(out, 1, 6*8+1, plotfp); - if (ret != 6*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "W %g %g %g %g %g %g\n", V3ARGS(min), V3ARGS(max)); - } -} - -void -pd_3space(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) -{ - size_t ret; - double in[6]; - unsigned char out[6*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = px1; - in[1] = py1; - in[2] = pz1; - in[3] = px2; - in[4] = py2; - in[5] = pz2; - bu_cv_htond(&out[1], (unsigned char *)in, 6); - - out[0] = 'W'; - ret = fwrite(out, 1, 6*8+1, plotfp); - if (ret != 6*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "W %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2); - } -} - -void -pdv_3point(register FILE *plotfp, const point_t pt) -{ - pdv_3(plotfp, pt, 'X'); /* calling common function pdv_3 */ -} - -void -pd_3point(register FILE *plotfp, double x, double y, double z) -{ - pd_3(plotfp, x, y, z, 'X'); /* calling common function pd_3 */ -} - -void -pdv_3move(register FILE *plotfp, const point_t pt) -{ - pdv_3(plotfp, pt, 'O'); /* calling common function pdv_3 */ -} - -void -pd_3move(register FILE *plotfp, double x, double y, double z) -{ - pd_3(plotfp, x, y, z, 'O'); /* calling common function pd_3 */ -} - -void -pdv_3cont(register FILE *plotfp, const point_t pt) -{ - pdv_3(plotfp, pt, 'Q'); /* calling common function pdv_3 */ -} - -void -pd_3cont(register FILE *plotfp, double x, double y, double z) -{ - pd_3(plotfp, x, y, z, 'Q'); /* calling common function pd_3 */ -} - -void -pdv_3line(register FILE *plotfp, const vect_t a, const vect_t b) -{ - size_t ret; - unsigned char out[6*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - bu_cv_htond(&out[1], (unsigned char *)a, 3); - bu_cv_htond(&out[3*8+1], (unsigned char *)b, 3); - - out[0] = 'V'; - ret = fwrite(out, 1, 6*8+1, plotfp); - if (ret != 6*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "V %g %g %g %g %g %g\n", V3ARGS(a), V3ARGS(b)); - } -} - -void -pd_3line(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) -{ - size_t ret; - double in[6]; - unsigned char out[6*8+1]; - - if (pl_outputMode == PL_OUTPUT_MODE_BINARY) { - in[0] = px1; - in[1] = py1; - in[2] = pz1; - in[3] = px2; - in[4] = py2; - in[5] = pz2; - bu_cv_htond(&out[1], (unsigned char *)in, 6); - - out[0] = 'V'; - ret = fwrite(out, 1, 6*8+1, plotfp); - if (ret != 6*8+1) { - perror("fwrite"); - } - } else { - fprintf(plotfp, "V %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2); - } -} - -void -pdv_3box(register FILE *plotfp, const vect_t a, const vect_t b) -{ - pd_3move(plotfp, a[X], a[Y], a[Z]); - /* first side */ - pd_3cont(plotfp, a[X], b[Y], a[Z]); - pd_3cont(plotfp, a[X], b[Y], b[Z]); - pd_3cont(plotfp, a[X], a[Y], b[Z]); - pd_3cont(plotfp, a[X], a[Y], a[Z]); - /* across */ - pd_3cont(plotfp, b[X], a[Y], a[Z]); - /* second side */ - pd_3cont(plotfp, b[X], b[Y], a[Z]); - pd_3cont(plotfp, b[X], b[Y], b[Z]); - pd_3cont(plotfp, b[X], a[Y], b[Z]); - pd_3cont(plotfp, b[X], a[Y], a[Z]); - /* front edge */ - pd_3move(plotfp, a[X], b[Y], a[Z]); - pd_3cont(plotfp, b[X], b[Y], a[Z]); - /* bottom back */ - pd_3move(plotfp, a[X], a[Y], b[Z]); - pd_3cont(plotfp, b[X], a[Y], b[Z]); - /* top back */ - pd_3move(plotfp, a[X], b[Y], b[Z]); - pd_3cont(plotfp, b[X], b[Y], b[Z]); -} - -void -pd_3box(register FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2) -{ - pd_3move(plotfp, px1, py1, pz1); - /* first side */ - pd_3cont(plotfp, px1, py2, pz1); - pd_3cont(plotfp, px1, py2, pz2); - pd_3cont(plotfp, px1, py1, pz2); - pd_3cont(plotfp, px1, py1, pz1); - /* across */ - pd_3cont(plotfp, px2, py1, pz1); - /* second side */ - pd_3cont(plotfp, px2, py2, pz1); - pd_3cont(plotfp, px2, py2, pz2); - pd_3cont(plotfp, px2, py1, pz2); - pd_3cont(plotfp, px2, py1, pz1); - /* front edge */ - pd_3move(plotfp, px1, py2, pz1); - pd_3cont(plotfp, px2, py2, pz1); - /* bottom back */ - pd_3move(plotfp, px1, py1, pz2); - pd_3cont(plotfp, px2, py1, pz2); - /* top back */ - pd_3move(plotfp, px1, py2, pz2); - pd_3cont(plotfp, px2, py2, pz2); -} - -/** - * Draw a ray - */ -void -pdv_3ray(FILE *fp, const point_t pt, const vect_t dir, double t) -{ - point_t tip; - - VJOIN1(tip, pt, t, dir); - pdv_3move(fp, pt); - pdv_3cont(fp, tip); -} - - -/* - * Routines to validate a plot file - */ - -static int -read_short(FILE *fp, int cnt, int mode) -{ - if (mode == PL_OUTPUT_MODE_BINARY) { - for (int i = 0; i < cnt * 2; i++) { - if (getc(fp) == EOF) - return 1; - } - return 0; - } - if (mode == PL_OUTPUT_MODE_TEXT) { - int ret; - double val; - for (int i = 0; i < cnt; i++) { - ret = fscanf(fp, "%lf", &val); - if (ret != 1) - return 1; - } - return 0; - } - - return 1; -} - -static int -read_ieee(FILE *fp, int cnt, int mode) -{ - size_t ret; - if (mode == PL_OUTPUT_MODE_BINARY) { - for (int i = 0; i < cnt; i++) { - char inbuf[SIZEOF_NETWORK_DOUBLE]; - ret = fread(inbuf, SIZEOF_NETWORK_DOUBLE, 1, fp); - if (ret != 1) - return 1; - } - return 0; - } - if (mode == PL_OUTPUT_MODE_TEXT) { - double val; - for (int i = 0; i < cnt; i++) { - ret = (size_t)fscanf(fp, "%lf", &val); - if (ret != 1) - return 1; - } - return 0; - } - return 1; -} - -static int -read_tstring(FILE *fp, int mode) -{ - int ret; - if (mode == PL_OUTPUT_MODE_BINARY) { - int str_done = 0; - int cc; - while (!feof(fp) && !str_done) { - cc = getc(fp); - if (cc == '\n') - str_done = 1; - } - return 0; - } - if (mode == PL_OUTPUT_MODE_TEXT) { - char carg[256] = {0}; - ret = fscanf(fp, "%255s\n", &carg[0]); - if (ret != 1) - return 1; - return 0; - } - return 1; -} - -int -plot3_invalid(FILE *fp, int mode) -{ - - /* Only two valid modes */ - if (mode != PL_OUTPUT_MODE_BINARY && mode != PL_OUTPUT_MODE_TEXT) { - return 1; - } - - /* A non-readable file isn't a valid file */ - if (!fp) { - return 1; - } - - int i = 0; - int c; - unsigned int tchar = 0; - - while (!feof(fp) && (c=getc(fp)) != EOF) { - if (c < 'A' || c > 'z') { - return 1; - } - switch (c) { - case 'C': - // TCHAR, 3, "color" - if (mode == PL_OUTPUT_MODE_BINARY) { - for (i = 0; i < 3; i++) { - if (getc(fp) == EOF) - return 1; - } - } - if (mode == PL_OUTPUT_MODE_TEXT) { - i = fscanf(fp, "%u", &tchar); - if (i != 1) - return 1; - } - break; - case 'F': - // TNONE, 0, "flush" - break; - case 'L': - // TSHORT, 6, "3line" - if (read_short(fp, 6, mode)) - return 1; - break; - case 'M': - // TSHORT, 3, "3move" - if (read_short(fp, 3, mode)) - return 1; - break; - case 'N': - // TSHORT, 3, "3cont" - if (read_short(fp, 3, mode)) - return 1; - break; - case 'O': - // TIEEE, 3, "d_3move" - if (read_ieee(fp, 3, mode)) - return 1; - break; - case 'P': - // TSHORT, 3, "3point" - if (read_short(fp, 3, mode)) - return 1; - break; - case 'Q': - // TIEEE, 3, "d_3cont" - if (read_ieee(fp, 3, mode)) - return 1; - break; - case 'S': - // TSHORT, 6, "3space" - if (read_short(fp, 6, mode)) - return 1; - break; - case 'V': - // TIEEE, 6, "d_3line" - if (read_ieee(fp, 6, mode)) - return 1; - break; - case 'W': - // TIEEE, 6, "d_3space" - if (read_ieee(fp, 6, mode)) - return 1; - break; - case 'X': - // TIEEE, 3, "d_3point" - if (read_ieee(fp, 3, mode)) - return 1; - break; - case 'a': - // TSHORT, 6, "arc" - if (read_short(fp, 6, mode)) - return 1; - break; - case 'c': - // TSHORT, 3, "circle" - if (read_short(fp, 3, mode)) - return 1; - break; - case 'e': - // TNONE, 0, "erase" - break; - case 'f': - // TSTRING, 1, "linmod" - if (read_tstring(fp, mode)) - return 1; - break; - case 'i': - // TIEEE, 3, "d_circle" - if (read_ieee(fp, 3, mode)) - return 1; - break; - case 'l': - // TSHORT, 4, "line" - if (read_short(fp, 4, mode)) - return 1; - break; - case 'm': - // TSHORT, 2, "move" - if (read_short(fp, 2, mode)) - return 1; - break; - case 'n': - // TSHORT, 2, "cont" - if (read_short(fp, 2, mode)) - return 1; - break; - case 'o': - // TIEEE, 2, "d_move" - if (read_ieee(fp, 2, mode)) - return 1; - break; - case 'p': - // TSHORT, 2, "point" - if (read_short(fp, 2, mode)) - return 1; - break; - case 'q': - // TIEEE, 2, "d_cont" - if (read_ieee(fp, 2, mode)) - return 1; - break; - case 'r': - // TIEEE, 6, "d_arc" - if (read_ieee(fp, 6, mode)) - return 1; - break; - case 's': - // TSHORT, 4, "space" - if (read_short(fp, 4, mode)) - return 1; - break; - case 't': - // TSTRING, 1, "label" - if (read_tstring(fp, mode)) - return 1; - break; - case 'v': - // TIEEE, 4, "d_line" - if (read_ieee(fp, 4, mode)) - return 1; - break; - case 'w': - // TIEEE, 4, "d_space" - if (read_ieee(fp, 4, mode)) - return 1; - break; - case 'x': - // TIEEE, 2, "d_point" - if (read_ieee(fp, 2, mode)) - return 1; - break; - default: - return 1; - break; - }; - } - - return 0; -} - -/** @} */ -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libbv/polygon.c b/src/libbv/polygon.c new file mode 100644 index 00000000000..2543d354dcc --- /dev/null +++ b/src/libbv/polygon.c @@ -0,0 +1,857 @@ +/* P O L Y G O N . C + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file polygons.c + * + * Utility functions for working with polygons in a view context. + * + */ + +#include "common.h" +#include +#include "vmath.h" +#include "bu/log.h" +#include "bu/malloc.h" +#include "bu/str.h" +#include "bn/mat.h" +#include "bn/tol.h" +#include "bv/vlist.h" +#include "bv/defines.h" +#include "bv/util.h" +#include "bg/lseg.h" +#include "bg/plane.h" +#include "bg/polygon.h" +#include "bv/defines.h" +#include "bv/polygon.h" +#include "bv/snap.h" + +void +bv_polygon_contour(struct bv_scene_obj *s, struct bg_poly_contour *c, int curr_c, int curr_i, int do_pnt) +{ + if (!s || !c || !s->s_v) + return; + + if (do_pnt) { + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[0], BV_VLIST_POINT_DRAW); + return; + } + + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[0], BV_VLIST_LINE_MOVE); + for (size_t i = 0; i < c->num_points; i++) { + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[i], BV_VLIST_LINE_DRAW); + } + if (!c->open) + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[0], BV_VLIST_LINE_DRAW); + + if (curr_c && curr_i >= 0) { + point_t psize; + VSET(psize, 10, 0, 0); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[curr_i], BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, psize, BV_VLIST_POINT_SIZE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, c->point[curr_i], BV_VLIST_POINT_DRAW); + } +} + +void +bv_fill_polygon(struct bv_scene_obj *s) +{ + if (!s) + return; + + // free old fill, if present + struct bv_scene_obj *fobj = bv_find_child(s, "*fill*"); + if (fobj) + bv_obj_put(fobj); + + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + if (!p || !p->polygon.num_contours) + return; + + if (!p->polygon.contour || p->polygon.contour[0].open) + return; + + if (p->fill_delta < BN_TOL_DIST) + return; + + struct bg_polygon *fill = bv_polygon_fill_segments(&p->polygon, &p->vp, p->fill_dir, p->fill_delta); + if (!fill) + return; + + // Got fill, create lines + fobj = bv_obj_get_child(s); + bu_vls_printf(&fobj->s_name, ":fill"); + fobj->s_os->s_line_width = 1; + fobj->s_soldash = 0; + bu_color_to_rgb_chars(&p->fill_color, fobj->s_color); + for (size_t i = 0; i < fill->num_contours; i++) { + bv_polygon_contour(fobj, &fill->contour[i], 0, -1, 0); + } +} + +void +bv_polygon_vlist(struct bv_scene_obj *s) +{ + if (!s) + return; + + // Reset obj drawing data + if (BU_LIST_IS_INITIALIZED(&s->s_vlist)) { + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + } + BU_LIST_INIT(&(s->s_vlist)); + + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + int type = p->type; + + // Clear any old holes + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); + bv_obj_put(s_c); + } + + for (size_t i = 0; i < p->polygon.num_contours; ++i) { + /* Draw holes using segmented lines. Since vlists don't have a style + * command for that, we make child scene objects for the holes. */ + size_t pcnt = p->polygon.contour[i].num_points; + int do_pnt = 0; + if (pcnt == 1) + do_pnt = 1; + if (type == BV_POLYGON_CIRCLE && pcnt == 3) + do_pnt = 1; + if (type == BV_POLYGON_ELLIPSE && pcnt == 4) + do_pnt = 1; + if (type == BV_POLYGON_RECTANGLE) { + if (NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[1]), SMALL_FASTF) && + NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[2]), SMALL_FASTF)) + do_pnt = 1; + } + if (type == BV_POLYGON_SQUARE) { + if (NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[1]), SMALL_FASTF) && + NEAR_ZERO(DIST_PNT_PNT_SQ(p->polygon.contour[0].point[0], p->polygon.contour[0].point[2]), SMALL_FASTF)) + do_pnt = 1; + } + + if (p->polygon.hole[i]) { + struct bv_scene_obj *s_c = bv_obj_get_child(s); + s_c->s_soldash = 1; + s_c->s_color[0] = s->s_color[0]; + s_c->s_color[1] = s->s_color[1]; + s_c->s_color[2] = s->s_color[2]; + s_c->s_v = s->s_v; + bv_polygon_contour(s_c, &p->polygon.contour[i], ((int)i == p->curr_contour_i), p->curr_point_i, do_pnt); + bu_ptbl_ins(&s->children, (long *)s_c); + continue; + } + + bv_polygon_contour(s, &p->polygon.contour[i], ((int)i == p->curr_contour_i), p->curr_point_i, do_pnt); + } + + if (p->fill_flag) { + bv_fill_polygon(s); + } else { + struct bv_scene_obj *fobj = bv_find_child(s, "*fill*"); + if (fobj) + bv_obj_put(fobj); + + } +} + +struct bv_scene_obj * +bv_create_polygon_obj(struct bview *v, int flags, struct bv_polygon *p) +{ + struct bv_scene_obj *s = bv_obj_get(v, flags); + s->s_type_flags |= BV_POLYGONS; + s->s_type_flags |= BV_VIEWONLY; + + // Construct the plane + bv_view_plane(&p->vp, v); + + s->s_os->s_line_width = 1; + s->s_color[0] = 255; + s->s_color[1] = 255; + s->s_color[2] = 0; + s->s_i_data = (void *)p; + s->s_update_callback = &bv_update_polygon; + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* updated */ + s->s_changed++; + + return s; +} + +struct bv_scene_obj * +bv_create_polygon(struct bview *v, int flags, int type, point_t fp) +{ + + struct bv_polygon *p; + BU_GET(p, struct bv_polygon); + p->type = type; + p->curr_contour_i = -1; + p->curr_point_i = -1; + + // Set default fill color to blue + unsigned char frgb[3] = {0, 0, 255}; + bu_color_from_rgb_chars(&p->fill_color, frgb); + + // Construct the plane + bv_view_plane(&p->vp, v); + + // Construct closest point to fp on plane + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, p->vp, fp); + point_t m_pt; + bg_plane_pt_at(&m_pt, p->vp, fx, fy); + + // This is now the origin point + VMOVE(p->origin_point, m_pt); + + int pcnt = 1; + if (type == BV_POLYGON_CIRCLE) + pcnt = 3; + if (type == BV_POLYGON_ELLIPSE) + pcnt = 4; + if (type == BV_POLYGON_RECTANGLE) + pcnt = 4; + if (type == BV_POLYGON_SQUARE) + pcnt = 4; + + p->polygon.num_contours = 1; + p->polygon.hole = (int *)bu_calloc(1, sizeof(int), "hole"); + p->polygon.contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); + p->polygon.contour[0].num_points = pcnt; + p->polygon.contour[0].open = 0; + p->polygon.contour[0].point = (point_t *)bu_calloc(pcnt, sizeof(point_t), "point"); + p->polygon.hole[0] = 0; + for (int i = 0; i < pcnt; i++) { + VMOVE(p->polygon.contour[0].point[i], m_pt); + } + + // Only the general polygon isn't closed out of the gate + if (type == BV_POLYGON_GENERAL) + p->polygon.contour[0].open = 1; + + // Have polygon, now make scene object + struct bv_scene_obj *s = bv_create_polygon_obj(v, flags, p); + if (!s) + BU_PUT(p, struct bv_polygon); + return s; +} + +void +bv_polygon_cpy(struct bv_polygon *dest, struct bv_polygon *src) +{ + if (!src || !dest) + return; + + dest->type = src->type; + dest->fill_flag = src->fill_flag; + V2MOVE(dest->fill_dir, src->fill_dir); + dest->fill_delta = src->fill_delta; + BU_COLOR_CPY(&dest->fill_color, &src->fill_color); + dest->curr_contour_i = src->curr_contour_i; + dest->curr_point_i = src->curr_point_i; + VMOVE(dest->origin_point, src->origin_point); + HMOVE(dest->vp, src->vp); + dest->vZ = src->vZ; + bg_polygon_free(&dest->polygon); + bg_polygon_cpy(&dest->polygon, &src->polygon); + dest->u_data = src->u_data; +} + +int +bv_append_polygon_pt(struct bv_scene_obj *s, point_t np) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + if (p->type != BV_POLYGON_GENERAL) + return -1; + + if (p->curr_contour_i < 0) + return -1; + + // Construct closest point to np on plane + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, p->vp, np); + point_t m_pt; + bg_plane_pt_at(&m_pt, p->vp, fx, fy); + + struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; + c->num_points++; + c->point = (point_t *)bu_realloc(c->point,c->num_points * sizeof(point_t), "realloc contour points"); + VMOVE(c->point[c->num_points-1], m_pt); + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 0; +} + +// NOTE: This is a naive brute force search for the closest projected edge at +// the moment... Would be better for repeated sampling of relatively static +// scenes to build an RTree first... +struct bv_scene_obj * +bv_select_polygon(struct bu_ptbl *objs, point_t cp) +{ + if (!objs) + return NULL; + + struct bv_scene_obj *closest = NULL; + double dist_min_sq = DBL_MAX; + + for (size_t i = 0; i < BU_PTBL_LEN(objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(objs, i); + if (s->s_type_flags & BV_POLYGONS) { + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + // Because we're working in 2D orthogonal when processing polygons, + // the specific value of Z for each individual polygon isn't + // relevant - we want to find the closest edge in the projected + // view plane. Accordingly, always construct the test point using + // whatever the current vZ is for the polygon being tested. + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, zpln, cp); + point_t m_pt; + bg_plane_pt_at(&m_pt, zpln, fx, fy); + + for (size_t j = 0; j < p->polygon.num_contours; j++) { + struct bg_poly_contour *c = &p->polygon.contour[j]; + for (size_t k = 0; k < c->num_points; k++) { + double dcand; + if (k < c->num_points - 1) { + dcand = bg_distsq_lseg3_pt(NULL, c->point[k], c->point[k+1], m_pt); + } else { + dcand = bg_distsq_lseg3_pt(NULL, c->point[k], c->point[0], m_pt); + } + if (dcand < dist_min_sq) { + dist_min_sq = dcand; + closest = s; + } + } + } + } + } + + return closest; +} + +int +bv_select_polygon_pt(struct bv_scene_obj *s, point_t cp) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + if (p->type != BV_POLYGON_GENERAL) + return -1; + + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + fastf_t fx, fy; + bg_plane_closest_pt(&fx, &fy, zpln, cp); + point_t m_pt; + bg_plane_pt_at(&m_pt, zpln, fx, fy); + + // If a contour is selected, restrict our closest point candidates to + // that contour's points + double dist_min_sq = DBL_MAX; + long closest_ind = -1; + long closest_contour = -1; + if (p->curr_contour_i >= 0) { + struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; + closest_contour = p->curr_contour_i; + for (size_t i = 0; i < c->num_points; i++) { + double dcand = DIST_PNT_PNT_SQ(c->point[i], m_pt); + if (dcand < dist_min_sq) { + closest_ind = (long)i; + dist_min_sq = dcand; + } + } + } else { + for (size_t j = 0; j < p->polygon.num_contours; j++) { + struct bg_poly_contour *c = &p->polygon.contour[j]; + for (size_t i = 0; i < c->num_points; i++) { + double dcand = DIST_PNT_PNT_SQ(c->point[i], m_pt); + if (dcand < dist_min_sq) { + closest_ind = (long)i; + closest_contour = (long)j; + dist_min_sq = dcand; + } + } + } + } + + p->curr_point_i = closest_ind; + p->curr_contour_i = closest_contour; + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 0; +} + + +void +bv_select_clear_polygon_pt(struct bv_scene_obj *s) +{ + if (!s) + return; + + if (s->s_type_flags & BV_POLYGONS) { + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + p->curr_point_i = -1; + p->curr_contour_i = -1; + bv_polygon_vlist(s); + /* Updated */ + s->s_changed++; + } +} + + +int +bv_move_polygon(struct bv_scene_obj *s, point_t cp, point_t prev_point) +{ + fastf_t pfx, pfy, fx, fy; + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&pfx, &pfy, zpln, prev_point); + bg_plane_closest_pt(&fx, &fy, zpln, cp); + point_t pm_pt, m_pt; + bg_plane_pt_at(&pm_pt, p->vp, pfx, pfy); + bg_plane_pt_at(&m_pt, p->vp, fx, fy); + vect_t v_mv; + VSUB2(v_mv, m_pt, pm_pt); + + for (size_t j = 0; j < p->polygon.num_contours; j++) { + struct bg_poly_contour *c = &p->polygon.contour[j]; + for (size_t i = 0; i < c->num_points; i++) { + VADD2(c->point[i], c->point[i], v_mv); + } + } + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + // Shift the origin point. + VADD2(p->origin_point, p->origin_point, v_mv); + + /* Updated */ + s->s_changed++; + + return 0; +} + +int +bv_move_polygon_pt(struct bv_scene_obj *s, point_t mp) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + if (p->type != BV_POLYGON_GENERAL) + return -1; + + // Need to have a point selected before we can move + if (p->curr_point_i < 0 || p->curr_contour_i < 0) + return -1; + + fastf_t fx, fy; + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&fx, &fy, zpln, mp); + point_t m_pt; + bg_plane_pt_at(&m_pt, zpln, fx, fy); + + struct bg_poly_contour *c = &p->polygon.contour[p->curr_contour_i]; + VMOVE(c->point[p->curr_point_i], m_pt); + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 0; +} + +int +bv_update_polygon_circle(struct bv_scene_obj *s, point_t cp, fastf_t pixel_size) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + fastf_t curr_fx, curr_fy; + fastf_t r, arc; + int nsegs, n; + + r = DIST_PNT_PNT(cp, p->origin_point); + + /* use a variable number of segments based on the size of the + * circle being created so small circles have few segments and + * large ones are nice and smooth. + */ + nsegs = M_PI_2 * r / pixel_size; + if (nsegs < 32) + nsegs = 32; + + struct bg_polygon gp; + struct bg_polygon *gpp = &gp; + gpp->num_contours = 1; + gpp->hole = (int *)bu_calloc(1, sizeof(int), "hole");; + gpp->contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); + gpp->contour[0].num_points = nsegs; + gpp->contour[0].open = 0; + gpp->contour[0].point = (point_t *)bu_calloc(nsegs, sizeof(point_t), "point"); + + fastf_t pfx, pfy, fx, fy; + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&fx, &fy, zpln, cp); + bg_plane_closest_pt(&pfx, &pfy, zpln, p->origin_point); + + arc = 360.0 / nsegs; + for (n = 0; n < nsegs; ++n) { + fastf_t ang = n * arc; + + curr_fx = cos(ang*DEG2RAD) * r + pfx; + curr_fy = sin(ang*DEG2RAD) * r + pfy; + point_t v_pt; + bg_plane_pt_at(&v_pt, p->vp, curr_fx, curr_fy); + VMOVE(gpp->contour[0].point[n], v_pt); + } + + bg_polygon_free(&p->polygon); + + /* Not doing a struct copy to avoid overwriting other properties. */ + p->polygon.num_contours = gp.num_contours; + p->polygon.hole = gp.hole; + p->polygon.contour = gp.contour; + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 1; +} + +int +bv_update_polygon_ellipse(struct bv_scene_obj *s, point_t cp, fastf_t pixel_size) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + /* use a variable number of segments based on the size of the + * circle being created so small circles have few segments and + * large ones are nice and smooth. select a chord length that + * results in segments approximately 4 pixels in length. + * + * circumference / 4 = PI * diameter / 4 + * + */ + + fastf_t r = DIST_PNT_PNT(cp, p->origin_point); + + /* use a variable number of segments based on the size of the + * circle being created so small circles have few segments and + * large ones are nice and smooth. + */ + int nsegs = M_PI_2 * r / pixel_size; + if (nsegs < 32) + nsegs = 32; + + fastf_t pfx, pfy, fx, fy; + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&fx, &fy, zpln, cp); + bg_plane_closest_pt(&pfx, &pfy, zpln, p->origin_point); + + fastf_t a, b, arc; + point_t pv_pt; + point_t ellout; + point_t A, B; + + VSET(pv_pt, pfx, pfy, 0); + a = fx - pfx; + b = fy - pfy; + + /* + * For angle alpha, compute surface point as + * + * V + cos(alpha) * A + sin(alpha) * B + * + * note that sin(alpha) is cos(90-alpha). + */ + + VSET(A, a, 0, 0); + VSET(B, 0, b, 0); + + struct bg_polygon gp; + struct bg_polygon *gpp = &gp; + gpp->num_contours = 1; + gpp->hole = (int *)bu_calloc(1, sizeof(int), "hole");; + gpp->contour = (struct bg_poly_contour *)bu_calloc(1, sizeof(struct bg_poly_contour), "contour"); + gpp->contour[0].num_points = nsegs; + gpp->contour[0].open = 0; + gpp->contour[0].point = (point_t *)bu_calloc(nsegs, sizeof(point_t), "point"); + + arc = 360.0 / nsegs; + for (int n = 0; n < nsegs; ++n) { + fastf_t cosa = cos(n * arc * DEG2RAD); + fastf_t sina = sin(n * arc * DEG2RAD); + + VJOIN2(ellout, pv_pt, cosa, A, sina, B); + + // Use the polygon's plane for actually adding the points + bg_plane_pt_at(&gpp->contour[0].point[n], zpln, ellout[0], ellout[1]); + } + + bg_polygon_free(&p->polygon); + + /* Not doing a struct copy to avoid overwriting other properties. */ + p->polygon.num_contours = gp.num_contours; + p->polygon.hole = gp.hole; + p->polygon.contour = gp.contour; + + /* Have new polygon, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 1; +} + +int +bv_update_polygon_rectangle(struct bv_scene_obj *s, point_t cp) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + fastf_t pfx, pfy, fx, fy; + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&pfx, &pfy, zpln, p->origin_point); + bg_plane_closest_pt(&fx, &fy, zpln, cp); + + // Use the polygon's plane for actually adjusting the points + bg_plane_pt_at(&p->polygon.contour[0].point[0], zpln, pfx, pfy); + bg_plane_pt_at(&p->polygon.contour[0].point[1], zpln, pfx, fy); + bg_plane_pt_at(&p->polygon.contour[0].point[2], zpln, fx, fy); + bg_plane_pt_at(&p->polygon.contour[0].point[3], zpln, fx, pfy); + + p->polygon.contour[0].open = 0; + + /* Polygon updated, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 1; +} + +int +bv_update_polygon_square(struct bv_scene_obj *s, point_t cp) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + fastf_t pfx, pfy, fx, fy; + plane_t zpln; + HMOVE(zpln, p->vp); + zpln[3] += p->vZ; + bg_plane_closest_pt(&pfx, &pfy, zpln, p->origin_point); + bg_plane_closest_pt(&fx, &fy, zpln, cp); + + fastf_t dx = fx - pfx; + fastf_t dy = fy - pfy; + + if (fabs(dx) > fabs(dy)) { + if (dy < 0.0) + fy = pfy - fabs(dx); + else + fy = pfy + fabs(dx); + } else { + if (dx < 0.0) + fx = pfx - fabs(dy); + else + fx = pfx + fabs(dy); + } + + + // Use the polygon's plane for actually adjusting the points + bg_plane_pt_at(&p->polygon.contour[0].point[0], zpln, pfx, pfy); + bg_plane_pt_at(&p->polygon.contour[0].point[1], zpln, pfx, fy); + bg_plane_pt_at(&p->polygon.contour[0].point[2], zpln, fx, fy); + bg_plane_pt_at(&p->polygon.contour[0].point[3], zpln, fx, pfy); + + /* Polygon updated, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 1; +} + +int +bv_update_general_polygon(struct bv_scene_obj *s, int utype, point_t cp) +{ + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + if (p->type != BV_POLYGON_GENERAL) + return 0; + + if (utype == BV_POLYGON_UPDATE_PT_APPEND) { + return bv_append_polygon_pt(s, cp); + } + + if (utype == BV_POLYGON_UPDATE_PT_SELECT) { + return bv_select_polygon_pt(s, cp); + } + + if (utype == BV_POLYGON_UPDATE_PT_SELECT_CLEAR) { + bv_select_clear_polygon_pt(s); + return 1; + } + + if (utype == BV_POLYGON_UPDATE_PT_MOVE) { + return bv_move_polygon_pt(s, cp); + } + + /* Polygon updated, now update view object vlist */ + bv_polygon_vlist(s); + + /* Updated */ + s->s_changed++; + + return 0; +} + +int +bv_update_polygon(struct bv_scene_obj *s, struct bview *v, int utype) +{ + if (!s) + return 0; + + struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; + + // Regardless of type, sync fill color + struct bv_scene_obj *fobj = bv_find_child(s, "*fill*"); + if (fobj) { + bu_color_to_rgb_chars(&p->fill_color, fobj->s_color); + } + + if (utype == BV_POLYGON_UPDATE_PROPS_ONLY) { + + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); + if (!s_c) + continue; + s_c->s_color[0] = s->s_color[0]; + s_c->s_color[1] = s->s_color[1]; + s_c->s_color[2] = s->s_color[2]; + } + + if (p->fill_flag) { + bv_fill_polygon(s); + } else { + if (fobj) + bv_obj_put(fobj); + } + + return 0; + } + + /* Need pixel dimension for calculating segment approximations on these + * shapes - based on view info */ + if (p->type == BV_POLYGON_CIRCLE || p->type == BV_POLYGON_ELLIPSE) { + + // Need the length of the diagonal of a pixel + vect_t c1 = VINIT_ZERO; + vect_t c2 = VINIT_ZERO; + bv_screen_to_view(v, &c1[0], &c1[1], 0, 0); + bv_screen_to_view(v, &c2[0], &c2[1], 1, 1); + point_t p1, p2; + MAT4X3PNT(p1, v->gv_view2model, c1); + MAT4X3PNT(p2, v->gv_view2model, c2); + fastf_t d = DIST_PNT_PNT(p1, p2); + + if (p->type == BV_POLYGON_CIRCLE) + return bv_update_polygon_circle(s, v->gv_point, d); + if (p->type == BV_POLYGON_ELLIPSE) + return bv_update_polygon_ellipse(s, v->gv_point, d); + } + + if (p->type == BV_POLYGON_RECTANGLE) + return bv_update_polygon_rectangle(s, v->gv_point); + if (p->type == BV_POLYGON_SQUARE) + return bv_update_polygon_square(s, v->gv_point); + if (p->type != BV_POLYGON_GENERAL) + return 0; + return bv_update_general_polygon(s, utype, v->gv_point); +} + +struct bv_scene_obj * +bv_dup_view_polygon(const char *nname, struct bv_scene_obj *s) +{ + if (!nname || !s) + return NULL; + + struct bv_polygon *ip = (struct bv_polygon *)s->s_i_data; + + struct bv_polygon *p; + BU_GET(p, struct bv_polygon); + bv_polygon_cpy(p, ip); + + struct bv_scene_obj *np = bv_create_polygon_obj(s->s_v, s->s_type_flags, p); + + // Have geometry, now copy visual settings + VMOVE(np->s_color, s->s_color); + + // Update scene obj vlist + bv_polygon_vlist(np); + + // Set new name + bu_vls_init(&np->s_name); + bu_vls_sprintf(&np->s_name, "%s", nname); + + // Return new object + return np; +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libbg/polygon_fill.cpp b/src/libbv/polygon_fill.cpp similarity index 89% rename from src/libbg/polygon_fill.cpp rename to src/libbv/polygon_fill.cpp index 3ed2167765a..235c2494bb7 100644 --- a/src/libbg/polygon_fill.cpp +++ b/src/libbv/polygon_fill.cpp @@ -19,7 +19,7 @@ */ /** @addtogroup libged */ /** @{ */ -/** @file libged/polyclip.cpp +/** @file libbv/polygon_fill.cpp * * Add internal lines to polygons to indicate "filled" areas. */ @@ -32,28 +32,19 @@ #include "bu/vls.h" #include "bg/plane.h" /* bg_fit_plane */ #include "bg/polygon.h" +#include "bv/polygon.h" /* Note - line_slope encodes the fill line slope as a vector. Doing it as a * this way instead of a single number allows us to handle vertical lines (i.e. * infinite slope) cleanly */ struct bg_polygon * -bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t line_spacing) +bv_polygon_fill_segments(struct bg_polygon *poly, plane_t *vp, vect2d_t line_slope, fastf_t line_spacing) { struct bg_polygon poly_2d; - if (poly->num_contours < 1 || poly->contour[0].num_points < 3) + if (poly->num_contours < 1 || poly->contour[0].num_points < 3 || !vp) return NULL; - // Fit the outer contour to get a 2D plane (bg_polygon is in principle a 3D data structure) - point_t pcenter; - vect_t pnorm; - plane_t pl; - if (bg_fit_plane(&pcenter, &pnorm, poly->contour[0].num_points, poly->contour[0].point)) { - return NULL; - } - bg_plane_pt_nrml(&pl, pcenter, pnorm); - - /* Project poly onto the fit plane. While we're at it, build the 2D AABB */ vect2d_t b2d_min = {MAX_FASTF, MAX_FASTF}; vect2d_t b2d_max = {-MAX_FASTF, -MAX_FASTF}; @@ -66,7 +57,7 @@ bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t l poly_2d.contour[i].point = (point_t *)bu_calloc(poly->contour[i].num_points, sizeof(point_t), "pc_point"); for (size_t j = 0; j < poly->contour[i].num_points; ++j) { vect2d_t p2d; - bg_plane_closest_pt(&p2d[0], &p2d[1], pl, poly->contour[i].point[j]); + bg_plane_closest_pt(&p2d[0], &p2d[1], *vp, poly->contour[i].point[j]); VSET(poly_2d.contour[i].point[j], p2d[0], p2d[1], 0); // bounding box V2MINMAX(b2d_min, b2d_max, p2d); @@ -89,7 +80,6 @@ bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t l bcenter[1] = (b2d_max[1] - b2d_min[1]) * 0.5 + b2d_min[1]; fastf_t ldiag = DIST_PNT2_PNT2(b2d_max, b2d_min); V2MOVE(lseg, line_slope); - lseg[0] = -1 * lseg[0]; // Looks like the projection flips this... V2UNITIZE(lseg); int dir_step_cnt = (int)(0.5*ldiag / fabs(line_spacing) + 1); @@ -151,7 +141,7 @@ bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t l * fill lines */ mat_t m; MAT_IDN(m); - struct bg_polygon *fpoly = bg_clip_polygon(bg_Intersection, &poly_lines, &poly_2d, CLIPPER_MAX, m, m); + struct bg_polygon *fpoly = bg_clip_polygon(bg_Intersection, &poly_lines, &poly_2d, CLIPPER_MAX, NULL); if (!fpoly || !fpoly->num_contours) { bg_polygon_free(&poly_lines); bg_polygon_free(&poly_2d); @@ -179,7 +169,7 @@ bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t l poly_fill->contour[i].num_points = fpoly->contour[i].num_points; poly_fill->contour[i].point = (point_t *)bu_calloc(fpoly->contour[i].num_points, sizeof(point_t), "f_point"); for (size_t j = 0; j < fpoly->contour[i].num_points; ++j) { - bg_plane_pt_at(&poly_fill->contour[i].point[j], pl, fpoly->contour[i].point[j][0], fpoly->contour[i].point[j][1]); + bg_plane_pt_at(&poly_fill->contour[i].point[j], *vp, fpoly->contour[i].point[j][0], fpoly->contour[i].point[j][1]); } } @@ -200,6 +190,22 @@ bg_polygon_fill_segments(struct bg_polygon *poly, vect2d_t line_slope, fastf_t l return poly_fill; } + +extern "C" +int bv_polygon_calc_fdelta(struct bv_polygon *p) +{ + if (!p) + return 0; + // TODO - project all contours onto a 2d fit plane, get bounding boxes, + // and find the smallest diagonal. Default fill delta will be 20%(?) of + // that dimension. + // + // Will need to sanity check smallest against average - if we have a huge + // polygon with a crazy tiny hole, we don't want a superdense fill to + // capture the hole. + return 0; +} + // Local Variables: // tab-width: 8 // mode: C++ diff --git a/src/libbv/polygon_op.cpp b/src/libbv/polygon_op.cpp new file mode 100644 index 00000000000..920c308b2e5 --- /dev/null +++ b/src/libbv/polygon_op.cpp @@ -0,0 +1,124 @@ +/* P O L Y G O N _ O P . C P P + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file polygon_op.cpp + * + * Routines for operating on polygons. + * + */ + +#include "common.h" + +#include +#include + +#include "vmath.h" +#include "bu/log.h" +#include "bu/malloc.h" +#include "bv/polygon.h" +#include "bv/util.h" + +int +bv_polygon_csg(struct bv_scene_obj *target, struct bv_scene_obj *stencil, bg_clip_t op) +{ + // Need data + if (!target || !stencil) + return 0; + + // Need polygons + if (!(target->s_type_flags & BV_POLYGONS) || !(stencil->s_type_flags & BV_POLYGONS)) + return 0; + + // None op == no change + if (op == bg_None) + return 0; + + struct bv_polygon *polyA = (struct bv_polygon *)target->s_i_data; + struct bv_polygon *polyB = (struct bv_polygon *)stencil->s_i_data; + if (!polyA || !polyB) + return 0; + + // If the stencil is empty, it's all moot + if (!polyB->polygon.num_contours) + return 0; + + // Make sure the polygons overlap before we operate, since clipper results are + // always general polygons. We don't want to perform a no-op clip and lose our + // type info. There is however one exception to this - if our target is empty + // and our op is a union, we still want to proceed even without an overlap. + if (polyA->polygon.num_contours || op != bg_Union) { + const struct bn_tol poly_tol = BN_TOL_INIT_TOL; + if (!stencil->s_v) + return 0; + int ovlp = bg_polygons_overlap(&polyA->polygon, &polyB->polygon, &polyA->vp, &poly_tol, stencil->s_v->gv_scale); + if (!ovlp) + return 0; + } else { + // In the case of a union into an empty polygon, what we do is copy the + // stencil intact into target and preserve its type - no need to use + // bg_clip_polygon and lose the type info + bg_polygon_free(&polyA->polygon); + bg_polygon_cpy(&polyA->polygon, &polyB->polygon); + + // We want to leave the color and fill settings in dest, but we should + // sync some of the information so the target polygon shape can be + // updated correctly. In particular, for a non-generic polygon, + // origin_point is important to updating. + polyA->type = polyB->type; + polyA->vZ = polyB->vZ; + polyA->curr_contour_i = polyB->curr_contour_i; + polyA->curr_point_i = polyB->curr_point_i; + VMOVE(polyA->origin_point, polyB->origin_point); + HMOVE(polyA->vp, polyB->vp); + bv_update_polygon(target, target->s_v, BV_POLYGON_UPDATE_DEFAULT); + return 1; + } + + // Perform the specified operation and get the new polygon + struct bg_polygon *cp = bg_clip_polygon(op, &polyA->polygon, &polyB->polygon, CLIPPER_MAX, &polyA->vp); + + // Replace the original target polygon with the result + bg_polygon_free(&polyA->polygon); + polyA->polygon.num_contours = cp->num_contours; + polyA->polygon.hole = cp->hole; + polyA->polygon.contour = cp->contour; + + // We stole the data from cp and put it in polyA - no longer need the + // original cp container + BU_PUT(cp, struct bg_polygon); + + // clipper results are always general polygons + polyA->type = BV_POLYGON_GENERAL; + + // Make sure everything's current + bv_update_polygon(target, target->s_v, BV_POLYGON_UPDATE_DEFAULT); + + return 1; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libbv/snap.c b/src/libbv/snap.c new file mode 100644 index 00000000000..46db75bc6f1 --- /dev/null +++ b/src/libbv/snap.c @@ -0,0 +1,445 @@ +/* S N A P . C + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libbv/snap.c + * + * Logic for snapping points to visual elements. + * + */ + +#include "common.h" + +#include +#include +#include +#include + +#include "bu/opt.h" +#include "bu/ptbl.h" +#include "bu/vls.h" +#include "bn/tol.h" +#include "bg/lseg.h" +#include "bv/defines.h" +#include "bv/snap.h" +#include "bv/util.h" +#include "bv/vlist.h" + +struct bv_cp_info { + double ctol_sq; // square of the distance that defines "close to a line" + point_t cp; // closest point on closest line + double dsq; // squared distance to closest line + point_t cp2; // closest point on closest line + double dsq2; // squared distance to 2nd closest line +}; +#define BV_CP_INFO_INIT {BN_TOL_DIST, VINIT_ZERO, DBL_MAX, VINIT_ZERO, DBL_MAX} + +struct bv_cp_info_tcl { + struct bv_cp_info c; + struct bv_data_line_state *c_lset; // container holding closest line + int c_l; // index of closest line + + struct bv_data_line_state *c_lset2; // container holding 2nd closest line + int c_l2; // index of 2nd closest line +}; +#define BV_CP_INFO_TCL_INIT {BV_CP_INFO_INIT, NULL, -1, NULL, -1} + +static int +_find_closest_tcl_point(struct bv_cp_info_tcl *s, point_t *p, struct bv_data_line_state *lines) +{ + int ret = 0; + point_t P0, P1; + + if (lines->gdls_num_points < 2) { + return ret; + } + + // TODO - if we have a large number of lines drawn, we could really benefit + // from an acceleration structure such as the RTree to localize these tests + // rather than checking everything... + for (int i = 0; i < lines->gdls_num_points; i+=2) { + if (s->c_l == i && s->c_lset == lines) { + continue; + } + point_t c; + VMOVE(P0, lines->gdls_points[i]); + VMOVE(P1, lines->gdls_points[i+1]); + double dsq = bg_distsq_lseg3_pt(&c, P0, P1, *p); + // If we're outside tolerance, continue + if (dsq > s->c.ctol_sq) { + continue; + } + // If this is the closest we've seen, record it + if (s->c.dsq > dsq) { + // Closest is now second closest + VMOVE(s->c.cp2, s->c.cp); + s->c.dsq2 = s->c.dsq; + s->c_l2 = s->c_l; + s->c_lset2 = s->c_lset; + + // set new closest + VMOVE(s->c.cp, c); + s->c.dsq = dsq; + s->c_l = i; + s->c_lset = lines; + ret = 1; + continue; + } + // Not the closest - is it closer than the second closest? + if (s->c.dsq2 > dsq) { + VMOVE(s->c.cp2, c); + s->c.dsq2 = dsq; + s->c_l2 = i; + s->c_lset2 = lines; + ret = 2; + continue; + } + } + + return ret; +} + +static void +_find_close_isect(struct bv_cp_info *s, point_t *p, point_t *P0, point_t *P1, point_t *Q0, point_t *Q1) +{ + point_t c1, c2; + + if (!s || !p) + return; + + double csdist_sq = bg_distsq_lseg3_lseg3(&c1, &c2, *P0, *P1, *Q0, *Q1); + if (csdist_sq > s->ctol_sq) { + // Line segments are too far away to use both of them to override the + // original answer + return; + } + + // If either closest segment point is too far from the test point, go with + // the original answer rather than changing it + double d1_sq = DIST_PNT_PNT_SQ(*p, c1); + if (d1_sq > s->ctol_sq) { + // Too far away to work + return; + } + + double d2_sq = DIST_PNT_PNT_SQ(*p, c2); + if (d2_sq > s->ctol_sq) { + // Too far away to work + return; + } + + // Go with the closest segment point to the original point. If + // the segments intersect the two points should be the same and + // it won't matter which is chosen, but if they don't then the + // intuitive behavior is to prefer the closest point that attempts + // to satisfy both line segments + if (d1_sq < d2_sq) { + VMOVE(s->cp, c1); + } else { + VMOVE(s->cp, c2); + } +} + +static void +_find_close_isect_tcl(struct bv_cp_info_tcl *s, point_t *p) +{ + point_t P0, P1, Q0, Q1; + + if (!s || !s->c_lset || !p) + return; + + VMOVE(P0, s->c_lset->gdls_points[s->c_l]); + VMOVE(P1, s->c_lset->gdls_points[s->c_l+1]); + + VMOVE(Q0, s->c_lset2->gdls_points[s->c_l2]); + VMOVE(Q1, s->c_lset2->gdls_points[s->c_l2+1]); + + _find_close_isect(&s->c, p, &P0, &P1, &Q0, &Q1); +} + +static int +_find_closest_obj_point(struct bv_cp_info *s, point_t *p, struct bv_scene_obj *o) +{ + int ret = 0; + if (!s || !p || !o) + return 0; + if (!bu_list_len(&o->s_vlist)) + return 0; + + struct bv_vlist *tvp; + for (BU_LIST_FOR(tvp, bv_vlist, &o->s_vlist)) { + int nused = tvp->nused; + int *cmd = tvp->cmd; + point_t *pt = tvp->pt; + point_t *pt1 = NULL; + point_t *pt2 = NULL; + for (int i = 0; i < nused; i++, cmd++, pt++) { + switch (*cmd) { + case BV_VLIST_LINE_MOVE: + pt2 = pt; + break; + case BV_VLIST_LINE_DRAW: + pt1 = pt2; + pt2 = pt; + break; + } + if (pt1 && pt2) { + point_t c; + double dsq = bg_distsq_lseg3_pt(&c, *pt1, *pt2, *p); + // If we're outside tolerance, continue + if (dsq > s->ctol_sq) { + continue; + } + // If this is the closest we've seen, record it + if (s->dsq > dsq) { + // Closest is now second closest + VMOVE(s->cp2, s->cp); + s->dsq2 = s->dsq; + + // set new closest + VMOVE(s->cp, c); + s->dsq = dsq; + ret = 1; + continue; + } + // Not the closest - is it closer than the second closest? + if (s->dsq2 > dsq) { + VMOVE(s->cp2, c); + s->dsq2 = dsq; + ret = 2; + continue; + } + } + } + } + + return ret; +} + +static double +line_tol_sq(struct bview *v, int lwidth) +{ + if (!v || lwidth <= 0) + return 100*100; + + // NOTE - make sure calling applications update these values from + // the display manager info before command execution. + int width = v->gv_width; + int height = v->gv_height; + + if (!width || !height) + return 100*100; + + double lavg = ((double)width + (double)height) * 0.5; + double lratio = ((double)lwidth)/lavg; + + struct bview_settings *gv_s = (v->gv_s) ? v->gv_s : &v->gv_ls; + double lrsize = v->gv_size * lratio * gv_s->gv_snap_tol_factor; + + return lrsize*lrsize; +} + +int +bv_snap_lines_3d(point_t *out_pt, struct bview *v, point_t *p) +{ + int ret = 0; + struct bview_settings *gv_s = (v->gv_s) ? v->gv_s : &v->gv_ls; + struct bv_cp_info_tcl cpinfo = BV_CP_INFO_TCL_INIT; + + if (!p || !v) return 0; + + // If we're not in Tcl mode only, we are looking at objects - either + // all of them, or a specified subset + if (gv_s->gv_snap_flags != BV_SNAP_TCL) { + struct bv_cp_info *s = &cpinfo.c; + s->ctol_sq = line_tol_sq(v, 1); + if (BU_PTBL_LEN(&gv_s->gv_snap_objs) > 0) { + for (size_t i = 0; i < BU_PTBL_LEN(&gv_s->gv_snap_objs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(&gv_s->gv_snap_objs, i); + if (gv_s->gv_snap_flags) { + if (gv_s->gv_snap_flags == BV_SNAP_DB && (!(so->s_type_flags & BV_DB_OBJS))) + continue; + if (gv_s->gv_snap_flags == BV_SNAP_VIEW && (!(so->s_type_flags & BV_VIEW_OBJS))) + continue; + } + struct bv_obj_settings *s_os = (so->s_os) ? so->s_os : &so->s_local_os; + s->ctol_sq = line_tol_sq(v, (s_os->s_line_width) ? s_os->s_line_width : 1); + ret += _find_closest_obj_point(s, p, so); + } + } else { + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_DB)) { + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_SHARED)) { + struct bu_ptbl *sobjs = bv_view_objs(v, BV_DB_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(sobjs, i); + ret += _find_closest_obj_point(s, p, so); + } + } + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_LOCAL)) { + struct bu_ptbl *sobjs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(sobjs, i); + ret += _find_closest_obj_point(s, p, so); + } + } + } + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_VIEW)) { + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_SHARED)) { + struct bu_ptbl *sobjs = bv_view_objs(v, BV_VIEW_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(sobjs, i); + ret += _find_closest_obj_point(s, p, so); + } + } + if (!gv_s->gv_snap_flags || (gv_s->gv_snap_flags & BV_SNAP_LOCAL)) { + struct bu_ptbl *sobjs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(sobjs, i); + ret += _find_closest_obj_point(s, p, so); + } + } + } + } + } + + // There are some issues with line snapping that don't come up with grid + // snapping - in particular, when are we "close enough" to a line to snap, + // and how do we handle snapping when close enough to multiple lines? We + // probably want to prefer intersections between lines to closest line + // point if we are close to multiple lines... + if (!gv_s->gv_snap_flags || gv_s->gv_snap_flags & BV_SNAP_TCL) { + int tret = 0; + int lwidth; + lwidth = (v->gv_tcl.gv_data_lines.gdls_line_width) ? v->gv_tcl.gv_data_lines.gdls_line_width : 1; + cpinfo.c.ctol_sq = line_tol_sq(v, lwidth); + tret += _find_closest_tcl_point(&cpinfo, p, &v->gv_tcl.gv_data_lines); + lwidth = (v->gv_tcl.gv_sdata_lines.gdls_line_width) ? v->gv_tcl.gv_sdata_lines.gdls_line_width : 1; + cpinfo.c.ctol_sq = line_tol_sq(v, lwidth); + tret += _find_closest_tcl_point(&cpinfo, p, &v->gv_tcl.gv_sdata_lines); + + // Check if we are close enough to two line segments to warrant using the + // closest approach point. The intersection may not be close enough to + // use, but if it is prefer it as it satisfies two lines instead of one. + // + // TODO - as implemented this will only prefer the intersection between + // two Tcl lines, rather than all lines... + if (tret > 1) { + _find_close_isect_tcl(&cpinfo, p); + } + ret += tret; + } + + // If we found something, we can snap + if (ret) { + VMOVE(*out_pt, cpinfo.c.cp); + return 1; + } + + return 0; +} + +int +bv_snap_lines_2d(struct bview *v, fastf_t *vx, fastf_t *vy) +{ + if (!v || !vx || !vy) return 0; + + point2d_t p2d = {0.0, 0.0}; + V2SET(p2d, *vx, *vy); + point_t vp = VINIT_ZERO; + VSET(vp, p2d[0], p2d[1], 0); + point_t p = VINIT_ZERO; + MAT4X3PNT(p, v->gv_view2model, vp); + point_t out_pt = VINIT_ZERO; + if (bv_snap_lines_3d(&out_pt, v, &p) == 1) { + MAT4X3PNT(vp, v->gv_model2view, out_pt); + (*vx) = vp[0]; + (*vy) = vp[1]; + return 1; + } + + return 0; +} + +void +bv_view_center_linesnap(struct bview *v) +{ + point_t view_pt; + point_t model_pt; + + MAT_DELTAS_GET_NEG(model_pt, v->gv_center); + MAT4X3PNT(view_pt, v->gv_model2view, model_pt); + bv_snap_lines_2d(v, &view_pt[X], &view_pt[Y]); + MAT4X3PNT(model_pt, v->gv_view2model, view_pt); + MAT_DELTAS_VEC_NEG(v->gv_center, model_pt); + bv_update(v); +} + +int +bv_snap_grid_2d(struct bview *v, fastf_t *vx, fastf_t *vy) +{ + point_t view_pt; + point_t grid_origin; + fastf_t inv_grid_res_h, inv_grid_res_v; + + if (!v || !vx || !vy) + return 0; + + struct bview_settings *gv_s = (v->gv_s) ? v->gv_s : &v->gv_ls; + + if (ZERO(gv_s->gv_grid.res_h) || + ZERO(gv_s->gv_grid.res_v)) + return 0; + + inv_grid_res_h = 1/(gv_s->gv_grid.res_h * v->gv_base2local); + inv_grid_res_v = 1/(gv_s->gv_grid.res_v * v->gv_base2local); + + VSET(view_pt, *vx, *vy, 0.0); + VSCALE(view_pt, view_pt, v->gv_scale); + MAT4X3PNT(grid_origin, v->gv_model2view, gv_s->gv_grid.anchor); + VSCALE(grid_origin, grid_origin, v->gv_scale); + + fastf_t grid_units_h = (view_pt[X] - grid_origin[X]) * inv_grid_res_h; + fastf_t grid_units_v = (view_pt[Y] - grid_origin[Y]) * inv_grid_res_v; + int nh, nv; /* whole grid units */ + nh = floor(view_pt[X]); + nv = floor(view_pt[Y]); + grid_units_h -= nh; /* now contains only the fraction part */ + grid_units_v -= nv; /* now contains only the fraction part */ + int hstep = round(grid_units_h); + int vstep = round(grid_units_v); + fastf_t fnh = nh + hstep + grid_origin[X]; + fastf_t fnv = nv + vstep + grid_origin[Y]; + VSET(view_pt, fnh * gv_s->gv_grid.res_h * v->gv_base2local, fnv * gv_s->gv_grid.res_v * v->gv_base2local, 0.0); + VSCALE(view_pt, view_pt, 1.0/v->gv_scale); + + *vx = view_pt[X]; + *vy = view_pt[Y]; + + return 1; +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libbv/util.cpp b/src/libbv/util.cpp index e5e7446a3fc..38ab8b8489e 100644 --- a/src/libbv/util.cpp +++ b/src/libbv/util.cpp @@ -31,13 +31,159 @@ #include "bu/path.h" #include "bu/ptbl.h" #include "bu/str.h" +#include "bu/vls.h" #include "bn/mat.h" +#include "bg/plane.h" #include "bv/defines.h" -#include "bv/vlist.h" +#include "bv/snap.h" #include "bv/util.h" #include "bv/view_sets.h" +#include "bv/vlist.h" #include "./bv_private.h" +#define VIEW_NAME_MAXTRIES 100000 +#define DM_DEFAULT_FONT_SIZE 20 + +static void +_data_tclcad_init(struct bv_data_tclcad *d) +{ + d->gv_polygon_mode = 0; + d->gv_hide = 0; + + d->gv_data_arrows.gdas_draw = 0; + d->gv_data_arrows.gdas_color[0] = 0; + d->gv_data_arrows.gdas_color[1] = 0; + d->gv_data_arrows.gdas_color[2] = 0; + d->gv_data_arrows.gdas_line_width = 0; + d->gv_data_arrows.gdas_tip_length = 0; + d->gv_data_arrows.gdas_tip_width = 0; + d->gv_data_arrows.gdas_num_points = 0; + d->gv_data_arrows.gdas_points = NULL; + + d->gv_data_axes.draw = 0; + d->gv_data_axes.color[0] = 0; + d->gv_data_axes.color[1] = 0; + d->gv_data_axes.color[2] = 0; + d->gv_data_axes.line_width = 0; + d->gv_data_axes.size = 0; + d->gv_data_axes.num_points = 0; + d->gv_data_axes.points = NULL; + + d->gv_data_labels.gdls_draw = 0; + d->gv_data_labels.gdls_color[0] = 0; + d->gv_data_labels.gdls_color[1] = 0; + d->gv_data_labels.gdls_color[2] = 0; + d->gv_data_labels.gdls_num_labels = 0; + d->gv_data_labels.gdls_size = 0; + d->gv_data_labels.gdls_labels = NULL; + d->gv_data_labels.gdls_points = NULL; + + d->gv_data_lines.gdls_draw = 0; + d->gv_data_lines.gdls_color[0] = 0; + d->gv_data_lines.gdls_color[1] = 0; + d->gv_data_lines.gdls_color[2] = 0; + d->gv_data_lines.gdls_line_width = 0; + d->gv_data_lines.gdls_num_points = 0; + d->gv_data_lines.gdls_points = NULL; + + d->gv_data_polygons.gdps_draw = 0; + d->gv_data_polygons.gdps_moveAll = 0; + d->gv_data_polygons.gdps_color[0] = 0; + d->gv_data_polygons.gdps_color[1] = 0; + d->gv_data_polygons.gdps_color[2] = 0; + d->gv_data_polygons.gdps_line_width = 0; + d->gv_data_polygons.gdps_line_style = 0; + d->gv_data_polygons.gdps_cflag = 0; + d->gv_data_polygons.gdps_target_polygon_i = 0; + d->gv_data_polygons.gdps_curr_polygon_i = 0; + d->gv_data_polygons.gdps_curr_point_i = 0; + d->gv_data_polygons.gdps_prev_point[0] = 0; + d->gv_data_polygons.gdps_prev_point[1] = 0; + d->gv_data_polygons.gdps_prev_point[2] = 0; + d->gv_data_polygons.gdps_clip_type = bg_Union; + d->gv_data_polygons.gdps_scale = 0; + d->gv_data_polygons.gdps_origin[0] = 0; + d->gv_data_polygons.gdps_origin[1] = 0; + d->gv_data_polygons.gdps_origin[2] = 0; + MAT_ZERO(d->gv_data_polygons.gdps_rotation); + MAT_ZERO(d->gv_data_polygons.gdps_view2model); + MAT_ZERO(d->gv_data_polygons.gdps_model2view); + d->gv_data_polygons.gdps_polygons.num_polygons = 0; + d->gv_data_polygons.gdps_polygons.polygon = NULL; + d->gv_data_polygons.gdps_data_vZ = 0; + + d->gv_sdata_arrows.gdas_draw = 0; + d->gv_sdata_arrows.gdas_color[0] = 0; + d->gv_sdata_arrows.gdas_color[1] = 0; + d->gv_sdata_arrows.gdas_color[2] = 0; + d->gv_sdata_arrows.gdas_line_width = 0; + d->gv_sdata_arrows.gdas_tip_length = 0; + d->gv_sdata_arrows.gdas_tip_width = 0; + d->gv_sdata_arrows.gdas_num_points = 0; + d->gv_sdata_arrows.gdas_points = NULL; + + d->gv_sdata_axes.draw = 0; + d->gv_sdata_axes.color[0] = 0; + d->gv_sdata_axes.color[1] = 0; + d->gv_sdata_axes.color[2] = 0; + d->gv_sdata_axes.line_width = 0; + d->gv_sdata_axes.size = 0; + d->gv_sdata_axes.num_points = 0; + d->gv_sdata_axes.points = NULL; + + d->gv_sdata_labels.gdls_draw = 0; + d->gv_sdata_labels.gdls_color[0] = 0; + d->gv_sdata_labels.gdls_color[1] = 0; + d->gv_sdata_labels.gdls_color[2] = 0; + d->gv_sdata_labels.gdls_num_labels = 0; + d->gv_sdata_labels.gdls_size = 0; + d->gv_sdata_labels.gdls_labels = NULL; + d->gv_sdata_labels.gdls_points = NULL; + + d->gv_sdata_lines.gdls_draw = 0; + d->gv_sdata_lines.gdls_color[0] = 0; + d->gv_sdata_lines.gdls_color[1] = 0; + d->gv_sdata_lines.gdls_color[2] = 0; + d->gv_sdata_lines.gdls_line_width = 0; + d->gv_sdata_lines.gdls_num_points = 0; + d->gv_sdata_lines.gdls_points = NULL; + + d->gv_sdata_polygons.gdps_draw = 0; + d->gv_sdata_polygons.gdps_moveAll = 0; + d->gv_sdata_polygons.gdps_color[0] = 0; + d->gv_sdata_polygons.gdps_color[1] = 0; + d->gv_sdata_polygons.gdps_color[2] = 0; + d->gv_sdata_polygons.gdps_line_width = 0; + d->gv_sdata_polygons.gdps_line_style = 0; + d->gv_sdata_polygons.gdps_cflag = 0; + d->gv_sdata_polygons.gdps_target_polygon_i = 0; + d->gv_sdata_polygons.gdps_curr_polygon_i = 0; + d->gv_sdata_polygons.gdps_curr_point_i = 0; + d->gv_sdata_polygons.gdps_prev_point[0] = 0; + d->gv_sdata_polygons.gdps_prev_point[1] = 0; + d->gv_sdata_polygons.gdps_prev_point[2] = 0; + d->gv_sdata_polygons.gdps_clip_type = bg_Union; + d->gv_sdata_polygons.gdps_scale = 0; + d->gv_sdata_polygons.gdps_origin[0] = 0; + d->gv_sdata_polygons.gdps_origin[1] = 0; + d->gv_sdata_polygons.gdps_origin[2] = 0; + MAT_ZERO(d->gv_sdata_polygons.gdps_rotation); + MAT_ZERO(d->gv_sdata_polygons.gdps_view2model); + MAT_ZERO(d->gv_sdata_polygons.gdps_model2view); + d->gv_sdata_polygons.gdps_polygons.num_polygons = 0; + d->gv_sdata_polygons.gdps_polygons.polygon = NULL; + d->gv_sdata_polygons.gdps_data_vZ = 0; + + d->gv_prim_labels.gos_draw = 0; + d->gv_prim_labels.gos_font_size = DM_DEFAULT_FONT_SIZE; + d->gv_prim_labels.gos_line_color[0] = 0; + d->gv_prim_labels.gos_line_color[1] = 0; + d->gv_prim_labels.gos_line_color[2] = 0; + d->gv_prim_labels.gos_text_color[0] = 0; + d->gv_prim_labels.gos_text_color[1] = 0; + d->gv_prim_labels.gos_text_color[2] = 0; +} + void bv_init(struct bview *gvp, struct bview_set *s) { @@ -45,17 +191,48 @@ bv_init(struct bview *gvp, struct bview_set *s) return; gvp->magic = BV_MAGIC; - gvp->vset = s; if (!BU_VLS_IS_INITIALIZED(&gvp->gv_name)) { bu_vls_init(&gvp->gv_name); } - // Independent has to be the default, since we don't - // have shared containers until they are supplied from - // an outside source. - gvp->independent = 1; + // TODO - Archer doesn't seem to like it when we set initial + // view names +#if 0 + // If we have a non-null set, go ahead and generate a unique + // view name to start out with. App may override, but make + // sure we at least start out with a unique name + bu_vls_sprintf(&gvp->gv_name, "V0"); + bool name_collide = false; + int view_try_cnt = 0; + struct bu_ptbl *views = bv_set_views(s); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *nv = (struct bview *)BU_PTBL_GET(views, i); + if (!bu_vls_strcmp(&nv->gv_name, &gvp->gv_name)) { + name_collide = true; + break; + } + } + while (name_collide && view_try_cnt < VIEW_NAME_MAXTRIES) { + bu_vls_incr(&gvp->gv_name, NULL, "0:0:0:0", NULL, NULL); + name_collide = false; + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *nv = (struct bview *)BU_PTBL_GET(views, i); + if (!bu_vls_strcmp(&nv->gv_name, &gvp->gv_name)) { + name_collide = true; + break; + } + view_try_cnt++; + } + } + if (view_try_cnt >= VIEW_NAME_MAXTRIES) { + bu_log("Warning - unable to generate view name unique to view set\n"); + } +#endif + + // If we're part of a set, we're not independent + gvp->independent = (gvp->vset) ? 0 : 1; gvp->gv_scale = 500.0; gvp->gv_i_scale = gvp->gv_scale; @@ -66,6 +243,8 @@ bv_init(struct bview *gvp, struct bview_set *s) VSET(gvp->gv_eye_pos, 0.0, 0.0, 1.0); MAT_IDN(gvp->gv_rotation); MAT_IDN(gvp->gv_center); + MAT_IDN(gvp->gv_view2model); + MAT_IDN(gvp->gv_model2view); VSETALL(gvp->gv_keypoint, 0.0); gvp->gv_coord = 'v'; gvp->gv_rotate_about = 'v'; @@ -73,8 +252,14 @@ bv_init(struct bview *gvp, struct bview_set *s) gvp->gv_maxMouseDelta = 20; gvp->gv_rscale = 0.4; gvp->gv_sscale = 2.0; + gvp->gv_perspective = 0.0; - gvp->gv_data_vZ = 0.0; + gvp->gv_prevMouseX = 0; + gvp->gv_prevMouseY = 0; + gvp->gv_mouse_x = 0; + gvp->gv_mouse_y = 0; + VSETALL(gvp->gv_prev_point, 0.0); + VSETALL(gvp->gv_point, 0.0); /* Initialize local settings */ bv_settings_init(&gvp->gv_ls); @@ -89,6 +274,7 @@ bv_init(struct bview *gvp, struct bview_set *s) /* bv_mat_aet(gvp); */ gvp->gv_tcl.gv_prim_labels.gos_draw = 0; + gvp->gv_tcl.gv_prim_labels.gos_font_size = DM_DEFAULT_FONT_SIZE; VSET(gvp->gv_tcl.gv_prim_labels.gos_text_color, 255, 255, 0); @@ -113,6 +299,19 @@ bv_init(struct bview *gvp, struct bview_set *s) gvp->gv_callback = NULL; gvp->gv_bounds_update= NULL; + // Also don't have a display manager + // TODO - What the heck Archer??? Initializing this to NULL causes + // problems even without the gv_name setting logic above? + //gvp->dmp = NULL; + + // Initial scaling factors are 1 + gvp->gv_base2local = 1.0; + gvp->gv_local2base = 1.0; + + // Initialize tclcad specific data (primarily doing this so hashing calculations + // can succeed) + _data_tclcad_init(&gvp->gv_tcl); + bv_update(gvp); } @@ -143,6 +342,10 @@ bv_free(struct bview *gvp) sp = nsp; } BU_PUT(gvp->gv_objs.free_scene_obj, struct bv_scene_obj); + if (gvp->gv_s) + bu_ptbl_free(&gvp->gv_s->gv_snap_objs); + if (gvp->gv_s != &gvp->gv_ls) + bu_ptbl_free(&gvp->gv_ls.gv_snap_objs); if (gvp->gv_ls.gv_selected) { bu_ptbl_free(gvp->gv_ls.gv_selected); @@ -163,7 +366,7 @@ _bound_objs(int *is_empty, int *have_geom_objs, vect_t min, vect_t max, struct b for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(so, i); _bound_objs(is_empty, have_geom_objs, min, max, &g->children, v); - if (bv_scene_obj_bound(g, v)) { + if (g->have_bbox || bv_scene_obj_bound(g, v)) { (*is_empty) = 0; (*have_geom_objs) = 1; minus[X] = g->s_center[X] - g->s_size; @@ -210,7 +413,7 @@ _bound_objs_view(int *is_empty, vect_t min, vect_t max, struct bu_ptbl *so, stru continue; } if (bv_scene_obj_bound(s, v)) { - is_empty = 0; + (*is_empty) = 0; minus[X] = s->s_center[X] - s->s_size; minus[Y] = s->s_center[Y] - s->s_size; minus[Z] = s->s_center[Z] - s->s_size; @@ -246,7 +449,11 @@ bv_autoview(struct bview *v, double factor, int all_view_objs) VSETALL(max, -INFINITY); struct bu_ptbl *so = bv_view_objs(v, BV_DB_OBJS); - _bound_objs(&is_empty, &have_geom_objs, min, max, so, v); + if (so) + _bound_objs(&is_empty, &have_geom_objs, min, max, so, v); + struct bu_ptbl *sol = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (sol) + _bound_objs(&is_empty, &have_geom_objs, min, max, sol, v); // When it comes to view-only objects, normally we will only include those // that are db object based, polygons or labels, unless the flag to @@ -256,8 +463,15 @@ bv_autoview(struct bview *v, double factor, int all_view_objs) // then basing autoview on the view-only objs is more intuitive than just // using the default view settings. so = bv_view_objs(v, BV_VIEW_OBJS); - _find_view_geom(&have_geom_objs, so); - _bound_objs_view(&is_empty,min, max, so, v, have_geom_objs, all_view_objs); + if (so) { + _find_view_geom(&have_geom_objs, so); + _bound_objs_view(&is_empty,min, max, so, v, have_geom_objs, all_view_objs); + } + sol = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (sol) { + _find_view_geom(&have_geom_objs, sol); + _bound_objs_view(&is_empty,min, max, sol, v, have_geom_objs, all_view_objs); + } if (is_empty) { /* Nothing is in view */ @@ -312,16 +526,19 @@ bv_mat_aet(struct bview *v) void bv_settings_init(struct bview_settings *s) { - struct bv_obj_settings defaults = BV_OBJ_SETTINGS_INIT; - bv_obj_settings_sync(&s->obj_s, &defaults); + s->obj_s = BV_OBJ_SETTINGS_INIT; s->gv_cleared = 1; + s->gv_adc.draw = 0; s->gv_adc.a1 = 45.0; s->gv_adc.a2 = 45.0; VSET(s->gv_adc.line_color, 255, 255, 0); VSET(s->gv_adc.tick_color, 255, 255, 255); + s->gv_grid.draw = 0; + s->gv_grid.adaptive = 0; + s->gv_grid.snap = 0; VSET(s->gv_grid.anchor, 0.0, 0.0, 0.0); s->gv_grid.res_h = 1.0; s->gv_grid.res_v = 1.0; @@ -365,16 +582,24 @@ bv_settings_init(struct bview_settings *s) VSET(s->gv_model_axes.tick_major_color, 255, 0, 0); s->gv_center_dot.gos_draw = 0; + s->gv_center_dot.gos_font_size = DM_DEFAULT_FONT_SIZE; VSET(s->gv_center_dot.gos_line_color, 255, 255, 0); - s->gv_view_params.gos_draw = 0; - VSET(s->gv_view_params.gos_text_color, 255, 255, 0); + s->gv_view_params.draw = 0; + s->gv_view_params.draw_size = 1; + s->gv_view_params.draw_center = 1; + s->gv_view_params.draw_az = 1; + s->gv_view_params.draw_el = 1; + s->gv_view_params.draw_tw = 1; + s->gv_view_params.draw_fps = 0; + VSET(s->gv_view_params.color, 255, 255, 0); + s->gv_view_params.font_size = DM_DEFAULT_FONT_SIZE; s->gv_view_scale.gos_draw = 0; + s->gv_view_scale.gos_font_size = DM_DEFAULT_FONT_SIZE; VSET(s->gv_view_scale.gos_line_color, 255, 255, 0); VSET(s->gv_view_scale.gos_text_color, 255, 255, 255); - s->gv_fps = 0; s->gv_frametime = 1; s->gv_fb_mode = 0; @@ -391,6 +616,8 @@ bv_settings_init(struct bview_settings *s) // Higher values indicate more aggressive behavior (i.e. points further away will be snapped). s->gv_snap_tol_factor = 10; s->gv_snap_lines = 0; + BU_PTBL_INIT(&s->gv_snap_objs); + s->gv_snap_flags = 0; } // TODO - investigate saveview/loadview logic, see if anything @@ -491,18 +718,51 @@ bv_update(struct bview *gvp) } } -void +int bv_obj_settings_sync(struct bv_obj_settings *dest, struct bv_obj_settings *src) { - dest->s_line_width = src->s_line_width; - dest->s_arrow_tip_length = src->s_arrow_tip_length; - dest->s_arrow_tip_width = src->s_arrow_tip_width; - dest->transparency = src->transparency; - dest->s_dmode = src->s_dmode; - dest->color_override = src->color_override; - VMOVE(dest->color, src->color); - dest->draw_solid_lines_only = src->draw_solid_lines_only; - dest->draw_non_subtract_only = src->draw_non_subtract_only; + int ret = 0; + if (!dest || !src) + return ret; + + if (dest->s_line_width != src->s_line_width) { + dest->s_line_width = src->s_line_width; + ret = 1; + } + if (!NEAR_EQUAL(dest->s_arrow_tip_length, src->s_arrow_tip_length, SMALL_FASTF)) { + dest->s_arrow_tip_length = src->s_arrow_tip_length; + ret = 1; + } + if (!NEAR_EQUAL(dest->s_arrow_tip_width, src->s_arrow_tip_width, SMALL_FASTF)) { + dest->s_arrow_tip_width = src->s_arrow_tip_width; + ret = 1; + } + if (!NEAR_EQUAL(dest->transparency, src->transparency, SMALL_FASTF)) { + dest->transparency = src->transparency; + ret = 1; + } + if (dest->s_dmode != src->s_dmode) { + dest->s_dmode = src->s_dmode; + ret = 1; + } + if (dest->color_override != src->color_override) { + dest->color_override = src->color_override; + ret = 1; + } + if (!VNEAR_EQUAL(dest->color, src->color, SMALL_FASTF)) { + VMOVE(dest->color, src->color); + ret = 1; + } + if (dest->draw_solid_lines_only != src->draw_solid_lines_only) { + dest->draw_solid_lines_only = src->draw_solid_lines_only; + ret = 1; + } + if (dest->draw_non_subtract_only != src->draw_non_subtract_only) { + dest->draw_non_subtract_only = src->draw_non_subtract_only; + ret = 1; + } + + return ret; } int @@ -664,9 +924,56 @@ bv_screen_to_view(struct bview *v, fastf_t *fx, fastf_t *fy, fastf_t x, fastf_t (*fy) = ty; } + // If snapping is enabled, apply it + int snapped = 0; + if (v->gv_s) { + if (v->gv_s->gv_snap_lines) { + snapped = bv_snap_lines_2d(v, fx, fy); + } + if (!snapped && v->gv_s->gv_grid.snap) { + bv_snap_grid_2d(v, fx, fy); + } + } + return 0; } +int +bv_screen_pt(point_t *p, fastf_t x, fastf_t y, struct bview *v) +{ + if (!p || !v) + return -1; + + if (!v->gv_width || !v->gv_height) + return -1; + + fastf_t tx, ty; + if (bv_screen_to_view(v, &tx, &ty, x, y)) + return -1; + + point_t vpt; + VSET(vpt, tx, ty, 0); + MAT4X3PNT(*p, v->gv_view2model, vpt); + return 0; +} + +int +bv_view_plane(plane_t *p, struct bview *v) +{ + if (!p || !v) + return -1; + + point_t cpt = VINIT_ZERO; + vect_t vnrml = VINIT_ZERO; + + MAT_DELTAS_GET_NEG(cpt, v->gv_center); + VMOVEN(vnrml, v->gv_rotation + 8, 3); + VUNITIZE(vnrml); + VSCALE(vnrml, vnrml, -1.0); + + return bg_plane_pt_nrml(p, cpt, vnrml); +} + size_t bv_clear(struct bview *v, int flags) { @@ -725,7 +1032,7 @@ bv_clear(struct bview *v, int flags) ocnt += (sgl && sgl != sg) ? BU_PTBL_LEN(sgl) : 0; ocnt += (sv) ? BU_PTBL_LEN(sv) : 0; ocnt += (svl && svl != sv) ? BU_PTBL_LEN(svl) : 0; - return ocnt ; + return ocnt; } void @@ -753,8 +1060,9 @@ bv_obj_create(struct bview *v, int type) if (!v) return NULL; + bv_log(1, "bv_obj_create (%s)", bu_vls_cstr(&v->gv_name)); + struct bv_scene_obj *s = NULL; - struct bu_ptbl *otbl = NULL; // What we get and from where is based on the requested obj type and the // view type. If the caller is not asking for a local object, we will try @@ -764,26 +1072,39 @@ bv_obj_create(struct bview *v, int type) // regardless of whether or not a shared repository is available. struct bv_scene_obj *free_scene_obj = NULL; struct bu_list *vlfree = NULL; - if (type & BV_LOCAL_OBJS || v->independent || !v->vset) { + if (type & BV_LOCAL_OBJS || type & BV_CHILD_OBJS || v->independent || !v->vset) { free_scene_obj = v->gv_objs.free_scene_obj; - if (type & BV_DB_OBJS) { - otbl = v->gv_objs.db_objs; - } else { - otbl = v->gv_objs.view_objs; - } vlfree = &v->gv_objs.gv_vlfree; } else { free_scene_obj = v->vset->i->free_scene_obj; + vlfree = &v->vset->i->vlfree; + } + if (!free_scene_obj) + return NULL; + + // The table has an additional complication - we don't want child objects + // to be stored in it, because they are part of the scene only by virtue + // of their parent object + struct bu_ptbl *otbl = NULL; + if (type & BV_LOCAL_OBJS || type & BV_CHILD_OBJS || v->independent || !v->vset) { + if (!(type & BV_CHILD_OBJS)) { + if (type & BV_DB_OBJS) { + otbl = v->gv_objs.db_objs; + } else { + otbl = v->gv_objs.view_objs; + } + } + } else { if (type & BV_DB_OBJS) { otbl = &v->vset->i->shared_db_objs; } else { otbl = &v->vset->i->shared_view_objs; } - vlfree = &v->vset->i->vlfree; } if (!free_scene_obj) return NULL; + // We know where we're going to get the object from - get it if (BU_LIST_IS_EMPTY(&free_scene_obj->l)) { BU_ALLOC(s, struct bv_scene_obj); @@ -792,58 +1113,25 @@ bv_obj_create(struct bview *v, int type) s = BU_LIST_NEXT(bv_scene_obj, &free_scene_obj->l); BU_LIST_DEQUEUE(&((s)->l)); } - BU_LIST_INIT( &((s)->s_vlist) ); - // Do the initializations + // Zero out callback pointers s->s_type_flags = 0; - BU_LIST_INIT(&(s->s_vlist)); - BU_VLS_INIT(&s->s_name); - bu_vls_trunc(&s->s_name, 0); - s->s_path = NULL; - BU_VLS_INIT(&s->s_uuid); - if (type & BV_LOCAL_OBJS) { - if (type & BV_DB_OBJS) { - bu_vls_sprintf(&s->s_uuid, "sl:%zd", BU_PTBL_LEN(otbl)); - } else { - bu_vls_sprintf(&s->s_uuid, "vl:%zd", BU_PTBL_LEN(otbl)); - } - } else { - if (type & BV_DB_OBJS) { - bu_vls_sprintf(&s->s_uuid, "s:%zd", BU_PTBL_LEN(otbl)); - } else { - bu_vls_sprintf(&s->s_uuid, "v:%zd", BU_PTBL_LEN(otbl)); - } - } - MAT_IDN(s->s_mat); - s->s_size = 0; - s->s_v = v; - - s->s_i_data = NULL; - s->s_update_callback = NULL; s->s_free_callback = NULL; + s->s_dlist_free_callback = NULL; - s->adaptive_wireframe = 0; - s->view_scale = 0.0; - - s->s_flag = UP; - s->s_iflag = DOWN; - VSET(s->s_color, 255, 0, 0); - s->s_soldash = 0; - s->s_arrow = 0; + // Use reset to do most of the initialization + bv_obj_reset(s); - struct bv_obj_settings defaults = BV_OBJ_SETTINGS_INIT; - bv_obj_settings_sync(&s->s_local_os, &defaults); - s->s_os = &s->s_local_os; + // Set view + s->s_v = v; - if (!BU_PTBL_IS_INITIALIZED(&s->children)) { - BU_PTBL_INIT(&s->children); - } - bu_ptbl_reset(&s->children); + // Set the type flag(s) on the object itself + s->s_type_flags = type; + // Set this object's containers s->free_scene_obj = free_scene_obj; s->vlfree = vlfree; s->otbl = otbl; - s->current = 0; return s; } @@ -854,11 +1142,18 @@ bv_obj_get(struct bview *v, int type) if (!v) return NULL; - struct bv_scene_obj *s = bv_obj_create(v, type); + bv_log(1, "bv_obj_get %d(%s)", type, bu_vls_cstr(&v->gv_name)); + + int ltype = type; + if (v->independent) + ltype |= BV_LOCAL_OBJS; + + struct bv_scene_obj *s = bv_obj_create(v, ltype); if (!s) return NULL; - bu_ptbl_ins(s->otbl, (long *)s); + if (s->otbl) + bu_ptbl_ins(s->otbl, (long *)s); return s; } @@ -869,6 +1164,8 @@ bv_obj_get_child(struct bv_scene_obj *sp) if (!sp) return NULL; + bv_log(1, "bv_obj_get_child %s(%s)", bu_vls_cstr(&sp->s_name), bu_vls_cstr(&sp->s_v->gv_name)); + struct bv_scene_obj *s = NULL; // Children use their parent's info @@ -884,47 +1181,16 @@ bv_obj_get_child(struct bv_scene_obj *sp) BU_LIST_DEQUEUE(&((s)->l)); } } - BU_LIST_INIT( &((s)->s_vlist) ); - - // Do the initializations - s->s_type_flags = 0; - BU_LIST_INIT(&(s->s_vlist)); - if (!BU_VLS_IS_INITIALIZED(&s->s_name)) - BU_VLS_INIT(&s->s_name); - bu_vls_trunc(&s->s_name, 0); - s->s_path = NULL; - if (!BU_VLS_IS_INITIALIZED(&s->s_uuid)) - BU_VLS_INIT(&s->s_uuid); - bu_vls_sprintf(&s->s_uuid, "child:%s:%zd", bu_vls_cstr(&sp->s_uuid), BU_PTBL_LEN(&sp->children)); - MAT_IDN(s->s_mat); - - s->s_v = sp->s_v; - - s->s_i_data = NULL; - s->s_update_callback = NULL; - s->s_free_callback = NULL; - - s->adaptive_wireframe = 0; - s->view_scale = 0.0; - - s->s_flag = UP; - s->s_iflag = DOWN; - VSET(s->s_color, 255, 0, 0); - s->s_soldash = 0; - s->s_arrow = 0; - struct bv_obj_settings defaults = BV_OBJ_SETTINGS_INIT; - bv_obj_settings_sync(&s->s_local_os, &defaults); - s->s_os = &s->s_local_os; + // Use reset to do most of the initialization + bv_obj_reset(s); - if (!BU_PTBL_IS_INITIALIZED(&s->children)) { - BU_PTBL_INIT(&s->children); - } - bu_ptbl_reset(&s->children); + bu_vls_sprintf(&s->s_name, "child:%s:%zd", bu_vls_cstr(&sp->s_name), BU_PTBL_LEN(&sp->children)); + s->s_v = sp->s_v; + s->dp = sp->dp; s->free_scene_obj = sp->free_scene_obj; s->vlfree = sp->vlfree; - s->otbl = &sp->children; bu_ptbl_ins(&sp->children, (long *)s); @@ -940,23 +1206,26 @@ bv_obj_reset(struct bv_scene_obj *s) struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); bv_obj_put(s_c); } - bu_ptbl_reset(&s->children); + } else { + BU_PTBL_INIT(&s->children); } + bu_ptbl_reset(&s->children); - if (s->i) { + if (s->i) s->i->vobjs.clear(); - } // If we have a callback for the internal data, use it if (s->s_free_callback) (*s->s_free_callback)(s); + s->s_free_callback = NULL; // If we have a callback for the display list data, use it if (s->s_dlist_free_callback) (*s->s_dlist_free_callback)(s); + s->s_dlist_free_callback = NULL; // If we have a label, do the label freeing steps - // TODO - properly speaking this should be using the free callback rather + // TODO - this should be using the free callback rather // than special casing... if (s->s_type_flags & BV_LABELS) { struct bv_label *la = (struct bv_label *)s->s_i_data; @@ -970,20 +1239,40 @@ bv_obj_reset(struct bv_scene_obj *s) } BU_LIST_INIT(&(s->s_vlist)); - s->s_v = NULL; - s->current = 0; - VSETALL(s->bmin, INFINITY); + if (!BU_VLS_IS_INITIALIZED(&s->s_name)) + BU_VLS_INIT(&s->s_name); + bu_vls_trunc(&s->s_name, 0); + + struct bv_obj_settings defaults = BV_OBJ_SETTINGS_INIT; + bv_obj_settings_sync(&s->s_local_os, &defaults); + s->s_os = &s->s_local_os; + + MAT_IDN(s->s_mat); + VSET(s->s_color, 255, 0, 0); VSETALL(s->bmax, -INFINITY); - s->s_size = 0; - s->s_csize = 0; + VSETALL(s->bmin, INFINITY); VSETALL(s->s_center, 0); s->adaptive_wireframe = 0; - s->view_scale = 0; s->bot_threshold = 0; + s->csg_obj = 0; + s->current = 0; s->curve_scale = 0; - s->point_scale = 0; - + s->dp = NULL; s->draw_data = NULL; + s->have_bbox = 0; + s->mesh_obj = 0; + s->point_scale = 0; + s->s_arrow = 0; + s->s_csize = 0; + s->s_flag = UP; + s->s_i_data = NULL; + s->s_iflag = DOWN; + s->s_path = NULL; + s->s_size = 0; + s->s_soldash = 0; + s->s_update_callback = NULL; + s->s_v = NULL; + s->view_scale = 0; } #define FREE_BV_SCENE_OBJ(p, fp) { \ @@ -992,15 +1281,19 @@ bv_obj_reset(struct bv_scene_obj *s) void bv_obj_put(struct bv_scene_obj *s) { + bv_log(1, "bv_obj_put %s[%s]", bu_vls_cstr(&s->s_name), (s->s_v) ? bu_vls_cstr(&s->s_v->gv_name) : "NULL"); for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(&s->children, i); bv_obj_put(cg); } + // If this object was selected for snapping, it is no longer a valid candidate + if (s->s_v) + bu_ptbl_rm(&s->s_v->gv_s->gv_snap_objs, (long *)s); + bv_obj_reset(s); // Clear names - bu_vls_trunc(&s->s_uuid, 0); bu_vls_trunc(&s->s_name, 0); s->s_path = NULL; @@ -1048,58 +1341,176 @@ bv_find_obj(struct bview *v, const char *name) return s_c; } - // If none of the names matched, check uuids - if (!v->independent && v->vset) { + return NULL; +} + +static bool +_uniq_name(const char *name, struct bview *v) +{ + if (v->vset) { for (size_t i = 0; i < BU_PTBL_LEN(&v->vset->i->shared_db_objs); i++) { struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&v->vset->i->shared_db_objs, i); - if (!bu_path_match(name, bu_vls_cstr(&s_c->s_uuid), 0)) - return s_c; + if (BU_STR_EQUAL(name, bu_vls_cstr(&s_c->s_name))) + return false; } for (size_t i = 0; i < BU_PTBL_LEN(&v->vset->i->shared_view_objs); i++) { struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&v->vset->i->shared_view_objs, i); - if (!bu_path_match(name, bu_vls_cstr(&s_c->s_uuid), 0)) - return s_c; + if (BU_STR_EQUAL(name, bu_vls_cstr(&s_c->s_name))) + return false; } } + + // Next look locally for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.db_objs); i++) { struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.db_objs, i); - if (!bu_path_match(name, bu_vls_cstr(&s_c->s_uuid), 0)) - return s_c; + if (BU_STR_EQUAL(name, bu_vls_cstr(&s_c->s_name))) + return false; } + for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - if (!bu_path_match(name, bu_vls_cstr(&s_c->s_uuid), 0)) - return s_c; + if (BU_STR_EQUAL(name, bu_vls_cstr(&s_c->s_name))) + return false; } - return NULL; + return true; +} + +void +bv_uniq_obj_name(struct bu_vls *oname, const char *seed, struct bview *v) +{ + if (!oname || !v) + return; + + struct bu_vls vseed = BU_VLS_INIT_ZERO; + if (seed) { + bu_vls_sprintf(&vseed, "%s", seed); + } else { + bu_vls_sprintf(&vseed, "%s:obj_0", bu_vls_cstr(&v->gv_name)); + } + + + const char *npattern = "([-_:]*[0-9]+[-_:]*)[^0-9]*$"; + long int loop_guard = 0; + bool is_uniq = _uniq_name(bu_vls_cstr(&vseed), v); + while (!is_uniq && loop_guard < LONG_MAX) { + (void)bu_vls_incr(&vseed, npattern, NULL, NULL, NULL); + is_uniq = _uniq_name(bu_vls_cstr(&vseed), v); + loop_guard++; + } + + bu_vls_sprintf(oname, "%s", bu_vls_cstr(&vseed)); + bu_vls_free(&vseed); } struct bv_scene_obj * bv_obj_for_view(struct bv_scene_obj *s, struct bview *v) { if (!v || !s || !s->i) - return s; + return NULL; std::unordered_map::iterator vo_it; vo_it = s->i->vobjs.find(v); - if (vo_it == s->i->vobjs.end()) - return s; + if (vo_it == s->i->vobjs.end()) { + bv_log(1, "bv_obj_for_view %s(%s) - NONE", bu_vls_cstr(&s->s_name), bu_vls_cstr(&v->gv_name)); + return NULL; + } + bv_log(1, "bv_obj_for_view %s[%s]", bu_vls_cstr(&s->s_name), bu_vls_cstr(&v->gv_name)); return vo_it->second; } -void -bv_set_view_obj(struct bv_scene_obj *s, struct bview *v, struct bv_scene_obj *sv) +struct bv_scene_obj * +bv_obj_get_vo(struct bv_scene_obj *s, struct bview *v) { - if (!v || !s || !s->i || !sv) - return; + if (!v || !s || !s->i) + return NULL; std::unordered_map::iterator vo_it; vo_it = s->i->vobjs.find(v); if (vo_it != s->i->vobjs.end()) - bv_obj_put(vo_it->second); - s->i->vobjs[v] = sv; - sv->s_os = s->s_os; + return vo_it->second; + + + struct bv_scene_obj *vo = NULL; + + // View local object - use the view obj pool + struct bv_scene_obj *free_scene_obj = v->vset->i->free_scene_obj; + if (BU_LIST_IS_EMPTY(&free_scene_obj->l)) { + BU_ALLOC((vo), struct bv_scene_obj); + vo->i = new bv_scene_obj_internal; + } else { + vo = BU_LIST_NEXT(bv_scene_obj, &s->free_scene_obj->l); + if (!vo) { + BU_ALLOC((vo), struct bv_scene_obj); + vo->i = new bv_scene_obj_internal; + } else { + BU_LIST_DEQUEUE(&((vo)->l)); + } + } + + // Use reset to do most of the initialization + bv_obj_reset(vo); + + // Most of the view properties (color, size, etc.) are inherited from + // the parent + bv_obj_sync(vo, s); + + // View local object - the local vlist pool + vo->vlfree = &v->gv_objs.gv_vlfree; + + bu_vls_sprintf(&vo->s_name, "%s", bu_vls_cstr(&s->s_name)); + + vo->s_v = v; + vo->dp = s->dp; + + + + s->i->vobjs[v] = vo; + vo->s_os = s->s_os; + bv_log(1, "bv_obj_get_vo %s[%s]", bu_vls_cstr(&s->s_name), bu_vls_cstr(&v->gv_name)); + + return vo; +} + +int +bv_obj_have_vo(struct bv_scene_obj *s, struct bview *v) +{ + if (!s || !s->i || !v) + return 0; + + std::unordered_map::iterator vo_it; + vo_it = s->i->vobjs.find(v); + bv_log(1, "bv_have_view_obj %s[%s]: %d", bu_vls_cstr(&s->s_name), bu_vls_cstr(&v->gv_name), (vo_it != s->i->vobjs.end()) ? 1 : 0); + return (vo_it != s->i->vobjs.end()) ? 1 : 0; +} + +int +bv_clear_view_obj(struct bv_scene_obj *s, struct bview *v) +{ + if (!s || !s->i) + return 0; + + bv_log(1, "bv_clear_view_obj %s(%s)", bu_vls_cstr(&s->s_name), (v) ? bu_vls_cstr(&v->gv_name) : "NULL"); + + if (!v) { + std::unordered_map::iterator vo_it; + for (vo_it = s->i->vobjs.begin(); vo_it != s->i->vobjs.end(); vo_it++) { + struct bv_scene_obj *vobj = vo_it->second; + bv_obj_put(vobj); + } + s->i->vobjs.clear(); + } + + std::unordered_map::iterator vo_it; + vo_it = s->i->vobjs.find(v); + if (vo_it == s->i->vobjs.end()) + return 0; + + struct bv_scene_obj *vobj = vo_it->second; + bv_obj_put(vobj); + s->i->vobjs.erase(v); + + return 1; } struct bv_scene_obj * @@ -1112,11 +1523,6 @@ bv_find_child(struct bv_scene_obj *s, const char *vname) if (!bu_path_match(vname, bu_vls_cstr(&s_c->s_name), 0)) return s_c; } - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - if (!bu_path_match(vname, bu_vls_cstr(&s_c->s_uuid), 0)) - return s_c; - } return NULL; } @@ -1128,9 +1534,13 @@ bv_scene_obj_bound(struct bv_scene_obj *sp, struct bview *v) VSET(sp->bmin, INFINITY, INFINITY, INFINITY); VSET(sp->bmax, -INFINITY, -INFINITY, -INFINITY); int calc = 0; - if (sp->s_type_flags & BV_MESH_LOD) { - struct bv_scene_obj *sv = bv_obj_for_view(sp, v); - struct bv_mesh_lod *i = (struct bv_mesh_lod *)sv->draw_data; + // If we have a view object, use that, otherwise it's + // the top level object + struct bv_scene_obj *s = bv_obj_for_view(sp, v); + if (!s) + s = sp; + if (s->s_type_flags & BV_MESH_LOD) { + struct bv_mesh_lod *i = (struct bv_mesh_lod *)s->draw_data; if (i) { point_t obmin, obmax; VMOVE(obmin, i->bmin); @@ -1138,29 +1548,71 @@ bv_scene_obj_bound(struct bv_scene_obj *sp, struct bview *v) // Apply the scene matrix to the bounding box values to bound this // instance, since the BV_MESH_LOD data is based on the // non-instanced mesh. - MAT4X3PNT(sp->bmin, sp->s_mat, obmin); - MAT4X3PNT(sp->bmax, sp->s_mat, obmax); + MAT4X3PNT(s->bmin, s->s_mat, obmin); + MAT4X3PNT(s->bmax, s->s_mat, obmax); calc = 1; } - } else if (bu_list_len(&sp->s_vlist)) { - int dispmode; - cmd = bv_vlist_bbox(&sp->s_vlist, &sp->bmin, &sp->bmax, NULL, &dispmode); + } else if (bu_list_len(&s->s_vlist)) { + int dismode; + cmd = bv_vlist_bbox(&s->s_vlist, &s->bmin, &s->bmax, NULL, &dismode); if (cmd) { bu_log("unknown vlist op %d\n", cmd); } - sp->s_displayobj = dispmode; + s->s_displayobj = dismode; calc = 1; } + if (!calc) { + // If nothing else has given us an answer, see if other views + // can help + std::unordered_map::iterator vo_it; + for (vo_it = s->i->vobjs.begin(); vo_it != s->i->vobjs.end(); vo_it++) { + struct bv_scene_obj *lv = vo_it->second; + if (lv->s_type_flags & BV_MESH_LOD) { + struct bv_mesh_lod *i = (struct bv_mesh_lod *)lv->draw_data; + if (i) { + point_t obmin, obmax; + VMOVE(obmin, i->bmin); + VMOVE(obmax, i->bmax); + // Apply the scene matrix to the bounding box values to bound this + // instance, since the BV_MESH_LOD data is based on the + // non-instanced mesh. + MAT4X3PNT(lv->bmin, lv->s_mat, obmin); + MAT4X3PNT(lv->bmax, lv->s_mat, obmax); + calc = 1; + } + } else if (bu_list_len(&lv->s_vlist)) { + int dismode; + cmd = bv_vlist_bbox(&lv->s_vlist, &lv->bmin, &lv->bmax, NULL, &dismode); + if (cmd) { + bu_log("unknown vlist op %d\n", cmd); + } + calc = 1; + } + if (calc) { + VMOVE(s->bmin, lv->bmin); + VMOVE(s->bmax, lv->bmax); + break; + } + } + } if (calc) { - sp->s_center[X] = (sp->bmin[X] + sp->bmax[X]) * 0.5; - sp->s_center[Y] = (sp->bmin[Y] + sp->bmax[Y]) * 0.5; - sp->s_center[Z] = (sp->bmin[Z] + sp->bmax[Z]) * 0.5; + s->s_center[X] = (s->bmin[X] + s->bmax[X]) * 0.5; + s->s_center[Y] = (s->bmin[Y] + s->bmax[Y]) * 0.5; + s->s_center[Z] = (s->bmin[Z] + s->bmax[Z]) * 0.5; + + s->s_size = s->bmax[X] - s->bmin[X]; + V_MAX(s->s_size, s->bmax[Y] - s->bmin[Y]); + V_MAX(s->s_size, s->bmax[Z] - s->bmin[Z]); + + // sp may not be the same as s - propagate up + VMOVE(sp->s_center, s->s_center); + VMOVE(sp->bmin, s->bmin); + VMOVE(sp->bmax, s->bmax); + sp->s_size = s->s_size; - sp->s_size = sp->bmax[X] - sp->bmin[X]; - V_MAX(sp->s_size, sp->bmax[Y] - sp->bmin[Y]); - V_MAX(sp->s_size, sp->bmax[Z] - sp->bmin[Z]); return 1; } + return 0; } @@ -1210,18 +1662,20 @@ struct bu_ptbl * bv_view_objs(struct bview *v, int type) { if (type & BV_DB_OBJS) { - if (v->independent || type & BV_LOCAL_OBJS || !v->vset) { + if (type & BV_LOCAL_OBJS) { return v->gv_objs.db_objs; } else { - return &v->vset->i->shared_db_objs; + if (v->vset) + return &v->vset->i->shared_db_objs; } } if (type & BV_VIEW_OBJS) { - if (v->independent || type & BV_LOCAL_OBJS || !v->vset) { + if (type & BV_LOCAL_OBJS) { return v->gv_objs.view_objs; } else { - return &v->vset->i->shared_view_objs; + if (v->vset) + return &v->vset->i->shared_view_objs; } } @@ -1248,6 +1702,120 @@ bv_obj_sync(struct bv_scene_obj *dest, struct bv_scene_obj *src) dest->point_scale = src->point_scale; } +int +bv_illum_obj(struct bv_scene_obj *s, char ill_state) +{ + bool changed = 0; + for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { + struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); + int cchanged = bv_illum_obj(s_c, ill_state); + if (cchanged) + changed = 1; + } + if (ill_state != s->s_iflag) { + changed = 1; + s->s_iflag = ill_state; + //bv_obj_stale(s); + } + std::unordered_map::iterator vo_it; + for (vo_it = s->i->vobjs.begin(); vo_it != s->i->vobjs.end(); vo_it++) { + int cchanged = bv_illum_obj(vo_it->second, ill_state); + if (cchanged) + changed = 1; + } + + return changed; +} + +//#define USE_BV_LOG +void +#ifdef USE_BV_LOG +bv_log(int level, const char *fmt, ...) +#else +bv_log(int UNUSED(level), const char *UNUSED(fmt), ...) +#endif +{ +#ifdef USE_BV_LOG + if (level < 0 || !fmt) + return; + const char *brsig = getenv("BV_LOG"); + if (!brsig) + return; + if (brsig) { + int blev = atoi(brsig); + if (blev < level) + return; + } + + va_list ap; + struct bu_vls msg = BU_VLS_INIT_ZERO; + va_start(ap, fmt); + bu_vls_vprintf(&msg, fmt, ap); + bu_log("%s\n", bu_vls_cstr(&msg)); + bu_vls_free(&msg); + va_end(ap); +#endif +} + +void +bv_view_print(const char *title, struct bview *v, int UNUSED(verbosity)) +{ + if (!v) + return; + + struct bu_vls vtitle = BU_VLS_INIT_ZERO; + if (title) { + bu_vls_sprintf(&vtitle, "%s", title); + } else { + bu_vls_sprintf(&vtitle, "%s", bu_vls_cstr(&v->gv_name)); + } + + bu_log("%s\n", bu_vls_cstr(&vtitle)); + bu_vls_free(&vtitle); + + bu_log("Size info:\n"); + bu_log(" i_scale: %f\n", v->gv_i_scale); + bu_log(" a_scale: %f\n", v->gv_a_scale); + bu_log(" scale: %f\n", v->gv_scale); + bu_log(" size: %f\n", v->gv_size); + bu_log(" isize: %f\n", v->gv_isize); + bu_log(" base2local: %f\n", v->gv_base2local); + bu_log(" local2base: %f\n", v->gv_local2base); + bu_log(" rscale: %f\n", v->gv_rscale); + bu_log(" sscale: %f\n", v->gv_sscale); + + bu_log("Window info:"); + bu_log(" width: %d\n", v->gv_width); + bu_log(" height: %d\n", v->gv_height); + bu_log(" wmin: %f\n, %f", v->gv_wmin[0], v->gv_wmin[1]); + bu_log(" wmax: %f\n, %f", v->gv_wmax[0], v->gv_wmax[1]); + + bu_log("Camera info:"); + bu_log(" perspective: %f\n", v->gv_perspective); + bu_log(" aet: %f %f %f\n", V3ARGS(v->gv_aet)); + bu_log(" eye_pos: %f %f %f\n", V3ARGS(v->gv_eye_pos)); + bu_log(" keypoint: %f %f %f\n", V3ARGS(v->gv_keypoint)); + bu_log(" coord: %c\n", v->gv_coord); + bu_log(" rotate_about: %c\n", v->gv_rotate_about); + bn_mat_print("rotation", v->gv_rotation); + bn_mat_print("center", v->gv_center); + bn_mat_print("model2view", v->gv_model2view); + bn_mat_print("pmodel2view", v->gv_pmodel2view); + bn_mat_print("view2model", v->gv_view2model); + bn_mat_print("perspective", v->gv_pmat); + + bu_log("Keyboard/mouse info:"); + bu_log(" prevMouseX: %f\n", v->gv_prevMouseX); + bu_log(" prevMouseY: %f\n", v->gv_prevMouseY); + bu_log(" mouse_x: %d\n", v->gv_mouse_x); + bu_log(" mouse_y: %d\n", v->gv_mouse_y); + bu_log(" gv_prev_point:%f %f %f\n", V3ARGS(v->gv_prev_point)); + bu_log(" gv_point: %f %f %f\n", V3ARGS(v->gv_point)); + bu_log(" key: %c\n", v->gv_key); + bu_log(" mod_flags: %ld\n", v->gv_mod_flags); + bu_log(" minMousedelta:%f\n", v->gv_minMouseDelta); + bu_log(" maxMousedelta:%f\n", v->gv_maxMouseDelta); +} // Local Variables: // tab-width: 8 diff --git a/src/libbv/view_sets.cpp b/src/libbv/view_sets.cpp index 762101ff58b..ba8d901b960 100644 --- a/src/libbv/view_sets.cpp +++ b/src/libbv/view_sets.cpp @@ -52,16 +52,7 @@ void bv_set_free(struct bview_set *s) { if (s->i) { - // Note - it is the caller's responsibility to have freed any data - // associated with the ged or its i->views in the u_data pointers. - struct bview *gdvp; - for (size_t i = 0; i < BU_PTBL_LEN(&s->i->views); i++) { - gdvp = (struct bview *)BU_PTBL_GET(&s->i->views, i); - bv_free(gdvp); - bu_free((void *)gdvp, "bv"); - } bu_ptbl_free(&s->i->views); - bu_ptbl_free(&s->i->shared_db_objs); bu_ptbl_free(&s->i->shared_view_objs); @@ -91,7 +82,7 @@ bv_set_add_view(struct bview_set *s, struct bview *v){ if (!s || !v) return; - bu_ptbl_ins(&s->i->views, (long *)v); + bu_ptbl_ins_unique(&s->i->views, (long *)v); v->vset = s; @@ -102,9 +93,14 @@ bv_set_add_view(struct bview_set *s, struct bview *v){ void bv_set_rm_view(struct bview_set *s, struct bview *v){ - if (!s || !v) + if (!s) return; + if (!v) { + bu_ptbl_reset(&s->i->views); + return; + } + bu_ptbl_rm(&s->i->views, (long int *)v); v->vset = NULL; diff --git a/src/libbv/vlist.c b/src/libbv/vlist.c index 2cf67bc93ef..fd73d7fb73f 100644 --- a/src/libbv/vlist.c +++ b/src/libbv/vlist.c @@ -31,6 +31,7 @@ #include "bu/list.h" #include "bu/log.h" #include "bu/str.h" +#define PLOT3_IMPLEMENTATION #include "bv/plot3.h" #include "bv/vlist.h" #include "bv/util.h" @@ -529,7 +530,6 @@ bv_plot_vlblock(FILE *fp, const struct bv_vlblock *vbp) } \ bu_vls_init(&(p)->s_name); \ (p)->s_path = NULL; \ - bu_vls_init(&(p)->s_uuid); \ BU_LIST_INIT( &((p)->s_vlist) ); } #define FREE_BV_SCENE_OBJ(p, fp, vlf) { \ @@ -569,7 +569,6 @@ bv_vlblock_to_objs(struct bu_ptbl *out, const char *name_root, struct bv_vlblock s->s_type_flags = BV_VIEWONLY; s->s_v = v; bu_vls_sprintf(&s->s_name, "%sobj%zd", name_root, i); - bu_vls_sprintf(&s->s_uuid, "%sobj%zd", name_root, i); struct bv_vlist *bvl = (struct bv_vlist *)&vbp->head[i]; long int rgb = vbp->rgb[i]; s->s_vlen = bv_vlist_cmd_cnt(bvl); diff --git a/src/libdm/CMakeLists.txt b/src/libdm/CMakeLists.txt index f6235a5d445..2b386f22c78 100644 --- a/src/libdm/CMakeLists.txt +++ b/src/libdm/CMakeLists.txt @@ -57,7 +57,7 @@ set(LIBDM_SRCS ) set_property(SOURCE dm_obj.c APPEND PROPERTY COMPILE_DEFINITIONS FB_USE_INTERNAL_API) set_property(SOURCE dm_init.cpp APPEND PROPERTY COMPILE_DEFINITIONS "DM_PLUGIN_SUFFIX=\"${CMAKE_SHARED_LIBRARY_SUFFIX}\"") -BRLCAD_ADDLIB(libdm "${LIBDM_SRCS}" "librt;libicv;libbv;libbn;libbg;libbu;libpkg;${PNG_LIBRARIES}") +BRLCAD_ADDLIB(libdm "${LIBDM_SRCS}" "${libdm_deps};${PNG_LIBRARIES}") set_target_properties(libdm PROPERTIES VERSION 20.0.1 SOVERSION 20) if (TARGET profont_ProFont_ttf_cp) add_dependencies(libdm profont_ProFont_ttf_cp) diff --git a/src/libdm/dm-gl_lod.cpp b/src/libdm/dm-gl_lod.cpp index 44f03aa928d..413b1d4bd17 100644 --- a/src/libdm/dm-gl_lod.cpp +++ b/src/libdm/dm-gl_lod.cpp @@ -34,7 +34,7 @@ #include "bn.h" extern "C" { #include "bv/defines.h" -#include "bg/lod.h" +#include "bv/lod.h" #include "dm.h" #include "./dm-gl.h" #include "./include/private.h" @@ -92,6 +92,69 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) if (s->s_dlist_stale) { glDeleteLists(s->s_dlist, 1); s->s_dlist = 0; + + if (!pcnt || !fcnt) { + // If we've had a memshrink, the loaded data isn't + // going to be correct to generate new draw info. + // First, find out the current level: + int curr_level = bv_mesh_lod_level(s, -1, 0); + + // Trigger a load operation to restore it + bv_mesh_lod_level(s, curr_level, 1); + + fcnt = lod->fcnt; + pcnt = lod->pcnt; + faces = lod->faces; + points = lod->points; + points_orig = lod->points_orig; + normals = lod->normals; + } + } + + // We don't want color to be part of the dlist, to allow the app + // to change it without regeneration - hence, we need to do it + // up front + if (mode == 0) { + if (s->s_iflag == UP) { + dm_set_fg(dmp, 255, 255, 255, 0, s->s_os->transparency); + } + if (mvars->lighting_on) { + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mvars->i.wireColor); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black); + if (mvars->transparency_on) + glDisable(GL_BLEND); + } + } else { + if (s->s_iflag == UP) { + dm_set_fg(dmp, 255, 255, 255, 0, s->s_os->transparency); + } + if (mvars->lighting_on) { + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mvars->i.ambientColor); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mvars->i.specularColor); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mvars->i.diffuseColor); + switch (mvars->lighting_on) { + case 1: + break; + case 2: + glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.diffuseColor); + break; + case 3: + glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.backDiffuseColorDark); + break; + default: + glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.backDiffuseColorLight); + break; + } + } + if (mvars->lighting_on) { + if (mvars->transparency_on) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } } // If we have a dlist in the correct mode, use it @@ -104,6 +167,8 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glCallList(s->s_dlist); dm_loadmatrix(dmp, save_mat, 0); glLineWidth(originalLineWidth); + if (mvars->transparency_on) + glDisable(GL_BLEND); return BRLCAD_OK; } else { // Display list mode is incorrect (wireframe when we @@ -131,20 +196,14 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glNewList(s->s_dlist, GL_COMPILE); } else { bu_log("Not using dlist\n"); + // Straight-up drawing - set up the matrix + MAT_COPY(save_mat, s->s_v->gv_model2view); + bn_mat_mul(draw_mat, s->s_v->gv_model2view, s->s_mat); + dm_loadmatrix(dmp, draw_mat, 0); } // Wireframe if (mode == 0) { - - if (mvars->lighting_on) { - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mvars->i.wireColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black); - if (mvars->transparency_on) - glDisable(GL_BLEND); - } - // Draw all the triangles in faces array for (int i = 0; i < fcnt; i++) { @@ -171,9 +230,6 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glVertex3dv(dpt); glEnd(); } - if (mvars->lighting_on && mvars->transparency_on) - glDisable(GL_BLEND); - if (gen_dlist) { glEndList(); s->s_dlist_stale = 0; @@ -181,7 +237,7 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) // If the original data is sizable, clear it to save system memory. // The dlist has what it needs, and the LoD code will re-load info // as needed for updates. - bg_mesh_lod_memshrink(s); + bv_mesh_lod_memshrink(s); } MAT_COPY(save_mat, s->s_v->gv_model2view); @@ -193,6 +249,13 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glLineWidth(originalLineWidth); + if (mvars->transparency_on) + glDisable(GL_BLEND); + + // Without dlist, we had to set the matrix - restore + if (!s->s_dlist) + dm_loadmatrix(dmp, save_mat, 0); + return BRLCAD_OK; } @@ -207,34 +270,6 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &two_sided); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - if (mvars->lighting_on) { - - - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mvars->i.ambientColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mvars->i.specularColor); - glMaterialfv(GL_FRONT, GL_DIFFUSE, mvars->i.diffuseColor); - - switch (mvars->lighting_on) { - case 1: - break; - case 2: - glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.diffuseColor); - break; - case 3: - glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.backDiffuseColorDark); - break; - default: - glMaterialfv(GL_BACK, GL_DIFFUSE, mvars->i.backDiffuseColorLight); - break; - } - - if (mvars->transparency_on) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - } - glBegin(GL_TRIANGLES); // Draw all the triangles in faces array @@ -302,12 +337,6 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) glEnd(); - if (mvars->lighting_on && mvars->transparency_on) - glDisable(GL_BLEND); - - // Put the lighting model back where it was prior to this operation - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, two_sided); - if (gen_dlist) { glEndList(); s->s_dlist_stale = 0; @@ -315,7 +344,7 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) // If the original data is sizable, clear it to save system memory. // The dlist has what it needs, and the LoD code will re-load info // as needed for updates. - bg_mesh_lod_memshrink(s); + bv_mesh_lod_memshrink(s); } MAT_COPY(save_mat, s->s_v->gv_model2view); @@ -325,7 +354,18 @@ gl_draw_tri(struct dm *dmp, struct bv_mesh_lod *lod) dm_loadmatrix(dmp, save_mat, 0); } + if (mvars->lighting_on && mvars->transparency_on) + glDisable(GL_BLEND); + + // Put the lighting model back where it was prior to this operation + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, two_sided); + glLineWidth(originalLineWidth); + + // If we're not using a pre-baked dlist, restore matrix + if (!s->s_dlist) + dm_loadmatrix(dmp, save_mat, 0); + return BRLCAD_OK; } @@ -357,6 +397,21 @@ gl_csg_lod(struct dm *dmp, struct bv_scene_obj *s) s->s_dlist = 0; } + // We don't want color to be part of the dlist, to allow the app + // to change it without regeneration - hence, we need to do it + // up front + if (s->s_iflag == UP) { + dm_set_fg(dmp, 255, 255, 255, 0, s->s_os->transparency); + } + if (mvars->lighting_on) { + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mvars->i.wireColor); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black); + if (mvars->transparency_on) + glDisable(GL_BLEND); + } + // If we have a dlist in the correct mode, use it if (s->s_dlist) { if (mode == s->s_dlist_mode) { @@ -393,16 +448,10 @@ gl_csg_lod(struct dm *dmp, struct bv_scene_obj *s) glNewList(s->s_dlist, GL_COMPILE); } else { bu_log("Not using dlist\n"); - } - - // Wireframe - if (mvars->lighting_on) { - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mvars->i.wireColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, black); - if (mvars->transparency_on) - glDisable(GL_BLEND); + // Straight-up drawing - set up the matrix + MAT_COPY(save_mat, s->s_v->gv_model2view); + bn_mat_mul(draw_mat, s->s_v->gv_model2view, s->s_mat); + dm_loadmatrix(dmp, draw_mat, 0); } int first = 1; @@ -450,9 +499,6 @@ gl_csg_lod(struct dm *dmp, struct bv_scene_obj *s) if (first == 0) glEnd(); - if (mvars->lighting_on && mvars->transparency_on) - glDisable(GL_BLEND); - if (gen_dlist) { glEndList(); s->s_dlist_stale = 0; @@ -480,9 +526,16 @@ gl_csg_lod(struct dm *dmp, struct bv_scene_obj *s) dm_loadmatrix(dmp, save_mat, 0); } + if (mvars->lighting_on && mvars->transparency_on) + glDisable(GL_BLEND); + glPointSize(originalPointSize); glLineWidth(originalLineWidth); + // Without dlist, we had to set the matrix - restore + if (!s->s_dlist) + dm_loadmatrix(dmp, save_mat, 0); + return BRLCAD_OK; } diff --git a/src/libdm/glx/CMakeLists.txt b/src/libdm/glx/CMakeLists.txt index f61786527fa..b7267f2e570 100644 --- a/src/libdm/glx/CMakeLists.txt +++ b/src/libdm/glx/CMakeLists.txt @@ -21,9 +21,7 @@ if(BRLCAD_ENABLE_X11 AND BRLCAD_ENABLE_TK AND BRLCAD_ENABLE_OPENGL) ${BRLCAD_BINARY_DIR}/include ${BRLCAD_SOURCE_DIR}/include ${BU_INCLUDE_DIRS} - ) - include_directories( SYSTEM ${X11_INCLUDE_DIR} ${XOPENGL_INCLUDE_DIR_GL} diff --git a/src/libdm/qtgl/dm-qtgl.cpp b/src/libdm/qtgl/dm-qtgl.cpp index 905ee43e84a..d906d818802 100644 --- a/src/libdm/qtgl/dm-qtgl.cpp +++ b/src/libdm/qtgl/dm-qtgl.cpp @@ -125,6 +125,39 @@ qtgl_configureWin(struct dm *dmp, int UNUSED(force)) return BRLCAD_OK; } +static int +qtgl_getDisplayImage(struct dm *dmp, unsigned char **image, int flip, int alpha) +{ + gl_debug_print(dmp, "qgl_getDisplayImage", dmp->i->dm_debugLevel); + + struct qtgl_vars *privars = (struct qtgl_vars *)dmp->i->dm_vars.priv_vars; + QImage qimg = privars->qw->grabFramebuffer(); + unsigned char *idata; + int width; + int height; + + width = dmp->i->dm_width; + height = dmp->i->dm_height; + + if (!alpha) { + QImage img32 = qimg.convertToFormat(QImage::Format_RGB888); + idata = (unsigned char*)bu_calloc(height * width * 3, sizeof(unsigned char), "rgb data"); + memcpy(idata, img32.bits(), height * width * 3); + *image = idata; + } else { + QImage img32 = qimg.convertToFormat(QImage::Format_RGBA8888); + idata = (unsigned char*)bu_calloc(height * width * 4, sizeof(unsigned char), "rgba data"); + memcpy(idata, img32.bits(), height * width * 4); + *image = idata; + } + if (!flip) + flip_display_image_vertically(*image, width, height, alpha); + + return BRLCAD_OK; /* caller will need to bu_free(idata, "image data"); */ + +} + + /* * Gracefully release the display. */ @@ -597,7 +630,7 @@ struct dm_impl dm_qtgl_impl = { gl_freeDLists, gl_genDLists, gl_draw_display_list, - gl_getDisplayImage, /* display to image function */ + qtgl_getDisplayImage, /* display to image function */ gl_reshape, qtgl_makeCurrent, null_SwapBuffers, diff --git a/src/libdm/qtgl/dm-qtgl.h b/src/libdm/qtgl/dm-qtgl.h index ae7b822ee99..07b474ebe29 100644 --- a/src/libdm/qtgl/dm-qtgl.h +++ b/src/libdm/qtgl/dm-qtgl.h @@ -38,10 +38,11 @@ #endif #ifdef __cplusplus -# ifdef USE_QT6 -# include -# else +# include +# if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) # include +# else +# include # endif #endif diff --git a/src/libdm/qtgl/fb-qtgl.cpp b/src/libdm/qtgl/fb-qtgl.cpp index 444fd6f83b8..370ab309d71 100644 --- a/src/libdm/qtgl/fb-qtgl.cpp +++ b/src/libdm/qtgl/fb-qtgl.cpp @@ -72,7 +72,7 @@ struct qtglinfo { int ac; char **av; QApplication *qapp = NULL; - QtGLWin *mw = NULL; + QgGLWin *mw = NULL; int cmap_size; /* hardware colormap size */ int win_width; /* actual window width */ @@ -395,7 +395,7 @@ fb_qtgl_open(struct fb *ifp, const char *UNUSED(file), int width, int height) fmt.setDepthBufferSize(24); QSurfaceFormat::setDefaultFormat(fmt); - qi->mw = new QtGLWin(ifp); + qi->mw = new QgGLWin(ifp); qi->mw->canvas->setFixedSize(width, height); qi->mw->adjustSize(); qi->mw->setFixedSize(qi->mw->size()); diff --git a/src/libdm/qtgl/qtglwin.cpp b/src/libdm/qtgl/qtglwin.cpp index 934cfbcc08a..46fb19d2a2d 100644 --- a/src/libdm/qtgl/qtglwin.cpp +++ b/src/libdm/qtgl/qtglwin.cpp @@ -23,9 +23,9 @@ #include "qtglwin.h" -QtGLWin::QtGLWin(struct fb *fbp) +QgGLWin::QgGLWin(struct fb *fbp) { - canvas = new QtGL(this, fbp); + canvas = new QgGL(this, fbp); this->setCentralWidget(canvas); canvas->setMinimumSize(1,1); } diff --git a/src/libdm/qtgl/qtglwin.h b/src/libdm/qtgl/qtglwin.h index 40d42d54cd8..6a594224b6a 100644 --- a/src/libdm/qtgl/qtglwin.h +++ b/src/libdm/qtgl/qtglwin.h @@ -19,7 +19,7 @@ */ /** @file main_window.h * - * Defines the toplevel window for a stand-alone QtGL dm. + * Defines the toplevel window for a stand-alone QgGL dm. * */ @@ -28,14 +28,14 @@ #include #include "dm.h" -#include "qtcad/QtGL.h" +#include "qtcad/QgGL.h" -class QtGLWin : public QMainWindow +class QgGLWin : public QMainWindow { Q_OBJECT public: - QtGLWin(struct fb *fbp); - QtGL *canvas = NULL; + QgGLWin(struct fb *fbp); + QgGL *canvas = NULL; }; #endif /* QTGLWIN_H */ diff --git a/src/libdm/swrast/CMakeLists.txt b/src/libdm/swrast/CMakeLists.txt index c36a6ccfe64..5de6ff1f2ab 100644 --- a/src/libdm/swrast/CMakeLists.txt +++ b/src/libdm/swrast/CMakeLists.txt @@ -43,12 +43,12 @@ set(SWRAST_SRCS ${SWRAST_SRCS} ${swrast_moc_srcs}) dm_plugin_library(dm-swrast SHARED ${SWRAST_SRCS}) if(BRLCAD_ENABLE_QT) if(Qt6Widgets_FOUND) - target_link_libraries(dm-swrast libqtcad libdm libbu osmesa Qt6::Core Qt6::Widgets) + target_link_libraries(dm-swrast libqtcad libdm libbu ${OSMESA_LIBRARY} Qt6::Core Qt6::Widgets) else() - target_link_libraries(dm-swrast libqtcad libdm libbu osmesa Qt5::Core Qt5::Widgets) + target_link_libraries(dm-swrast libqtcad libdm libbu ${OSMESA_LIBRARY} Qt5::Core Qt5::Widgets) endif(Qt6Widgets_FOUND) else(BRLCAD_ENABLE_QT) - target_link_libraries(dm-swrast libdm libbu osmesa) + target_link_libraries(dm-swrast libdm libbu ${OSMESA_LIBRARY}) endif(BRLCAD_ENABLE_QT) set_property(TARGET dm-swrast APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H OSMESA) VALIDATE_STYLE(dm-swrast "${SWRAST_SRCS}") diff --git a/src/libdm/swrast/fb-swrast.cpp b/src/libdm/swrast/fb-swrast.cpp index 148c51f46e1..84d4be00a7c 100644 --- a/src/libdm/swrast/fb-swrast.cpp +++ b/src/libdm/swrast/fb-swrast.cpp @@ -59,7 +59,7 @@ struct swrastinfo { char **av; #ifdef SWRAST_QT QApplication *qapp = NULL; - QtSWWin *mw = NULL; + QgSWWin *mw = NULL; #endif int cmap_size; /* hardware colormap size */ int win_width; /* actual window width */ @@ -384,7 +384,7 @@ fb_swrast_open(struct fb *ifp, const char *UNUSED(file), int width, int height) #ifdef SWRAST_QT qi->qapp = new QApplication(qi->ac, qi->av); - qi->mw = new QtSWWin(ifp); + qi->mw = new QgSWWin(ifp); BU_GET(qi->mw->canvas->v, struct bview); bv_init(qi->mw->canvas->v, NULL); diff --git a/src/libdm/swrast/swrastwin.cpp b/src/libdm/swrast/swrastwin.cpp index 8a58f3c2bfe..efa8c27c60f 100644 --- a/src/libdm/swrast/swrastwin.cpp +++ b/src/libdm/swrast/swrastwin.cpp @@ -23,9 +23,9 @@ #include "swrastwin.h" -QtSWWin::QtSWWin(struct fb *fbp) +QgSWWin::QgSWWin(struct fb *fbp) { - canvas = new QtSW(this, fbp); + canvas = new QgSW(this, fbp); this->setCentralWidget(canvas); canvas->setMinimumSize(1,1); } diff --git a/src/libdm/swrast/swrastwin.h b/src/libdm/swrast/swrastwin.h index b94bd6083ae..47240b7c805 100644 --- a/src/libdm/swrast/swrastwin.h +++ b/src/libdm/swrast/swrastwin.h @@ -28,14 +28,14 @@ #include #include "dm.h" -#include "qtcad/QtSW.h" +#include "qtcad/QgSW.h" -class QtSWWin : public QMainWindow +class QgSWWin : public QMainWindow { Q_OBJECT public: - QtSWWin(struct fb *fbp); - QtSW *canvas = NULL; + QgSWWin(struct fb *fbp); + QgSW *canvas = NULL; }; #endif /* QTSWRASTWIN_H */ diff --git a/src/libdm/view.c b/src/libdm/view.c index b0db448fdec..a5f9e1c408f 100644 --- a/src/libdm/view.c +++ b/src/libdm/view.c @@ -24,8 +24,8 @@ #include "bu/units.h" #include "bu/vls.h" #include "bv/defines.h" +#include "bv/lod.h" #include "bv/util.h" -#include "bg/lod.h" #define DM_WITH_RT #include "dm.h" @@ -302,16 +302,18 @@ dm_draw_lines(struct dm *dmp, struct bv_data_line_state *gdlsp) void -dm_draw_faceplate(struct bview *v, double base2local, double local2base) +dm_draw_faceplate(struct bview *v) { + struct dm *dmp = (struct dm *)v->dmp; + /* Center dot */ if (v->gv_s->gv_center_dot.gos_draw) { - (void)dm_set_fg((struct dm *)v->dmp, + (void)dm_set_fg(dmp, v->gv_s->gv_center_dot.gos_line_color[0], v->gv_s->gv_center_dot.gos_line_color[1], v->gv_s->gv_center_dot.gos_line_color[2], 1, 1.0); - (void)dm_draw_point_2d((struct dm *)v->dmp, 0.0, 0.0); + (void)dm_draw_point_2d(dmp, 0.0, 0.0); } /* Model axes */ @@ -320,10 +322,10 @@ dm_draw_faceplate(struct bview *v, double base2local, double local2base) point_t save_map; VMOVE(save_map, v->gv_s->gv_model_axes.axes_pos); - VSCALE(map, v->gv_s->gv_model_axes.axes_pos, local2base); + VSCALE(map, v->gv_s->gv_model_axes.axes_pos, v->gv_local2base); MAT4X3PNT(v->gv_s->gv_model_axes.axes_pos, v->gv_model2view, map); - dm_draw_hud_axes((struct dm *)v->dmp, + dm_draw_hud_axes(dmp, v->gv_size, v->gv_rotation, &v->gv_s->gv_model_axes); @@ -338,11 +340,11 @@ dm_draw_faceplate(struct bview *v, double base2local, double local2base) fastf_t save_ypos; save_ypos = v->gv_s->gv_view_axes.axes_pos[Y]; - width = dm_get_width((struct dm *)v->dmp); - height = dm_get_height((struct dm *)v->dmp); + width = dm_get_width(dmp); + height = dm_get_height(dmp); inv_aspect = (fastf_t)height / (fastf_t)width; v->gv_s->gv_view_axes.axes_pos[Y] = save_ypos * inv_aspect; - dm_draw_hud_axes((struct dm *)v->dmp, + dm_draw_hud_axes(dmp, v->gv_size, v->gv_rotation, &v->gv_s->gv_view_axes); @@ -351,70 +353,93 @@ dm_draw_faceplate(struct bview *v, double base2local, double local2base) } - /* View scale */ + /* View scale - TODO view_scale needs its own text color */ if (v->gv_s->gv_view_scale.gos_draw) - dm_draw_scale((struct dm *)v->dmp, - v->gv_size*base2local, - bu_units_string(1/base2local), + dm_draw_scale(dmp, + v->gv_size*v->gv_base2local, + bu_units_string(1/v->gv_base2local), v->gv_s->gv_view_scale.gos_line_color, - v->gv_s->gv_view_params.gos_text_color); + v->gv_s->gv_view_params.color); /* Draw the angle distance cursor */ if (v->gv_s->gv_adc.draw) - dm_draw_adc((struct dm *)v->dmp, &(v->gv_s->gv_adc), v->gv_view2model, v->gv_model2view); + dm_draw_adc(dmp, &(v->gv_s->gv_adc), v->gv_view2model, v->gv_model2view); /* Draw grid */ if (v->gv_s->gv_grid.draw) { - dm_draw_grid((struct dm *)v->dmp, &v->gv_s->gv_grid, v->gv_scale, v->gv_model2view, base2local); + dm_draw_grid(dmp, &v->gv_s->gv_grid, v->gv_scale, v->gv_model2view, v->gv_base2local); } /* Draw rect */ if (v->gv_s->gv_rect.draw && v->gv_s->gv_rect.line_width) - dm_draw_rect((struct dm *)v->dmp, &v->gv_s->gv_rect); + dm_draw_rect(dmp, &v->gv_s->gv_rect); /* View parameters - drawn last so the FPS incorporates as much as possible * of the drawing work. */ - if (v->gv_s->gv_view_params.gos_draw || v->gv_s->gv_fps) { + if (v->gv_s->gv_view_params.draw) { + + // Save current font size + int ofontsize = dm_get_fontsize(dmp); + // Set font size for params + dm_set_fontsize(dmp, v->gv_s->gv_view_params.font_size); + struct bu_vls vls = BU_VLS_INIT_ZERO; point_t center; - char *ustr = (char *)bu_units_string(local2base); + char *ustr = (char *)bu_units_string(v->gv_local2base); MAT_DELTAS_GET_NEG(center, v->gv_center); - VSCALE(center, center, base2local); - int64_t elapsed_time = bu_gettime() - ((struct dm *)v->dmp)->start_time; + VSCALE(center, center, v->gv_base2local); + int64_t elapsed_time = bu_gettime() - (dmp)->start_time; /* Only use reasonable measurements */ if (elapsed_time > 10LL && elapsed_time < 30000000LL) { /* Smoothly transition to new speed */ v->gv_s->gv_frametime = 0.9 * v->gv_s->gv_frametime + 0.1 * elapsed_time / 1000000LL; } - if (v->gv_s->gv_view_params.gos_draw && v->gv_s->gv_fps) { - bu_vls_printf(&vls, "units:%s size:%.2f center:(%.2f, %.2f, %.2f) az:%.2f el:%.2f tw::%.2f FPS:%.2f", - ustr, - v->gv_size * base2local, - V3ARGS(center), - V3ARGS(v->gv_aet), - 1/v->gv_s->gv_frametime - ); - } else if (v->gv_s->gv_view_params.gos_draw && !v->gv_s->gv_fps) { - bu_vls_printf(&vls, "units:%s size:%.2f center:(%.2f, %.2f, %.2f) az:%.2f el:%.2f tw::%.2f", - ustr, - v->gv_size * base2local, - V3ARGS(center), - V3ARGS(v->gv_aet)); - } else if (!v->gv_s->gv_view_params.gos_draw || v->gv_s->gv_fps) { + struct bv_params_state *ps = &v->gv_s->gv_view_params; + if (ps->draw_size) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); + bu_vls_printf(&vls, "size[%s]: %.2f", ustr, v->gv_size * v->gv_base2local); + } + if (ps->draw_center) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); + bu_vls_printf(&vls, "center[%s]: (%.2f, %.2f, %.2f)", ustr, V3ARGS(center)); + } + if (ps->draw_az) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); + bu_vls_printf(&vls, "az:%.2f", v->gv_aet[0]); + } + if (ps->draw_el) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); + bu_vls_printf(&vls, "el:%.2f", v->gv_aet[1]); + } + if (ps->draw_tw) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); + bu_vls_printf(&vls, "tw:%.2f", v->gv_aet[2]); + } + if (ps->draw_fps) { + if (bu_vls_strlen(&vls) > 0) + bu_vls_printf(&vls, " "); bu_vls_printf(&vls, "FPS:%.2f", 1/v->gv_s->gv_frametime); } // TODO - really should put a rectangle behind this to ensure visibility... - (void)dm_set_fg((struct dm *)v->dmp, - v->gv_s->gv_view_params.gos_text_color[0], - v->gv_s->gv_view_params.gos_text_color[1], - v->gv_s->gv_view_params.gos_text_color[2], + (void)dm_set_fg(dmp, + v->gv_s->gv_view_params.color[0], + v->gv_s->gv_view_params.color[1], + v->gv_s->gv_view_params.color[2], 1, 1.0); - (void)dm_draw_string_2d((struct dm *)v->dmp, bu_vls_addr(&vls), -0.98, -0.965, 10, 0); + (void)dm_draw_string_2d(dmp, bu_vls_addr(&vls), -0.98, -0.965, 10, 0); bu_vls_free(&vls); + + // Restore previous font setting + dm_set_fontsize(dmp, ofontsize); } } @@ -549,33 +574,49 @@ dm_draw_labels(struct dm *dmp, struct bv_data_label_state *gdlsp, matp_t m2vmat) static void draw_scene_obj(struct dm *dmp, struct bv_scene_obj *s, struct bview *v) { - if (s->s_flag == DOWN) + if (!s || !v || s->s_flag == DOWN) return; - // If this is a database object, it may have a view dependent - // update to do. - if (s->s_update_callback) - (*s->s_update_callback)(s, v, 0); - // Draw children. TODO - drawing children first may not // always be the desired behavior - might need interior and exterior // children tables to provide some control for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - struct bv_scene_obj *sv = bv_obj_for_view(s_c, s->s_v); - draw_scene_obj(dmp, sv, v); + draw_scene_obj(dmp, s_c, v); } // Assign color attributes - if (s->s_os->color_override) { - dm_set_fg(dmp, s->s_os->color[0], s->s_os->color[1], s->s_os->color[2], 0, s->s_os->transparency); + if (s->s_iflag == UP) { + dm_set_fg(dmp, 255, 255, 255, 0, s->s_os->transparency); } else { - dm_set_fg(dmp, s->s_color[0], s->s_color[1], s->s_color[2], 0, s->s_os->transparency); + if (s->s_os->color_override) { + dm_set_fg(dmp, s->s_os->color[0], s->s_os->color[1], s->s_os->color[2], 0, s->s_os->transparency); + } else { + dm_set_fg(dmp, s->s_color[0], s->s_color[1], s->s_color[2], 0, s->s_os->transparency); + } } dm_set_line_attr(dmp, s->s_os->s_line_width, s->s_soldash); - // Primary object drawing - dm_draw_obj(dmp, s); + // Primary object drawing. See if we have an active view-specific object - if so, + // use that, otherwise use the original object + if (s->s_type_flags & BV_DB_OBJS) { + struct bv_scene_obj *vo = bv_obj_for_view(s, v); + if (!vo) { + vo = s; + bv_log(1, "draw_scene_obj - no view obj, drawing %s", bu_vls_cstr(&s->s_name)); + } else { + bv_log(1, "draw_scene_obj - drawing view obj %s[%s]", bu_vls_cstr(&vo->s_name), bu_vls_cstr(&v->gv_name)); + } + + // If this is a database object, it may have a view dependent + // update to do. + if (vo->s_update_callback) + (*vo->s_update_callback)(vo, v, 0); + + dm_draw_obj(dmp, vo); + } else { + dm_draw_obj(dmp, s); + } if (!(s->s_type_flags & BV_MESH_LOD)) { dm_add_arrows(dmp, s); @@ -588,12 +629,12 @@ draw_scene_obj(struct dm *dmp, struct bv_scene_obj *s, struct bview *v) if (s->s_type_flags & BV_LABELS) { dm_draw_label(dmp, s); } - } void -dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *vd, double base2local, double local2base) +dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *vd) { + bv_log(3, "libdm:dm_draw_viewobjs"); struct dm *dmp = (struct dm *)v->dmp; int width = dm_get_width(dmp); fastf_t sf = (fastf_t)(v->gv_size) / (fastf_t)width; @@ -632,24 +673,40 @@ dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *vd, // Draw geometry view objects struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { - struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); - struct bv_scene_obj *s = bv_obj_for_view(g, v); - draw_scene_obj(dmp, s, v); + if (db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); + draw_scene_obj(dmp, g, v); + } + } + struct bu_ptbl *local_db_objs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (local_db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_db_objs); i++) { + struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(local_db_objs, i); + draw_scene_obj(dmp, g, v); + } } // Draw view-only objects struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); - struct bv_scene_obj *sv = bv_obj_for_view(s, v); - draw_scene_obj(dmp, sv, v); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + draw_scene_obj(dmp, s, v); + } + } + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + draw_scene_obj(dmp, s, v); + } } /* Set up matrices for HUD drawing, rather than 3D scene drawing. */ (void)dm_hud_begin(dmp); - dm_draw_faceplate(v, base2local, local2base); + dm_draw_faceplate(v); if (v->gv_tcl.gv_data_labels.gdls_draw) dm_draw_labels(dmp, &v->gv_tcl.gv_data_labels, v->gv_model2view); @@ -686,14 +743,19 @@ dm_draw_viewobjs(struct rt_wdb *wdbp, struct bview *v, struct dm_view_data *vd, // doesn't guarantee raw OpenGL drawing is supported, but the dmp should // provide enough information for the calling app to know if that is possible.) void -dm_draw_objs(struct bview *v, double base2local, double local2base, void (*dm_draw_custom)(struct bview *, double, double, void *), void *u_data) +dm_draw_objs(struct bview *v, void (*dm_draw_custom)(struct bview *, void *), void *u_data) { + bv_log(3, "libdm:dm_draw_objs"); if (dm_draw_custom) { - (*dm_draw_custom)(v, base2local, local2base, u_data); + (*dm_draw_custom)(v, u_data); return; } struct dm *dmp = (struct dm *)v->dmp; + if (!dmp) { + bu_log("Warning - dm_draw_objs called when view has no associated display manager\n"); + return; + } // This is the start of a draw cycle - start the stopwatch to time the // frame. If the faceplate fps display is enabled, the faceplate draw at @@ -716,15 +778,6 @@ dm_draw_objs(struct bview *v, double base2local, double local2base, void (*dm_dr } } - -#if 0 - // Update selections (if any) - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_selected); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_selected, i); - // TODO - set illum flag or otherwise visually indicate what is selected - } -#endif - // On to the scene objects - for drawing those we need the view matrix matp_t mat = v->gv_model2view; dm_loadmatrix(dmp, mat, 0); @@ -741,33 +794,32 @@ dm_draw_objs(struct bview *v, double base2local, double local2base, void (*dm_dr // Draw geometry view objects // TODO - draw opaque, then transparent struct bu_ptbl *sobjs = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { - struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(sobjs, i); - struct bv_scene_obj *s = bv_obj_for_view(g, v); - //bu_log("dm_draw_objs %s\n", bu_vls_cstr(&g->s_name)); - draw_scene_obj(dmp, s, v); + if (!v->independent && sobjs) { + for (size_t i = 0; i < BU_PTBL_LEN(sobjs); i++) { + struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(sobjs, i); + //bu_log("dm_draw_objs %s\n", bu_vls_cstr(&g->s_name)); + draw_scene_obj(dmp, g, v); + } } struct bu_ptbl *iobjs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); - if (iobjs != sobjs) { + if (iobjs && (iobjs != sobjs || v->independent)) { for (size_t i = 0; i < BU_PTBL_LEN(iobjs); i++) { struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(iobjs, i); - struct bv_scene_obj *s = bv_obj_for_view(g, v); //bu_log("dm_draw_objs(i) %s\n", bu_vls_cstr(&g->s_name)); - draw_scene_obj(dmp, s, v); + draw_scene_obj(dmp, g, v); } } - // Draw view-only objects (shared if settings match, otherwise view-specific) + // Draw view-only objects struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); - struct bv_scene_obj *sv = bv_obj_for_view(s, v); - draw_scene_obj(dmp, sv, v); + if (view_objs && !v->independent) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + draw_scene_obj(dmp, s, v); + } } - - // Draw view-specific view-only objects if we haven't already done so struct bu_ptbl *vo = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); - if (vo != view_objs) { + if (vo && (vo != view_objs || v->independent)) { for (size_t i = 0; i < BU_PTBL_LEN(vo); i++) { struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(vo, i); draw_scene_obj(dmp, s, v); @@ -782,7 +834,7 @@ dm_draw_objs(struct bview *v, double base2local, double local2base, void (*dm_dr (void)dm_hud_begin(dmp); /* Draw faceplate elements based on their current enable/disable settings */ - dm_draw_faceplate(v, base2local, local2base); + dm_draw_faceplate(v); /* Restore non-HUD settings. */ (void)dm_hud_end(dmp); diff --git a/src/libdm/wgl/CMakeLists.txt b/src/libdm/wgl/CMakeLists.txt index 191d164e3b8..9d7f6bf83c2 100644 --- a/src/libdm/wgl/CMakeLists.txt +++ b/src/libdm/wgl/CMakeLists.txt @@ -3,7 +3,7 @@ set(WGL_SRCS if_wgl.c ) -if(WIN32 AND BRLCAD_ENABLE_OPENGL) +if (WIN32 AND BRLCAD_ENABLE_OPENGL AND BRLCAD_ENABLE_TK) find_package(OpenGL) find_package(TCL) @@ -15,9 +15,8 @@ if(WIN32 AND BRLCAD_ENABLE_OPENGL) ${OPENGL_INCLUDE_DIR_GL} ${TCL_INCLUDE_PATH} ${TK_INCLUDE_PATH} - # Needed for tkWinInt.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../other/ext/tk/generic - ${CMAKE_CURRENT_SOURCE_DIR}/../../other/ext/tk/win + # Private Tk headers needed for the internal Tk function TkWinGetHWND + ${CMAKE_CURRENT_SOURCE_DIR}/wintk ) set_property(SOURCE dm-wgl.c APPEND PROPERTY COMPILE_DEFINITIONS FB_USE_INTERNAL_API) @@ -39,13 +38,20 @@ if(WIN32 AND BRLCAD_ENABLE_OPENGL) PLUGIN_SETUP(dm-wgl dm) -endif(WIN32 AND BRLCAD_ENABLE_OPENGL) +endif (WIN32 AND BRLCAD_ENABLE_OPENGL AND BRLCAD_ENABLE_TK) CMAKEFILES( CMakeLists.txt ${WGL_SRCS} dm-wgl.h fb_wgl.h + wintk/tkWinPort.h + wintk/tkIntDecls.h + wintk/tkWinInt.h + wintk/tkInt.h + wintk/tkWin.h + wintk/tkIntPlatDecls.h + wintk/tkPort.h ) # Local Variables: @@ -54,3 +60,4 @@ CMAKEFILES( # indent-tabs-mode: t # End: # ex: shiftwidth=2 tabstop=8 + diff --git a/src/libdm/wgl/wintk/tkInt.h b/src/libdm/wgl/wintk/tkInt.h new file mode 100644 index 00000000000..35b7e673804 --- /dev/null +++ b/src/libdm/wgl/wintk/tkInt.h @@ -0,0 +1,1389 @@ +/* + * tkInt.h -- + * + * Declarations for things used internally by the Tk functions but not + * exported outside the module. + * + * Copyright (c) 1990-1994 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKINT +#define _TKINT + +#ifndef _TKPORT +#include "tkPort.h" +#endif + +#define TK_OPTION_ENUM_VAR ((int)(sizeof(Tk_OptionType)&(sizeof(int)-1))<<6) + +/* + * Ensure WORDS_BIGENDIAN is defined correctly: + * Needs to happen here in addition to configure to work with fat compiles on + * Darwin (where configure runs only once for multiple architectures). + */ + +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_PARAM_H +# include +#endif +#ifdef BYTE_ORDER +# ifdef BIG_ENDIAN +# if BYTE_ORDER == BIG_ENDIAN +# undef WORDS_BIGENDIAN +# define WORDS_BIGENDIAN 1 +# endif +# endif +# ifdef LITTLE_ENDIAN +# if BYTE_ORDER == LITTLE_ENDIAN +# undef WORDS_BIGENDIAN +# endif +# endif +#endif + +/* + * Used to tag functions that are only to be visible within the module being + * built and not outside it (where this is supported by the linker). + */ + +#ifndef MODULE_SCOPE +# ifdef __cplusplus +# define MODULE_SCOPE extern "C" +# else +# define MODULE_SCOPE extern +# endif +#endif + +#ifndef JOIN +# define JOIN(a,b) JOIN1(a,b) +# define JOIN1(a,b) a##b +#endif + +#ifndef TCL_UNUSED +# if defined(__cplusplus) +# define TCL_UNUSED(T) T +# elif defined(__GNUC__) && (__GNUC__ > 2) +# define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused)) +# else +# define TCL_UNUSED(T) T JOIN(dummy, __LINE__) +# endif +#endif + +#if defined(_WIN32) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7) +# if TCL_UTF_MAX > 3 +# define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c) +# define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c) +# else +# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString) +# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString) +# endif +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define TKFLEXARRAY +#elif defined(__GNUC__) && (__GNUC__ > 2) +# define TKFLEXARRAY 0 +#else +# define TKFLEXARRAY 1 +#endif + +#ifndef Tcl_GetParent +# define Tcl_GetParent Tcl_GetMaster +#endif + +/* + * Macros used to cast between pointers and integers (e.g. when storing an int + * in ClientData), on 64-bit architectures they avoid gcc warning about "cast + * to/from pointer from/to integer of different size". + */ + +#if !defined(INT2PTR) && !defined(PTR2INT) +# if defined(HAVE_INTPTR_T) || defined(intptr_t) +# define INT2PTR(p) ((void*)(intptr_t)(p)) +# define PTR2INT(p) ((int)(intptr_t)(p)) +# else +# define INT2PTR(p) ((void*)(p)) +# define PTR2INT(p) ((int)(p)) +# endif +#endif +#if !defined(UINT2PTR) && !defined(PTR2UINT) +# if defined(HAVE_UINTPTR_T) || defined(uintptr_t) +# define UINT2PTR(p) ((void*)(uintptr_t)(p)) +# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p)) +# else +# define UINT2PTR(p) ((void*)(p)) +# define PTR2UINT(p) ((unsigned int)(p)) +# endif +#endif + +#ifndef TCL_Z_MODIFIER +# if defined(_WIN64) +# define TCL_Z_MODIFIER "I" +# elif defined(__GNUC__) && !defined(_WIN32) +# define TCL_Z_MODIFIER "z" +# else +# define TCL_Z_MODIFIER "" +# endif +#endif /* !TCL_Z_MODIFIER */ + +/* + * Opaque type declarations: + */ + +typedef struct TkColormap TkColormap; +typedef struct TkFontAttributes TkFontAttributes; +typedef struct TkGrabEvent TkGrabEvent; +typedef struct TkpCursor_ *TkpCursor; +typedef struct TkRegion_ *TkRegion; +typedef struct TkStressedCmap TkStressedCmap; +typedef struct TkBindInfo_ *TkBindInfo; +typedef struct Busy *TkBusy; + +/* + * One of the following structures is maintained for each cursor in use in the + * system. This structure is used by tkCursor.c and the various system- + * specific cursor files. + */ + +typedef struct TkCursor { + Tk_Cursor cursor; /* System specific identifier for cursor. */ + Display *display; /* Display containing cursor. Needed for + * disposal and retrieval of cursors. */ + int resourceRefCount; /* Number of active uses of this cursor (each + * active use corresponds to a call to + * Tk_AllocPreserveFromObj or Tk_Preserve). If + * this count is 0, then this structure is no + * longer valid and it isn't present in a hash + * table: it is being kept around only because + * there are objects referring to it. The + * structure is freed when resourceRefCount + * and objRefCount are both 0. */ + int objRefCount; /* Number of Tcl objects that reference this + * structure.. */ + Tcl_HashTable *otherTable; /* Second table (other than idTable) used to + * index this entry. */ + Tcl_HashEntry *hashPtr; /* Entry in otherTable for this structure + * (needed when deleting). */ + Tcl_HashEntry *idHashPtr; /* Entry in idTable for this structure (needed + * when deleting). */ + struct TkCursor *nextPtr; /* Points to the next TkCursor structure with + * the same name. Cursors with the same name + * but different displays are chained together + * off a single hash table entry. */ +} TkCursor; + +/* + * The following structure is kept one-per-TkDisplay to maintain information + * about the caret (cursor location) on this display. This is used to dictate + * global focus location (Windows Accessibility guidelines) and to position + * the IME or XIM over-the-spot window. + */ + +typedef struct TkCaret { + struct TkWindow *winPtr; /* The window on which we requested caret + * placement. */ + int x; /* Relative x coord of the caret. */ + int y; /* Relative y coord of the caret. */ + int height; /* Specified height of the window. */ +} TkCaret; + +/* + * One of the following structures is maintained for each display containing a + * window managed by Tk. In part, the structure is used to store thread- + * specific data, since each thread will have its own TkDisplay structure. + */ + +typedef struct TkDisplay { + Display *display; /* Xlib's info about display. */ + struct TkDisplay *nextPtr; /* Next in list of all displays. */ + char *name; /* Name of display (with any screen identifier + * removed). Malloc-ed. */ + Time lastEventTime; /* Time of last event received for this + * display. */ + + /* + * Information used primarily by tk3d.c: + */ + + int borderInit; /* 0 means borderTable needs initializing. */ + Tcl_HashTable borderTable; /* Maps from color name to TkBorder + * structure. */ + + /* + * Information used by tkAtom.c only: + */ + + int atomInit; /* 0 means stuff below hasn't been initialized + * yet. */ + Tcl_HashTable nameTable; /* Maps from names to Atom's. */ + Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ + + /* + * Information used primarily by tkBind.c: + */ + + int bindInfoStale; /* Non-zero means the variables in this part + * of the structure are potentially incorrect + * and should be recomputed. */ + unsigned int modeModMask; /* Has one bit set to indicate the modifier + * corresponding to "mode shift". If no such + * modifier, than this is zero. */ + unsigned int metaModMask; /* Has one bit set to indicate the modifier + * corresponding to the "Meta" key. If no such + * modifier, then this is zero. */ + unsigned int altModMask; /* Has one bit set to indicate the modifier + * corresponding to the "Meta" key. If no such + * modifier, then this is zero. */ + enum {LU_IGNORE, LU_CAPS, LU_SHIFT} lockUsage; + /* Indicates how to interpret lock + * modifier. */ + int numModKeyCodes; /* Number of entries in modKeyCodes array + * below. */ + KeyCode *modKeyCodes; /* Pointer to an array giving keycodes for all + * of the keys that have modifiers associated + * with them. Malloc'ed, but may be NULL. */ + + /* + * Information used by tkBitmap.c only: + */ + + int bitmapInit; /* 0 means tables above need initializing. */ + int bitmapAutoNumber; /* Used to number bitmaps. */ + Tcl_HashTable bitmapNameTable; + /* Maps from name of bitmap to the first + * TkBitmap record for that name. */ + Tcl_HashTable bitmapIdTable;/* Maps from bitmap id to the TkBitmap + * structure for the bitmap. */ + Tcl_HashTable bitmapDataTable; + /* Used by Tk_GetBitmapFromData to map from a + * collection of in-core data about a bitmap + * to a reference giving an automatically- + * generated name for the bitmap. */ + + /* + * Information used by tkCanvas.c only: + */ + + int numIdSearches; + int numSlowSearches; + + /* + * Used by tkColor.c only: + */ + + int colorInit; /* 0 means color module needs initializing. */ + TkStressedCmap *stressPtr; /* First in list of colormaps that have filled + * up, so we have to pick an approximate + * color. */ + Tcl_HashTable colorNameTable; + /* Maps from color name to TkColor structure + * for that color. */ + Tcl_HashTable colorValueTable; + /* Maps from integer RGB values to TkColor + * structures. */ + + /* + * Used by tkCursor.c only: + */ + + int cursorInit; /* 0 means cursor module need initializing. */ + Tcl_HashTable cursorNameTable; + /* Maps from a string name to a cursor to the + * TkCursor record for the cursor. */ + Tcl_HashTable cursorDataTable; + /* Maps from a collection of in-core data + * about a cursor to a TkCursor structure. */ + Tcl_HashTable cursorIdTable; + /* Maps from a cursor id to the TkCursor + * structure for the cursor. */ + char cursorString[20]; /* Used to store a cursor id string. */ + Font cursorFont; /* Font to use for standard cursors. None + * means font not loaded yet. */ + + /* + * Information used by tkError.c only: + */ + + struct TkErrorHandler *errorPtr; + /* First in list of error handlers for this + * display. NULL means no handlers exist at + * present. */ + int deleteCount; /* Counts # of handlers deleted since last + * time inactive handlers were garbage- + * collected. When this number gets big, + * handlers get cleaned up. */ + + /* + * Used by tkEvent.c only: + */ + + struct TkWindowEvent *delayedMotionPtr; + /* Points to a malloc-ed motion event whose + * processing has been delayed in the hopes + * that another motion event will come along + * right away and we can merge the two of them + * together. NULL means that there is no + * delayed motion event. */ + + /* + * Information used by tkFocus.c only: + */ + + int focusDebug; /* 1 means collect focus debugging + * statistics. */ + struct TkWindow *implicitWinPtr; + /* If the focus arrived at a toplevel window + * implicitly via an Enter event (rather than + * via a FocusIn event), this points to the + * toplevel window. Otherwise it is NULL. */ + struct TkWindow *focusPtr; /* Points to the window on this display that + * should be receiving keyboard events. When + * multiple applications on the display have + * the focus, this will refer to the innermost + * window in the innermost application. This + * information isn't used on Windows, but it's + * needed on the Mac, and also on X11 when XIM + * processing is being done. */ + + /* + * Information used by tkGC.c only: + */ + + Tcl_HashTable gcValueTable; /* Maps from a GC's values to a TkGC structure + * describing a GC with those values. */ + Tcl_HashTable gcIdTable; /* Maps from a GC to a TkGC. */ + int gcInit; /* 0 means the tables below need + * initializing. */ + + /* + * Information used by tkGeometry.c only: + */ + + Tcl_HashTable maintainHashTable; + /* Hash table that maps from a container's + * Tk_Window token to a list of windows managed + * by that container. */ + int geomInit; + + /* + * Information used by tkGrid.c, tkPack.c, tkPlace.c, tkPointer.c, + * and ttkMacOSXTheme.c: + */ + +#define TkGetContainer(tkwin) (Tk_TopWinHierarchy((TkWindow *)tkwin) ? NULL : \ + (((TkWindow *)tkwin)->maintainerPtr != NULL ? \ + ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr)) + + /* + * Information used by tkGet.c only: + */ + + Tcl_HashTable uidTable; /* Stores all Tk_Uid used in a thread. */ + int uidInit; /* 0 means uidTable needs initializing. */ + + /* + * Information used by tkGrab.c only: + */ + + struct TkWindow *grabWinPtr;/* Window in which the pointer is currently + * grabbed, or NULL if none. */ + struct TkWindow *eventualGrabWinPtr; + /* Value that grabWinPtr will have once the + * grab event queue (below) has been + * completely emptied. */ + struct TkWindow *buttonWinPtr; + /* Window in which first mouse button was + * pressed while grab was in effect, or NULL + * if no such press in effect. */ + struct TkWindow *serverWinPtr; + /* If no application contains the pointer then + * this is NULL. Otherwise it contains the + * last window for which we've gotten an Enter + * or Leave event from the server (i.e. the + * last window known to have contained the + * pointer). Doesn't reflect events that were + * synthesized in tkGrab.c. */ + TkGrabEvent *firstGrabEventPtr; + /* First in list of enter/leave events + * synthesized by grab code. These events must + * be processed in order before any other + * events are processed. NULL means no such + * events. */ + TkGrabEvent *lastGrabEventPtr; + /* Last in list of synthesized events, or NULL + * if list is empty. */ + int grabFlags; /* Miscellaneous flag values. See definitions + * in tkGrab.c. */ + + /* + * Information used by tkGrid.c only: + */ + + int gridInit; /* 0 means table below needs initializing. */ + Tcl_HashTable gridHashTable;/* Maps from Tk_Window tokens to corresponding + * Grid structures. */ + + /* + * Information used by tkImage.c only: + */ + + int imageId; /* Value used to number image ids. */ + + /* + * Information used by tkMacWinMenu.c only: + */ + + int postCommandGeneration; + + /* + * Information used by tkPack.c only. + */ + + int packInit; /* 0 means table below needs initializing. */ + Tcl_HashTable packerHashTable; + /* Maps from Tk_Window tokens to corresponding + * Packer structures. */ + + /* + * Information used by tkPlace.c only. + */ + + int placeInit; /* 0 means tables below need initializing. */ + Tcl_HashTable masterTable; /* Maps from Tk_Window toke to the Master + * structure for the window, if it exists. */ + Tcl_HashTable slaveTable; /* Maps from Tk_Window toke to the Slave + * structure for the window, if it exists. */ + + /* + * Information used by tkSelect.c and tkClipboard.c only: + */ + + struct TkSelectionInfo *selectionInfoPtr; + /* First in list of selection information + * records. Each entry contains information + * about the current owner of a particular + * selection on this display. */ + Atom multipleAtom; /* Atom for MULTIPLE. None means selection + * stuff isn't initialized. */ + Atom incrAtom; /* Atom for INCR. */ + Atom targetsAtom; /* Atom for TARGETS. */ + Atom timestampAtom; /* Atom for TIMESTAMP. */ + Atom textAtom; /* Atom for TEXT. */ + Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ + Atom applicationAtom; /* Atom for TK_APPLICATION. */ + Atom windowAtom; /* Atom for TK_WINDOW. */ + Atom clipboardAtom; /* Atom for CLIPBOARD. */ + Atom utf8Atom; /* Atom for UTF8_STRING. */ + Atom atomPairAtom; /* Atom for ATOM_PAIR. */ + + Tk_Window clipWindow; /* Window used for clipboard ownership and to + * retrieve selections between processes. NULL + * means clipboard info hasn't been + * initialized. */ + int clipboardActive; /* 1 means we currently own the clipboard + * selection, 0 means we don't. */ + struct TkMainInfo *clipboardAppPtr; + /* Last application that owned clipboard. */ + struct TkClipboardTarget *clipTargetPtr; + /* First in list of clipboard type information + * records. Each entry contains information + * about the buffers for a given selection + * target. */ + + /* + * Information used by tkSend.c only: + */ + + Tk_Window commTkwin; /* Window used for communication between + * interpreters during "send" commands. NULL + * means send info hasn't been initialized + * yet. */ + Atom commProperty; /* X's name for comm property. */ + Atom registryProperty; /* X's name for property containing registry + * of interpreter names. */ + Atom appNameProperty; /* X's name for property used to hold the + * application name on each comm window. */ + + /* + * Information used by tkUnixWm.c and tkWinWm.c only: + */ + + struct TkWmInfo *firstWmPtr;/* Points to first top-level window. */ + struct TkWmInfo *foregroundWmPtr; + /* Points to the foreground window. */ + + /* + * Information used by tkVisual.c only: + */ + + TkColormap *cmapPtr; /* First in list of all non-default colormaps + * allocated for this display. */ + + /* + * Miscellaneous information: + */ + +#ifdef TK_USE_INPUT_METHODS + XIM inputMethod; /* Input method for this display. */ + XIMStyle inputStyle; /* Input style selected for this display. */ + XFontSet inputXfs; /* XFontSet cached for over-the-spot XIM. */ +#endif /* TK_USE_INPUT_METHODS */ + Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */ + + int refCount; /* Reference count of how many Tk applications + * are using this display. Used to clean up + * the display when we no longer have any Tk + * applications using it. */ + + /* + * The following field were all added for Tk8.3 + */ + + int mouseButtonState; /* Current mouse button state for this + * display. NOT USED as of 8.6.10 */ + Window mouseButtonWindow; /* Window the button state was set in, added + * in Tk 8.4. */ + Tk_Window warpWindow; + Tk_Window warpMainwin; /* For finding the root window for warping + * purposes. */ + int warpX; + int warpY; + + /* + * The following field(s) were all added for Tk8.4 + */ + + unsigned int flags; /* Various flag values: these are all defined + * in below. */ + TkCaret caret; /* Information about the caret for this + * display. This is not a pointer. */ + + int iconDataSize; /* Size of default iconphoto image data. */ + unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */ +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ +} TkDisplay; + +/* + * Flag values for TkDisplay flags. + * TK_DISPLAY_COLLAPSE_MOTION_EVENTS: (default on) + * Indicates that we should collapse motion events on this display + * TK_DISPLAY_USE_IM: (default on, set via tk.tcl) + * Whether to use input methods for this display + * TK_DISPLAY_WM_TRACING: (default off) + * Whether we should do wm tracing on this display. + * TK_DISPLAY_IN_WARP: (default off) + * Indicates that we are in a pointer warp + */ + +#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS (1 << 0) +#define TK_DISPLAY_USE_IM (1 << 1) +#define TK_DISPLAY_WM_TRACING (1 << 3) +#define TK_DISPLAY_IN_WARP (1 << 4) +#define TK_DISPLAY_USE_XKB (1 << 5) + +/* + * One of the following structures exists for each error handler created by a + * call to Tk_CreateErrorHandler. The structure is managed by tkError.c. + */ + +typedef struct TkErrorHandler { + TkDisplay *dispPtr; /* Display to which handler applies. */ + unsigned long firstRequest; /* Only errors with serial numbers >= to this + * are considered. */ + unsigned long lastRequest; /* Only errors with serial numbers <= to this + * are considered. This field is filled in + * when XUnhandle is called. -1 means + * XUnhandle hasn't been called yet. */ + int error; /* Consider only errors with this error_code + * (-1 means consider all errors). */ + int request; /* Consider only errors with this major + * request code (-1 means consider all major + * codes). */ + int minorCode; /* Consider only errors with this minor + * request code (-1 means consider all minor + * codes). */ + Tk_ErrorProc *errorProc; /* Function to invoke when a matching error + * occurs. NULL means just ignore errors. */ + ClientData clientData; /* Arbitrary value to pass to errorProc. */ + struct TkErrorHandler *nextPtr; + /* Pointer to next older handler for this + * display, or NULL for end of list. */ +} TkErrorHandler; + +/* + * One of the following structures exists for each event handler created by + * calling Tk_CreateEventHandler. This information is used by tkEvent.c only. + */ + +typedef struct TkEventHandler { + unsigned long mask; /* Events for which to invoke proc. */ + Tk_EventProc *proc; /* Function to invoke when an event in mask + * occurs. */ + ClientData clientData; /* Argument to pass to proc. */ + struct TkEventHandler *nextPtr; + /* Next in list of handlers associated with + * window (NULL means end of list). */ +} TkEventHandler; + +/* + * Tk keeps one of the following data structures for each main window (created + * by a call to TkCreateMainWindow). It stores information that is shared by + * all of the windows associated with a particular main window. + */ + +typedef struct TkMainInfo { + int refCount; /* Number of windows whose "mainPtr" fields + * point here. When this becomes zero, can + * free up the structure (the reference count + * is zero because windows can get deleted in + * almost any order; the main window isn't + * necessarily the last one deleted). */ + struct TkWindow *winPtr; /* Pointer to main window. */ + Tcl_Interp *interp; /* Interpreter associated with application. */ + Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow + * structs for all windows related to this + * main window. Managed by tkWindow.c. */ + long deletionEpoch; /* Incremented by window deletions. */ + Tk_BindingTable bindingTable; + /* Used in conjunction with "bind" command to + * bind events to Tcl commands. */ + TkBindInfo bindInfo; /* Information used by tkBind.c on a per + * application basis. */ + struct TkFontInfo *fontInfoPtr; + /* Information used by tkFont.c on a per + * application basis. */ + + /* + * Information used only by tkFocus.c and tk*Embed.c: + */ + + struct TkToplevelFocusInfo *tlFocusPtr; + /* First in list of records containing focus + * information for each top-level in the + * application. Used only by tkFocus.c. */ + struct TkDisplayFocusInfo *displayFocusPtr; + /* First in list of records containing focus + * information for each display that this + * application has ever used. Used only by + * tkFocus.c. */ + + struct ElArray *optionRootPtr; + /* Top level of option hierarchy for this main + * window. NULL means uninitialized. Managed + * by tkOption.c. */ + Tcl_HashTable imageTable; /* Maps from image names to Tk_ImageModel + * structures. Managed by tkImage.c. */ + int strictMotif; /* This is linked to the tk_strictMotif global + * variable. */ + int alwaysShowSelection; /* This is linked to the + * ::tk::AlwaysShowSelection variable. */ + struct TkMainInfo *nextPtr; /* Next in list of all main windows managed by + * this process. */ + Tcl_HashTable busyTable; /* Information used by [tk busy] command. */ + Tcl_ObjCmdProc *tclUpdateObjProc; + /* Saved Tcl [update] command, used to restore + * Tcl's version of [update] after Tk is shut + * down */ +} TkMainInfo; + +/* + * Tk keeps the following data structure for each of it's builtin bitmaps. + * This structure is only used by tkBitmap.c and other platform specific + * bitmap files. + */ + +typedef struct { + const void *source; /* Bits for bitmap. */ + int width, height; /* Dimensions of bitmap. */ + int native; /* 0 means generic (X style) bitmap, 1 means + * native style bitmap. */ +} TkPredefBitmap; + +/* + * Tk keeps one of the following structures for each window. Some of the + * information (like size and location) is a shadow of information managed by + * the X server, and some is special information used here, such as event and + * geometry management information. This information is (mostly) managed by + * tkWindow.c. WARNING: the declaration below must be kept consistent with the + * Tk_FakeWin structure in tk.h. If you change one, be sure to change the + * other! + */ + +typedef struct TkWindow { + /* + * Structural information: + */ + + Display *display; /* Display containing window. */ + TkDisplay *dispPtr; /* Tk's information about display for + * window. */ + int screenNum; /* Index of screen for window, among all those + * for dispPtr. */ + Visual *visual; /* Visual to use for window. If not default, + * MUST be set before X window is created. */ + int depth; /* Number of bits/pixel. */ + Window window; /* X's id for window. None means window hasn't + * actually been created yet, or it's been + * deleted. */ + struct TkWindow *childList; /* First in list of child windows, or NULL if + * no children. List is in stacking order, + * lowest window first.*/ + struct TkWindow *lastChildPtr; + /* Last in list of child windows (highest in + * stacking order), or NULL if no children. */ + struct TkWindow *parentPtr; /* Pointer to parent window (logical parent, + * not necessarily X parent). NULL means + * either this is the main window, or the + * window's parent has already been deleted. */ + struct TkWindow *nextPtr; /* Next higher sibling (in stacking order) in + * list of children with same parent. NULL + * means end of list. */ + TkMainInfo *mainPtr; /* Information shared by all windows + * associated with a particular main window. + * NULL means this window is a rogue that is + * not associated with any application (at + * present, this only happens for the dummy + * windows used for "send" communication). */ + + /* + * Name and type information for the window: + */ + + char *pathName; /* Path name of window (concatenation of all + * names between this window and its top-level + * ancestor). This is a pointer into an entry + * in mainPtr->nameTable. NULL means that the + * window hasn't been completely created + * yet. */ + Tk_Uid nameUid; /* Name of the window within its parent + * (unique within the parent). */ + Tk_Uid classUid; /* Class of the window. NULL means window + * hasn't been given a class yet. */ + + /* + * Geometry and other attributes of window. This information may not be + * updated on the server immediately; stuff that hasn't been reflected in + * the server yet is called "dirty". At present, information can be dirty + * only if the window hasn't yet been created. + */ + + XWindowChanges changes; /* Geometry and other info about window. */ + unsigned int dirtyChanges; /* Bits indicate fields of "changes" that are + * dirty. */ + XSetWindowAttributes atts; /* Current attributes of window. */ + unsigned long dirtyAtts; /* Bits indicate fields of "atts" that are + * dirty. */ + + unsigned int flags; /* Various flag values: these are all defined + * in tk.h (confusing, but they're needed + * there for some query macros). */ + + /* + * Information kept by the event manager (tkEvent.c): + */ + + TkEventHandler *handlerList;/* First in list of event handlers declared + * for this window, or NULL if none. */ +#ifdef TK_USE_INPUT_METHODS + XIC inputContext; /* XIM input context. */ +#endif /* TK_USE_INPUT_METHODS */ + + /* + * Information used for event bindings (see "bind" and "bindtags" commands + * in tkCmds.c): + */ + + ClientData *tagPtr; /* Points to array of tags used for bindings + * on this window. Each tag is a Tk_Uid. + * Malloc'ed. NULL means no tags. */ + int numTags; /* Number of tags at *tagPtr. */ + + /* + * Information used by tkOption.c to manage options for the window. + */ + + int optionLevel; /* -1 means no option information is currently + * cached for this window. Otherwise this + * gives the level in the option stack at + * which info is cached. */ + /* + * Information used by tkSelect.c to manage the selection. + */ + + struct TkSelHandler *selHandlerList; + /* First in list of handlers for returning the + * selection in various forms. */ + + /* + * Information used by tkGeometry.c for geometry management. + */ + + const Tk_GeomMgr *geomMgrPtr; + /* Information about geometry manager for this + * window. */ + ClientData geomData; /* Argument for geometry manager functions. */ + int reqWidth, reqHeight; /* Arguments from last call to + * Tk_GeometryRequest, or 0's if + * Tk_GeometryRequest hasn't been called. */ + int internalBorderLeft; /* Width of internal border of window (0 means + * no internal border). Geometry managers + * should not normally place children on top + * of the border. Fields for the other three + * sides are found below. */ + + /* + * Information maintained by tkWm.c for window manager communication. + */ + + struct TkWmInfo *wmInfoPtr; /* For top-level windows (and also for special + * Unix menubar and wrapper windows), points + * to structure with wm-related info (see + * tkWm.c). For other windows, this is + * NULL. */ + + /* + * Information used by widget classes. + */ + + const Tk_ClassProcs *classProcsPtr; + ClientData instanceData; + + /* + * Platform specific information private to each port. + */ + + struct TkWindowPrivate *privatePtr; + + /* + * More information used by tkGeometry.c for geometry management. + */ + + /* The remaining fields of internal border. */ + int internalBorderRight; + int internalBorderTop; + int internalBorderBottom; + + int minReqWidth; /* Minimum requested width. */ + int minReqHeight; /* Minimum requested height. */ +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ + char *geomMgrName; /* Records the name of the geometry manager. */ + struct TkWindow *maintainerPtr; + /* The geometry container for this window. The + * value is NULL if the window has no container or + * if its container is its parent. */ +} TkWindow; + +/* + * String tables: + */ + +MODULE_SCOPE const char *const tkStateStrings[]; +MODULE_SCOPE const char *const tkCompoundStrings[]; + +/* + * Real definition of some events. Note that these events come from outside + * but have internally generated pieces added to them. + */ + +typedef struct { + XKeyEvent keyEvent; /* The real event from X11. */ +#ifdef _WIN32 + char trans_chars[XMaxTransChars]; + /* translated characters */ + unsigned char nbytes; +#elif !defined(MAC_OSX_TK) + char *charValuePtr; /* A pointer to a string that holds the key's + * %A substitution text (before backslash + * adding), or NULL if that has not been + * computed yet. If non-NULL, this string was + * allocated with ckalloc(). */ + int charValueLen; /* Length of string in charValuePtr when that + * is non-NULL. */ + KeySym keysym; /* Key symbol computed after input methods + * have been invoked */ +#endif +} TkKeyEvent; + +/* + * Flags passed to TkpMakeMenuWindow's 'transient' argument. + */ + +#define TK_MAKE_MENU_TEAROFF 0 /* Only non-transient case. */ +#define TK_MAKE_MENU_POPUP 1 +#define TK_MAKE_MENU_DROPDOWN 2 + +/* + * The following structure is used with TkMakeEnsemble to create ensemble + * commands and optionally to create sub-ensembles. + */ + +typedef struct TkEnsemble { + const char *name; + Tcl_ObjCmdProc *proc; + const struct TkEnsemble *subensemble; +} TkEnsemble; + +/* + * The following structure is used as a two way map between integers and + * strings, usually to map between an internal C representation and the + * strings used in Tcl. + */ + +typedef struct TkStateMap { + int numKey; /* Integer representation of a value. */ + const char *strKey; /* String representation of a value. */ +} TkStateMap; + +/* + * This structure is used by the Mac and Window porting layers as the internal + * representation of a clip_mask in a GC. + */ + +typedef struct TkpClipMask { + int type; /* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */ + union { + Pixmap pixmap; + TkRegion region; + } value; +} TkpClipMask; + +#define TKP_CLIP_PIXMAP 0 +#define TKP_CLIP_REGION 1 + +/* + * Return values from TkGrabState: + */ + +#define TK_GRAB_NONE 0 +#define TK_GRAB_IN_TREE 1 +#define TK_GRAB_ANCESTOR 2 +#define TK_GRAB_EXCLUDED 3 + +/* + * Additional flag for TkpMeasureCharsInContext. Coordinate with other flags + * for this routine, but don't make public until TkpMeasureCharsInContext is + * made public, too. + */ + +#define TK_ISOLATE_END 32 + +/* + * The macro below is used to modify a "char" value (e.g. by casting it to an + * unsigned character) so that it can be used safely with macros such as + * isspace(). + */ + +#define UCHAR(c) ((unsigned char) (c)) + +/* + * The following symbol is used in the mode field of FocusIn events generated + * by an embedded application to request the input focus from its container. + */ + +#define EMBEDDED_APP_WANTS_FOCUS (NotifyNormal + 20) + +/* + * The following special modifier mask bits are defined, to indicate logical + * modifiers such as Meta and Alt that may float among the actual modifier + * bits. + */ + +#define META_MASK (AnyModifier<<1) +#define ALT_MASK (AnyModifier<<2) +#define EXTENDED_MASK (AnyModifier<<3) + +/* + * Mask that selects any of the state bits corresponding to buttons, plus + * masks that select individual buttons' bits: + */ + +#define ALL_BUTTONS \ + (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) + + +MODULE_SCOPE unsigned TkGetButtonMask(unsigned); + +/* + * Object types not declared in tkObj.c need to be mentioned here so they can + * be properly registered with Tcl: + */ + +MODULE_SCOPE const Tcl_ObjType tkBorderObjType; +MODULE_SCOPE const Tcl_ObjType tkBitmapObjType; +MODULE_SCOPE const Tcl_ObjType tkColorObjType; +MODULE_SCOPE const Tcl_ObjType tkCursorObjType; +MODULE_SCOPE const Tcl_ObjType tkFontObjType; +MODULE_SCOPE const Tcl_ObjType tkStateKeyObjType; +MODULE_SCOPE const Tcl_ObjType tkTextIndexType; + +/* + * Miscellaneous variables shared among Tk modules but not exported to the + * outside world: + */ + +MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod; +MODULE_SCOPE Tk_ImageType tkBitmapImageType; +MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF; +MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr); +MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG; +MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM; +MODULE_SCOPE TkMainInfo *tkMainWindowList; +MODULE_SCOPE Tk_ImageType tkPhotoImageType; +MODULE_SCOPE Tcl_HashTable tkPredefBitmapTable; + +MODULE_SCOPE const char *const tkWebColors[20]; + +/* + * The definition of pi, at least from the perspective of double-precision + * floats. + */ + +#ifndef PI +#ifdef M_PI +#define PI M_PI +#else +#define PI 3.14159265358979323846 +#endif +#endif + +/* + * Support for Clang Static Analyzer + */ + +#if defined(PURIFY) && defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) && \ + !defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED) +void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn)); +#endif +#if !defined(CLANG_ASSERT) +#define CLANG_ASSERT(x) assert(x) +#endif +#elif !defined(CLANG_ASSERT) +#define CLANG_ASSERT(x) +#endif /* PURIFY && __clang__ */ + +/* + * The following magic value is stored in the "send_event" field of FocusIn + * and FocusOut events. This allows us to separate "real" events coming from + * the server from those that we generated. + */ + +#define GENERATED_FOCUS_EVENT_MAGIC ((Bool) 0x547321ac) + +/* + * Exported internals. + */ + +#include "tkIntDecls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Themed widget set init function: + */ + +MODULE_SCOPE int Ttk_Init(Tcl_Interp *interp); + +/* + * Internal functions shared among Tk modules but not exported to the outside + * world: + */ + +MODULE_SCOPE int Tk_BellObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_BindObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_BindtagsObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_BusyObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ButtonObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_CanvasObjCmd(ClientData clientData, + Tcl_Interp *interp, int argc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_CheckbuttonObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ClipboardObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ChooseColorObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ChooseDirectoryObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_DestroyObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_EntryObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_EventObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_FrameObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_FocusObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_FontObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_GetOpenFileObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_GetSaveFileObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_GrabObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_GridObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ImageObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_LabelObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_LabelframeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ListboxObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_LowerObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MenuObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MenubuttonObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MessageBoxObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MessageObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_PanedWindowObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_OptionObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_PackObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_PlaceObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_RadiobuttonObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_RaiseObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ScaleObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ScrollbarObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_SelectionObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData, + Tcl_Interp *interp,int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_SpinboxObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_TextObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_TkwaitObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_ToplevelObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_UpdateObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_WinfoObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); + +MODULE_SCOPE int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *objPtr, + double *doublePtr); +#define TkSetGeometryContainer TkSetGeometryMaster +MODULE_SCOPE int TkSetGeometryContainer(Tcl_Interp *interp, + Tk_Window tkwin, const char *name); +#define TkFreeGeometryContainer TkFreeGeometryMaster +MODULE_SCOPE void TkFreeGeometryContainer(Tk_Window tkwin, + const char *name); + +MODULE_SCOPE void TkEventInit(void); +MODULE_SCOPE void TkRegisterObjTypes(void); +MODULE_SCOPE int TkDeadAppObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int TkCanvasGetCoordObj(Tcl_Interp *interp, + Tk_Canvas canvas, Tcl_Obj *obj, + double *doublePtr); +MODULE_SCOPE int TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin, + const char *string, double *doublePtr); +MODULE_SCOPE int TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin, + Tk_PostscriptInfo psInfo, XImage *ximage, + int x, int y, int width, int height); +MODULE_SCOPE void TkMapTopFrame(Tk_Window tkwin); +MODULE_SCOPE XEvent * TkpGetBindingXEvent(Tcl_Interp *interp); +MODULE_SCOPE void TkCreateExitHandler(Tcl_ExitProc *proc, + void *clientData); +MODULE_SCOPE void TkDeleteExitHandler(Tcl_ExitProc *proc, + ClientData clientData); +MODULE_SCOPE Tcl_ExitProc TkFinalize; +MODULE_SCOPE Tcl_ExitProc TkFinalizeThread; +MODULE_SCOPE void TkpBuildRegionFromAlphaData(TkRegion region, + unsigned x, unsigned y, unsigned width, + unsigned height, unsigned char *dataPtr, + unsigned pixelStride, unsigned lineStride); +MODULE_SCOPE void TkAppendPadAmount(Tcl_Obj *bufferObj, + const char *buffer, int pad1, int pad2); +MODULE_SCOPE int TkParsePadAmount(Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *objPtr, + int *pad1Ptr, int *pad2Ptr); +MODULE_SCOPE void TkFocusSplit(TkWindow *winPtr); +MODULE_SCOPE void TkFocusJoin(TkWindow *winPtr); +MODULE_SCOPE int TkpAlwaysShowSelection(Tk_Window tkwin); +MODULE_SCOPE void TkpDrawCharsInContext(Display * display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, int rangeStart, + int rangeLength, int x, int y); +MODULE_SCOPE void TkpDrawAngledCharsInContext(Display * display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, int rangeStart, + int rangeLength, double x, double y, double angle); +MODULE_SCOPE int TkpMeasureCharsInContext(Tk_Font tkfont, + const char *source, int numBytes, int rangeStart, + int rangeLength, int maxLength, int flags, + int *lengthPtr); +MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *string, int numBytes, int x, int y, + int firstByte, int lastByte); +MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, + int c, struct TkFontAttributes *faPtr); +MODULE_SCOPE Tcl_Obj * TkNewWindowObj(Tk_Window tkwin); +MODULE_SCOPE void TkpShowBusyWindow(TkBusy busy); +MODULE_SCOPE void TkpHideBusyWindow(TkBusy busy); +MODULE_SCOPE void TkpMakeTransparentWindowExist(Tk_Window tkwin, + Window parent); +MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef, + Window *parentPtr, Tk_Window tkParent, + TkBusy busy); +MODULE_SCOPE int TkBackgroundEvalObjv(Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv, int flags); +MODULE_SCOPE void TkSendVirtualEvent(Tk_Window tgtWin, + const char *eventName, Tcl_Obj *detail); +MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp, + const char *nsname, const char *name, + ClientData clientData, const TkEnsemble *map); +MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, + ClientData clientData); +MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, + ClientData clientData); +MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); +MODULE_SCOPE int TkListCreateFrame(ClientData clientData, + Tcl_Interp *interp, Tcl_Obj *listObj, + int toplevel, Tcl_Obj *nameObj); + +#ifdef _WIN32 +#define TkParseColor XParseColor +#else +MODULE_SCOPE Status TkParseColor (Display * display, + Colormap map, const char* spec, + XColor * colorPtr); +#endif +#ifdef HAVE_XFT +MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); +#endif + +#if !defined(__cplusplus) && !defined(c_plusplus) +# define c_class class +#endif + +/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */ +#if TCL_UTF_MAX > (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6)) +# define TkUtfToUniChar Tcl_UtfToUniChar +# define TkUniCharToUtf Tcl_UniCharToUtf +# define TkUtfPrev Tcl_UtfPrev +# define TkUtfAtIndex Tcl_UtfAtIndex +#else + MODULE_SCOPE int TkUtfToUniChar(const char *, int *); + MODULE_SCOPE int TkUniCharToUtf(int, char *); + MODULE_SCOPE const char *TkUtfPrev(const char *, const char *); + MODULE_SCOPE const char *TkUtfAtIndex(const char *src, int index); +#endif + +/* + * Unsupported commands. + */ + +MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); + +/* + * For Tktest. + */ +MODULE_SCOPE int SquareObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); +MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) +#define TkplatformtestInit(x) TCL_OK +#else +MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _TKINT */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/src/libdm/wgl/wintk/tkIntDecls.h b/src/libdm/wgl/wintk/tkIntDecls.h new file mode 100644 index 00000000000..cb4379cb7f7 --- /dev/null +++ b/src/libdm/wgl/wintk/tkIntDecls.h @@ -0,0 +1,1235 @@ +/* + * tkIntDecls.h -- + * + * This file contains the declarations for all unsupported + * functions that are exported by the Tk library. These + * interfaces are not guaranteed to remain the same between + * versions. Use at your own risk. + * + * Copyright (c) 1998-1999 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKINTDECLS +#define _TKINTDECLS + +#ifdef BUILD_tk +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT +#endif + +struct TkText; +typedef struct TkTextBTree_ *TkTextBTree; +struct TkTextDispChunk; +struct TkTextIndex; +struct TkTextSegment; +struct TkSharedText; + +/* + * WARNING: This file is automatically generated by the tools/genStubs.tcl + * script. Any modifications to the function declarations below should be made + * in the generic/tkInt.decls script. + */ + +/* !BEGIN!: Do not edit below this line. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Exported function declarations: + */ + +/* 0 */ +EXTERN TkWindow * TkAllocWindow(TkDisplay *dispPtr, int screenNum, + TkWindow *parentPtr); +/* 1 */ +EXTERN void TkBezierPoints(double control[], int numSteps, + double *coordPtr); +/* 2 */ +EXTERN void TkBezierScreenPoints(Tk_Canvas canvas, + double control[], int numSteps, + XPoint *xPointPtr); +/* Slot 3 is reserved */ +/* 4 */ +EXTERN void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr); +/* 5 */ +EXTERN void TkBindFree(TkMainInfo *mainPtr); +/* 6 */ +EXTERN void TkBindInit(TkMainInfo *mainPtr); +/* 7 */ +EXTERN void TkChangeEventWindow(XEvent *eventPtr, + TkWindow *winPtr); +/* 8 */ +EXTERN int TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr); +/* 9 */ +EXTERN void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, + int padX, int padY, int innerWidth, + int innerHeight, int *xPtr, int *yPtr); +/* Slot 10 is reserved */ +/* Slot 11 is reserved */ +/* 12 */ +EXTERN TkCursor * TkCreateCursorFromData(Tk_Window tkwin, + const char *source, const char *mask, + int width, int height, int xHot, int yHot, + XColor fg, XColor bg); +/* 13 */ +EXTERN int TkCreateFrame(ClientData clientData, + Tcl_Interp *interp, int argc, + const char *const *argv, int toplevel, + const char *appName); +/* 14 */ +EXTERN Tk_Window TkCreateMainWindow(Tcl_Interp *interp, + const char *screenName, const char *baseName); +/* 15 */ +EXTERN Time TkCurrentTime(TkDisplay *dispPtr); +/* 16 */ +EXTERN void TkDeleteAllImages(TkMainInfo *mainPtr); +/* 17 */ +EXTERN void TkDoConfigureNotify(TkWindow *winPtr); +/* 18 */ +EXTERN void TkDrawInsetFocusHighlight(Tk_Window tkwin, GC gc, + int width, Drawable drawable, int padding); +/* 19 */ +EXTERN void TkEventDeadWindow(TkWindow *winPtr); +/* 20 */ +EXTERN void TkFillPolygon(Tk_Canvas canvas, double *coordPtr, + int numPoints, Display *display, + Drawable drawable, GC gc, GC outlineGC); +/* 21 */ +EXTERN int TkFindStateNum(Tcl_Interp *interp, + const char *option, const TkStateMap *mapPtr, + const char *strKey); +/* 22 */ +EXTERN CONST86 char * TkFindStateString(const TkStateMap *mapPtr, + int numKey); +/* 23 */ +EXTERN void TkFocusDeadWindow(TkWindow *winPtr); +/* 24 */ +EXTERN int TkFocusFilterEvent(TkWindow *winPtr, + XEvent *eventPtr); +/* 25 */ +EXTERN TkWindow * TkFocusKeyEvent(TkWindow *winPtr, XEvent *eventPtr); +/* 26 */ +EXTERN void TkFontPkgInit(TkMainInfo *mainPtr); +/* 27 */ +EXTERN void TkFontPkgFree(TkMainInfo *mainPtr); +/* 28 */ +EXTERN void TkFreeBindingTags(TkWindow *winPtr); +/* 29 */ +EXTERN void TkpFreeCursor(TkCursor *cursorPtr); +/* 30 */ +EXTERN char * TkGetBitmapData(Tcl_Interp *interp, + const char *string, const char *fileName, + int *widthPtr, int *heightPtr, int *hotXPtr, + int *hotYPtr); +/* 31 */ +EXTERN void TkGetButtPoints(double p1[], double p2[], + double width, int project, double m1[], + double m2[]); +/* 32 */ +EXTERN TkCursor * TkGetCursorByName(Tcl_Interp *interp, + Tk_Window tkwin, Tk_Uid string); +/* 33 */ +EXTERN const char * TkGetDefaultScreenName(Tcl_Interp *interp, + const char *screenName); +/* 34 */ +EXTERN TkDisplay * TkGetDisplay(Display *display); +/* 35 */ +EXTERN int TkGetDisplayOf(Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[], Tk_Window *tkwinPtr); +/* 36 */ +EXTERN TkWindow * TkGetFocusWin(TkWindow *winPtr); +/* 37 */ +EXTERN int TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin); +/* 38 */ +EXTERN int TkGetMiterPoints(double p1[], double p2[], + double p3[], double width, double m1[], + double m2[]); +/* 39 */ +EXTERN void TkGetPointerCoords(Tk_Window tkwin, int *xPtr, + int *yPtr); +/* 40 */ +EXTERN void TkGetServerInfo(Tcl_Interp *interp, Tk_Window tkwin); +/* 41 */ +EXTERN void TkGrabDeadWindow(TkWindow *winPtr); +/* 42 */ +EXTERN int TkGrabState(TkWindow *winPtr); +/* 43 */ +EXTERN void TkIncludePoint(Tk_Item *itemPtr, double *pointPtr); +/* 44 */ +EXTERN void TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr, + TkWindow *destPtr, int leaveType, + int enterType, Tcl_QueuePosition position); +/* 45 */ +EXTERN void TkInstallFrameMenu(Tk_Window tkwin); +/* 46 */ +EXTERN CONST86 char * TkKeysymToString(KeySym keysym); +/* 47 */ +EXTERN int TkLineToArea(double end1Ptr[], double end2Ptr[], + double rectPtr[]); +/* 48 */ +EXTERN double TkLineToPoint(double end1Ptr[], double end2Ptr[], + double pointPtr[]); +/* 49 */ +EXTERN int TkMakeBezierCurve(Tk_Canvas canvas, double *pointPtr, + int numPoints, int numSteps, + XPoint xPoints[], double dblPoints[]); +/* 50 */ +EXTERN void TkMakeBezierPostscript(Tcl_Interp *interp, + Tk_Canvas canvas, double *pointPtr, + int numPoints); +/* 51 */ +EXTERN void TkOptionClassChanged(TkWindow *winPtr); +/* 52 */ +EXTERN void TkOptionDeadWindow(TkWindow *winPtr); +/* 53 */ +EXTERN int TkOvalToArea(double *ovalPtr, double *rectPtr); +/* 54 */ +EXTERN double TkOvalToPoint(double ovalPtr[], double width, + int filled, double pointPtr[]); +/* 55 */ +EXTERN int TkpChangeFocus(TkWindow *winPtr, int force); +/* 56 */ +EXTERN void TkpCloseDisplay(TkDisplay *dispPtr); +/* 57 */ +EXTERN void TkpClaimFocus(TkWindow *topLevelPtr, int force); +/* 58 */ +EXTERN void TkpDisplayWarning(const char *msg, const char *title); +/* 59 */ +EXTERN void TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name); +/* 60 */ +EXTERN TkWindow * TkpGetOtherWindow(TkWindow *winPtr); +/* 61 */ +EXTERN TkWindow * TkpGetWrapperWindow(TkWindow *winPtr); +/* 62 */ +EXTERN int TkpInit(Tcl_Interp *interp); +/* 63 */ +EXTERN void TkpInitializeMenuBindings(Tcl_Interp *interp, + Tk_BindingTable bindingTable); +/* 64 */ +EXTERN void TkpMakeContainer(Tk_Window tkwin); +/* 65 */ +EXTERN void TkpMakeMenuWindow(Tk_Window tkwin, int transient); +/* 66 */ +EXTERN Window TkpMakeWindow(TkWindow *winPtr, Window parent); +/* 67 */ +EXTERN void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, + const char *menuName); +/* 68 */ +EXTERN TkDisplay * TkpOpenDisplay(const char *display_name); +/* 69 */ +EXTERN int TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr); +/* 70 */ +EXTERN int TkPolygonToArea(double *polyPtr, int numPoints, + double *rectPtr); +/* 71 */ +EXTERN double TkPolygonToPoint(double *polyPtr, int numPoints, + double *pointPtr); +/* 72 */ +EXTERN int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr); +/* 73 */ +EXTERN void TkpRedirectKeyEvent(TkWindow *winPtr, + XEvent *eventPtr); +/* 74 */ +EXTERN void TkpSetMainMenubar(Tcl_Interp *interp, + Tk_Window tkwin, const char *menuName); +/* 75 */ +EXTERN int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, + const char *string); +/* Slot 76 is reserved */ +/* 77 */ +EXTERN void TkQueueEventForAllChildren(TkWindow *winPtr, + XEvent *eventPtr); +/* 78 */ +EXTERN int TkReadBitmapFile(Display *display, Drawable d, + const char *filename, + unsigned int *width_return, + unsigned int *height_return, + Pixmap *bitmap_return, int *x_hot_return, + int *y_hot_return); +/* 79 */ +EXTERN int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y, + int width, int height, int dx, int dy, + TkRegion damageRgn); +/* 80 */ +EXTERN void TkSelDeadWindow(TkWindow *winPtr); +/* 81 */ +EXTERN void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr); +/* 82 */ +EXTERN void TkSelInit(Tk_Window tkwin); +/* 83 */ +EXTERN void TkSelPropProc(XEvent *eventPtr); +/* Slot 84 is reserved */ +/* 85 */ +EXTERN void TkSetWindowMenuBar(Tcl_Interp *interp, + Tk_Window tkwin, const char *oldMenuName, + const char *menuName); +/* 86 */ +EXTERN KeySym TkStringToKeysym(const char *name); +/* 87 */ +EXTERN int TkThickPolyLineToArea(double *coordPtr, + int numPoints, double width, int capStyle, + int joinStyle, double *rectPtr); +/* 88 */ +EXTERN void TkWmAddToColormapWindows(TkWindow *winPtr); +/* 89 */ +EXTERN void TkWmDeadWindow(TkWindow *winPtr); +/* 90 */ +EXTERN TkWindow * TkWmFocusToplevel(TkWindow *winPtr); +/* 91 */ +EXTERN void TkWmMapWindow(TkWindow *winPtr); +/* 92 */ +EXTERN void TkWmNewWindow(TkWindow *winPtr); +/* 93 */ +EXTERN void TkWmProtocolEventProc(TkWindow *winPtr, + XEvent *evenvPtr); +/* 94 */ +EXTERN void TkWmRemoveFromColormapWindows(TkWindow *winPtr); +/* 95 */ +EXTERN void TkWmRestackToplevel(TkWindow *winPtr, int aboveBelow, + TkWindow *otherPtr); +/* 96 */ +EXTERN void TkWmSetClass(TkWindow *winPtr); +/* 97 */ +EXTERN void TkWmUnmapWindow(TkWindow *winPtr); +/* 98 */ +EXTERN Tcl_Obj * TkDebugBitmap(Tk_Window tkwin, const char *name); +/* 99 */ +EXTERN Tcl_Obj * TkDebugBorder(Tk_Window tkwin, const char *name); +/* 100 */ +EXTERN Tcl_Obj * TkDebugCursor(Tk_Window tkwin, const char *name); +/* 101 */ +EXTERN Tcl_Obj * TkDebugColor(Tk_Window tkwin, const char *name); +/* 102 */ +EXTERN Tcl_Obj * TkDebugConfig(Tcl_Interp *interp, + Tk_OptionTable table); +/* 103 */ +EXTERN Tcl_Obj * TkDebugFont(Tk_Window tkwin, const char *name); +/* 104 */ +EXTERN int TkFindStateNumObj(Tcl_Interp *interp, + Tcl_Obj *optionPtr, const TkStateMap *mapPtr, + Tcl_Obj *keyPtr); +/* 105 */ +EXTERN Tcl_HashTable * TkGetBitmapPredefTable(void); +/* 106 */ +EXTERN TkDisplay * TkGetDisplayList(void); +/* 107 */ +EXTERN TkMainInfo * TkGetMainInfoList(void); +/* 108 */ +EXTERN int TkGetWindowFromObj(Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *objPtr, + Tk_Window *windowPtr); +/* 109 */ +EXTERN CONST86 char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr, + Tcl_DString *dsPtr); +/* 110 */ +EXTERN void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont); +/* 111 */ +EXTERN Tcl_Obj * TkpGetSystemDefault(Tk_Window tkwin, + const char *dbName, const char *className); +/* 112 */ +EXTERN void TkpMenuThreadInit(void); +/* 113 */ +EXTERN int TkClipBox(TkRegion rgn, XRectangle *rect_return); +/* 114 */ +EXTERN TkRegion TkCreateRegion(void); +/* 115 */ +EXTERN int TkDestroyRegion(TkRegion rgn); +/* 116 */ +EXTERN int TkIntersectRegion(TkRegion sra, TkRegion srcb, + TkRegion dr_return); +/* 117 */ +EXTERN int TkRectInRegion(TkRegion rgn, int x, int y, + unsigned int width, unsigned int height); +/* 118 */ +EXTERN int TkSetRegion(Display *display, GC gc, TkRegion rgn); +/* 119 */ +EXTERN int TkUnionRectWithRegion(XRectangle *rect, TkRegion src, + TkRegion dr_return); +/* Slot 120 is reserved */ +#ifdef MAC_OSX_TK /* AQUA */ +/* 121 */ +EXTERN Pixmap TkpCreateNativeBitmap(Display *display, + const void *source); +#endif /* AQUA */ +#ifdef MAC_OSX_TK /* AQUA */ +/* 122 */ +EXTERN void TkpDefineNativeBitmaps(void); +#endif /* AQUA */ +/* Slot 123 is reserved */ +#ifdef MAC_OSX_TK /* AQUA */ +/* 124 */ +EXTERN Pixmap TkpGetNativeAppBitmap(Display *display, + const char *name, int *width, int *height); +#endif /* AQUA */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +/* Slot 129 is reserved */ +/* Slot 130 is reserved */ +/* Slot 131 is reserved */ +/* Slot 132 is reserved */ +/* Slot 133 is reserved */ +/* Slot 134 is reserved */ +/* 135 */ +EXTERN void TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC, + GC bgGC, int highlightWidth, + Drawable drawable); +/* 136 */ +EXTERN void TkSetFocusWin(TkWindow *winPtr, int force); +/* 137 */ +EXTERN void TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym, + XEvent *eventPtr); +/* 138 */ +EXTERN KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr); +/* 139 */ +EXTERN void TkpInitKeymapInfo(TkDisplay *dispPtr); +/* 140 */ +EXTERN TkRegion TkPhotoGetValidRegion(Tk_PhotoHandle handle); +/* 141 */ +EXTERN TkWindow ** TkWmStackorderToplevel(TkWindow *parentPtr); +/* 142 */ +EXTERN void TkFocusFree(TkMainInfo *mainPtr); +/* 143 */ +EXTERN void TkClipCleanup(TkDisplay *dispPtr); +/* 144 */ +EXTERN void TkGCCleanup(TkDisplay *dispPtr); +/* 145 */ +EXTERN int TkSubtractRegion(TkRegion sra, TkRegion srcb, + TkRegion dr_return); +/* 146 */ +EXTERN void TkStylePkgInit(TkMainInfo *mainPtr); +/* 147 */ +EXTERN void TkStylePkgFree(TkMainInfo *mainPtr); +/* 148 */ +EXTERN Tk_Window TkToplevelWindowForCommand(Tcl_Interp *interp, + const char *cmdName); +/* 149 */ +EXTERN const Tk_OptionSpec * TkGetOptionSpec(const char *name, + Tk_OptionTable optionTable); +/* 150 */ +EXTERN int TkMakeRawCurve(Tk_Canvas canvas, double *pointPtr, + int numPoints, int numSteps, + XPoint xPoints[], double dblPoints[]); +/* 151 */ +EXTERN void TkMakeRawCurvePostscript(Tcl_Interp *interp, + Tk_Canvas canvas, double *pointPtr, + int numPoints); +/* 152 */ +EXTERN void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border, + int highlightWidth, int borderWidth, + int relief); +/* 153 */ +EXTERN void TkCreateThreadExitHandler(Tcl_ExitProc *proc, + ClientData clientData); +/* 154 */ +EXTERN void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, + ClientData clientData); +/* Slot 155 is reserved */ +/* 156 */ +EXTERN int TkpTestembedCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +/* 157 */ +EXTERN int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +/* 158 */ +EXTERN int TkSelGetSelection(Tcl_Interp *interp, + Tk_Window tkwin, Atom selection, Atom target, + Tk_GetSelProc *proc, ClientData clientData); +/* 159 */ +EXTERN int TkTextGetIndex(Tcl_Interp *interp, + struct TkText *textPtr, const char *string, + struct TkTextIndex *indexPtr); +/* 160 */ +EXTERN int TkTextIndexBackBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr); +/* 161 */ +EXTERN int TkTextIndexForwBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr); +/* 162 */ +EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree, + const struct TkText *textPtr, int lineIndex, + int byteIndex, struct TkTextIndex *indexPtr); +/* 163 */ +EXTERN int TkTextPrintIndex(const struct TkText *textPtr, + const struct TkTextIndex *indexPtr, + char *string); +/* 164 */ +EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr, + const char *name, + struct TkTextIndex *indexPtr); +/* 165 */ +EXTERN int TkTextXviewCmd(struct TkText *textPtr, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +/* 166 */ +EXTERN void TkTextChanged(struct TkSharedText *sharedTextPtr, + struct TkText *textPtr, + const struct TkTextIndex *index1Ptr, + const struct TkTextIndex *index2Ptr); +/* 167 */ +EXTERN int TkBTreeNumLines(TkTextBTree tree, + const struct TkText *textPtr); +/* 168 */ +EXTERN void TkTextInsertDisplayProc(struct TkText *textPtr, + struct TkTextDispChunk *chunkPtr, int x, + int y, int height, int baseline, + Display *display, Drawable dst, int screenY); +/* 169 */ +EXTERN int TkStateParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 170 */ +EXTERN CONST86 char * TkStatePrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 171 */ +EXTERN int TkCanvasDashParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 172 */ +EXTERN CONST86 char * TkCanvasDashPrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 173 */ +EXTERN int TkOffsetParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 174 */ +EXTERN CONST86 char * TkOffsetPrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 175 */ +EXTERN int TkPixelParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 176 */ +EXTERN CONST86 char * TkPixelPrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 177 */ +EXTERN int TkOrientParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 178 */ +EXTERN CONST86 char * TkOrientPrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 179 */ +EXTERN int TkSmoothParseProc(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + const char *value, char *widgRec, int offset); +/* 180 */ +EXTERN CONST86 char * TkSmoothPrintProc(ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, + Tcl_FreeProc **freeProcPtr); +/* 181 */ +EXTERN void TkDrawAngledTextLayout(Display *display, + Drawable drawable, GC gc, + Tk_TextLayout layout, int x, int y, + double angle, int firstChar, int lastChar); +/* 182 */ +EXTERN void TkUnderlineAngledTextLayout(Display *display, + Drawable drawable, GC gc, + Tk_TextLayout layout, int x, int y, + double angle, int underline); +/* 183 */ +EXTERN int TkIntersectAngledTextLayout(Tk_TextLayout layout, + int x, int y, int width, int height, + double angle); +/* 184 */ +EXTERN void TkDrawAngledChars(Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, double x, + double y, double angle); +#ifdef MAC_OSX_TCL /* MACOSX */ +/* 185 */ +EXTERN void TkpRedrawWidget(Tk_Window tkwin); +#endif /* MACOSX */ +#ifdef MAC_OSX_TCL /* MACOSX */ +/* 186 */ +EXTERN int TkpWillDrawWidget(Tk_Window tkwin); +#endif /* MACOSX */ +/* 187 */ +EXTERN void TkUnusedStubEntry(void); + +typedef struct TkIntStubs { + int magic; + void *hooks; + + TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */ + void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */ + void (*tkBezierScreenPoints) (Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr); /* 2 */ + void (*reserved3)(void); + void (*tkBindEventProc) (TkWindow *winPtr, XEvent *eventPtr); /* 4 */ + void (*tkBindFree) (TkMainInfo *mainPtr); /* 5 */ + void (*tkBindInit) (TkMainInfo *mainPtr); /* 6 */ + void (*tkChangeEventWindow) (XEvent *eventPtr, TkWindow *winPtr); /* 7 */ + int (*tkClipInit) (Tcl_Interp *interp, TkDisplay *dispPtr); /* 8 */ + void (*tkComputeAnchor) (Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */ + void (*reserved10)(void); + void (*reserved11)(void); + TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */ + int (*tkCreateFrame) (ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv, int toplevel, const char *appName); /* 13 */ + Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, const char *screenName, const char *baseName); /* 14 */ + Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */ + void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */ + void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */ + void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */ + void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */ + void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */ + int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */ + CONST86 char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */ + void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */ + int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */ + TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */ + void (*tkFontPkgInit) (TkMainInfo *mainPtr); /* 26 */ + void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */ + void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */ + void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */ + char * (*tkGetBitmapData) (Tcl_Interp *interp, const char *string, const char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */ + void (*tkGetButtPoints) (double p1[], double p2[], double width, int project, double m1[], double m2[]); /* 31 */ + TkCursor * (*tkGetCursorByName) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); /* 32 */ + const char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, const char *screenName); /* 33 */ + TkDisplay * (*tkGetDisplay) (Display *display); /* 34 */ + int (*tkGetDisplayOf) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tk_Window *tkwinPtr); /* 35 */ + TkWindow * (*tkGetFocusWin) (TkWindow *winPtr); /* 36 */ + int (*tkGetInterpNames) (Tcl_Interp *interp, Tk_Window tkwin); /* 37 */ + int (*tkGetMiterPoints) (double p1[], double p2[], double p3[], double width, double m1[], double m2[]); /* 38 */ + void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */ + void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */ + void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */ + int (*tkGrabState) (TkWindow *winPtr); /* 42 */ + void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */ + void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */ + void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */ + CONST86 char * (*tkKeysymToString) (KeySym keysym); /* 46 */ + int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */ + double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */ + int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */ + void (*tkMakeBezierPostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 50 */ + void (*tkOptionClassChanged) (TkWindow *winPtr); /* 51 */ + void (*tkOptionDeadWindow) (TkWindow *winPtr); /* 52 */ + int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */ + double (*tkOvalToPoint) (double ovalPtr[], double width, int filled, double pointPtr[]); /* 54 */ + int (*tkpChangeFocus) (TkWindow *winPtr, int force); /* 55 */ + void (*tkpCloseDisplay) (TkDisplay *dispPtr); /* 56 */ + void (*tkpClaimFocus) (TkWindow *topLevelPtr, int force); /* 57 */ + void (*tkpDisplayWarning) (const char *msg, const char *title); /* 58 */ + void (*tkpGetAppName) (Tcl_Interp *interp, Tcl_DString *name); /* 59 */ + TkWindow * (*tkpGetOtherWindow) (TkWindow *winPtr); /* 60 */ + TkWindow * (*tkpGetWrapperWindow) (TkWindow *winPtr); /* 61 */ + int (*tkpInit) (Tcl_Interp *interp); /* 62 */ + void (*tkpInitializeMenuBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable); /* 63 */ + void (*tkpMakeContainer) (Tk_Window tkwin); /* 64 */ + void (*tkpMakeMenuWindow) (Tk_Window tkwin, int transient); /* 65 */ + Window (*tkpMakeWindow) (TkWindow *winPtr, Window parent); /* 66 */ + void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, const char *menuName); /* 67 */ + TkDisplay * (*tkpOpenDisplay) (const char *display_name); /* 68 */ + int (*tkPointerEvent) (XEvent *eventPtr, TkWindow *winPtr); /* 69 */ + int (*tkPolygonToArea) (double *polyPtr, int numPoints, double *rectPtr); /* 70 */ + double (*tkPolygonToPoint) (double *polyPtr, int numPoints, double *pointPtr); /* 71 */ + int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */ + void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */ + void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *menuName); /* 74 */ + int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 75 */ + void (*reserved76)(void); + void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */ + int (*tkReadBitmapFile) (Display *display, Drawable d, const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */ + int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn); /* 79 */ + void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */ + void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */ + void (*tkSelInit) (Tk_Window tkwin); /* 82 */ + void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */ + void (*reserved84)(void); + void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */ + KeySym (*tkStringToKeysym) (const char *name); /* 86 */ + int (*tkThickPolyLineToArea) (double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); /* 87 */ + void (*tkWmAddToColormapWindows) (TkWindow *winPtr); /* 88 */ + void (*tkWmDeadWindow) (TkWindow *winPtr); /* 89 */ + TkWindow * (*tkWmFocusToplevel) (TkWindow *winPtr); /* 90 */ + void (*tkWmMapWindow) (TkWindow *winPtr); /* 91 */ + void (*tkWmNewWindow) (TkWindow *winPtr); /* 92 */ + void (*tkWmProtocolEventProc) (TkWindow *winPtr, XEvent *evenvPtr); /* 93 */ + void (*tkWmRemoveFromColormapWindows) (TkWindow *winPtr); /* 94 */ + void (*tkWmRestackToplevel) (TkWindow *winPtr, int aboveBelow, TkWindow *otherPtr); /* 95 */ + void (*tkWmSetClass) (TkWindow *winPtr); /* 96 */ + void (*tkWmUnmapWindow) (TkWindow *winPtr); /* 97 */ + Tcl_Obj * (*tkDebugBitmap) (Tk_Window tkwin, const char *name); /* 98 */ + Tcl_Obj * (*tkDebugBorder) (Tk_Window tkwin, const char *name); /* 99 */ + Tcl_Obj * (*tkDebugCursor) (Tk_Window tkwin, const char *name); /* 100 */ + Tcl_Obj * (*tkDebugColor) (Tk_Window tkwin, const char *name); /* 101 */ + Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */ + Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, const char *name); /* 103 */ + int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */ + Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */ + TkDisplay * (*tkGetDisplayList) (void); /* 106 */ + TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */ + int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */ + CONST86 char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */ + void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */ + Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */ + void (*tkpMenuThreadInit) (void); /* 112 */ + int (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */ + TkRegion (*tkCreateRegion) (void); /* 114 */ + int (*tkDestroyRegion) (TkRegion rgn); /* 115 */ + int (*tkIntersectRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 116 */ + int (*tkRectInRegion) (TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */ + int (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */ + int (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion dr_return); /* 119 */ + void (*reserved120)(void); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved121)(void); +#endif /* X11 */ +#if defined(_WIN32) /* WIN */ + void (*reserved121)(void); +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ + void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */ + Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */ +#endif /* AQUA */ +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved122)(void); +#endif /* X11 */ +#if defined(_WIN32) /* WIN */ + void (*reserved122)(void); +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ + void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */ + void (*tkpDefineNativeBitmaps) (void); /* 122 */ +#endif /* AQUA */ + void (*reserved123)(void); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved124)(void); +#endif /* X11 */ +#if defined(_WIN32) /* WIN */ + void (*reserved124)(void); +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ + void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */ + Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */ +#endif /* AQUA */ + void (*reserved125)(void); + void (*reserved126)(void); + void (*reserved127)(void); + void (*reserved128)(void); + void (*reserved129)(void); + void (*reserved130)(void); + void (*reserved131)(void); + void (*reserved132)(void); + void (*reserved133)(void); + void (*reserved134)(void); + void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */ + void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */ + void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */ + KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */ + void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */ + TkRegion (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */ + TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */ + void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */ + void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */ + void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */ + int (*tkSubtractRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 145 */ + void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */ + void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */ + Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */ + const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */ + int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */ + void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */ + void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */ + void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */ + void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */ + void (*reserved155)(void); + int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */ + int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */ + int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */ + int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */ + int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */ + int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */ + struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */ + int (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */ + struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */ + int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */ + void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */ + int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */ + void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */ + int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */ + CONST86 char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */ + int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 171 */ + CONST86 char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */ + int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 173 */ + CONST86 char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */ + int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 175 */ + CONST86 char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */ + int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 177 */ + CONST86 char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */ + int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 179 */ + CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */ + void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */ + void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */ + int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */ + void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */ +#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */ + void (*reserved185)(void); +#endif /* UNIX */ +#if defined(_WIN32) /* WIN */ + void (*reserved185)(void); +#endif /* WIN */ +#ifdef MAC_OSX_TCL /* MACOSX */ + void (*tkpRedrawWidget) (Tk_Window tkwin); /* 185 */ +#endif /* MACOSX */ +#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */ + void (*reserved186)(void); +#endif /* UNIX */ +#if defined(_WIN32) /* WIN */ + void (*reserved186)(void); +#endif /* WIN */ +#ifdef MAC_OSX_TCL /* MACOSX */ + int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */ +#endif /* MACOSX */ + void (*tkUnusedStubEntry) (void); /* 187 */ +} TkIntStubs; + +extern const TkIntStubs *tkIntStubsPtr; + +#ifdef __cplusplus +} +#endif + +#if defined(USE_TK_STUBS) + +/* + * Inline function declarations: + */ + +#define TkAllocWindow \ + (tkIntStubsPtr->tkAllocWindow) /* 0 */ +#define TkBezierPoints \ + (tkIntStubsPtr->tkBezierPoints) /* 1 */ +#define TkBezierScreenPoints \ + (tkIntStubsPtr->tkBezierScreenPoints) /* 2 */ +/* Slot 3 is reserved */ +#define TkBindEventProc \ + (tkIntStubsPtr->tkBindEventProc) /* 4 */ +#define TkBindFree \ + (tkIntStubsPtr->tkBindFree) /* 5 */ +#define TkBindInit \ + (tkIntStubsPtr->tkBindInit) /* 6 */ +#define TkChangeEventWindow \ + (tkIntStubsPtr->tkChangeEventWindow) /* 7 */ +#define TkClipInit \ + (tkIntStubsPtr->tkClipInit) /* 8 */ +#define TkComputeAnchor \ + (tkIntStubsPtr->tkComputeAnchor) /* 9 */ +/* Slot 10 is reserved */ +/* Slot 11 is reserved */ +#define TkCreateCursorFromData \ + (tkIntStubsPtr->tkCreateCursorFromData) /* 12 */ +#define TkCreateFrame \ + (tkIntStubsPtr->tkCreateFrame) /* 13 */ +#define TkCreateMainWindow \ + (tkIntStubsPtr->tkCreateMainWindow) /* 14 */ +#define TkCurrentTime \ + (tkIntStubsPtr->tkCurrentTime) /* 15 */ +#define TkDeleteAllImages \ + (tkIntStubsPtr->tkDeleteAllImages) /* 16 */ +#define TkDoConfigureNotify \ + (tkIntStubsPtr->tkDoConfigureNotify) /* 17 */ +#define TkDrawInsetFocusHighlight \ + (tkIntStubsPtr->tkDrawInsetFocusHighlight) /* 18 */ +#define TkEventDeadWindow \ + (tkIntStubsPtr->tkEventDeadWindow) /* 19 */ +#define TkFillPolygon \ + (tkIntStubsPtr->tkFillPolygon) /* 20 */ +#define TkFindStateNum \ + (tkIntStubsPtr->tkFindStateNum) /* 21 */ +#define TkFindStateString \ + (tkIntStubsPtr->tkFindStateString) /* 22 */ +#define TkFocusDeadWindow \ + (tkIntStubsPtr->tkFocusDeadWindow) /* 23 */ +#define TkFocusFilterEvent \ + (tkIntStubsPtr->tkFocusFilterEvent) /* 24 */ +#define TkFocusKeyEvent \ + (tkIntStubsPtr->tkFocusKeyEvent) /* 25 */ +#define TkFontPkgInit \ + (tkIntStubsPtr->tkFontPkgInit) /* 26 */ +#define TkFontPkgFree \ + (tkIntStubsPtr->tkFontPkgFree) /* 27 */ +#define TkFreeBindingTags \ + (tkIntStubsPtr->tkFreeBindingTags) /* 28 */ +#define TkpFreeCursor \ + (tkIntStubsPtr->tkpFreeCursor) /* 29 */ +#define TkGetBitmapData \ + (tkIntStubsPtr->tkGetBitmapData) /* 30 */ +#define TkGetButtPoints \ + (tkIntStubsPtr->tkGetButtPoints) /* 31 */ +#define TkGetCursorByName \ + (tkIntStubsPtr->tkGetCursorByName) /* 32 */ +#define TkGetDefaultScreenName \ + (tkIntStubsPtr->tkGetDefaultScreenName) /* 33 */ +#define TkGetDisplay \ + (tkIntStubsPtr->tkGetDisplay) /* 34 */ +#define TkGetDisplayOf \ + (tkIntStubsPtr->tkGetDisplayOf) /* 35 */ +#define TkGetFocusWin \ + (tkIntStubsPtr->tkGetFocusWin) /* 36 */ +#define TkGetInterpNames \ + (tkIntStubsPtr->tkGetInterpNames) /* 37 */ +#define TkGetMiterPoints \ + (tkIntStubsPtr->tkGetMiterPoints) /* 38 */ +#define TkGetPointerCoords \ + (tkIntStubsPtr->tkGetPointerCoords) /* 39 */ +#define TkGetServerInfo \ + (tkIntStubsPtr->tkGetServerInfo) /* 40 */ +#define TkGrabDeadWindow \ + (tkIntStubsPtr->tkGrabDeadWindow) /* 41 */ +#define TkGrabState \ + (tkIntStubsPtr->tkGrabState) /* 42 */ +#define TkIncludePoint \ + (tkIntStubsPtr->tkIncludePoint) /* 43 */ +#define TkInOutEvents \ + (tkIntStubsPtr->tkInOutEvents) /* 44 */ +#define TkInstallFrameMenu \ + (tkIntStubsPtr->tkInstallFrameMenu) /* 45 */ +#define TkKeysymToString \ + (tkIntStubsPtr->tkKeysymToString) /* 46 */ +#define TkLineToArea \ + (tkIntStubsPtr->tkLineToArea) /* 47 */ +#define TkLineToPoint \ + (tkIntStubsPtr->tkLineToPoint) /* 48 */ +#define TkMakeBezierCurve \ + (tkIntStubsPtr->tkMakeBezierCurve) /* 49 */ +#define TkMakeBezierPostscript \ + (tkIntStubsPtr->tkMakeBezierPostscript) /* 50 */ +#define TkOptionClassChanged \ + (tkIntStubsPtr->tkOptionClassChanged) /* 51 */ +#define TkOptionDeadWindow \ + (tkIntStubsPtr->tkOptionDeadWindow) /* 52 */ +#define TkOvalToArea \ + (tkIntStubsPtr->tkOvalToArea) /* 53 */ +#define TkOvalToPoint \ + (tkIntStubsPtr->tkOvalToPoint) /* 54 */ +#define TkpChangeFocus \ + (tkIntStubsPtr->tkpChangeFocus) /* 55 */ +#define TkpCloseDisplay \ + (tkIntStubsPtr->tkpCloseDisplay) /* 56 */ +#define TkpClaimFocus \ + (tkIntStubsPtr->tkpClaimFocus) /* 57 */ +#define TkpDisplayWarning \ + (tkIntStubsPtr->tkpDisplayWarning) /* 58 */ +#define TkpGetAppName \ + (tkIntStubsPtr->tkpGetAppName) /* 59 */ +#define TkpGetOtherWindow \ + (tkIntStubsPtr->tkpGetOtherWindow) /* 60 */ +#define TkpGetWrapperWindow \ + (tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */ +#define TkpInit \ + (tkIntStubsPtr->tkpInit) /* 62 */ +#define TkpInitializeMenuBindings \ + (tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */ +#define TkpMakeContainer \ + (tkIntStubsPtr->tkpMakeContainer) /* 64 */ +#define TkpMakeMenuWindow \ + (tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */ +#define TkpMakeWindow \ + (tkIntStubsPtr->tkpMakeWindow) /* 66 */ +#define TkpMenuNotifyToplevelCreate \ + (tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */ +#define TkpOpenDisplay \ + (tkIntStubsPtr->tkpOpenDisplay) /* 68 */ +#define TkPointerEvent \ + (tkIntStubsPtr->tkPointerEvent) /* 69 */ +#define TkPolygonToArea \ + (tkIntStubsPtr->tkPolygonToArea) /* 70 */ +#define TkPolygonToPoint \ + (tkIntStubsPtr->tkPolygonToPoint) /* 71 */ +#define TkPositionInTree \ + (tkIntStubsPtr->tkPositionInTree) /* 72 */ +#define TkpRedirectKeyEvent \ + (tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */ +#define TkpSetMainMenubar \ + (tkIntStubsPtr->tkpSetMainMenubar) /* 74 */ +#define TkpUseWindow \ + (tkIntStubsPtr->tkpUseWindow) /* 75 */ +/* Slot 76 is reserved */ +#define TkQueueEventForAllChildren \ + (tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */ +#define TkReadBitmapFile \ + (tkIntStubsPtr->tkReadBitmapFile) /* 78 */ +#define TkScrollWindow \ + (tkIntStubsPtr->tkScrollWindow) /* 79 */ +#define TkSelDeadWindow \ + (tkIntStubsPtr->tkSelDeadWindow) /* 80 */ +#define TkSelEventProc \ + (tkIntStubsPtr->tkSelEventProc) /* 81 */ +#define TkSelInit \ + (tkIntStubsPtr->tkSelInit) /* 82 */ +#define TkSelPropProc \ + (tkIntStubsPtr->tkSelPropProc) /* 83 */ +/* Slot 84 is reserved */ +#define TkSetWindowMenuBar \ + (tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */ +#define TkStringToKeysym \ + (tkIntStubsPtr->tkStringToKeysym) /* 86 */ +#define TkThickPolyLineToArea \ + (tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */ +#define TkWmAddToColormapWindows \ + (tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */ +#define TkWmDeadWindow \ + (tkIntStubsPtr->tkWmDeadWindow) /* 89 */ +#define TkWmFocusToplevel \ + (tkIntStubsPtr->tkWmFocusToplevel) /* 90 */ +#define TkWmMapWindow \ + (tkIntStubsPtr->tkWmMapWindow) /* 91 */ +#define TkWmNewWindow \ + (tkIntStubsPtr->tkWmNewWindow) /* 92 */ +#define TkWmProtocolEventProc \ + (tkIntStubsPtr->tkWmProtocolEventProc) /* 93 */ +#define TkWmRemoveFromColormapWindows \ + (tkIntStubsPtr->tkWmRemoveFromColormapWindows) /* 94 */ +#define TkWmRestackToplevel \ + (tkIntStubsPtr->tkWmRestackToplevel) /* 95 */ +#define TkWmSetClass \ + (tkIntStubsPtr->tkWmSetClass) /* 96 */ +#define TkWmUnmapWindow \ + (tkIntStubsPtr->tkWmUnmapWindow) /* 97 */ +#define TkDebugBitmap \ + (tkIntStubsPtr->tkDebugBitmap) /* 98 */ +#define TkDebugBorder \ + (tkIntStubsPtr->tkDebugBorder) /* 99 */ +#define TkDebugCursor \ + (tkIntStubsPtr->tkDebugCursor) /* 100 */ +#define TkDebugColor \ + (tkIntStubsPtr->tkDebugColor) /* 101 */ +#define TkDebugConfig \ + (tkIntStubsPtr->tkDebugConfig) /* 102 */ +#define TkDebugFont \ + (tkIntStubsPtr->tkDebugFont) /* 103 */ +#define TkFindStateNumObj \ + (tkIntStubsPtr->tkFindStateNumObj) /* 104 */ +#define TkGetBitmapPredefTable \ + (tkIntStubsPtr->tkGetBitmapPredefTable) /* 105 */ +#define TkGetDisplayList \ + (tkIntStubsPtr->tkGetDisplayList) /* 106 */ +#define TkGetMainInfoList \ + (tkIntStubsPtr->tkGetMainInfoList) /* 107 */ +#define TkGetWindowFromObj \ + (tkIntStubsPtr->tkGetWindowFromObj) /* 108 */ +#define TkpGetString \ + (tkIntStubsPtr->tkpGetString) /* 109 */ +#define TkpGetSubFonts \ + (tkIntStubsPtr->tkpGetSubFonts) /* 110 */ +#define TkpGetSystemDefault \ + (tkIntStubsPtr->tkpGetSystemDefault) /* 111 */ +#define TkpMenuThreadInit \ + (tkIntStubsPtr->tkpMenuThreadInit) /* 112 */ +#define TkClipBox \ + (tkIntStubsPtr->tkClipBox) /* 113 */ +#define TkCreateRegion \ + (tkIntStubsPtr->tkCreateRegion) /* 114 */ +#define TkDestroyRegion \ + (tkIntStubsPtr->tkDestroyRegion) /* 115 */ +#define TkIntersectRegion \ + (tkIntStubsPtr->tkIntersectRegion) /* 116 */ +#define TkRectInRegion \ + (tkIntStubsPtr->tkRectInRegion) /* 117 */ +#define TkSetRegion \ + (tkIntStubsPtr->tkSetRegion) /* 118 */ +#define TkUnionRectWithRegion \ + (tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */ +/* Slot 120 is reserved */ +#ifdef MAC_OSX_TK /* AQUA */ +#define TkpCreateNativeBitmap \ + (tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */ +#endif /* AQUA */ +#ifdef MAC_OSX_TK /* AQUA */ +#define TkpDefineNativeBitmaps \ + (tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */ +#endif /* AQUA */ +/* Slot 123 is reserved */ +#ifdef MAC_OSX_TK /* AQUA */ +#define TkpGetNativeAppBitmap \ + (tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */ +#endif /* AQUA */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +/* Slot 129 is reserved */ +/* Slot 130 is reserved */ +/* Slot 131 is reserved */ +/* Slot 132 is reserved */ +/* Slot 133 is reserved */ +/* Slot 134 is reserved */ +#define TkpDrawHighlightBorder \ + (tkIntStubsPtr->tkpDrawHighlightBorder) /* 135 */ +#define TkSetFocusWin \ + (tkIntStubsPtr->tkSetFocusWin) /* 136 */ +#define TkpSetKeycodeAndState \ + (tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */ +#define TkpGetKeySym \ + (tkIntStubsPtr->tkpGetKeySym) /* 138 */ +#define TkpInitKeymapInfo \ + (tkIntStubsPtr->tkpInitKeymapInfo) /* 139 */ +#define TkPhotoGetValidRegion \ + (tkIntStubsPtr->tkPhotoGetValidRegion) /* 140 */ +#define TkWmStackorderToplevel \ + (tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */ +#define TkFocusFree \ + (tkIntStubsPtr->tkFocusFree) /* 142 */ +#define TkClipCleanup \ + (tkIntStubsPtr->tkClipCleanup) /* 143 */ +#define TkGCCleanup \ + (tkIntStubsPtr->tkGCCleanup) /* 144 */ +#define TkSubtractRegion \ + (tkIntStubsPtr->tkSubtractRegion) /* 145 */ +#define TkStylePkgInit \ + (tkIntStubsPtr->tkStylePkgInit) /* 146 */ +#define TkStylePkgFree \ + (tkIntStubsPtr->tkStylePkgFree) /* 147 */ +#define TkToplevelWindowForCommand \ + (tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */ +#define TkGetOptionSpec \ + (tkIntStubsPtr->tkGetOptionSpec) /* 149 */ +#define TkMakeRawCurve \ + (tkIntStubsPtr->tkMakeRawCurve) /* 150 */ +#define TkMakeRawCurvePostscript \ + (tkIntStubsPtr->tkMakeRawCurvePostscript) /* 151 */ +#define TkpDrawFrame \ + (tkIntStubsPtr->tkpDrawFrame) /* 152 */ +#define TkCreateThreadExitHandler \ + (tkIntStubsPtr->tkCreateThreadExitHandler) /* 153 */ +#define TkDeleteThreadExitHandler \ + (tkIntStubsPtr->tkDeleteThreadExitHandler) /* 154 */ +/* Slot 155 is reserved */ +#define TkpTestembedCmd \ + (tkIntStubsPtr->tkpTestembedCmd) /* 156 */ +#define TkpTesttextCmd \ + (tkIntStubsPtr->tkpTesttextCmd) /* 157 */ +#define TkSelGetSelection \ + (tkIntStubsPtr->tkSelGetSelection) /* 158 */ +#define TkTextGetIndex \ + (tkIntStubsPtr->tkTextGetIndex) /* 159 */ +#define TkTextIndexBackBytes \ + (tkIntStubsPtr->tkTextIndexBackBytes) /* 160 */ +#define TkTextIndexForwBytes \ + (tkIntStubsPtr->tkTextIndexForwBytes) /* 161 */ +#define TkTextMakeByteIndex \ + (tkIntStubsPtr->tkTextMakeByteIndex) /* 162 */ +#define TkTextPrintIndex \ + (tkIntStubsPtr->tkTextPrintIndex) /* 163 */ +#define TkTextSetMark \ + (tkIntStubsPtr->tkTextSetMark) /* 164 */ +#define TkTextXviewCmd \ + (tkIntStubsPtr->tkTextXviewCmd) /* 165 */ +#define TkTextChanged \ + (tkIntStubsPtr->tkTextChanged) /* 166 */ +#define TkBTreeNumLines \ + (tkIntStubsPtr->tkBTreeNumLines) /* 167 */ +#define TkTextInsertDisplayProc \ + (tkIntStubsPtr->tkTextInsertDisplayProc) /* 168 */ +#define TkStateParseProc \ + (tkIntStubsPtr->tkStateParseProc) /* 169 */ +#define TkStatePrintProc \ + (tkIntStubsPtr->tkStatePrintProc) /* 170 */ +#define TkCanvasDashParseProc \ + (tkIntStubsPtr->tkCanvasDashParseProc) /* 171 */ +#define TkCanvasDashPrintProc \ + (tkIntStubsPtr->tkCanvasDashPrintProc) /* 172 */ +#define TkOffsetParseProc \ + (tkIntStubsPtr->tkOffsetParseProc) /* 173 */ +#define TkOffsetPrintProc \ + (tkIntStubsPtr->tkOffsetPrintProc) /* 174 */ +#define TkPixelParseProc \ + (tkIntStubsPtr->tkPixelParseProc) /* 175 */ +#define TkPixelPrintProc \ + (tkIntStubsPtr->tkPixelPrintProc) /* 176 */ +#define TkOrientParseProc \ + (tkIntStubsPtr->tkOrientParseProc) /* 177 */ +#define TkOrientPrintProc \ + (tkIntStubsPtr->tkOrientPrintProc) /* 178 */ +#define TkSmoothParseProc \ + (tkIntStubsPtr->tkSmoothParseProc) /* 179 */ +#define TkSmoothPrintProc \ + (tkIntStubsPtr->tkSmoothPrintProc) /* 180 */ +#define TkDrawAngledTextLayout \ + (tkIntStubsPtr->tkDrawAngledTextLayout) /* 181 */ +#define TkUnderlineAngledTextLayout \ + (tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */ +#define TkIntersectAngledTextLayout \ + (tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */ +#define TkDrawAngledChars \ + (tkIntStubsPtr->tkDrawAngledChars) /* 184 */ +#ifdef MAC_OSX_TCL /* MACOSX */ +#define TkpRedrawWidget \ + (tkIntStubsPtr->tkpRedrawWidget) /* 185 */ +#endif /* MACOSX */ +#ifdef MAC_OSX_TCL /* MACOSX */ +#define TkpWillDrawWidget \ + (tkIntStubsPtr->tkpWillDrawWidget) /* 186 */ +#endif /* MACOSX */ +#define TkUnusedStubEntry \ + (tkIntStubsPtr->tkUnusedStubEntry) /* 187 */ + +#endif /* defined(USE_TK_STUBS) */ + +/* !END!: Do not edit above this line. */ + +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLIMPORT + +/* + * On X11, these macros are just wrappers for the equivalent X Region calls. + */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ + +#undef TkClipBox +#undef TkCreateRegion +#undef TkDestroyRegion +#undef TkIntersectRegion +#undef TkRectInRegion +#undef TkSetRegion +#undef TkSubtractRegion +#undef TkUnionRectWithRegion +#undef TkpCmapStressed_ +#undef TkpSync_ +#undef TkUnixContainerId_ +#undef TkUnixDoOneXEvent_ +#undef TkUnixSetMenubar_ +#undef TkWmCleanup_ +#undef TkSendCleanup_ +#undef TkpTestsendCmd_ + +#define TkClipBox(rgn, rect) XClipBox((Region) rgn, rect) +#define TkCreateRegion() (TkRegion) XCreateRegion() +#define TkDestroyRegion(rgn) XDestroyRegion((Region) rgn) +#define TkIntersectRegion(a, b, r) XIntersectRegion((Region) a, \ + (Region) b, (Region) r) +#define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) r, x, y, w, h) +#define TkSetRegion(d, gc, rgn) XSetRegion(d, gc, (Region) rgn) +#define TkSubtractRegion(a, b, r) XSubtractRegion((Region) a, \ + (Region) b, (Region) r) +#define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion(rect, \ + (Region) src, (Region) ret) + +#endif /* UNIX */ + +#if !defined(MAC_OSX_TK) +# undef TkpWillDrawWidget +# undef TkpRedrawWidget +# define TkpWillDrawWidget(w) 0 +# define TkpRedrawWidget(w) +#endif + +#undef TkUnusedStubEntry + +#endif /* _TKINTDECLS */ + diff --git a/src/libdm/wgl/wintk/tkIntPlatDecls.h b/src/libdm/wgl/wintk/tkIntPlatDecls.h new file mode 100644 index 00000000000..e9b3a6548d2 --- /dev/null +++ b/src/libdm/wgl/wintk/tkIntPlatDecls.h @@ -0,0 +1,802 @@ +/* + * tkIntPlatDecls.h -- + * + * This file contains the declarations for all platform dependent + * unsupported functions that are exported by the Tk library. These + * interfaces are not guaranteed to remain the same between + * versions. Use at your own risk. + * + * Copyright (c) 1998-1999 by Scriptics Corporation. + * All rights reserved. + */ + +#ifndef _TKINTPLATDECLS +#define _TKINTPLATDECLS + +#ifdef BUILD_tk +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT +#endif + +/* + * WARNING: This file is automatically generated by the tools/genStubs.tcl + * script. Any modifications to the function declarations below should be made + * in the generic/tkInt.decls script. + */ + +/* !BEGIN!: Do not edit below this line. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Exported function declarations: + */ + +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ +/* 0 */ +EXTERN char * TkAlignImageData(XImage *image, int alignment, + int bitOrder); +/* Slot 1 is reserved */ +/* 2 */ +EXTERN void TkGenerateActivateEvents(TkWindow *winPtr, + int active); +/* 3 */ +EXTERN unsigned long TkpGetMS(void); +/* 4 */ +EXTERN void TkPointerDeadWindow(TkWindow *winPtr); +/* 5 */ +EXTERN void TkpPrintWindowId(char *buf, Window window); +/* 6 */ +EXTERN int TkpScanWindowId(Tcl_Interp *interp, + const char *string, Window *idPtr); +/* 7 */ +EXTERN void TkpSetCapture(TkWindow *winPtr); +/* 8 */ +EXTERN void TkpSetCursor(TkpCursor cursor); +/* 9 */ +EXTERN int TkpWmSetState(TkWindow *winPtr, int state); +/* 10 */ +EXTERN void TkSetPixmapColormap(Pixmap pixmap, Colormap colormap); +/* 11 */ +EXTERN void TkWinCancelMouseTimer(void); +/* 12 */ +EXTERN void TkWinClipboardRender(TkDisplay *dispPtr, UINT format); +/* 13 */ +EXTERN LRESULT TkWinEmbeddedEventProc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +/* 14 */ +EXTERN void TkWinFillRect(HDC dc, int x, int y, int width, + int height, int pixel); +/* 15 */ +EXTERN COLORREF TkWinGetBorderPixels(Tk_Window tkwin, + Tk_3DBorder border, int which); +/* 16 */ +EXTERN HDC TkWinGetDrawableDC(Display *display, Drawable d, + TkWinDCState *state); +/* 17 */ +EXTERN int TkWinGetModifierState(void); +/* 18 */ +EXTERN HPALETTE TkWinGetSystemPalette(void); +/* 19 */ +EXTERN HWND TkWinGetWrapperWindow(Tk_Window tkwin); +/* 20 */ +EXTERN int TkWinHandleMenuEvent(HWND *phwnd, UINT *pMessage, + WPARAM *pwParam, LPARAM *plParam, + LRESULT *plResult); +/* 21 */ +EXTERN int TkWinIndexOfColor(XColor *colorPtr); +/* 22 */ +EXTERN void TkWinReleaseDrawableDC(Drawable d, HDC hdc, + TkWinDCState *state); +/* 23 */ +EXTERN LRESULT TkWinResendEvent(WNDPROC wndproc, HWND hwnd, + XEvent *eventPtr); +/* 24 */ +EXTERN HPALETTE TkWinSelectPalette(HDC dc, Colormap colormap); +/* 25 */ +EXTERN void TkWinSetMenu(Tk_Window tkwin, HMENU hMenu); +/* 26 */ +EXTERN void TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd, + int pos); +/* 27 */ +EXTERN void TkWinWmCleanup(HINSTANCE hInstance); +/* 28 */ +EXTERN void TkWinXCleanup(ClientData clientData); +/* 29 */ +EXTERN void TkWinXInit(HINSTANCE hInstance); +/* 30 */ +EXTERN void TkWinSetForegroundWindow(TkWindow *winPtr); +/* 31 */ +EXTERN void TkWinDialogDebug(int debug); +/* 32 */ +EXTERN Tcl_Obj * TkWinGetMenuSystemDefault(Tk_Window tkwin, + const char *dbName, const char *className); +/* 33 */ +EXTERN int TkWinGetPlatformId(void); +/* 34 */ +EXTERN void TkWinSetHINSTANCE(HINSTANCE hInstance); +/* 35 */ +EXTERN int TkWinGetPlatformTheme(void); +/* 36 */ +EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +/* 37 */ +EXTERN void TkCreateXEventSource(void); +/* 38 */ +EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap); +/* 39 */ +EXTERN void TkpSync(Display *display); +/* 40 */ +EXTERN Window TkUnixContainerId(TkWindow *winPtr); +/* 41 */ +EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr); +/* 42 */ +EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar); +/* 43 */ +EXTERN void TkWmCleanup(TkDisplay *dispPtr); +/* 44 */ +EXTERN void TkSendCleanup(TkDisplay *dispPtr); +/* 45 */ +EXTERN int TkpTestsendCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +/* Slot 46 is reserved */ +/* 47 */ +EXTERN Tk_Window TkpGetCapture(void); +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ +/* 0 */ +EXTERN void TkGenerateActivateEvents(TkWindow *winPtr, + int active); +/* Slot 1 is reserved */ +/* 2 */ +EXTERN void TkGenerateActivateEvents_(TkWindow *winPtr, + int active); +/* 3 */ +EXTERN void TkPointerDeadWindow(TkWindow *winPtr); +/* 4 */ +EXTERN void TkpSetCapture(TkWindow *winPtr); +/* 5 */ +EXTERN void TkpSetCursor(TkpCursor cursor); +/* 6 */ +EXTERN void TkpWmSetState(TkWindow *winPtr, int state); +/* 7 */ +EXTERN void TkAboutDlg(void); +/* 8 */ +EXTERN unsigned int TkMacOSXButtonKeyState(void); +/* 9 */ +EXTERN void TkMacOSXClearMenubarActive(void); +/* 10 */ +EXTERN int TkMacOSXDispatchMenuEvent(int menuID, int index); +/* 11 */ +EXTERN void TkMacOSXInstallCursor(int resizeOverride); +/* 12 */ +EXTERN void TkMacOSXHandleTearoffMenu(void); +/* Slot 13 is reserved */ +/* 14 */ +EXTERN int TkMacOSXDoHLEvent(void *theEvent); +/* Slot 15 is reserved */ +/* 16 */ +EXTERN Window TkMacOSXGetXWindow(void *macWinPtr); +/* 17 */ +EXTERN int TkMacOSXGrowToplevel(void *whichWindow, XPoint start); +/* 18 */ +EXTERN void TkMacOSXHandleMenuSelect(short theMenu, + unsigned short theItem, int optionKeyPressed); +/* Slot 19 is reserved */ +/* Slot 20 is reserved */ +/* 21 */ +EXTERN void TkMacOSXInvalidateWindow(MacDrawable *macWin, + int flag); +/* 22 */ +EXTERN int TkMacOSXIsCharacterMissing(Tk_Font tkfont, + unsigned int searchChar); +/* 23 */ +EXTERN void TkMacOSXMakeRealWindowExist(TkWindow *winPtr); +/* 24 */ +EXTERN void * TkMacOSXMakeStippleMap(Drawable d1, Drawable d2); +/* 25 */ +EXTERN void TkMacOSXMenuClick(void); +/* Slot 26 is reserved */ +/* 27 */ +EXTERN int TkMacOSXResizable(TkWindow *winPtr); +/* 28 */ +EXTERN void TkMacOSXSetHelpMenuItemCount(void); +/* 29 */ +EXTERN void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag); +/* 30 */ +EXTERN void TkMacOSXSetUpClippingRgn(Drawable drawable); +/* 31 */ +EXTERN void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort); +/* 32 */ +EXTERN void TkMacOSXUpdateClipRgn(TkWindow *winPtr); +/* Slot 33 is reserved */ +/* 34 */ +EXTERN int TkMacOSXUseMenuID(short macID); +/* 35 */ +EXTERN TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr); +/* 36 */ +EXTERN void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry); +/* 37 */ +EXTERN void TkMacOSXWindowOffset(void *wRef, int *xOffset, + int *yOffset); +/* 38 */ +EXTERN int TkSetMacColor(unsigned long pixel, void *macColor); +/* 39 */ +EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid); +/* Slot 40 is reserved */ +/* 41 */ +EXTERN int TkMacOSXZoomToplevel(void *whichWindow, + short zoomPart); +/* 42 */ +EXTERN Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, + int rootY, int *newX, int *newY); +/* 43 */ +EXTERN MacDrawable * TkMacOSXContainerId(TkWindow *winPtr); +/* 44 */ +EXTERN MacDrawable * TkMacOSXGetHostToplevel(TkWindow *winPtr); +/* 45 */ +EXTERN void TkMacOSXPreprocessMenu(void); +/* 46 */ +EXTERN int TkpIsWindowFloating(void *window); +/* 47 */ +EXTERN Tk_Window TkMacOSXGetCapture(void); +/* Slot 48 is reserved */ +/* 49 */ +EXTERN Tk_Window TkGetTransientMaster(TkWindow *winPtr); +/* 50 */ +EXTERN int TkGenerateButtonEvent(int x, int y, Window window, + unsigned int state); +/* 51 */ +EXTERN void TkGenWMDestroyEvent(Tk_Window tkwin); +/* 52 */ +EXTERN void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag); +/* 53 */ +EXTERN unsigned long TkpGetMS(void); +/* 54 */ +EXTERN void * TkMacOSXDrawable(Drawable drawable); +/* 55 */ +EXTERN int TkpScanWindowId(Tcl_Interp *interp, + const char *string, Window *idPtr); +#endif /* AQUA */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ +/* 0 */ +EXTERN void TkCreateXEventSource(void); +/* Slot 1 is reserved */ +/* 2 */ +EXTERN void TkGenerateActivateEvents(TkWindow *winPtr, + int active); +/* 3 */ +EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap); +/* 4 */ +EXTERN void TkpSync(Display *display); +/* 5 */ +EXTERN Window TkUnixContainerId(TkWindow *winPtr); +/* 6 */ +EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr); +/* 7 */ +EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar); +/* 8 */ +EXTERN int TkpScanWindowId(Tcl_Interp *interp, + const char *string, Window *idPtr); +/* 9 */ +EXTERN void TkWmCleanup(TkDisplay *dispPtr); +/* 10 */ +EXTERN void TkSendCleanup(TkDisplay *dispPtr); +/* Slot 11 is reserved */ +/* 12 */ +EXTERN int TkpWmSetState(TkWindow *winPtr, int state); +/* 13 */ +EXTERN int TkpTestsendCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +/* Slot 14 is reserved */ +/* Slot 15 is reserved */ +/* Slot 16 is reserved */ +/* Slot 17 is reserved */ +/* Slot 18 is reserved */ +/* Slot 19 is reserved */ +/* Slot 20 is reserved */ +/* Slot 21 is reserved */ +/* Slot 22 is reserved */ +/* Slot 23 is reserved */ +/* Slot 24 is reserved */ +/* Slot 25 is reserved */ +/* Slot 26 is reserved */ +/* Slot 27 is reserved */ +/* Slot 28 is reserved */ +/* Slot 29 is reserved */ +/* Slot 30 is reserved */ +/* Slot 31 is reserved */ +/* Slot 32 is reserved */ +/* Slot 33 is reserved */ +/* Slot 34 is reserved */ +/* Slot 35 is reserved */ +/* Slot 36 is reserved */ +/* Slot 37 is reserved */ +/* 38 */ +EXTERN int TkpCmapStressed_(Tk_Window tkwin, Colormap colormap); +/* 39 */ +EXTERN void TkpSync_(Display *display); +/* 40 */ +EXTERN Window TkUnixContainerId_(TkWindow *winPtr); +/* 41 */ +EXTERN int TkUnixDoOneXEvent_(Tcl_Time *timePtr); +/* 42 */ +EXTERN void TkUnixSetMenubar_(Tk_Window tkwin, Tk_Window menubar); +/* 43 */ +EXTERN void TkWmCleanup_(TkDisplay *dispPtr); +/* 44 */ +EXTERN void TkSendCleanup_(TkDisplay *dispPtr); +/* 45 */ +EXTERN int TkpTestsendCmd_(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +#endif /* X11 */ + +typedef struct TkIntPlatStubs { + int magic; + void *hooks; + +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ + char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */ + void (*reserved1)(void); + void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */ + unsigned long (*tkpGetMS) (void); /* 3 */ + void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */ + void (*tkpPrintWindowId) (char *buf, Window window); /* 5 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */ + void (*tkpSetCapture) (TkWindow *winPtr); /* 7 */ + void (*tkpSetCursor) (TkpCursor cursor); /* 8 */ + int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 9 */ + void (*tkSetPixmapColormap) (Pixmap pixmap, Colormap colormap); /* 10 */ + void (*tkWinCancelMouseTimer) (void); /* 11 */ + void (*tkWinClipboardRender) (TkDisplay *dispPtr, UINT format); /* 12 */ + LRESULT (*tkWinEmbeddedEventProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 13 */ + void (*tkWinFillRect) (HDC dc, int x, int y, int width, int height, int pixel); /* 14 */ + COLORREF (*tkWinGetBorderPixels) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 15 */ + HDC (*tkWinGetDrawableDC) (Display *display, Drawable d, TkWinDCState *state); /* 16 */ + int (*tkWinGetModifierState) (void); /* 17 */ + HPALETTE (*tkWinGetSystemPalette) (void); /* 18 */ + HWND (*tkWinGetWrapperWindow) (Tk_Window tkwin); /* 19 */ + int (*tkWinHandleMenuEvent) (HWND *phwnd, UINT *pMessage, WPARAM *pwParam, LPARAM *plParam, LRESULT *plResult); /* 20 */ + int (*tkWinIndexOfColor) (XColor *colorPtr); /* 21 */ + void (*tkWinReleaseDrawableDC) (Drawable d, HDC hdc, TkWinDCState *state); /* 22 */ + LRESULT (*tkWinResendEvent) (WNDPROC wndproc, HWND hwnd, XEvent *eventPtr); /* 23 */ + HPALETTE (*tkWinSelectPalette) (HDC dc, Colormap colormap); /* 24 */ + void (*tkWinSetMenu) (Tk_Window tkwin, HMENU hMenu); /* 25 */ + void (*tkWinSetWindowPos) (HWND hwnd, HWND siblingHwnd, int pos); /* 26 */ + void (*tkWinWmCleanup) (HINSTANCE hInstance); /* 27 */ + void (*tkWinXCleanup) (ClientData clientData); /* 28 */ + void (*tkWinXInit) (HINSTANCE hInstance); /* 29 */ + void (*tkWinSetForegroundWindow) (TkWindow *winPtr); /* 30 */ + void (*tkWinDialogDebug) (int debug); /* 31 */ + Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 32 */ + int (*tkWinGetPlatformId) (void); /* 33 */ + void (*tkWinSetHINSTANCE) (HINSTANCE hInstance); /* 34 */ + int (*tkWinGetPlatformTheme) (void); /* 35 */ + LRESULT (__stdcall *tkWinChildProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 36 */ + void (*tkCreateXEventSource) (void); /* 37 */ + int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 38 */ + void (*tkpSync) (Display *display); /* 39 */ + Window (*tkUnixContainerId) (TkWindow *winPtr); /* 40 */ + int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 41 */ + void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */ + void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */ + void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */ + int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */ + void (*reserved46)(void); + Tk_Window (*tkpGetCapture) (void); /* 47 */ +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ + void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */ + void (*reserved1)(void); + void (*tkGenerateActivateEvents_) (TkWindow *winPtr, int active); /* 2 */ + void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 3 */ + void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */ + void (*tkpSetCursor) (TkpCursor cursor); /* 5 */ + void (*tkpWmSetState) (TkWindow *winPtr, int state); /* 6 */ + void (*tkAboutDlg) (void); /* 7 */ + unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */ + void (*tkMacOSXClearMenubarActive) (void); /* 9 */ + int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */ + void (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */ + void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */ + void (*reserved13)(void); + int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */ + void (*reserved15)(void); + Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */ + int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */ + void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */ + void (*reserved19)(void); + void (*reserved20)(void); + void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */ + int (*tkMacOSXIsCharacterMissing) (Tk_Font tkfont, unsigned int searchChar); /* 22 */ + void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */ + void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */ + void (*tkMacOSXMenuClick) (void); /* 25 */ + void (*reserved26)(void); + int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */ + void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */ + void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */ + void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */ + void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */ + void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */ + void (*reserved33)(void); + int (*tkMacOSXUseMenuID) (short macID); /* 34 */ + TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */ + void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */ + void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */ + int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */ + void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */ + void (*reserved40)(void); + int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */ + Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */ + MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */ + MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */ + void (*tkMacOSXPreprocessMenu) (void); /* 45 */ + int (*tkpIsWindowFloating) (void *window); /* 46 */ + Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */ + void (*reserved48)(void); + Tk_Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */ + int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */ + void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */ + void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */ + unsigned long (*tkpGetMS) (void); /* 53 */ + void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */ +#endif /* AQUA */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ + void (*tkCreateXEventSource) (void); /* 0 */ + void (*reserved1)(void); + void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */ + int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 3 */ + void (*tkpSync) (Display *display); /* 4 */ + Window (*tkUnixContainerId) (TkWindow *winPtr); /* 5 */ + int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 6 */ + void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 7 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 8 */ + void (*tkWmCleanup) (TkDisplay *dispPtr); /* 9 */ + void (*tkSendCleanup) (TkDisplay *dispPtr); /* 10 */ + void (*reserved11)(void); + int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */ + int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 13 */ + void (*reserved14)(void); + void (*reserved15)(void); + void (*reserved16)(void); + void (*reserved17)(void); + void (*reserved18)(void); + void (*reserved19)(void); + void (*reserved20)(void); + void (*reserved21)(void); + void (*reserved22)(void); + void (*reserved23)(void); + void (*reserved24)(void); + void (*reserved25)(void); + void (*reserved26)(void); + void (*reserved27)(void); + void (*reserved28)(void); + void (*reserved29)(void); + void (*reserved30)(void); + void (*reserved31)(void); + void (*reserved32)(void); + void (*reserved33)(void); + void (*reserved34)(void); + void (*reserved35)(void); + void (*reserved36)(void); + void (*reserved37)(void); + int (*tkpCmapStressed_) (Tk_Window tkwin, Colormap colormap); /* 38 */ + void (*tkpSync_) (Display *display); /* 39 */ + Window (*tkUnixContainerId_) (TkWindow *winPtr); /* 40 */ + int (*tkUnixDoOneXEvent_) (Tcl_Time *timePtr); /* 41 */ + void (*tkUnixSetMenubar_) (Tk_Window tkwin, Tk_Window menubar); /* 42 */ + void (*tkWmCleanup_) (TkDisplay *dispPtr); /* 43 */ + void (*tkSendCleanup_) (TkDisplay *dispPtr); /* 44 */ + int (*tkpTestsendCmd_) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */ +#endif /* X11 */ +} TkIntPlatStubs; + +extern const TkIntPlatStubs *tkIntPlatStubsPtr; + +#ifdef __cplusplus +} +#endif + +#if defined(USE_TK_STUBS) + +/* + * Inline function declarations: + */ + +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ +#define TkAlignImageData \ + (tkIntPlatStubsPtr->tkAlignImageData) /* 0 */ +/* Slot 1 is reserved */ +#define TkGenerateActivateEvents \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */ +#define TkpGetMS \ + (tkIntPlatStubsPtr->tkpGetMS) /* 3 */ +#define TkPointerDeadWindow \ + (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */ +#define TkpPrintWindowId \ + (tkIntPlatStubsPtr->tkpPrintWindowId) /* 5 */ +#define TkpScanWindowId \ + (tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */ +#define TkpSetCapture \ + (tkIntPlatStubsPtr->tkpSetCapture) /* 7 */ +#define TkpSetCursor \ + (tkIntPlatStubsPtr->tkpSetCursor) /* 8 */ +#define TkpWmSetState \ + (tkIntPlatStubsPtr->tkpWmSetState) /* 9 */ +#define TkSetPixmapColormap \ + (tkIntPlatStubsPtr->tkSetPixmapColormap) /* 10 */ +#define TkWinCancelMouseTimer \ + (tkIntPlatStubsPtr->tkWinCancelMouseTimer) /* 11 */ +#define TkWinClipboardRender \ + (tkIntPlatStubsPtr->tkWinClipboardRender) /* 12 */ +#define TkWinEmbeddedEventProc \ + (tkIntPlatStubsPtr->tkWinEmbeddedEventProc) /* 13 */ +#define TkWinFillRect \ + (tkIntPlatStubsPtr->tkWinFillRect) /* 14 */ +#define TkWinGetBorderPixels \ + (tkIntPlatStubsPtr->tkWinGetBorderPixels) /* 15 */ +#define TkWinGetDrawableDC \ + (tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 16 */ +#define TkWinGetModifierState \ + (tkIntPlatStubsPtr->tkWinGetModifierState) /* 17 */ +#define TkWinGetSystemPalette \ + (tkIntPlatStubsPtr->tkWinGetSystemPalette) /* 18 */ +#define TkWinGetWrapperWindow \ + (tkIntPlatStubsPtr->tkWinGetWrapperWindow) /* 19 */ +#define TkWinHandleMenuEvent \ + (tkIntPlatStubsPtr->tkWinHandleMenuEvent) /* 20 */ +#define TkWinIndexOfColor \ + (tkIntPlatStubsPtr->tkWinIndexOfColor) /* 21 */ +#define TkWinReleaseDrawableDC \ + (tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 22 */ +#define TkWinResendEvent \ + (tkIntPlatStubsPtr->tkWinResendEvent) /* 23 */ +#define TkWinSelectPalette \ + (tkIntPlatStubsPtr->tkWinSelectPalette) /* 24 */ +#define TkWinSetMenu \ + (tkIntPlatStubsPtr->tkWinSetMenu) /* 25 */ +#define TkWinSetWindowPos \ + (tkIntPlatStubsPtr->tkWinSetWindowPos) /* 26 */ +#define TkWinWmCleanup \ + (tkIntPlatStubsPtr->tkWinWmCleanup) /* 27 */ +#define TkWinXCleanup \ + (tkIntPlatStubsPtr->tkWinXCleanup) /* 28 */ +#define TkWinXInit \ + (tkIntPlatStubsPtr->tkWinXInit) /* 29 */ +#define TkWinSetForegroundWindow \ + (tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */ +#define TkWinDialogDebug \ + (tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */ +#define TkWinGetMenuSystemDefault \ + (tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */ +#define TkWinGetPlatformId \ + (tkIntPlatStubsPtr->tkWinGetPlatformId) /* 33 */ +#define TkWinSetHINSTANCE \ + (tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */ +#define TkWinGetPlatformTheme \ + (tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */ +#define TkWinChildProc \ + (tkIntPlatStubsPtr->tkWinChildProc) /* 36 */ +#define TkCreateXEventSource \ + (tkIntPlatStubsPtr->tkCreateXEventSource) /* 37 */ +#define TkpCmapStressed \ + (tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */ +#define TkpSync \ + (tkIntPlatStubsPtr->tkpSync) /* 39 */ +#define TkUnixContainerId \ + (tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */ +#define TkUnixDoOneXEvent \ + (tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 41 */ +#define TkUnixSetMenubar \ + (tkIntPlatStubsPtr->tkUnixSetMenubar) /* 42 */ +#define TkWmCleanup \ + (tkIntPlatStubsPtr->tkWmCleanup) /* 43 */ +#define TkSendCleanup \ + (tkIntPlatStubsPtr->tkSendCleanup) /* 44 */ +#define TkpTestsendCmd \ + (tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */ +/* Slot 46 is reserved */ +#define TkpGetCapture \ + (tkIntPlatStubsPtr->tkpGetCapture) /* 47 */ +#endif /* WIN */ +#ifdef MAC_OSX_TK /* AQUA */ +#define TkGenerateActivateEvents \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 0 */ +/* Slot 1 is reserved */ +#define TkGenerateActivateEvents_ \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents_) /* 2 */ +#define TkPointerDeadWindow \ + (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 3 */ +#define TkpSetCapture \ + (tkIntPlatStubsPtr->tkpSetCapture) /* 4 */ +#define TkpSetCursor \ + (tkIntPlatStubsPtr->tkpSetCursor) /* 5 */ +#define TkpWmSetState \ + (tkIntPlatStubsPtr->tkpWmSetState) /* 6 */ +#define TkAboutDlg \ + (tkIntPlatStubsPtr->tkAboutDlg) /* 7 */ +#define TkMacOSXButtonKeyState \ + (tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */ +#define TkMacOSXClearMenubarActive \ + (tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */ +#define TkMacOSXDispatchMenuEvent \ + (tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */ +#define TkMacOSXInstallCursor \ + (tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */ +#define TkMacOSXHandleTearoffMenu \ + (tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */ +/* Slot 13 is reserved */ +#define TkMacOSXDoHLEvent \ + (tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */ +/* Slot 15 is reserved */ +#define TkMacOSXGetXWindow \ + (tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */ +#define TkMacOSXGrowToplevel \ + (tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */ +#define TkMacOSXHandleMenuSelect \ + (tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */ +/* Slot 19 is reserved */ +/* Slot 20 is reserved */ +#define TkMacOSXInvalidateWindow \ + (tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */ +#define TkMacOSXIsCharacterMissing \ + (tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */ +#define TkMacOSXMakeRealWindowExist \ + (tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */ +#define TkMacOSXMakeStippleMap \ + (tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */ +#define TkMacOSXMenuClick \ + (tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */ +/* Slot 26 is reserved */ +#define TkMacOSXResizable \ + (tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */ +#define TkMacOSXSetHelpMenuItemCount \ + (tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */ +#define TkMacOSXSetScrollbarGrow \ + (tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */ +#define TkMacOSXSetUpClippingRgn \ + (tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */ +#define TkMacOSXSetUpGraphicsPort \ + (tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */ +#define TkMacOSXUpdateClipRgn \ + (tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */ +/* Slot 33 is reserved */ +#define TkMacOSXUseMenuID \ + (tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */ +#define TkMacOSXVisableClipRgn \ + (tkIntPlatStubsPtr->tkMacOSXVisableClipRgn) /* 35 */ +#define TkMacOSXWinBounds \ + (tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */ +#define TkMacOSXWindowOffset \ + (tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */ +#define TkSetMacColor \ + (tkIntPlatStubsPtr->tkSetMacColor) /* 38 */ +#define TkSetWMName \ + (tkIntPlatStubsPtr->tkSetWMName) /* 39 */ +/* Slot 40 is reserved */ +#define TkMacOSXZoomToplevel \ + (tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */ +#define Tk_TopCoordsToWindow \ + (tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */ +#define TkMacOSXContainerId \ + (tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */ +#define TkMacOSXGetHostToplevel \ + (tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */ +#define TkMacOSXPreprocessMenu \ + (tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */ +#define TkpIsWindowFloating \ + (tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */ +#define TkMacOSXGetCapture \ + (tkIntPlatStubsPtr->tkMacOSXGetCapture) /* 47 */ +/* Slot 48 is reserved */ +#define TkGetTransientMaster \ + (tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */ +#define TkGenerateButtonEvent \ + (tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */ +#define TkGenWMDestroyEvent \ + (tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */ +#define TkMacOSXSetDrawingEnabled \ + (tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */ +#define TkpGetMS \ + (tkIntPlatStubsPtr->tkpGetMS) /* 53 */ +#define TkMacOSXDrawable \ + (tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */ +#define TkpScanWindowId \ + (tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */ +#endif /* AQUA */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ +#define TkCreateXEventSource \ + (tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */ +/* Slot 1 is reserved */ +#define TkGenerateActivateEvents \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */ +#define TkpCmapStressed \ + (tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */ +#define TkpSync \ + (tkIntPlatStubsPtr->tkpSync) /* 4 */ +#define TkUnixContainerId \ + (tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */ +#define TkUnixDoOneXEvent \ + (tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */ +#define TkUnixSetMenubar \ + (tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */ +#define TkpScanWindowId \ + (tkIntPlatStubsPtr->tkpScanWindowId) /* 8 */ +#define TkWmCleanup \ + (tkIntPlatStubsPtr->tkWmCleanup) /* 9 */ +#define TkSendCleanup \ + (tkIntPlatStubsPtr->tkSendCleanup) /* 10 */ +/* Slot 11 is reserved */ +#define TkpWmSetState \ + (tkIntPlatStubsPtr->tkpWmSetState) /* 12 */ +#define TkpTestsendCmd \ + (tkIntPlatStubsPtr->tkpTestsendCmd) /* 13 */ +/* Slot 14 is reserved */ +/* Slot 15 is reserved */ +/* Slot 16 is reserved */ +/* Slot 17 is reserved */ +/* Slot 18 is reserved */ +/* Slot 19 is reserved */ +/* Slot 20 is reserved */ +/* Slot 21 is reserved */ +/* Slot 22 is reserved */ +/* Slot 23 is reserved */ +/* Slot 24 is reserved */ +/* Slot 25 is reserved */ +/* Slot 26 is reserved */ +/* Slot 27 is reserved */ +/* Slot 28 is reserved */ +/* Slot 29 is reserved */ +/* Slot 30 is reserved */ +/* Slot 31 is reserved */ +/* Slot 32 is reserved */ +/* Slot 33 is reserved */ +/* Slot 34 is reserved */ +/* Slot 35 is reserved */ +/* Slot 36 is reserved */ +/* Slot 37 is reserved */ +#define TkpCmapStressed_ \ + (tkIntPlatStubsPtr->tkpCmapStressed_) /* 38 */ +#define TkpSync_ \ + (tkIntPlatStubsPtr->tkpSync_) /* 39 */ +#define TkUnixContainerId_ \ + (tkIntPlatStubsPtr->tkUnixContainerId_) /* 40 */ +#define TkUnixDoOneXEvent_ \ + (tkIntPlatStubsPtr->tkUnixDoOneXEvent_) /* 41 */ +#define TkUnixSetMenubar_ \ + (tkIntPlatStubsPtr->tkUnixSetMenubar_) /* 42 */ +#define TkWmCleanup_ \ + (tkIntPlatStubsPtr->tkWmCleanup_) /* 43 */ +#define TkSendCleanup_ \ + (tkIntPlatStubsPtr->tkSendCleanup_) /* 44 */ +#define TkpTestsendCmd_ \ + (tkIntPlatStubsPtr->tkpTestsendCmd_) /* 45 */ +#endif /* X11 */ + +#endif /* defined(USE_TK_STUBS) */ + +/* !END!: Do not edit above this line. */ + +#undef TkpCmapStressed_ +#undef TkpSync_ +#undef TkUnixContainerId_ +#undef TkUnixDoOneXEvent_ +#undef TkUnixSetMenubar_ +#undef TkWmCleanup_ +#undef TkSendCleanup_ +#undef TkpTestsendCmd_ +#undef TkGenerateActivateEvents_ + +#define TkMacOSXGetContainer TkGetTransientMaster + +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLIMPORT + +#endif /* _TKINTPLATDECLS */ diff --git a/src/libdm/wgl/wintk/tkPort.h b/src/libdm/wgl/wintk/tkPort.h new file mode 100644 index 00000000000..d6db449ec06 --- /dev/null +++ b/src/libdm/wgl/wintk/tkPort.h @@ -0,0 +1,31 @@ +/* + * tkPort.h -- + * + * This header file handles porting issues that occur because of + * differences between systems. It reads in platform specific + * portability files. + * + * Copyright (c) 1995 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKPORT +#define _TKPORT + +#if defined(_WIN32) +# include "tkWinPort.h" +#endif +#ifndef _TK +# include "tk.h" +#endif +#if !defined(_WIN32) +# if defined(MAC_OSX_TK) +# include "tkMacOSXPort.h" +# else +# include "tkUnixPort.h" +# endif +#endif + +#endif /* _TKPORT */ diff --git a/src/libdm/wgl/wintk/tkWin.h b/src/libdm/wgl/wintk/tkWin.h new file mode 100644 index 00000000000..4d278d791d8 --- /dev/null +++ b/src/libdm/wgl/wintk/tkWin.h @@ -0,0 +1,81 @@ +/* + * tkWin.h -- + * + * Declarations of public types and interfaces that are only + * available under Windows. + * + * Copyright (c) 1996-1997 by Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKWIN +#define _TKWIN + +/* + * We must specify the lower version we intend to support. In particular + * the SystemParametersInfo API doesn't like to receive structures that + * are larger than it expects which affects the font assignments. + * + * WINVER = 0x0500 means Windows 2000 and above + */ + +#ifndef WINVER +#define WINVER 0x0500 +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif + +#ifndef _TK +#include +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +/* + * The following messages are used to communicate between a Tk toplevel + * and its container window. A Tk container may not be able to provide + * service to all of the following requests at the moment. But an embedded + * Tk window will send out these requests to support external Tk container + * application. + */ + +#define TK_CLAIMFOCUS (WM_USER) /* an embedded window requests to focus */ +#define TK_GEOMETRYREQ (WM_USER+1) /* an embedded window requests to change size */ +#define TK_ATTACHWINDOW (WM_USER+2) /* an embedded window requests to attach */ +#define TK_DETACHWINDOW (WM_USER+3) /* an embedded window requests to detach */ +#define TK_MOVEWINDOW (WM_USER+4) /* an embedded window requests to move */ +#define TK_RAISEWINDOW (WM_USER+5) /* an embedded window requests to raise */ +#define TK_ICONIFY (WM_USER+6) /* an embedded window requests to iconify */ +#define TK_DEICONIFY (WM_USER+7) /* an embedded window requests to deiconify */ +#define TK_WITHDRAW (WM_USER+8) /* an embedded window requests to withdraw */ +#define TK_GETFRAMEWID (WM_USER+9) /* an embedded window requests a frame window id */ +#define TK_OVERRIDEREDIRECT (WM_USER+10) /* an embedded window requests to overrideredirect */ +#define TK_SETMENU (WM_USER+11) /* an embedded window requests to setup menu */ +#define TK_STATE (WM_USER+12) /* an embedded window sets/gets state */ +#define TK_INFO (WM_USER+13) /* an embedded window requests a container's info */ + +/* + * The following are sub-messages (wParam) for TK_INFO. An embedded window may + * send a TK_INFO message with one of the sub-messages to query a container + * for verification and availability + */ +#define TK_CONTAINER_VERIFY 0x01 +#define TK_CONTAINER_ISAVAILABLE 0x02 + + +/* + *-------------------------------------------------------------- + * + * Exported procedures defined for the Windows platform only. + * + *-------------------------------------------------------------- + */ + +#include "tkPlatDecls.h" + +#endif /* _TKWIN */ diff --git a/src/libdm/wgl/wintk/tkWinInt.h b/src/libdm/wgl/wintk/tkWinInt.h new file mode 100644 index 00000000000..ccc57dbaef0 --- /dev/null +++ b/src/libdm/wgl/wintk/tkWinInt.h @@ -0,0 +1,245 @@ +/* + * tkWinInt.h -- + * + * This file contains declarations that are shared among the + * Windows-specific parts of Tk, but aren't used by the rest of Tk. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-2000 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKWININT +#define _TKWININT + +#ifndef _TKINT +#include "tkInt.h" +#endif + +/* + * Include platform specific public interfaces. + */ + +#ifndef _TKWIN +#include "tkWin.h" +#endif + +/* + * Define constants missing from older Win32 SDK header files. + */ + +#ifndef WS_EX_TOOLWINDOW +#define WS_EX_TOOLWINDOW 0x00000080L +#endif +#ifndef SPI_SETKEYBOARDCUES +#define SPI_SETKEYBOARDCUES 0x100B +#endif + +/* + * The TkWinDCState is used to save the state of a device context so that it + * can be restored later. + */ + +typedef struct TkWinDCState { + HPALETTE palette; + int bkmode; +} TkWinDCState; + +/* + * The TkWinDrawable is the internal implementation of an X Drawable (either a + * Window or a Pixmap). The following constants define the valid Drawable + * types. + */ + +#define TWD_BITMAP 1 +#define TWD_WINDOW 2 +#define TWD_WINDC 3 + +typedef struct { + int type; + HWND handle; + TkWindow *winPtr; +} TkWinWindow; + +typedef struct { + int type; + HBITMAP handle; + Colormap colormap; + int depth; +} TkWinBitmap; + +typedef struct { + int type; + HDC hdc; +}TkWinDC; + +typedef union { + int type; + TkWinWindow window; + TkWinBitmap bitmap; + TkWinDC winDC; +} TkWinDrawable; + +/* + * The following macros are used to retrieve internal values from a Drawable. + */ + +#define TkWinGetHWND(w) (((TkWinDrawable *) w)->window.handle) +#define TkWinGetWinPtr(w) (((TkWinDrawable *) w)->window.winPtr) +#define TkWinGetHBITMAP(w) (((TkWinDrawable *) w)->bitmap.handle) +#define TkWinGetColormap(w) (((TkWinDrawable *) w)->bitmap.colormap) +#define TkWinGetHDC(w) (((TkWinDrawable *) w)->winDC.hdc) + +/* + * The following structure is used to encapsulate palette information. + */ + +typedef struct { + HPALETTE palette; /* Palette handle used when drawing. */ + UINT size; /* Number of entries in the palette. */ + int stale; /* 1 if palette needs to be realized, + * otherwise 0. If the palette is stale, then + * an idle handler is scheduled to realize the + * palette. */ + Tcl_HashTable refCounts; /* Hash table of palette entry reference + * counts indexed by pixel value. */ +} TkWinColormap; + +/* + * The following macro retrieves the Win32 palette from a colormap. + */ + +#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette) + +/* + * The following macros define the class names for Tk Window types. + */ + +#define TK_WIN_TOPLEVEL_CLASS_NAME L"TkTopLevel" +#define TK_WIN_CHILD_CLASS_NAME L"TkChild" + +/* + * The following variable is a translation table between X gc functions and + * Win32 raster and BitBlt op modes. + */ + +MODULE_SCOPE const int tkpWinRopModes[]; +MODULE_SCOPE const int tkpWinBltModes[]; + +/* + * The following defines are used with TkWinGetBorderPixels to get the extra 2 + * border colors from a Tk_3DBorder. + */ + +#define TK_3D_LIGHT2 TK_3D_DARK_GC+1 +#define TK_3D_DARK2 TK_3D_DARK_GC+2 + +/* + * Internal functions used by more than one source file. + */ + +#include "tkIntPlatDecls.h" + +/* + * Special proc needed as tsd accessor function between + * tkWinX.c:GenerateXEvent and tkWinClipboard.c:UpdateClipboard + */ + +MODULE_SCOPE void TkWinUpdatingClipboard(int mode); + +/* + * Used by tkWinDialog.c to associate the right icon with tk_messageBox + */ + +MODULE_SCOPE HICON TkWinGetIcon(Tk_Window tkw, DWORD iconsize); + +/* + * Used by tkWinX.c on for certain system display change messages and cleanup + * up containers + */ + +MODULE_SCOPE void TkWinDisplayChanged(Display *display); +MODULE_SCOPE void TkWinCleanupContainerList(void); + +/* + * Used by tkWinWm.c for embedded menu handling. May become public. + */ + +MODULE_SCOPE HWND Tk_GetMenuHWND(Tk_Window tkwin); +MODULE_SCOPE HWND Tk_GetEmbeddedMenuHWND(Tk_Window tkwin); + +/* + * The following allows us to cache these encoding for multiple functions. + */ + + +MODULE_SCOPE Tcl_Encoding TkWinGetKeyInputEncoding(void); +MODULE_SCOPE Tcl_Encoding TkWinGetUnicodeEncoding(void); +MODULE_SCOPE void TkWinSetupSystemFonts(TkMainInfo *mainPtr); + +/* + * Values returned by TkWinGetPlatformTheme. + */ + +#define TK_THEME_WIN_CLASSIC 1 +#define TK_THEME_WIN_XP 2 +#define TK_THEME_WIN_VISTA 3 + +/* + * The following is implemented in tkWinWm and used by tkWinEmbed.c + */ + +MODULE_SCOPE void TkpWinToplevelWithDraw(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelIconify(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelDeiconify(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelIsControlledByWm(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelMove(TkWindow *winPtr, int x, int y); +MODULE_SCOPE long TkpWinToplevelOverrideRedirect(TkWindow *winPtr, + int reqValue); +MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); +MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); + +/* + * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c + */ + +MODULE_SCOPE void TkSetCursorPos(int x, int y); + +/* + * Common routines used in Windows implementation + */ +MODULE_SCOPE Tcl_Obj * TkWin32ErrorObj(HRESULT hrError); + + +/* + * The following functions are not present in old versions of Windows + * API headers but are used in the Tk source to ensure 64bit + * compatibility. + */ + +#ifndef GetClassLongPtr +# define GetClassLongPtrW GetClassLongW +# define SetClassLongPtrW SetClassLongW +#endif /* !GetClassLongPtr */ +#ifndef GCLP_HICON +# define GCLP_HICON GCL_HICON +#endif /* !GCLP_HICON */ +#ifndef GCLP_HICONSM +# define GCLP_HICONSM (-34) +#endif /* !GCLP_HICONSM */ + +#ifndef GetWindowLongPtr +# define GetWindowLongPtrW GetWindowLongW +# define SetWindowLongPtrW SetWindowLongW +#endif /* !GetWindowLongPtr */ +#ifndef GWLP_WNDPROC +#define GWLP_WNDPROC GWL_WNDPROC +#define GWLP_HINSTANCE GWL_HINSTANCE +#define GWLP_HWNDPARENT GWL_HWNDPARENT +#define GWLP_USERDATA GWL_USERDATA +#define GWLP_ID GWL_ID +#endif /* !GWLP_WNDPROC */ + +#endif /* _TKWININT */ diff --git a/src/libdm/wgl/wintk/tkWinPort.h b/src/libdm/wgl/wintk/tkWinPort.h new file mode 100644 index 00000000000..e5e9e6c0506 --- /dev/null +++ b/src/libdm/wgl/wintk/tkWinPort.h @@ -0,0 +1,137 @@ +/* + * tkWinPort.h -- + * + * This header file handles porting issues that occur because of + * differences between Windows and Unix. It should be the only + * file that contains #ifdefs to handle different flavors of OS. + * + * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _WINPORT +#define _WINPORT + +/* + *--------------------------------------------------------------------------- + * The following sets of #includes and #ifdefs are required to get Tcl to + * compile under the windows compilers. + *--------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Need to block out this include for building extensions with MetroWerks + * compiler for Win32. + */ + +#ifndef __MWERKS__ +#include +#endif + +#include + +#ifdef _MSC_VER +# ifndef hypot +# define hypot _hypot +# endif +#endif /* _MSC_VER */ + +/* + * Pull in the typedef of TCHAR for windows. + */ +#include +#ifndef _TCHAR_DEFINED + /* Borland seems to forget to set this. */ + typedef _TCHAR TCHAR; +# define _TCHAR_DEFINED +#endif +#if defined(_MSC_VER) && defined(__STDC__) + /* VS2005 SP1 misses this. See [Bug #3110161] */ + typedef _TCHAR TCHAR; +#endif + +#if defined(__GNUC__) && !defined(__cplusplus) +# pragma GCC diagnostic ignored "-Wc++-compat" +#endif +#include +#include +#include +#include +#include + +#ifndef __GNUC__ +# define strncasecmp _strnicmp +# define strcasecmp _stricmp +#endif + +#define NBBY 8 + +#ifndef OPEN_MAX +#define OPEN_MAX 32 +#endif + +/* + * The following define causes Tk to use its internal keysym hash table + */ + +#define REDO_KEYSYM_LOOKUP + +/* + * See ticket [916c1095438eae56]: GetVersionExW triggers warnings + */ +#if defined(_MSC_VER) +# pragma warning(disable:4090) /* see: https://developercommunity.visualstudio.com/t/c-compiler-incorrect-propagation-of-const-qualifie/390711 */ +# pragma warning(disable:4146) +# pragma warning(disable:4267) +# pragma warning(disable:4244) +# pragma warning(disable:4311) +# pragma warning(disable:4312) +# pragma warning(disable:4996) +#if !defined(_WIN64) +# pragma warning(disable:4305) +#endif +#endif + +/* + * The following macro checks to see whether there is buffered + * input data available for a stdio FILE. + */ + +#ifdef _MSC_VER +# define TK_READ_DATA_PENDING(f) ((f)->_cnt > 0) +#else /* _MSC_VER */ +# define TK_READ_DATA_PENDING(f) ((f)->level > 0) +#endif /* _MSC_VER */ + +/* + * The following Tk functions are implemented as macros under Windows. + */ + +#define TkpGetPixel(p) (((((p)->red >> 8) & 0xff) \ + | ((p)->green & 0xff00) | (((p)->blue << 8) & 0xff0000)) | 0x20000000) + +/* + * These calls implement native bitmaps which are not currently + * supported under Windows. The macros eliminate the calls. + */ + +#define TkpDefineNativeBitmaps() +#define TkpCreateNativeBitmap(display, source) None +#define TkpGetNativeAppBitmap(display, name, w, h) None + +#endif /* _WINPORT */ diff --git a/src/libfft/CMakeLists.txt b/src/libfft/CMakeLists.txt index a372a9261f9..089878dfd78 100644 --- a/src/libfft/CMakeLists.txt +++ b/src/libfft/CMakeLists.txt @@ -53,7 +53,7 @@ set(LIBFFT_SRCS ) fft_gen("${FFT_NUMLIST}" "${CMAKE_CURRENT_BINARY_DIR}/shared" FFT_GEN_SHARED_SRCS) fft_gen("${FFT_NUMLIST}" "${CMAKE_CURRENT_BINARY_DIR}/static" FFT_GEN_STATIC_SRCS) -BRLCAD_ADDLIB(libfft "${LIBFFT_SRCS}" "${M_LIBRARY}" SHARED_SRCS "${FFT_GEN_SHARED_SRCS}" STATIC_SRCS "${FFT_GEN_STATIC_SRCS}") +BRLCAD_ADDLIB(libfft "${LIBFFT_SRCS}" "${libfft_deps};${M_LIBRARY}" SHARED_SRCS "${FFT_GEN_SHARED_SRCS}" STATIC_SRCS "${FFT_GEN_STATIC_SRCS}") set_target_properties(libfft PROPERTIES LINKER_LANGUAGE C) set_target_properties(libfft PROPERTIES VERSION 20.0.1 SOVERSION 20) diff --git a/src/libgcv/CMakeLists.txt b/src/libgcv/CMakeLists.txt index 6494684b371..f759ea55dc1 100644 --- a/src/libgcv/CMakeLists.txt +++ b/src/libgcv/CMakeLists.txt @@ -27,7 +27,7 @@ set(LIBGCV_SOURCES ) -BRLCAD_ADDLIB(libgcv "${LIBGCV_SOURCES}" "librt;libwdb;libnmg;libbu" SHARED_SRCS "${GCV_SO_SRCS}" STATIC_SRCS "${GCV_STATIC_SRCS}") +BRLCAD_ADDLIB(libgcv "${LIBGCV_SOURCES}" "${libgcv_deps}" SHARED_SRCS "${GCV_SO_SRCS}" STATIC_SRCS "${GCV_STATIC_SRCS}") set_target_properties(libgcv PROPERTIES VERSION 20.0.1 SOVERSION 20) set_property(SOURCE gcv.c APPEND PROPERTY COMPILE_DEFINITIONS "LIBGCV_PLUGINS_DIRECTORY=\"${LIBGCV_PLUGINS_DIRECTORY}\"") set_property(SOURCE gcv.c APPEND PROPERTY COMPILE_DEFINITIONS "LIBGCV_PLUGINS_PATH=\"${LIBGCV_PLUGINS_PATH}\"") diff --git a/src/libgcv/bottess.c b/src/libgcv/bottess.c index 68646ac07a4..3f3f694f7b4 100644 --- a/src/libgcv/bottess.c +++ b/src/libgcv/bottess.c @@ -302,7 +302,7 @@ _tree_invert(union tree *tree) unsigned long int i; RT_CK_TREE(tree); - if (tree->tr_op != OP_NMG_TESS) { + if (tree->tr_op != OP_TESS) { bu_log("Erm, this isn't an nmg tess\n"); return tree; } @@ -408,7 +408,7 @@ evaluate(union tree *tr, const struct bg_tess_tol *ttol, const struct bn_tol *to switch (tr->tr_op) { case OP_NOP: return tr; - case OP_NMG_TESS: + case OP_TESS: /* ugh, keep it as nmg_tess and just shove the rt_bot_internal ptr * in as nmgregion. :/ Also, only doing the first shell of the first * model. Primitives should only provide a single shell, right? */ @@ -521,7 +521,7 @@ gcv_bottess(int argc, const char **argv, struct db_i *dbip, struct bg_tess_tol * struct db_tree_state tree_state = rt_initial_tree_state; tree_state.ts_ttol = ttol; - if (db_walk_tree(dbip, argc, argv, 1, &tree_state, NULL, gcv_bottess_region_end, nmg_booltree_leaf_tess, NULL) < 0) + if (db_walk_tree(dbip, argc, argv, 1, &tree_state, NULL, gcv_bottess_region_end, rt_booltree_leaf_tess, NULL) < 0) bu_log("gcv_bottess: db_walk_tree failure\n"); return NULL; diff --git a/src/libgcv/facetize.c b/src/libgcv/facetize.c index a38774e3982..ccd3e2a0cd0 100644 --- a/src/libgcv/facetize.c +++ b/src/libgcv/facetize.c @@ -27,6 +27,7 @@ #include "bu/parallel.h" #include "gcv/util.h" +#include "rt/conv.h" #include "rt/db5.h" #include "rt/db_internal.h" #include "rt/wdb.h" @@ -165,7 +166,7 @@ gcv_facetize(struct db_i *db, const struct db_full_path *path, nmg_model = nmg_mm(); if (db_walk_tree(db, 1, (const char **)&str_path, 1, &initial_tree_state, NULL, - _gcv_facetize_region_end, nmg_booltree_leaf_tess, &facetize_tree)) { + _gcv_facetize_region_end, rt_booltree_leaf_tess, &facetize_tree)) { bu_log("gcv_facetize(): error in db_walk_tree()\n"); bu_free(str_path, "str_path"); return _gcv_facetize_cleanup(nmg_model, facetize_tree); diff --git a/src/libgcv/plugins/assetimport/assetimport_write.cpp b/src/libgcv/plugins/assetimport/assetimport_write.cpp index 6be791bf36d..e792befe62a 100644 --- a/src/libgcv/plugins/assetimport/assetimport_write.cpp +++ b/src/libgcv/plugins/assetimport/assetimport_write.cpp @@ -412,7 +412,7 @@ assetimport_write(struct gcv_context *context, const struct gcv_opts *gcv_option &tree_state, 0, /* take all regions */ (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?gcv_region_end_mc:gcv_region_end, - (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:nmg_booltree_leaf_tess, + (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:rt_booltree_leaf_tess, (void *)&gcvwriter); } else { (void) db_walk_tree(context->dbip, gcv_options->num_objects, (const char **)gcv_options->object_names, @@ -420,7 +420,7 @@ assetimport_write(struct gcv_context *context, const struct gcv_opts *gcv_option &tree_state, 0, /* take all regions */ (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?gcv_region_end_mc:gcv_region_end, - (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:nmg_booltree_leaf_tess, + (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:rt_booltree_leaf_tess, (void *)&gcvwriter); } diff --git a/src/libgcv/plugins/fastgen4/fastgen4_write.cpp b/src/libgcv/plugins/fastgen4/fastgen4_write.cpp index abac1bda3c5..955f00307b1 100644 --- a/src/libgcv/plugins/fastgen4/fastgen4_write.cpp +++ b/src/libgcv/plugins/fastgen4/fastgen4_write.cpp @@ -2414,7 +2414,7 @@ convert_leaf(db_tree_state *tree_state, const db_full_path *path, if (!facetize && subtracted) data.m_failed_regions.insert(region_dir); else - return nmg_booltree_leaf_tess(tree_state, path, internal, client_data); + return rt_booltree_leaf_tess(tree_state, path, internal, client_data); } tree *result; diff --git a/src/libgcv/plugins/obj/obj_write.c b/src/libgcv/plugins/obj/obj_write.c index a72d46e26ba..7d4436671fb 100644 --- a/src/libgcv/plugins/obj/obj_write.c +++ b/src/libgcv/plugins/obj/obj_write.c @@ -544,7 +544,7 @@ obj_write(struct gcv_context *context, const struct gcv_opts *gcv_options, const /* Walk indicated tree(s). Each region will be output separately */ (void) db_walk_tree(context->dbip, state.gcv_options->num_objects, (const char **)state.gcv_options->object_names, - 1, &tree_state, NULL, do_region_end, nmg_booltree_leaf_tess, (void *)&state); + 1, &tree_state, NULL, do_region_end, rt_booltree_leaf_tess, (void *)&state); if (state.regions_tried) { double percent = ((double)state.regions_converted * 100.0) / state.regions_tried; diff --git a/src/libgcv/plugins/obj/wfobj/CMake/FindLEMON.cmake b/src/libgcv/plugins/obj/wfobj/CMake/FindLEMON.cmake index 59db72763cb..65455856eee 100644 --- a/src/libgcv/plugins/obj/wfobj/CMake/FindLEMON.cmake +++ b/src/libgcv/plugins/obj/wfobj/CMake/FindLEMON.cmake @@ -86,7 +86,7 @@ endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) # look for the template in bin dir - get_filename_component(lemon_path ${LEMON_EXECUTABLE} PATH) + get_filename_component(lemon_path ${LEMON_EXECUTABLE} DIRECTORY) if (lemon_path) if (EXISTS ${lemon_path}/lempar.c) set (LEMON_TEMPLATE "${lemon_path}/lempar.c") @@ -153,7 +153,7 @@ if(NOT COMMAND LEMON_TARGET) if ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c) else ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} PATH) + get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_SRC_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") @@ -164,7 +164,7 @@ if(NOT COMMAND LEMON_TARGET) if ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h) else ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} PATH) + get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} DIRECTORY) if(NOT "${specified_out_dir}" STREQUAL "") message(FATAL_ERROR "\nFull path specified for OUT_HDR_FILE - should be filename only.\n") endif(NOT "${specified_out_dir}" STREQUAL "") diff --git a/src/libgcv/plugins/obj/wfobj/CMakeLists.txt b/src/libgcv/plugins/obj/wfobj/CMakeLists.txt index 042c2ebbf57..51db2670b0f 100644 --- a/src/libgcv/plugins/obj/wfobj/CMakeLists.txt +++ b/src/libgcv/plugins/obj/wfobj/CMakeLists.txt @@ -77,8 +77,11 @@ if(HAVE_UNIQUE_PTR) endif(HAVE_UNIQUE_PTR) # Find tools for generating source files +set(LEMON_ROOT "${BRLCAD_EXT_NOINSTALL_DIR}") find_package(LEMON REQUIRED) +set(RE2C_ROOT "${BRLCAD_EXT_NOINSTALL_DIR}") find_package(RE2C REQUIRED) +set(PERPLEX_ROOT "${BRLCAD_EXT_NOINSTALL_DIR}") find_package(PERPLEX REQUIRED) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/WFBOBJ_SCANNER_SO") diff --git a/src/libgcv/plugins/ply/ply_write.c b/src/libgcv/plugins/ply/ply_write.c index b77e3d57710..1bf10851575 100644 --- a/src/libgcv/plugins/ply/ply_write.c +++ b/src/libgcv/plugins/ply/ply_write.c @@ -723,7 +723,7 @@ ply_write_gcv(struct gcv_context* context, const struct gcv_opts* gcv_options, c &tree_state, 0, /* take all regions */ do_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void*)&state); if (state.ply_write_options->verbose || state.gcv_options->verbosity_level) diff --git a/src/libgcv/plugins/stl/stl_write.c b/src/libgcv/plugins/stl/stl_write.c index abaffe25ef1..5979f5303fe 100644 --- a/src/libgcv/plugins/stl/stl_write.c +++ b/src/libgcv/plugins/stl/stl_write.c @@ -415,7 +415,7 @@ stl_write(struct gcv_context *context, const struct gcv_opts *gcv_options, const &tree_state, 0, /* take all regions */ (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?gcv_region_end_mc:gcv_region_end, - (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:nmg_booltree_leaf_tess, + (gcv_options->tessellation_algorithm == GCV_TESS_MARCHING_CUBES)?NULL:rt_booltree_leaf_tess, (void *)&gcvwriter); if (state.regions_tried>0) { diff --git a/src/libgcv/plugins/vrml/vrml_read/node.cpp b/src/libgcv/plugins/vrml/vrml_read/node.cpp index ce42b4eb925..d854b69a5a2 100644 --- a/src/libgcv/plugins/vrml/vrml_read/node.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/node.cpp @@ -44,8 +44,6 @@ #include "bu.h" -using namespace std; - static const char *fields[] = { "", "rotation", @@ -99,8 +97,8 @@ void getSFVec3f(float *p); void getSFVec4f(float *p); void getInt(int &n); void getFloat(float &n); -void getCoordIndex(vector &ccoordindex); -void getPoint(vector &cpoint); +void getCoordIndex(std::vector &ccoordindex); +void getPoint(std::vector &cpoint); //Initialize transform node data void @@ -536,7 +534,7 @@ NODE::getPolyRep(NODE *node) { //Gets and stores vertices for nodes pointed to by noderef vector void -NODE::doMakePoly(vector &noderef) +NODE::doMakePoly(std::vector &noderef) { int ssize = static_cast(noderef.size()); diff --git a/src/libgcv/plugins/vrml/vrml_read/node.h b/src/libgcv/plugins/vrml/vrml_read/node.h index 14d14eb0804..fcb9d4783f8 100644 --- a/src/libgcv/plugins/vrml/vrml_read/node.h +++ b/src/libgcv/plugins/vrml/vrml_read/node.h @@ -99,8 +99,6 @@ #define FIELDNAMEMAX 43 -using namespace std; - char *getNextWord( char *nextword); char *nextWord(char *inputstring, char *nextwd); @@ -112,8 +110,8 @@ class NODE int nchild; int isprotodef; int ispoly; - vector children; - string nodetypename; + std::vector children; + std::string nodetypename; float color[3]; float diffusecolor[3]; float scale[3]; // = {1, 1, 1}; @@ -124,9 +122,9 @@ class NODE float bottomradius; float height; double rotmat[16]; - vector coordindex; - vector point; - vector vertics; + std::vector coordindex; + std::vector point; + std::vector vertics; NODE *createNewNode(int nodetype); @@ -141,7 +139,7 @@ class NODE void getSphere (NODE *node); void getPolyRep(NODE *node); void rotXNode(NODE *node, double rad); - void doMakePoly(vector &noderef); + void doMakePoly(std::vector &noderef); }; #endif diff --git a/src/libgcv/plugins/vrml/vrml_read/node_type.cpp b/src/libgcv/plugins/vrml/vrml_read/node_type.cpp index c8af8eabb7e..87c39bbe201 100644 --- a/src/libgcv/plugins/vrml/vrml_read/node_type.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/node_type.cpp @@ -35,8 +35,6 @@ #include "string_util.h" #include "node.h" -using namespace std; - static const char *nodeTypeString[] = { "", "Appearance", @@ -56,7 +54,7 @@ static const char *nodeTypeString[] = { int -NODETYPE::findNodeType(string instring) +NODETYPE::findNodeType(std::string instring) { int i; diff --git a/src/libgcv/plugins/vrml/vrml_read/node_type.h b/src/libgcv/plugins/vrml/vrml_read/node_type.h index 0980b8f37f7..14afad63487 100644 --- a/src/libgcv/plugins/vrml/vrml_read/node_type.h +++ b/src/libgcv/plugins/vrml/vrml_read/node_type.h @@ -33,14 +33,12 @@ #define NODETYPEMAX 14 -using namespace std; - class NODE; //forward declaration of class class NODETYPE { public: - int findNodeType(string instring); + int findNodeType(std::string instring); int findNodeType(NODE *innode); }; diff --git a/src/libgcv/plugins/vrml/vrml_read/parser.cpp b/src/libgcv/plugins/vrml/vrml_read/parser.cpp index c55d69fecee..910ce1b2122 100644 --- a/src/libgcv/plugins/vrml/vrml_read/parser.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/parser.cpp @@ -42,13 +42,11 @@ #include "node_type.h" #include "transform_node.h" -using namespace std; - char *getNextWord(char *instring, char *nextword); char *getNextWord( char *nextword); bool findKeyWord(char *inputstring, int kw); -void stringcopy(string &str1, char *str2); -int stringcompare(string &str1, char *str2); +void stringcopy(std::string &str1, char *str2); +int stringcompare(std::string &str1, char *str2); int findFieldName(char *instring); @@ -87,7 +85,7 @@ PARSER::parseNodeString(char *instring, NODE *node) { if (findKeyWord(instring, KWPROTO)) { char protoname[MAXSTRSIZE]; int sqbrcount = 0; - string protostring; + std::string protostring; getNextWord(protoname); stringcopy(protostring, protoname); @@ -129,7 +127,7 @@ NODE * PARSER::parsekwdef(NODE * node) { char nextwd[MAXSTRSIZE]; - string defstring; + std::string defstring; getNextWord(nextwd); //get the defnode idname stringcopy(defstring, nextwd);// convert defnode idname from type char *to c++ string @@ -174,7 +172,7 @@ NODE * PARSER::parseNode(char *instring, NODE *node) { - string nextwd; + std::string nextwd; NODETYPE ntype; NODE tempnode; int nodeid, curly = 0; @@ -232,7 +230,7 @@ PARSER::parseNode(char *instring, NODE *node) //Get list of children for specified node int -PARSER::getChildNodeList(NODE *rtnode, vector &childlist) +PARSER::getChildNodeList(NODE *rtnode, std::vector &childlist) { unsigned int i; @@ -271,7 +269,7 @@ PARSER::findChild(NODE *node, int search) { int size; int i; NODETYPE ntype; - vector childlist; + std::vector childlist; getChildNodeList(node,childlist); size = static_cast(childlist.size()); @@ -286,7 +284,7 @@ PARSER::findChild(NODE *node, int search) { } void -PARSER::doColor(vector &childlist) { +PARSER::doColor(std::vector &childlist) { int size = static_cast(childlist.size()); int i; @@ -307,7 +305,7 @@ PARSER::doColor(vector &childlist) { } void -PARSER::freeSceneNode(vector &childlist) { +PARSER::freeSceneNode(std::vector &childlist) { int size = static_cast(childlist.size()); int i; diff --git a/src/libgcv/plugins/vrml/vrml_read/parser.h b/src/libgcv/plugins/vrml/vrml_read/parser.h index f53c7ecc917..fe8d6e7c76a 100644 --- a/src/libgcv/plugins/vrml/vrml_read/parser.h +++ b/src/libgcv/plugins/vrml/vrml_read/parser.h @@ -37,16 +37,14 @@ #include -using namespace std; - class PARSER { public: - vector userdeftypes; //Store DEF node names - vector protodeftypes; //Store PROTO node names - vector protonodelist; //Stores pointer to PROTO nodes - vector defnodelist; //Stores pointer to DEF nodes - vector scenevert; //Store all vertices in the scenegraph + std::vector userdeftypes; //Store DEF node names + std::vector protodeftypes; //Store PROTO node names + std::vector protonodelist; //Stores pointer to PROTO nodes + std::vector defnodelist; //Stores pointer to DEF nodes + std::vector scenevert; //Store all vertices in the scenegraph NODE rootnode; //Parent scene node int ntopchild; // Number of direct children to the root node @@ -55,13 +53,13 @@ class PARSER NODE *parsekwdef(NODE *node); NODE *parsekwuse(char *instring, NODE *node); NODE *parseNode(char *instring, NODE *node); - int getChildNodeList(NODE *rtnode, vector &childlist); + int getChildNodeList(NODE *rtnode, std::vector &childlist); int copyNode(NODE *destnode, NODE *sourcenode); void transformChild(NODE *pnode); NODE *parseProtoNode(char *instring, NODE *node); NODE *findChild(NODE *node, int search); - void doColor(vector &childlist); - void freeSceneNode(vector &childlist); + void doColor(std::vector &childlist); + void freeSceneNode(std::vector &childlist); }; diff --git a/src/libgcv/plugins/vrml/vrml_read/string_util.cpp b/src/libgcv/plugins/vrml/vrml_read/string_util.cpp index e12d2d1b918..793fe09306c 100644 --- a/src/libgcv/plugins/vrml/vrml_read/string_util.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/string_util.cpp @@ -34,8 +34,6 @@ #include "string_util.h" -using namespace std; - static char *ptr = NULL; //pointer to current position in input file data static const char *keyword[]= { "DEF", "USE", "PROTO"}; @@ -98,7 +96,7 @@ findKeyWord(char *inputstring, int kw) } void -stringcopy(string &str1, char *str2) +stringcopy(std::string &str1, char *str2) { int i; @@ -109,7 +107,7 @@ stringcopy(string &str1, char *str2) } int -stringcompare(string &str1, char *str2) +stringcompare(std::string &str1, char *str2) { return bu_strcmp(str1.c_str(), str2); } @@ -142,10 +140,10 @@ getNextWord(char *nextword) } void -replaceStringChars(string &str, char ch, const char *rstring) +replaceStringChars(std::string &str, char ch, const char *rstring) { int pos = str.find(ch); - int n = static_cast(string::npos); + int n = static_cast(std::string::npos); while (pos != n) { str.replace(pos, 1, rstring, 0, 3); @@ -156,7 +154,7 @@ replaceStringChars(string &str, char ch, const char *rstring) void formatString(char *instring) { - string str; + std::string str; stringcopy(str, instring); replaceStringChars(str, '#', "\n# "); @@ -218,7 +216,7 @@ getFloat(float &n) } void -getCoordIndex(vector &ccoordindex) +getCoordIndex(std::vector &ccoordindex) { int n; char val[MAXSTRSIZE]; @@ -239,7 +237,7 @@ getCoordIndex(vector &ccoordindex) } void -getPoint(vector &cpoint) +getPoint(std::vector &cpoint) { float n; char val[MAXSTRSIZE]; diff --git a/src/libgcv/plugins/vrml/vrml_read/string_util.h b/src/libgcv/plugins/vrml/vrml_read/string_util.h index 37edadaeb93..da03cec6364 100644 --- a/src/libgcv/plugins/vrml/vrml_read/string_util.h +++ b/src/libgcv/plugins/vrml/vrml_read/string_util.h @@ -38,22 +38,20 @@ #define KWPROTO 2 #define MAXSTRSIZE 512 -using namespace std; - char *nextWord(char *inputstring, char *nextwd); bool findKeyWord(char *inputstring, int kw); -void stringcopy(string &str1, char *str2); -int stringcompare(string &str1, char *str2); +void stringcopy(std::string &str1, char *str2); +int stringcompare(std::string &str1, char *str2); char *getNextWord(char *instring, char *nextword); char *getNextWord(char *nextword); -void replaceStringChars(string &str, char ch,const char *rstring); +void replaceStringChars(std::string &str, char ch,const char *rstring); void formatString(char *instring); int findFieldName(char *instring); void getSFVec4f(float *p); void getInt(int &n); void getFloat(float &n); -void getCoordIndex(vector &ccoordindex); -void getPoint(vector &cpoint); +void getCoordIndex(std::vector &ccoordindex); +void getPoint(std::vector &cpoint); #endif diff --git a/src/libgcv/plugins/vrml/vrml_read/transform_node.cpp b/src/libgcv/plugins/vrml/vrml_read/transform_node.cpp index ebdd2030d80..4bc59f75d42 100644 --- a/src/libgcv/plugins/vrml/vrml_read/transform_node.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/transform_node.cpp @@ -32,14 +32,12 @@ #include "node.h" #include "parser.h" -using namespace std; - //Peforms transforms on transform node children void TRANSFORM::transformChild(NODE *pnode) { PARSER parse; - vector mychildlist; + std::vector mychildlist; unsigned int count; double tempvec[3]; double temprotvec[3]; @@ -106,7 +104,7 @@ TRANSFORM::matrotate(double *output, double angle, double x, double y, double z) } void -TRANSFORM::transformSceneVert(vector &scenenoderef) +TRANSFORM::transformSceneVert(std::vector &scenenoderef) { int size = static_cast(scenenoderef.size()); int i; diff --git a/src/libgcv/plugins/vrml/vrml_read/transform_node.h b/src/libgcv/plugins/vrml/vrml_read/transform_node.h index af373462a20..db0f3ebca62 100644 --- a/src/libgcv/plugins/vrml/vrml_read/transform_node.h +++ b/src/libgcv/plugins/vrml/vrml_read/transform_node.h @@ -37,7 +37,7 @@ class TRANSFORM public: void transformChild(NODE *pnode); void matrotate(double *Result, double Theta, double x, double y, double z); - void transformSceneVert(vector &scenenoderef); + void transformSceneVert(std::vector &scenenoderef); }; diff --git a/src/libgcv/plugins/vrml/vrml_read/vrml_read.cpp b/src/libgcv/plugins/vrml/vrml_read/vrml_read.cpp index e3f0fc7ac52..f66863754b3 100644 --- a/src/libgcv/plugins/vrml/vrml_read/vrml_read.cpp +++ b/src/libgcv/plugins/vrml/vrml_read/vrml_read.cpp @@ -50,8 +50,6 @@ void formatString(char *instring); void get4vec(float *p); void get3vec(float *p); -using namespace std; - static struct bg_vert_tree *tree; static struct wmember all_head; static int *bot_faces=NULL; /* array of ints (indices into tree->the_array array) three per face */ @@ -176,7 +174,7 @@ parseNodeData(NODE* node) } static void -Parse_input(vector &childlist) +Parse_input(std::vector &childlist) { size_t size = childlist.size(); size_t i; @@ -203,8 +201,8 @@ Parse_input(vector &childlist) static int vrml_read(struct gcv_context *context, const struct gcv_opts *gcv_options, const void *UNUSED(options_data), const char *source_path) { - vector childlist; - vector parent; + std::vector childlist; + std::vector parent; NODE snode; TRANSFORM tnode; int type; diff --git a/src/libgcv/plugins/vrml/vrml_write.c b/src/libgcv/plugins/vrml/vrml_write.c index 3f366c383bf..1e7f4c7ae31 100644 --- a/src/libgcv/plugins/vrml/vrml_write.c +++ b/src/libgcv/plugins/vrml/vrml_write.c @@ -305,7 +305,7 @@ leaf_tess1(struct db_tree_state *tsp, const struct db_full_path *pathp, struct r if (ip->idb_type != ID_BOT) { data->pmp->num_nonbots++; - return nmg_booltree_leaf_tess(tsp, pathp, ip, client_data); + return rt_booltree_leaf_tess(tsp, pathp, ip, client_data); } bot = (struct rt_bot_internal *)ip->idb_ptr; @@ -1300,7 +1300,7 @@ vrml_write(struct gcv_context *context, const struct gcv_opts *gcv_options, cons &tree_state, 0, nmg_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)®ion_end_data); /* in librt/nmg_bool.c */ goto out; } diff --git a/src/libged/CMakeLists.txt b/src/libged/CMakeLists.txt index 80abc0ae474..866a2ec64dc 100644 --- a/src/libged/CMakeLists.txt +++ b/src/libged/CMakeLists.txt @@ -28,11 +28,12 @@ set(LIBGED_SOURCES exec_mapping.cpp ged_init.cpp columns.c + dbi_state.cpp display_list.c draw.cpp facedef.c - ged.c - ged_util.c + ged.cpp + ged_util.cpp get_obj_bounds.c get_solid_kp.c inside.c @@ -46,7 +47,6 @@ set(LIBGED_SOURCES rotate_extrude.c rotate_hyp.c rotate_tgc.c - select.cpp tab_complete.cpp trace.c track.c @@ -85,7 +85,7 @@ set(GED_LOCAL_INCLUDE_DIRS BRLCAD_LIB_INCLUDE_DIRS(ged GED_INCLUDE_DIRS GED_LOCAL_INCLUDE_DIRS) -BRLCAD_ADDLIB(libged "${LIBGED_SOURCES}" "libwdb;liboptical;librt;libbrep;libnmg;libbv;libbg;libbn;libbu;libicv;libanalyze;${PNG_LIBRARIES};${REGEX_LIBRARIES};${WINSOCK_LIB};${M_LIBRARY}") +BRLCAD_ADDLIB(libged "${LIBGED_SOURCES}" "${libged_deps};${PNG_LIBRARIES};${REGEX_LIBRARIES};${WINSOCK_LIB};${M_LIBRARY}") SET_TARGET_PROPERTIES(libged PROPERTIES VERSION 20.0.1 SOVERSION 20) add_subdirectory(tests) @@ -93,33 +93,6 @@ add_subdirectory(simulate/tests) BRLCAD_ADDEXEC(test_help help/test_help.c libged TEST) -set(ged_ignore_files - CMakeLists.txt - NOTES - README - TODO - alphanum.h - bot/ged_bot.h - brep/ged_brep.h - check/check_private.h - ged_private.h - joint/joint.h - osg.cpp - pscale/pscale.h - pnts_util.h - qray.h - simulate/NOTES - simulate/rt_collision_algorithm.hpp - simulate/rt_collision_shape.hpp - simulate/rt_debug_draw.hpp - simulate/rt_instance.hpp - simulate/rt_motion_state.hpp - simulate/simulation.hpp - simulate/utility.hpp - include/plugin.h - ) -CMAKEFILES(${ged_ignore_files}) - # Plugins add_subdirectory(3ptarb) add_subdirectory(adc) @@ -355,6 +328,34 @@ add_subdirectory(xpush) add_subdirectory(zap) add_subdirectory(zoom) +set(ged_ignore_files + CMakeLists.txt + NOTES + README + TODO + alphanum.h + bot/ged_bot.h + brep/ged_brep.h + check/check_private.h + ged_private.h + joint/joint.h + osg.cpp + pscale/pscale.h + pnts_util.h + qray.h + simulate/NOTES + simulate/rt_collision_algorithm.hpp + simulate/rt_collision_shape.hpp + simulate/rt_debug_draw.hpp + simulate/rt_instance.hpp + simulate/rt_motion_state.hpp + simulate/simulation.hpp + simulate/utility.hpp + include/plugin.h + ) +CMAKEFILES(${ged_ignore_files}) + + # Local Variables: # tab-width: 8 # mode: cmake diff --git a/src/libged/adc/adc.c b/src/libged/adc/adc.c index 5cd609ec0e0..6665012630c 100644 --- a/src/libged/adc/adc.c +++ b/src/libged/adc/adc.c @@ -117,10 +117,13 @@ ged_adc_core(struct ged *gedp, int incr_flag; int i; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + struct bview *v = gedp->ged_gvp; + fastf_t gv_scale = (gedp->dbip) ? v->gv_scale * gedp->dbip->dbi_base2local : v->gv_scale; + double sval = (gedp->dbip) ? gedp->dbip->dbi_local2base : 1.0; + /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); @@ -219,14 +222,14 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dst")) { if (argc == 0) { - bu_vls_printf(gedp->ged_result_str, "%g", gedp->ged_gvp->gv_s->gv_adc.dst * gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + bu_vls_printf(gedp->ged_result_str, "%g", v->gv_s->gv_adc.dst * gv_scale); return BRLCAD_OK; } else if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_dst) { if (incr_flag) - gedp->ged_gvp->gv_s->gv_adc.dst += user_pt[0] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.dst += user_pt[0] / gv_scale; else - gedp->ged_gvp->gv_s->gv_adc.dst = user_pt[0] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.dst = user_pt[0] / gv_scale; gedp->ged_gvp->gv_s->gv_adc.dv_dist = (gedp->ged_gvp->gv_s->gv_adc.dst / M_SQRT1_2 - 1.0) * GED_MAX; } @@ -262,7 +265,7 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dh")) { if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { - gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] += user_pt[0] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] += user_pt[0] / gv_scale; adc_grid_to_adc_view(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_view2model, GED_MAX); MAT4X3PNT(gedp->ged_gvp->gv_s->gv_adc.pos_model, gedp->ged_gvp->gv_view2model, gedp->ged_gvp->gv_s->gv_adc.pos_view); } @@ -277,7 +280,7 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dv")) { if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { - gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] += user_pt[0] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] += user_pt[0] / gv_scale; adc_grid_to_adc_view(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_view2model, GED_MAX); MAT4X3PNT(gedp->ged_gvp->gv_s->gv_adc.pos_model, gedp->ged_gvp->gv_view2model, gedp->ged_gvp->gv_s->gv_adc.pos_view); } @@ -292,17 +295,17 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "hv")) { if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "%g %g", - gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] * gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local, - gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] * gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] * gv_scale, + gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] * gv_scale); return BRLCAD_OK; } else if (argc == 2) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { if (incr_flag) { - gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] += user_pt[X] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); - gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] += user_pt[Y] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] += user_pt[X] / gv_scale; + gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] += user_pt[Y] / gv_scale; } else { - gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] = user_pt[X] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); - gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] = user_pt[Y] / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_adc.pos_grid[X] = user_pt[X] / gv_scale; + gedp->ged_gvp->gv_s->gv_adc.pos_grid[Y] = user_pt[Y] / gv_scale; } gedp->ged_gvp->gv_s->gv_adc.pos_grid[Z] = 0.0; @@ -320,7 +323,8 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dx")) { if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { - gedp->ged_gvp->gv_s->gv_adc.pos_model[X] += user_pt[0] * gedp->dbip->dbi_local2base; + double pval = (gedp->dbip) ? (user_pt[0] * gedp->dbip->dbi_local2base) : user_pt[0]; + gedp->ged_gvp->gv_s->gv_adc.pos_model[X] += pval; adc_model_to_adc_view(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view, GED_MAX); adc_view_to_adc_grid(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view); } @@ -335,7 +339,8 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dy")) { if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { - gedp->ged_gvp->gv_s->gv_adc.pos_model[Y] += user_pt[0] * gedp->dbip->dbi_local2base; + double pval = (gedp->dbip) ? (user_pt[0] * gedp->dbip->dbi_local2base) : user_pt[0]; + gedp->ged_gvp->gv_s->gv_adc.pos_model[Y] += pval; adc_model_to_adc_view(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view, GED_MAX); adc_view_to_adc_grid(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view); } @@ -350,7 +355,8 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "dz")) { if (argc == 1) { if (!gedp->ged_gvp->gv_s->gv_adc.anchor_pos) { - gedp->ged_gvp->gv_s->gv_adc.pos_model[Z] += user_pt[0] * gedp->dbip->dbi_local2base; + double pval = (gedp->dbip) ? (user_pt[0] * gedp->dbip->dbi_local2base) : user_pt[0]; + gedp->ged_gvp->gv_s->gv_adc.pos_model[Z] += pval; adc_model_to_adc_view(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view, GED_MAX); adc_view_to_adc_grid(&(gedp->ged_gvp->gv_s->gv_adc), gedp->ged_gvp->gv_model2view); } @@ -364,11 +370,11 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "xyz")) { if (argc == 0) { - VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.pos_model, gedp->dbip->dbi_base2local); + VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.pos_model, sval); bu_vls_printf(gedp->ged_result_str, "%g %g %g", V3ARGS(scaled_pos)); return BRLCAD_OK; } else if (argc == 3) { - VSCALE(user_pt, user_pt, gedp->dbip->dbi_local2base); + VSCALE(user_pt, user_pt, sval); if (incr_flag) { VADD2(gedp->ged_gvp->gv_s->gv_adc.pos_model, gedp->ged_gvp->gv_s->gv_adc.pos_model, user_pt); @@ -481,12 +487,12 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "anchorpoint_a1")) { if (argc == 0) { - VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a1, gedp->dbip->dbi_base2local); + VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a1, sval); bu_vls_printf(gedp->ged_result_str, "%g %g %g", V3ARGS(scaled_pos)); return BRLCAD_OK; } else if (argc == 3) { - VSCALE(user_pt, user_pt, gedp->dbip->dbi_local2base); + VSCALE(user_pt, user_pt, sval); if (incr_flag) { VADD2(gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a1, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a1, user_pt); @@ -527,13 +533,13 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "anchorpoint_a2")) { if (argc == 0) { - VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a2, gedp->dbip->dbi_base2local); + VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a2, sval); bu_vls_printf(gedp->ged_result_str, "%g %g %g", V3ARGS(scaled_pos)); return BRLCAD_OK; } else if (argc == 3) { - VSCALE(user_pt, user_pt, gedp->dbip->dbi_local2base); + VSCALE(user_pt, user_pt, sval); if (incr_flag) { VADD2(gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a2, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_a2, user_pt); @@ -574,12 +580,12 @@ ged_adc_core(struct ged *gedp, if (BU_STR_EQUAL(parameter, "anchorpoint_dst")) { if (argc == 0) { - VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_dst, gedp->dbip->dbi_base2local); + VSCALE(scaled_pos, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_dst, sval); bu_vls_printf(gedp->ged_result_str, "%g %g %g", V3ARGS(scaled_pos)); return BRLCAD_OK; } else if (argc == 3) { - VSCALE(user_pt, user_pt, gedp->dbip->dbi_local2base); + VSCALE(user_pt, user_pt, sval); if (incr_flag) { VADD2(gedp->ged_gvp->gv_s->gv_adc.anchor_pt_dst, gedp->ged_gvp->gv_s->gv_adc.anchor_pt_dst, user_pt); @@ -608,7 +614,7 @@ ged_adc_core(struct ged *gedp, } if (BU_STR_EQUAL(parameter, "vars")) { - adc_vls_print(gedp->ged_gvp, gedp->dbip->dbi_base2local, gedp->ged_result_str); + adc_vls_print(gedp->ged_gvp, sval, gedp->ged_result_str); return BRLCAD_OK; } diff --git a/src/libged/ae2dir/ae2dir.c b/src/libged/ae2dir/ae2dir.c index e13e0cfe52a..2be65542cab 100644 --- a/src/libged/ae2dir/ae2dir.c +++ b/src/libged/ae2dir/ae2dir.c @@ -40,7 +40,6 @@ ged_ae2dir_core(struct ged *gedp, int argc, const char *argv[]) int iflag; static const char *usage = "[-i] az el"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ @@ -72,7 +71,7 @@ ged_ae2dir_core(struct ged *gedp, int argc, const char *argv[]) az *= DEG2RAD; el *= DEG2RAD; - V3DIR_FROM_AZEL(dir, az, el); + bn_vec_ae(dir, az, el); if (iflag) VSCALE(dir, dir, -1); diff --git a/src/libged/analyze/analyze.cpp b/src/libged/analyze/analyze.cpp index eed24ac33dd..81234cf1d95 100644 --- a/src/libged/analyze/analyze.cpp +++ b/src/libged/analyze/analyze.cpp @@ -36,8 +36,8 @@ extern "C" { extern "C" { #include "bu/cmd.h" #include "bu/opt.h" -#include "./ged_analyze.h" } +#include "./ged_analyze.h" #include "../ged_private.h" #define DB_SOLID INT_MAX diff --git a/src/libged/analyze/op_pnts_vol.cpp b/src/libged/analyze/op_pnts_vol.cpp index bac0dff3e52..4db4d46d0aa 100644 --- a/src/libged/analyze/op_pnts_vol.cpp +++ b/src/libged/analyze/op_pnts_vol.cpp @@ -35,10 +35,10 @@ extern "C" { extern "C" { #include "rt/geom.h" #include "analyze.h" +} #include "../ged_private.h" #include "../pnts_util.h" #include "./ged_analyze.h" -} struct ray_result { point_t *p; diff --git a/src/libged/analyze/util.cpp b/src/libged/analyze/util.cpp index 176e5eb0f6b..0315cf96688 100644 --- a/src/libged/analyze/util.cpp +++ b/src/libged/analyze/util.cpp @@ -37,8 +37,8 @@ extern "C" { extern "C" { #include "bu/malloc.h" #include "bu/vls.h" -#include "./ged_analyze.h" } +#include "./ged_analyze.h" #include "../ged_private.h" void get_dashes(field_t *f, const int ndashes) diff --git a/src/libged/annotate/annotate.c b/src/libged/annotate/annotate.c index bd7f16aadb6..521a50313a6 100644 --- a/src/libged/annotate/annotate.c +++ b/src/libged/annotate/annotate.c @@ -127,7 +127,6 @@ ged_annotate_core(struct ged *gedp, int argc, const char *argv[]) int object_count = 0; int i; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ diff --git a/src/libged/autoview/autoview.c b/src/libged/autoview/autoview.c index 36c472c6507..25542d4ce3a 100644 --- a/src/libged/autoview/autoview.c +++ b/src/libged/autoview/autoview.c @@ -51,7 +51,6 @@ ged_autoview_core(struct ged *gedp, int argc, const char *argv[]) /* less than or near zero uses default, 0.5 model scale == 2.0 view factor */ fastf_t factor = -1.0; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/autoview/autoview2.cpp b/src/libged/autoview/autoview2.cpp index 797daae50bf..b6f5add915f 100644 --- a/src/libged/autoview/autoview2.cpp +++ b/src/libged/autoview/autoview2.cpp @@ -47,7 +47,6 @@ ged_autoview2_core(struct ged *gedp, int argc, const char *argv[]) /* default, 0.5 model scale == 2.0 view factor */ fastf_t factor = BV_AUTOVIEW_SCALE_DEFAULT; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/bev/bev.c b/src/libged/bev/bev.c index f8efc1940c1..d22b8eb2689 100644 --- a/src/libged/bev/bev.c +++ b/src/libged/bev/bev.c @@ -169,7 +169,7 @@ ged_bev_core(struct ged *gedp, int argc, const char *argv[]) &wdbp->wdb_initial_tree_state, 0, /* take all regions */ bev_facetize_region_end, - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)gedp); if (i < 0) { diff --git a/src/libged/bigE/bigE.c b/src/libged/bigE/bigE.c index 05893faf896..bbafcaa41ea 100644 --- a/src/libged/bigE/bigE.c +++ b/src/libged/bigE/bigE.c @@ -2002,6 +2002,7 @@ ged_E_core(struct ged *gedp, int argc, const char *argv[]) /* XXX: where is this released? */ BU_ALLOC(dgcdp, struct _ged_client_data); dgcdp->gedp = gedp; + dgcdp->v = gedp->ged_gvp; dgcdp->wdbp = wdb_dbopen(dgcdp->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); dgcdp->do_polysolids = 0; dgcdp->vs.color_override = 0; diff --git a/src/libged/blast/blast.c b/src/libged/blast/blast.c index b089c356408..42f4fc63e41 100644 --- a/src/libged/blast/blast.c +++ b/src/libged/blast/blast.c @@ -37,7 +37,6 @@ ged_blast_core(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "object(s)"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/bot/decimate.cpp b/src/libged/bot/decimate.cpp index a4e5c7aba2b..0c6a1ef6884 100644 --- a/src/libged/bot/decimate.cpp +++ b/src/libged/bot/decimate.cpp @@ -184,14 +184,14 @@ om_bot_decimate(struct ged *gedp, struct rt_bot_internal *input_bot, double max_ #else /* BUILD_OPENMESH_TOOLS */ -static bool -om_bot_decimate(struct ged* gedp, struct rt_bot_internal* UNUSED(bot), int UNUSED(alg), double UNUSED(max_err)) +static struct rt_bot_internal * +om_bot_decimate(struct ged *gedp, struct rt_bot_internal *UNUSED(input_bot), double UNUSED(max_err)) { bu_vls_printf(gedp->ged_result_str, "WARNING: BoT OpenMesh subcommands are unavailable.\n" "BRL-CAD needs to be compiled with OpenMesh support.\n" "(cmake -DBRLCAD_ENABLE_OPENMESH=ON or set -DOPENMESH_ROOT=/path/to/openmesh)\n"); - return false; + return NULL; } #endif /* BUILD_OPENMESH_TOOLS */ diff --git a/src/libged/bot/smooth.cpp b/src/libged/bot/smooth.cpp index ae6ddd83b39..027bc988a17 100644 --- a/src/libged/bot/smooth.cpp +++ b/src/libged/bot/smooth.cpp @@ -204,14 +204,14 @@ bot_smooth(struct ged *gedp, struct rt_bot_internal *input_bot, int component, i #else /* BUILD_OPENMESH_TOOLS */ -static bool -bot_smooth(struct ged *gedp, struct rt_bot_internal *UNUSED(input_bot), int UNUSED(component), int UNUSED(continuity)) +static struct rt_bot_internal * +bot_smooth(struct ged *gedp, struct rt_bot_internal *UNUSED(input_bot), int UNUSED(component), int UNUSED(continuity), double UNUSED(max_lerr), double UNUSED(max_aerr), int UNUSED(iterations)) { bu_vls_printf(gedp->ged_result_str, "WARNING: BoT OpenMesh subcommands are unavailable.\n" "BRL-CAD needs to be compiled with OpenMesh support.\n" "(cmake -DBRLCAD_ENABLE_OPENVDB=ON or set -DOPENMESH_ROOT=/path/to/openmesh)\n"); - return false; + return NULL; } #endif /* BUILD_OPENMESH_TOOLS */ diff --git a/src/libged/bot/subdivide.cpp b/src/libged/bot/subdivide.cpp index 03c2820563d..c6228361657 100644 --- a/src/libged/bot/subdivide.cpp +++ b/src/libged/bot/subdivide.cpp @@ -229,14 +229,15 @@ bot_subd(struct ged *gedp, struct rt_bot_internal *input_bot, int alg, int level #else /* BUILD_OPENMESH_TOOLS */ -static bool -bot_subd(struct ged* gedp, struct rt_bot_internal* UNUSED(bot), int UNUSED(alg)) +static struct rt_bot_internal * +bot_subd(struct ged *gedp, struct rt_bot_internal *UNUSED(input_bot), int UNUSED(alg), int UNUSED(level)) + { bu_vls_printf(gedp->ged_result_str, "WARNING: BoT OpenMesh subcommands are unavailable.\n" "BRL-CAD needs to be compiled with OpenMesh support.\n" "(cmake -DBRLCAD_ENABLE_OPENVDB=ON or set -DOPENMESH_ROOT=/path/to/openmesh)\n"); - return false; + return NULL; } #endif /* BUILD_OPENMESH_TOOLS */ diff --git a/src/libged/brep/CMakeLists.txt b/src/libged/brep/CMakeLists.txt index 0ce477334ed..16792f6128b 100644 --- a/src/libged/brep/CMakeLists.txt +++ b/src/libged/brep/CMakeLists.txt @@ -1,6 +1,10 @@ set(DPLOT_READER dplot) +find_package(PERPLEX) +find_package(LEMON) +find_package(RE2C) + PERPLEX_TARGET( ${DPLOT_READER}_scanner ${DPLOT_READER}_scanner.perplex @@ -27,17 +31,18 @@ include_directories( set(BREP_SRCS ${PERPLEX_${DPLOT_READER}_scanner_SRC} ${LEMON_${DPLOT_READER}_parser_SRC} - curve.cpp - dplot.c brep.cpp conversion.cpp csg.cpp + dplot.c + geometry.cpp info.cpp intersect.cpp pick.cpp plot.cpp - surface.cpp + repair.cpp tikz.cpp + topology.cpp valid.cpp ) diff --git a/src/libged/brep/brep.cpp b/src/libged/brep/brep.cpp index 237f0b9ec5a..088c9930cfe 100644 --- a/src/libged/brep/brep.cpp +++ b/src/libged/brep/brep.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "bu/cmd.h" #include "bu/color.h" @@ -540,6 +541,80 @@ _brep_cmd_csg(void *bs, int argc, const char **argv) return _ged_brep_to_csg(gedp, gb->dp->d_namep, gb->verbosity); } +extern "C" int +_brep_cmd_dump(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] dump "; + const char *purpose_string = "Write the BRep object(s) in the tree to a .3dm file"; + if (_brep_cmd_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_info *gb = (struct _ged_brep_info *)bs; + struct ged *gedp = gb->gedp; + + argc--; argv++; + + if (!argc) { + bu_vls_printf(gedp->ged_result_str, "need output filename to store 3DM output in."); + return BRLCAD_ERROR; + } + if (bu_file_exists(argv[0], NULL)) { + bu_vls_sprintf(gedp->ged_result_str, "Error: file %s already exists\n", argv[0]); + return BRLCAD_ERROR; + } + + ONX_Model model; + struct bu_vls msg = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&msg, "BRL-CAD 3dm dump of brep objects in %s obj %s", gedp->dbip->dbi_filename, gb->solid_name.c_str()); + model.m_sStartSectionComments = bu_vls_cstr(&msg); + model.m_properties.m_Application.m_application_name = "BRL-CAD"; + model.m_properties.m_Application.m_application_URL = "https://brlcad.org"; + + // Find all brep paths + struct bu_ptbl breps = BU_PTBL_INIT_ZERO; + const char *brep_search = "-type brep"; + db_update_nref(gedp->dbip, &rt_uniresource); + (void)db_search(&breps, DB_SEARCH_TREE, brep_search, 1, &gb->dp, gedp->dbip, NULL); + for (size_t i = 0; i < BU_PTBL_LEN(&breps); i++) { + struct db_full_path *fp = (struct db_full_path *)BU_PTBL_GET(&breps, i); + mat_t m; + struct bu_color c; + MAT_IDN(m); + db_path_to_mat(gedp->dbip, fp, m, 0, &rt_uniresource); + db_full_path_color(&c, fp, gedp->dbip, &rt_uniresource); + struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); + struct rt_db_internal intern; + if (rt_db_get_internal(&intern, dp, gedp->dbip, m, &rt_uniresource) < 0) { + bu_log("Error - unable to get internal of %s\n", dp->d_namep); + continue; + } + ON_Brep *o_brep = ((struct rt_brep_internal *)intern.idb_ptr)->brep; + if (!o_brep) { + bu_log("Error - no ON_Brep data found for %s\n", dp->d_namep); + continue; + } + + ON_3dmObjectAttributes attrs; + + // NOTE: this naive conversion ONLY works on ASCII chars + std::string dnamep_str(dp->d_namep); + std::wstring wc(dnamep_str.begin(), dnamep_str.end()); + attrs.SetName(wc.c_str(), true); + + int rgb[3]; + bu_color_to_rgb_ints(&c, &rgb[0], &rgb[1], &rgb[2]); + attrs.m_color = ON_Color(rgb[0], rgb[1], rgb[2]); + attrs.SetColorSource(ON::color_from_object); + + model.AddModelGeometryComponent(o_brep, &attrs, true); + } + + ON_TextLog error_log; // errors printed to stdout + model.Write(argv[0], 0, &error_log); + + return BRLCAD_OK; +} extern "C" int _brep_cmd_flip(void *bs, int argc, const char **argv) @@ -561,15 +636,6 @@ _brep_cmd_flip(void *bs, int argc, const char **argv) b_ip->brep->Flip(); - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - // Make the new one struct rt_wdb *wdbp = wdb_dbopen(gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); if (mk_brep(wdbp, gb->solid_name.c_str(), (void *)b_ip->brep)) { @@ -578,6 +644,29 @@ _brep_cmd_flip(void *bs, int argc, const char **argv) return BRLCAD_OK; } +extern "C" int +_brep_cmd_geo(void *bs, int argc, const char **argv) +{ + struct _ged_brep_info *gb = (struct _ged_brep_info *)bs; + const char *purpose_string = "NURBS geometry editing support for brep objects"; + if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { + bu_vls_printf(gb->gedp->ged_result_str, "%s\n", purpose_string); + return BRLCAD_OK; + } + if (argc >= 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + return brep_geo(gb, argc, argv); + } + + if (gb->intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BREP) { + bu_vls_printf(gb->gedp->ged_result_str, ": object %s is not of type brep\n", gb->solid_name.c_str()); + return BRLCAD_ERROR; + } + + argc--; argv++; + + return brep_geo(gb, argc, argv); +} + extern "C" int _brep_cmd_info(void *bs, int argc, const char **argv) { @@ -848,6 +937,32 @@ _brep_cmd_plot(void *bs, int argc, const char **argv) return brep_plot(gb, argc, argv); } +extern "C" int +_brep_cmd_repair(void *bs, int argc, const char **argv) +{ + struct _ged_brep_info *gb = (struct _ged_brep_info *)bs; + struct ged *gedp = gb->gedp; + + const char *purpose_string = "attempt repairs on the BRep object"; + if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { + bu_vls_printf(gb->gedp->ged_result_str, "%s\n", purpose_string); + return BRLCAD_OK; + } + if (argc >= 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + return brep_info(gedp->ged_result_str, NULL, argc, argv); + } + + if (gb->intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BREP) { + bu_vls_printf(gb->gedp->ged_result_str, ": object %s is not of type brep\n", gb->solid_name.c_str()); + return BRLCAD_ERROR; + } + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gb->intern.idb_ptr; + + argc--; argv++; + + return brep_repair(gedp, b_ip->brep, gb->solid_name.c_str(), argc, argv); +} + extern "C" int _brep_cmd_selection(void *bs, int argc, const char **argv) { @@ -1022,15 +1137,6 @@ _brep_cmd_shrink_surfaces(void *bs, int argc, const char **argv) b_ip->brep->ShrinkSurfaces(); - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - // Make the new one struct rt_wdb *wdbp = wdb_dbopen(gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); if (mk_brep(wdbp, gb->solid_name.c_str(), (void *)b_ip->brep)) { @@ -1261,16 +1367,16 @@ _brep_cmd_valid(void *bs, int argc, const char **argv) } static int -_brep_cmd_curve(void *bs, int argc, const char **argv) +_brep_cmd_topo(void *bs, int argc, const char **argv) { struct _ged_brep_info *gb = (struct _ged_brep_info *)bs; - const char *purpose_string = "NURBS curves editing support for brep objects"; + const char *purpose_string = "NURBS topology editing support for brep objects"; if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { bu_vls_printf(gb->gedp->ged_result_str, "%s\n", purpose_string); return BRLCAD_OK; } if (argc >= 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - return brep_curve(gb, argc, argv); + return brep_topo(gb, argc, argv); } if (gb->intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BREP) { @@ -1280,31 +1386,7 @@ _brep_cmd_curve(void *bs, int argc, const char **argv) argc--; argv++; - return brep_curve(gb, argc, argv); -} - - -static int -_brep_cmd_surface(void *bs, int argc, const char **argv) -{ - struct _ged_brep_info *gb = (struct _ged_brep_info *)bs; - const char *purpose_string = "NURBS surfaces editing support for brep objects"; - if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { - bu_vls_printf(gb->gedp->ged_result_str, "%s\n", purpose_string); - return BRLCAD_OK; - } - if (argc >= 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - return brep_surface(gb, argc, argv); - } - - if (gb->intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BREP) { - bu_vls_printf(gb->gedp->ged_result_str, ": object %s is not of type brep\n", gb->solid_name.c_str()); - return BRLCAD_ERROR; - } - - argc--; argv++; - - return brep_surface(gb, argc, argv); + return brep_topo(gb, argc, argv); } #if 0 @@ -1337,12 +1419,15 @@ const struct bu_cmdtab _brep_cmds[] = { { "bots", _brep_cmd_bots}, { "brep", _brep_cmd_brep}, { "csg", _brep_cmd_csg}, + { "dump", _brep_cmd_dump}, { "flip", _brep_cmd_flip}, + { "geo", _brep_cmd_geo}, { "info", _brep_cmd_info}, { "intersect", _brep_cmd_intersect}, { "pick", _brep_cmd_pick}, { "plate_mode", _brep_cmd_plate_mode}, { "plot", _brep_cmd_plot}, + { "repair", _brep_cmd_repair}, { "selection", _brep_cmd_selection}, { "solid", _brep_cmd_solid}, { "split", _brep_cmd_split}, @@ -1350,8 +1435,7 @@ const struct bu_cmdtab _brep_cmds[] = { { "tikz", _brep_cmd_tikz}, { "valid", _brep_cmd_valid}, //{ "weld", _brep_cmd_weld}, - { "curve", _brep_cmd_curve}, - { "surface", _brep_cmd_surface}, + { "topo", _brep_cmd_topo}, { (char *)NULL, NULL} }; @@ -1367,20 +1451,18 @@ _ged_brep_opt_color(struct bu_vls *msg, size_t argc, const char **argv, void *se extern "C" int ged_brep_core(struct ged *gedp, int argc, const char *argv[]) { - int help = 0; - struct _ged_brep_info gb; - gb.gedp = gedp; - gb.wdbp = wdb_dbopen(gb.gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - gb.cmds = _brep_cmds; - gb.verbosity = 0; - struct bu_color *color = NULL; - int plotres = 100; - // Sanity if (UNLIKELY(!gedp || !argc || !argv)) { return BRLCAD_ERROR; } + int help = 0; + struct bu_color *color = NULL; + int plotres = 100; + struct _ged_brep_info gb; + gb.verbosity = 0; + gb.gedp = gedp; + // Clear results bu_vls_trunc(gedp->ged_result_str, 0); @@ -1408,7 +1490,6 @@ ged_brep_core(struct ged *gedp, int argc, const char *argv[]) } - // High level options are only defined prior to the subcommand int cmd_pos = -1; for (int i = 0; i < argc; i++) { @@ -1454,6 +1535,9 @@ ged_brep_core(struct ged *gedp, int argc, const char *argv[]) GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + gb.gedp = gedp; + gb.wdbp = wdb_dbopen(gb.gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + gb.cmds = _brep_cmds; gb.solid_name = std::string(argv[0]); gb.dp = db_lookup(gedp->dbip, gb.solid_name.c_str(), LOOKUP_NOISY); if (gb.dp == RT_DIR_NULL) { diff --git a/src/libged/brep/curve.cpp b/src/libged/brep/curve.cpp deleted file mode 100644 index d92e2d3ad4e..00000000000 --- a/src/libged/brep/curve.cpp +++ /dev/null @@ -1,652 +0,0 @@ -/* C U R V E . C P P - * BRL-CAD - * - * Copyright (c) 2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libged/brep/curve.cpp - * - * NURBS curves editing support for brep objects - * - */ - -#include "common.h" - -#include "wdb.h" -#include "../ged_private.h" -#include "./ged_brep.h" - -using namespace brlcad; - -struct _ged_brep_icurve { - struct _ged_brep_info *gb; - struct bu_vls *vls; - const struct bu_cmdtab *cmds; -}; - -static int -_brep_curve_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps) -{ - struct _ged_brep_icurve *gb = (struct _ged_brep_icurve *)bs; - if (argc == 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - bu_vls_printf(gb->vls, "%s\n%s\n", us, ps); - return 1; - } - if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { - bu_vls_printf(gb->vls, "%s\n", ps); - return 1; - } - return 0; -} - -static int -_brep_cmd_curve_create(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve create "; - const char *purpose_string = "create a new NURBS curve"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - - argc--;argv++; - - ON_3dPoint position(0, 0, 0); - if (argc != 0 && argc != 3) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - if (argc == 3) { - position = ON_3dPoint(atof(argv[0]), atof(argv[1]), atof(argv[2])); - } - // Create a template nurbs curve - int curve_id = brep_curve_make(b_ip->brep, position); - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_in(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve in (if rational) ..."; - const char *purpose_string = "create a new NURBS curve given detailed description"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 4) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - bool is_rational = atoi(argv[1]); - int order = atoi(argv[2]); - int cv_count = atoi(argv[3]); - - if (order <= 0 || cv_count <= 0 || cv_count < order) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid order or cv_count\n"); - return BRLCAD_ERROR; - } - - if (argc < 4 + cv_count * (3 + (is_rational ? 1 : 0))) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments, you need to input %d more args about control vertices\n", 4 + cv_count * (3 + (is_rational ? 1 : 0)) - argc); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - - argc--;argv++; - - std::vector cv; - for (int i = 0; i < cv_count; i++) { - ON_4dPoint p; - p.x = atof(argv[3 + i * (3 + (is_rational ? 1 : 0))]); - p.y = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 1]); - p.z = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 2]); - if (is_rational) { - p.w = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 3]); - } else { - p.w = 1.0; - } - cv.push_back(p); - } - int curve_id = brep_curve_in(b_ip->brep, is_rational, order, cv_count, cv); - if (curve_id <= 0) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create curve\n"); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_interp(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve interp ..."; - const char *purpose_string = "create a new NURBS curve interpolating given control vertices"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 2) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int cv_count = atoi(argv[1]); - - if (cv_count <= 0) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid order or cv_count\n"); - return BRLCAD_ERROR; - } - - if (argc < 2 + cv_count * 3) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments, you need to input %d more args about control vertices\n", 2 + cv_count * 3 - argc); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - - argc--;argv++; - - std::vector points; - for (int i = 0; i < cv_count; i++) { - ON_3dPoint p; - p.x = atof(argv[1 + i * 3]); - p.y = atof(argv[1 + i * 3 + 1]); - p.z = atof(argv[1 + i * 3 + 2]); - points.push_back(p); - } - int curve_id = brep_curve_interpCrv(b_ip->brep, points); - if (curve_id <= 0) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create curve\n"); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_move(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve move "; - const char *purpose_string = "move a NURBS curve to a specified position"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - argc--;argv++; - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 4) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - ON_3dPoint p = ON_3dPoint(atof(argv[1]), atof(argv[2]), atof(argv[3])); - bool flag = brep_curve_move(b_ip->brep, atoi(argv[0]), p); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to move curve %s\n", argv[0]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_set_cv(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve set_cv []"; - const char *purpose_string = "set the control vertex of a NURBS curve"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - - if (argc < 6) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - - ON_4dPoint p = ON_4dPoint(atof(argv[3]), atof(argv[4]), atof(argv[5]), argc == 7 ? atof(argv[6]) : 1.0); - bool flag = brep_curve_set_cv(b_ip->brep, atoi(argv[1]), atoi(argv[2]), p); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to move control vertex %s of curve %s\n", argv[2], argv[1]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_flip(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] curve flip "; - const char *purpose_string = "Flip the direction of a NURBS curve"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 2) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int curve_id = 0; - try { - curve_id = std::stoi(argv[1]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - - bool flag = brep_curve_reverse(b_ip->brep, curve_id); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to reverse curve %s\n", argv[1]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_insert_knot(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] insert_knot "; - const char *purpose_string = "Insert a knot into a NURBS curve"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - argc--;argv++; - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 3) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int curve_id = 0; - try { - curve_id = std::stoi(argv[0]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - double knot_value = 0; - try { - knot_value = std::stod(argv[1]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid knot value\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - int multiplicity = 0; - try { - multiplicity = std::stoi(argv[2]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid multiplicity\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - bool flag = brep_curve_insert_knot(b_ip->brep, curve_id, knot_value, multiplicity); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to insert knot into curve %s\n", argv[0]); - return BRLCAD_ERROR; - } - - // Delete the old object - - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_trim(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] trim "; - const char *purpose_string = "trim a NURBS curve using start and end parameters"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - argc--;argv++; - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 3) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int curve_id = 0; - try { - curve_id = std::stoi(argv[0]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - double start_param = 0; - try { - start_param = std::stod(argv[1]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid start parameter\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - double end_param = 0; - try { - end_param = std::stod(argv[2]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid end parameter\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - bool flag = brep_curve_trim(b_ip->brep, curve_id, start_param, end_param); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to trim curve %s\n", argv[0]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_curve_join(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] join "; - const char *purpose_string = "join end of curve 1 to start of curve 2"; - if (_brep_curve_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - argc--;argv++; - struct _ged_brep_icurve *gib = (struct _ged_brep_icurve *)bs; - if (argc < 2) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int curve_id_1 = 0; - int curve_id_2 = 0; - try { - curve_id_1 = std::stoi(argv[0]); - curve_id_2 = std::stoi(argv[1]); - } catch (const std::exception &e) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - int flag = brep_curve_join(b_ip->brep, curve_id_1, curve_id_2); - if (flag < 0) { - bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to join curve %s and curve %s\n", argv[0], argv[1]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "joined curve id %d, old curves deleted.\n", flag); - return BRLCAD_OK; -} - -static void -_brep_curve_help(struct _ged_brep_icurve *bs, int argc, const char **argv) -{ - struct _ged_brep_icurve *gb = (struct _ged_brep_icurve *)bs; - if (!argc || !argv) { - bu_vls_printf(gb->vls, "brep [options] curve [args]\n"); - bu_vls_printf(gb->vls, "Available subcommands:\n"); - const struct bu_cmdtab *ctp = NULL; - int ret; - const char *helpflag[2]; - helpflag[1] = PURPOSEFLAG; - for (ctp = gb->cmds; ctp->ct_name != (char *)NULL; ctp++) { - bu_vls_printf(gb->vls, " %s\t\t", ctp->ct_name); - helpflag[0] = ctp->ct_name; - bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); - } - } else { - int ret; - const char *helpflag[2]; - helpflag[0] = argv[0]; - helpflag[1] = HELPFLAG; - bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); - } -} - -const struct bu_cmdtab _brep_curve_cmds[] = { - { "create", _brep_cmd_curve_create}, - { "in", _brep_cmd_curve_in}, - { "inter", _brep_cmd_curve_interp}, - { "move", _brep_cmd_curve_move}, - { "set_cv", _brep_cmd_curve_set_cv}, - { "flip", _brep_cmd_curve_flip}, - { "insert_knot", _brep_cmd_curve_insert_knot}, - { "trim", _brep_cmd_curve_trim}, - { "join", _brep_cmd_curve_join}, - { (char *)NULL, NULL} -}; - -int brep_curve(struct _ged_brep_info *gb, int argc, const char **argv) -{ - struct _ged_brep_icurve gib; - gib.gb = gb; - gib.vls = gb->gedp->ged_result_str; - gib.cmds = _brep_curve_cmds; - - const ON_Brep *brep = ((struct rt_brep_internal *)(gb->intern.idb_ptr))->brep; - if (brep == NULL) { - bu_vls_printf(gib.vls, "not a brep object\n"); - return BRLCAD_ERROR; - } - - if (!argc) { - _brep_curve_help(&gib, 0, NULL); - return BRLCAD_OK; - } - - // TODO: add help flag - if (argc > 1 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - argc--;argv++; - argc--;argv++; - _brep_curve_help(&gib, argc, argv); - return BRLCAD_OK; - } - - // Must have valid subcommand to process - if (bu_cmd_valid(_brep_curve_cmds, argv[0]) != BRLCAD_OK) { - bu_vls_printf(gib.vls, "invalid subcommand \"%s\" specified\n", argv[0]); - _brep_curve_help(&gib, 0, NULL); - return BRLCAD_ERROR; - } - - int ret; - if (bu_cmd(_brep_curve_cmds, argc, argv, 0, (void *)&gib, &ret) == BRLCAD_OK) { - return ret; - } - return BRLCAD_ERROR; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/brep/ged_brep.h b/src/libged/brep/ged_brep.h index a25d23b60ec..234b08d7820 100644 --- a/src/libged/brep/ged_brep.h +++ b/src/libged/brep/ged_brep.h @@ -96,10 +96,11 @@ _brep_indices(std::set &elements, struct bu_vls *vls, int argc, const char extern int _ged_brep_to_csg(struct ged *gedp, const char *obj_name, int verify); -extern int brep_curve(struct _ged_brep_info *gb, int argc, const char **argv); -extern int brep_surface(struct _ged_brep_info *gb, int argc, const char **argv); +extern int brep_geo(struct _ged_brep_info *gb, int argc, const char **argv); +extern int brep_topo(struct _ged_brep_info *gb, int argc, const char **argv); extern int brep_info(struct bu_vls *vls, const ON_Brep *brep, int argc, const char **argv); +extern int brep_repair(struct ged *gedp, const ON_Brep *brep, const char *oname, int argc, const char **argv); extern int brep_pick(struct _ged_brep_info *gb, int argc, const char **argv); extern int brep_plot(struct _ged_brep_info *gb, int argc, const char **argv); extern int brep_tikz(struct _ged_brep_info *gb, const char *outfile); diff --git a/src/libged/brep/geometry.cpp b/src/libged/brep/geometry.cpp new file mode 100644 index 00000000000..19d0915f8d7 --- /dev/null +++ b/src/libged/brep/geometry.cpp @@ -0,0 +1,1345 @@ +/* G E O M E T R Y . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/brep/geometry.cpp + * + * NURBS geometry editing support for brep objects + * + */ + +#include "common.h" + +#include "wdb.h" +#include "../ged_private.h" +#include "./ged_brep.h" + +using namespace brlcad; + +struct _ged_brep_igeo { + struct _ged_brep_info *gb; + struct bu_vls *vls; + const struct bu_cmdtab *cmds; +}; + +static int +_brep_geo_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps) +{ + struct _ged_brep_igeo *gb = (struct _ged_brep_igeo *)bs; + if (argc == 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + bu_vls_printf(gb->vls, "%s\n%s\n", us, ps); + return 1; + } + if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { + bu_vls_printf(gb->vls, "%s\n", ps); + return 1; + } + return 0; +} + +static int +_brep_cmd_geo_vertex_create(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo v_create "; + const char *purpose_string = "create a new vertex"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + ON_3dPoint position(atof(argv[0]), atof(argv[1]), atof(argv[2])); + int vertex = brep_vertex_create(b_ip->brep, position); + // Make the new one + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create vertex! id = %d", vertex); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_vertex_remove(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo v_remove "; + const char *purpose_string = "remove a vertex"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int v_id = atoi(argv[0]); + bool res = brep_vertex_remove(b_ip->brep, v_id); + if (!res) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to remove vertex %s\n", argv[0]); + return BRLCAD_ERROR; + } + // Make the new one + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "remove vertex %d", v_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve2d_create_line(void *bs, int argc, const char **argv) +{ + + const char *usage_string = "brep [options] geo c2_create_line "; + const char *purpose_string = "create a 2D parameter space geometric line"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + argc--;argv++; + + if (argc != 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + ON_2dPoint from(atof(argv[0]), atof(argv[1])); + ON_2dPoint to(atof(argv[2]), atof(argv[3])); + + // Create a 2d line + int curve_id = brep_curve2d_make_line(b_ip->brep, from, to); + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create C2 curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve2d_remove(void *bs, int argc, const char **argv) +{ + + const char *usage_string = "brep [options] geo remove "; + const char *purpose_string = "remove a 2D parameter space geometric curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + argc--;argv++; + + if (argc != 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = atoi(argv[0]); + + // Create a 2d line + bool res = brep_curve2d_remove(b_ip->brep, curve_id); + if (!res) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to remove curve %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "remove C2 curve %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_create(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_create "; + const char *purpose_string = "create a new NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + argc--;argv++; + + ON_3dPoint position(0, 0, 0); + if (argc != 0 && argc != 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + if (argc == 3) { + position = ON_3dPoint(atof(argv[0]), atof(argv[1]), atof(argv[2])); + } + // Create a template nurbs curve + int curve_id = brep_curve_make(b_ip->brep, position); + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_in(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_in (if rational) ..."; + const char *purpose_string = "create a new NURBS curve given detailed description"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + bool is_rational = atoi(argv[1]); + int order = atoi(argv[2]); + int cv_count = atoi(argv[3]); + + if (order <= 0 || cv_count <= 0 || cv_count < order) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid order or cv_count\n"); + return BRLCAD_ERROR; + } + + if (argc < 4 + cv_count * (3 + (is_rational ? 1 : 0))) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments, you need to input %d more args about control vertices\n", 4 + cv_count * (3 + (is_rational ? 1 : 0)) - argc); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + argc--;argv++; + + std::vector cv; + for (int i = 0; i < cv_count; i++) { + ON_4dPoint p; + p.x = atof(argv[3 + i * (3 + (is_rational ? 1 : 0))]); + p.y = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 1]); + p.z = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 2]); + if (is_rational) { + p.w = atof(argv[3 + i * (3 + (is_rational ? 1 : 0)) + 3]); + } else { + p.w = 1.0; + } + cv.push_back(p); + } + int curve_id = brep_curve_in(b_ip->brep, is_rational, order, cv_count, cv); + if (curve_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create curve\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_interp(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_interp ..."; + const char *purpose_string = "create a new NURBS curve interpolating given control vertices"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int cv_count = atoi(argv[1]); + + if (cv_count <= 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid cv_count\n"); + return BRLCAD_ERROR; + } + + if (argc < 2 + cv_count * 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments, you need to input %d more args about control vertices\n", 2 + cv_count * 3 - argc); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + argc--;argv++; + + std::vector points; + for (int i = 0; i < cv_count; i++) { + ON_3dPoint p; + p.x = atof(argv[1 + i * 3]); + p.y = atof(argv[1 + i * 3 + 1]); + p.z = atof(argv[1 + i * 3 + 2]); + points.push_back(p); + } + int curve_id = brep_curve_interpCrv(b_ip->brep, points); + if (curve_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create curve\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create C3 curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_copy(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_copy "; + const char *purpose_string = "copy a NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = atoi(argv[1]); + + if (curve_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve_id\n"); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + int res = brep_curve_copy(b_ip->brep, curve_id); + if (!res) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to copy curve\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "successful copy C3 curve! new curve id = %d", res); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_remove(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_remove "; + const char *purpose_string = "remove a NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = atoi(argv[1]); + + if (curve_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve_id\n"); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + bool res = brep_curve_remove(b_ip->brep, curve_id); + if (!res) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to remove curve\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "successful remove C3 curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_move(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_move "; + const char *purpose_string = "move a NURBS curve to a specified position"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + ON_3dPoint p = ON_3dPoint(atof(argv[1]), atof(argv[2]), atof(argv[3])); + bool flag = brep_curve_move(b_ip->brep, atoi(argv[0]), p); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to move curve %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_set_cv(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_set_cv []"; + const char *purpose_string = "set the control vertex of a NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + + if (argc < 6) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + ON_4dPoint p = ON_4dPoint(atof(argv[3]), atof(argv[4]), atof(argv[5]), argc == 7 ? atof(argv[6]) : 1.0); + bool flag = brep_curve_set_cv(b_ip->brep, atoi(argv[1]), atoi(argv[2]), p); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to move control vertex %s of curve %s\n", argv[2], argv[1]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_flip(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_flip "; + const char *purpose_string = "Flip the direction of a NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = 0; + try { + curve_id = std::stoi(argv[1]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + bool flag = brep_curve_reverse(b_ip->brep, curve_id); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to reverse curve %s\n", argv[1]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_insert_knot(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_insert_knot "; + const char *purpose_string = "Insert a knot into a NURBS curve"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = 0; + try { + curve_id = std::stoi(argv[0]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + double knot_value = 0; + try { + knot_value = std::stod(argv[1]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid knot value\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + int multiplicity = 0; + try { + multiplicity = std::stoi(argv[2]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid multiplicity\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_curve_insert_knot(b_ip->brep, curve_id, knot_value, multiplicity); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to insert knot into curve %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_trim(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_trim "; + const char *purpose_string = "trim a NURBS curve using start and end parameters"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = 0; + try { + curve_id = std::stoi(argv[0]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + double start_param = 0; + try { + start_param = std::stod(argv[1]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid start parameter\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + double end_param = 0; + try { + end_param = std::stod(argv[2]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid end parameter\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_curve_trim(b_ip->brep, curve_id, start_param, end_param); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to trim curve %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_split(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_split "; + const char *purpose_string = "split a NURBS curve into two at a parameter"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id = 0; + try { + curve_id = std::stoi(argv[0]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + double param = 0; + try { + param = std::stod(argv[1]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid parameter\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_curve_split(b_ip->brep, curve_id, param); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to split curve %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "split curve %s at parameter %s. Old curve removed.\n", argv[0], argv[1]); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_curve3d_join(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo c3_join "; + const char *purpose_string = "join end of curve 1 to start of curve 2"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int curve_id_1 = 0; + int curve_id_2 = 0; + try { + curve_id_1 = std::stoi(argv[0]); + curve_id_2 = std::stoi(argv[1]); + } catch (const std::exception &e) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid curve id\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", e.what()); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + int flag = brep_curve_join(b_ip->brep, curve_id_1, curve_id_2); + if (flag < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to join curve %s and curve %s\n", argv[0], argv[1]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "joined curve id %d, old curves deleted.\n", flag); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_create(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_create "; + const char *purpose_string = "create a new NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + ON_3dPoint position(0, 0, 0); + if (argc >= 3) { + position = ON_3dPoint(atof(argv[0]), atof(argv[1]), atof(argv[2])); + } + int surf_id = brep_surface_make(b_ip->brep, position); + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surf_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_interp(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_interp ..."; + const char *purpose_string = "create a new NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + argc--;argv++; + // Load and check the number of arguments + int cv_count_x = atoi(argv[0]); + int cv_count_y = atoi(argv[1]); + if (cv_count_x <= 2 || cv_count_y <= 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid cv_count, cv_count >= 3\n"); + return BRLCAD_ERROR; + } + + if (argc < 2 + (cv_count_x *cv_count_y) * 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments, you need to input %d more args about control vertices\n", 2 + (cv_count_x * cv_count_y) * 3 - argc); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + + std::vector points; + for (int i = 0; i < (cv_count_x * cv_count_y); i++) { + ON_3dPoint p; + p.x = atof(argv[2 + i * 3]); + p.y = atof(argv[2 + i * 3 + 1]); + p.z = atof(argv[2 + i * 3 + 2]); + points.push_back(p); + } + int surface_id = brep_surface_interpCrv(b_ip->brep, cv_count_x, cv_count_y, points); + if(surface_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create surface\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surface_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_copy(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_copy "; + const char *purpose_string = "copy a NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int surface_id = atoi(argv[1]); + + if (surface_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "invalid surface_id\n"); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + int res = brep_surface_copy(b_ip->brep, surface_id); + if (res < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to copy surface\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "successful copy surface! new surface id = %d", res); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_birail(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_birail "; + const char *purpose_string = "create a new NURBS surface using two curves"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc != 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int curve_id_1 = atoi(argv[0]); + int curve_id_2 = atoi(argv[1]); + int surf_id = brep_surface_create_ruled(b_ip->brep, curve_id_1, curve_id_2); + if (surf_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create surface\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surf_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_remove(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_remove "; + const char *purpose_string = "remove a NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_surface_remove(b_ip->brep, atoi(argv[0])); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to remove surface %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_move(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_move "; + const char *purpose_string = "move a NURBS surface to a specified position"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + ON_3dPoint p = ON_3dPoint(atof(argv[1]), atof(argv[2]), atof(argv[3])); + bool flag = brep_surface_move(b_ip->brep, atoi(argv[0]), p); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to move surface %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_set_cv(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_set_cv []"; + const char *purpose_string = "set a control vertex of a NURBS surface to a specified position"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 6) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + ON_4dPoint p = ON_4dPoint(atof(argv[3]), atof(argv[4]), atof(argv[5]), argc == 7 ? atof(argv[6]) : 1); + bool flag = brep_surface_set_cv(b_ip->brep, atoi(argv[0]), atoi(argv[1]), atoi(argv[2]), p); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to move surface cv \n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_trim(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_trim "; + const char *purpose_string = "trim a NURBS surface using start and end parameters."; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int surface_id = atoi(argv[0]); + int dir = atoi(argv[1]); + double start_param = atof(argv[2]); + double end_param = atof(argv[3]); + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_surface_trim(b_ip->brep, surface_id, dir, start_param, end_param); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to trim surface %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_split(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_split "; + const char *purpose_string = "split a NURBS surface into two given a parameter value."; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + argc--;argv++; + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int surface_id = atoi(argv[0]); + int dir = atoi(argv[1]); + double param = atof(argv[2]); + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + bool flag = brep_surface_split(b_ip->brep, surface_id, dir, param); + if (!flag) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to split the surface %s\n", argv[0]); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_tensor_product(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_tensor "; + const char *purpose_string = "create a new NURBS surface by extruding the first curve along the second curve."; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc != 2) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int curve_id_1 = atoi(argv[0]); + int curve_id_2 = atoi(argv[1]); + int surf_id = brep_surface_tensor_product(b_ip->brep, curve_id_1, curve_id_2); + if (surf_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to create surface\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surf_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_revolution(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_revolution []"; + const char *purpose_string = "create a new NURBS surface by rotating a curve around an axis by an angle."; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 7) { + bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int curve_id_1 = atoi(argv[0]); + ON_3dPoint line_start(atof(argv[1]), atof(argv[2]), atof(argv[3])); + ON_3dPoint line_end(atof(argv[4]), atof(argv[5]), atof(argv[6])); + double angle = 2 * ON_PI; + if(argc == 8) { + angle = atof(argv[7]); + } + int surf_id = brep_surface_revolution(b_ip->brep, curve_id_1, line_start, line_end, angle); + if (surf_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create surface\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surf_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_extract_vertex(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_ext_v "; + const char *purpose_string = "extract a vertex from a NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int surface_id = atoi(argv[0]); + double u = atof(argv[1]); + double v = atof(argv[2]); + int vertex_id = brep_surface_extract_vertex(b_ip->brep, surface_id, u, v); + + if(vertex_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create vertex\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create vertex! id = %d", vertex_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_geo_surface_extract_curve(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] geo s_ext_c3 "; + const char *purpose_string = "extract a curve from a NURBS surface"; + if (_brep_geo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_igeo *gib = (struct _ged_brep_igeo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + + int surface_id = atoi(argv[0]); + int dir = atoi(argv[1]); + double param = atof(argv[2]); + int curve_id = brep_surface_extract_curve(b_ip->brep, surface_id, dir, param); + + if(curve_id < 0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create curve\n"); + return BRLCAD_ERROR; + } + + // Update object in database + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create curve! id = %d", curve_id); + return BRLCAD_OK; +} + +static void +_brep_geo_help(struct _ged_brep_igeo *bs, int argc, const char **argv) +{ + struct _ged_brep_igeo *gb = (struct _ged_brep_igeo *)bs; + if (!argc || !argv) { + bu_vls_printf(gb->vls, "brep [options] geo [args]\n"); + bu_vls_printf(gb->vls, "Available subcommands:\n"); + const struct bu_cmdtab *ctp = NULL; + int ret; + const char *helpflag[2]; + helpflag[1] = PURPOSEFLAG; + for (ctp = gb->cmds; ctp->ct_name != (char *)NULL; ctp++) { + bu_vls_printf(gb->vls, " %s\t\t\t", ctp->ct_name); + helpflag[0] = ctp->ct_name; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } + } + else { + int ret; + const char *helpflag[2]; + helpflag[0] = argv[0]; + helpflag[1] = HELPFLAG; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } +} + +const struct bu_cmdtab _brep_geo_cmds[] = { + { "v_create", _brep_cmd_geo_vertex_create}, + { "v_remove", _brep_cmd_geo_vertex_remove}, + { "c2_create_line", _brep_cmd_geo_curve2d_create_line}, + { "c2_remove", _brep_cmd_geo_curve2d_remove}, + { "c3_create", _brep_cmd_geo_curve3d_create}, + { "c3_in", _brep_cmd_geo_curve3d_in}, + { "c3_interp", _brep_cmd_geo_curve3d_interp}, + { "c3_copy", _brep_cmd_geo_curve3d_copy}, + { "c3_remove", _brep_cmd_geo_curve3d_remove}, + { "c3_move", _brep_cmd_geo_curve3d_move}, + { "c3_set_cv", _brep_cmd_geo_curve3d_set_cv}, + { "c3_flip", _brep_cmd_geo_curve3d_flip}, + { "c3_insert_knot", _brep_cmd_geo_curve3d_insert_knot}, + { "c3_trim", _brep_cmd_geo_curve3d_trim}, + { "c3_split", _brep_cmd_geo_curve3d_split}, + { "c3_join", _brep_cmd_geo_curve3d_join}, + { "s_create", _brep_cmd_geo_surface_create}, + { "s_interp", _brep_cmd_geo_surface_interp}, + { "s_copy", _brep_cmd_geo_surface_copy}, + { "s_birail", _brep_cmd_geo_surface_birail}, + { "s_remove", _brep_cmd_geo_surface_remove}, + { "s_move", _brep_cmd_geo_surface_move}, + { "s_set_cv", _brep_cmd_geo_surface_set_cv}, + { "s_trim", _brep_cmd_geo_surface_trim}, + { "s_split", _brep_cmd_geo_surface_split}, + { "s_tensor", _brep_cmd_geo_surface_tensor_product}, + { "s_revolution", _brep_cmd_geo_surface_revolution}, + { "s_ext_v", _brep_cmd_geo_surface_extract_vertex}, + { "s_ext_c3", _brep_cmd_geo_surface_extract_curve}, + { (char *)NULL, NULL} +}; + +int brep_geo(struct _ged_brep_info *gb, int argc, const char **argv) +{ + struct _ged_brep_igeo gib; + gib.gb = gb; + gib.vls = gb->gedp->ged_result_str; + gib.cmds = _brep_geo_cmds; + + const ON_Brep *brep = ((struct rt_brep_internal *)(gb->intern.idb_ptr))->brep; + if (brep == NULL) { + bu_vls_printf(gib.vls, "not a brep object\n"); + return BRLCAD_ERROR; + } + + if (!argc) { + _brep_geo_help(&gib, 0, NULL); + return BRLCAD_OK; + } + + // TODO: add help flag + if (argc > 1 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + argc--;argv++; + argc--;argv++; + _brep_geo_help(&gib, argc, argv); + return BRLCAD_OK; + } + + // Must have valid subcommand to process + if (bu_cmd_valid(_brep_geo_cmds, argv[0]) != BRLCAD_OK) { + bu_vls_printf(gib.vls, "invalid subcommand \"%s\" specified\n", argv[0]); + _brep_geo_help(&gib, 0, NULL); + return BRLCAD_ERROR; + } + + int ret; + if (bu_cmd(_brep_geo_cmds, argc, argv, 0, (void *)&gib, &ret) == BRLCAD_OK) { + return ret; + } + return BRLCAD_ERROR; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/brep/info.cpp b/src/libged/brep/info.cpp index 8e73ad299af..15858dcbfc8 100644 --- a/src/libged/brep/info.cpp +++ b/src/libged/brep/info.cpp @@ -638,8 +638,8 @@ _brep_cmd_trim_info(void *bs, int argc, const char **argv) const ON_Surface* trim_srf = trim.SurfaceOf(); const ON_BrepLoop &loop = brep->m_L[trim.m_li]; const ON_BrepFace &face = brep->m_F[loop.m_fi]; - const char* sTrimType = "?"; - const char* sTrimIso = "-?"; + const char *sTrimType = NULL; + const char *sTrimIso = NULL; const ON_Curve* c2 = trim.TrimCurveOf(); ON_NurbsCurve* nc2 = ON_NurbsCurve::New(); c2->GetNurbForm(*nc2, 0.0); diff --git a/src/libged/brep/repair.cpp b/src/libged/brep/repair.cpp new file mode 100644 index 00000000000..89592883bae --- /dev/null +++ b/src/libged/brep/repair.cpp @@ -0,0 +1,264 @@ +/* R E P A I R . C P P + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/brep/repair.cpp + * + * LIBGED brep repair subcommand implementation - attempt various + * types of repairs to brep data. + * + */ + +#include "common.h" + +#include + +#include "opennurbs.h" +#include "bu/cmd.h" +#include "./ged_brep.h" + +struct _ged_brep_rinfo { + struct ged *gedp; + struct bu_vls *vls; + const ON_Brep *brep; + ON_Brep *obrep; + const struct bu_cmdtab *cmds; +}; + +static int +_brep_repair_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps) +{ + struct _ged_brep_rinfo *gb = (struct _ged_brep_rinfo *)bs; + if (argc == 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + bu_vls_printf(gb->vls, "%s\n%s\n", us, ps); + return 1; + } + if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { + bu_vls_printf(gb->vls, "%s\n", ps); + return 1; + } + return 0; +} + +// EC - regenerate 3D curves of topological edges +extern "C" int +_brep_cmd_edge_curve_repair(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] info EC [[index][index-index]]"; + const char *purpose_string = "rebuild invalid 3D edge curves from 2D trim curves"; + if (_brep_repair_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + argc--;argv++; + + struct _ged_brep_rinfo *gib = (struct _ged_brep_rinfo *)bs; + const ON_Brep *obrep = gib->brep; + ON_Brep brep(*obrep); + + std::set elements; + if (_brep_indices(elements, gib->vls, argc, argv) != BRLCAD_OK) { + return BRLCAD_ERROR; + } + // If we have nothing, check all + if (!elements.size()) { + for (int i = 0; i < brep.m_E.Count(); i++) + elements.insert(i); + } + + std::set::iterator e_it; + + bool updated = false; + for (e_it = elements.begin(); e_it != elements.end(); e_it++) { + + int ei = *e_it; + ON_BrepEdge &edge = brep.m_E[ei]; + if (edge.m_ti.Count() <= 0) { + bu_log("No associated trims, could not validate edge curve of %d\n", ei); + continue; + } + + const ON_BrepTrim *trim = NULL; + const ON_Curve *trimCurve = NULL; + for (int j = 0; j < edge.m_ti.Count(); j++) { + trim = &brep.m_T[edge.m_ti[j]]; + trimCurve = trim->TrimCurveOf(); + if (trimCurve) + break; + } + if (!trimCurve) { + bu_log("No associated trim curve found, could not validate edge curve of %d\n", ei); + continue; + } + const ON_BrepFace *f = trim->Face(); + if (!trimCurve) { + bu_log("No associated trim face found, could not validate edge curve of %d\n", ei); + continue; + } + const ON_Surface *s = f->SurfaceOf(); + if (!s) { + bu_log("No associated trim surface found, could not validate edge curve of %d\n", ei); + continue; + } + + const ON_Curve *c3 = edge.EdgeCurveOf(); + ON_3dPoint ep = c3->PointAt(c3->Domain().Min()); + + ON_Interval tdom = trimCurve->Domain(); + ON_3dPoint p2d1 = trimCurve->PointAt(tdom.Min()); + ON_3dPoint p2d2 = trimCurve->PointAt(tdom.Max()); + ON_3dPoint tp1 = s->PointAt(p2d1.x, p2d1.y); + ON_3dPoint tp2 = s->PointAt(p2d2.x, p2d2.y); + + ON_3dPoint cp = (tp1.DistanceTo(ep) > tp2.DistanceTo(ep)) ? tp2 : tp1; + + if (cp.DistanceTo(ep) < BN_TOL_DIST) + continue; + + // Conditions met - replace curve + updated = true; + bu_log("Edge %d - %fmm dist between edge curve (%g %g %g) and trim curve (%g %g %g)\n", ei, cp.DistanceTo(ep), ep.x, ep.y, ep.z, cp.x, cp.y, cp.z); + + ON_NurbsCurve nc; + trimCurve->GetNurbForm(nc); + + int plotres = nc.KnotCount() * 2; + ON_3dPointArray spnts; + for (int k = 0; k <= plotres; ++k) { + ON_3dPoint p = trimCurve->PointAt(tdom.ParameterAt((double)k / plotres)); + ON_3dPoint sp = s->PointAt(p.x, p.y); + spnts.Append(sp); + } + + // Loft a Bezier curve through the points sampled from the trimming + // curve and replace the existing curve on the ON_BrepEdge. Right now + // this is just a naive sample and loft operation - it may be that + // there are more intelligent methods that would produce better + // results... + ON_BezierCurve bc; + bc.Loft(spnts); + ON_NurbsCurve *bnc = ON_NurbsCurve::New(bc); + int c3i = brep.AddEdgeCurve(bnc); + edge.ChangeEdgeCurve(c3i); + } + + if (updated) { + brep.Compact(); + gib->obrep = ON_Brep::New(brep); + } + + return BRLCAD_OK; +} + +static void +_brep_repair_help(struct _ged_brep_rinfo *bs, int argc, const char **argv) +{ + struct _ged_brep_rinfo *gb = (struct _ged_brep_rinfo *)bs; + if (!argc || !argv) { + bu_vls_printf(gb->vls, "brep [options] repair [args]\n"); + bu_vls_printf(gb->vls, "Available subcommands:\n"); + const struct bu_cmdtab *ctp = NULL; + int ret; + const char *helpflag[2]; + helpflag[1] = PURPOSEFLAG; + for (ctp = gb->cmds; ctp->ct_name != (char *)NULL; ctp++) { + bu_vls_printf(gb->vls, " %s\t\t", ctp->ct_name); + helpflag[0] = ctp->ct_name; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } + } else { + int ret; + const char *helpflag[2]; + helpflag[0] = argv[0]; + helpflag[1] = HELPFLAG; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } +} + +const struct bu_cmdtab _brep_repair_cmds[] = { + { "EC", _brep_cmd_edge_curve_repair}, + { (char *)NULL, NULL} +}; + +int +brep_repair(struct ged *gedp, const ON_Brep *brep, const char *oname, int argc, const char **argv) +{ + struct _ged_brep_rinfo gib; + gib.gedp = gedp; + gib.vls = gedp->ged_result_str; + gib.brep = brep; + gib.obrep = NULL; + gib.cmds = _brep_repair_cmds; + + if (!argc) { + // In the no arg case, try all repairs + return BRLCAD_OK; + } + + if (argc > 1 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + argc--;argv++; + argc--;argv++; + _brep_repair_help(&gib, argc, argv); + return BRLCAD_OK; + } + + // Must have valid subcommand to process + if (bu_cmd_valid(_brep_repair_cmds, argv[0]) != BRLCAD_OK) { + bu_vls_printf(gib.vls, "invalid subcommand \"%s\" specified\n", argv[0]); + _brep_repair_help(&gib, 0, NULL); + return BRLCAD_ERROR; + } + + int ret; + if (bu_cmd(_brep_repair_cmds, argc, argv, 0, (void *)&gib, &ret) == BRLCAD_OK) { + + if (gib.obrep) { + + bu_log("Writing %s to disk\n", oname); + + struct rt_brep_internal *bip_out; + BU_ALLOC(bip_out, struct rt_brep_internal); + bip_out->magic = RT_BREP_INTERNAL_MAGIC; + bip_out->brep = gib.obrep; + + struct rt_db_internal intern; + RT_DB_INTERNAL_INIT(&intern); + intern.idb_ptr = (void *)bip_out; + intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; + intern.idb_meth = &OBJ[ID_BREP]; + intern.idb_minor_type = ID_BREP; + + struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + ret = wdb_export(wdbp, oname, intern.idb_ptr, ID_BREP, 1.0); + } + + return ret; + } + + + return BRLCAD_OK; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/brep/surface.cpp b/src/libged/brep/surface.cpp deleted file mode 100644 index 08fafbfb902..00000000000 --- a/src/libged/brep/surface.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* S U R F A C E . C P P - * BRL-CAD - * - * Copyright (c) 2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libged/brep/surface.cpp - * - * NURBS surfaces editing support for brep objects - * - */ - -#include "common.h" - -#include "wdb.h" -#include "../ged_private.h" -#include "./ged_brep.h" - -using namespace brlcad; - -struct _ged_brep_isurface { - struct _ged_brep_info *gb; - struct bu_vls *vls; - const struct bu_cmdtab *cmds; -}; - -static int -_brep_surface_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps) -{ - struct _ged_brep_isurface *gb = (struct _ged_brep_isurface *)bs; - if (argc == 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - bu_vls_printf(gb->vls, "%s\n%s\n", us, ps); - return 1; - } - if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { - bu_vls_printf(gb->vls, "%s\n", ps); - return 1; - } - return 0; -} - -static int -_brep_cmd_surface_create(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] surface create "; - const char *purpose_string = "create a new NURBS surface"; - if (_brep_surface_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_isurface *gib = (struct _ged_brep_isurface *)bs; - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - argc--;argv++; - ON_3dPoint position(0, 0, 0); - if (argc >= 3) { - position = ON_3dPoint(atof(argv[0]), atof(argv[1]), atof(argv[2])); - } - int surfcode = brep_surface_make(b_ip->brep, position); - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surfcode); - return BRLCAD_OK; -} - -static int -_brep_cmd_surface_birail(void *bs, int argc, const char **argv) -{ - - const char *usage_string = "brep [options] surface birail "; - const char *purpose_string = "create a new NURBS surface using two curves"; - if (_brep_surface_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - struct _ged_brep_isurface *gib = (struct _ged_brep_isurface *)bs; - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - argc--;argv++; - if (argc != 2) { - bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - int curve_id_1 = atoi(argv[0]); - int curve_id_2 = atoi(argv[1]); - int surfcode = brep_surface_create_ruled(b_ip->brep, curve_id_1, curve_id_2); - if (surfcode < 0) { - bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to create surface\n"); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - bu_vls_printf(gib->gb->gedp->ged_result_str, "create surface! id = %d", surfcode); - return BRLCAD_OK; -} - -static int -_brep_cmd_surface_move(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] surface move "; - const char *purpose_string = "move a NURBS surface to a specified position"; - if (_brep_surface_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - argc--;argv++; - struct _ged_brep_isurface *gib = (struct _ged_brep_isurface *)bs; - if (argc < 4) { - bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - ON_3dPoint p = ON_3dPoint(atof(argv[1]), atof(argv[2]), atof(argv[3])); - bool flag = brep_surface_move(b_ip->brep, atoi(argv[0]), p); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to move surface %s\n", argv[0]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_set_cv(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] surface set_cv []"; - const char *purpose_string = "set a control vertex of a NURBS surface to a specified position"; - if (_brep_surface_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - argc--;argv++; - struct _ged_brep_isurface *gib = (struct _ged_brep_isurface *)bs; - if (argc < 6) { - bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - ON_4dPoint p = ON_4dPoint(atof(argv[3]), atof(argv[4]), atof(argv[5]), argc == 7 ? atof(argv[6]) : 1); - bool flag = brep_surface_set_cv(b_ip->brep, atoi(argv[0]), atoi(argv[1]), atoi(argv[2]), p); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to move surface cv \n"); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static int -_brep_cmd_surface_trim(void *bs, int argc, const char **argv) -{ - const char *usage_string = "brep [options] trim "; - const char *purpose_string = "trim a NURBS surface using start and end parameters."; - if (_brep_surface_msgs(bs, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - argc--;argv++; - struct _ged_brep_isurface *gib = (struct _ged_brep_isurface *)bs; - if (argc < 4) { - bu_vls_printf(gib->gb->gedp->ged_result_str, " not enough arguments\n"); - bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); - return BRLCAD_ERROR; - } - - int surface_id = atoi(argv[0]); - int dir = atoi(argv[1]); - double start_param = atof(argv[2]); - double end_param = atof(argv[3]); - struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; - bool flag = brep_surface_trim(b_ip->brep, surface_id, dir, start_param, end_param); - if (!flag) { - bu_vls_printf(gib->gb->gedp->ged_result_str, ": failed to trim surface %s\n", argv[0]); - return BRLCAD_ERROR; - } - - // Delete the old object - const char *av[3]; - char *ncpy = bu_strdup(gib->gb->solid_name.c_str()); - av[0] = "kill"; - av[1] = ncpy; - av[2] = NULL; - (void)ged_exec(gib->gb->gedp, 2, (const char **)av); - bu_free(ncpy, "free name cpy"); - - // Make the new one - struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - - if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { - return BRLCAD_ERROR; - } - return BRLCAD_OK; -} - -static void -_brep_surface_help(struct _ged_brep_isurface *bs, int argc, const char **argv) -{ - struct _ged_brep_isurface *gb = (struct _ged_brep_isurface *)bs; - if (!argc || !argv) { - bu_vls_printf(gb->vls, "brep [options] surface [args]\n"); - bu_vls_printf(gb->vls, "Available subcommands:\n"); - const struct bu_cmdtab *ctp = NULL; - int ret; - const char *helpflag[2]; - helpflag[1] = PURPOSEFLAG; - for (ctp = gb->cmds; ctp->ct_name != (char *)NULL; ctp++) { - bu_vls_printf(gb->vls, " %s\t\t", ctp->ct_name); - helpflag[0] = ctp->ct_name; - bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); - } - } - else { - int ret; - const char *helpflag[2]; - helpflag[0] = argv[0]; - helpflag[1] = HELPFLAG; - bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); - } -} - -const struct bu_cmdtab _brep_surface_cmds[] = { - { "create", _brep_cmd_surface_create}, - { "birail", _brep_cmd_surface_birail}, - { "move", _brep_cmd_surface_move}, - { "set_cv", _brep_cmd_set_cv}, - { "trim", _brep_cmd_surface_trim}, - { (char *)NULL, NULL} -}; - -int brep_surface(struct _ged_brep_info *gb, int argc, const char **argv) -{ - struct _ged_brep_isurface gib; - gib.gb = gb; - gib.vls = gb->gedp->ged_result_str; - gib.cmds = _brep_surface_cmds; - - const ON_Brep *brep = ((struct rt_brep_internal *)(gb->intern.idb_ptr))->brep; - if (brep == NULL) { - bu_vls_printf(gib.vls, "not a brep object\n"); - return BRLCAD_ERROR; - } - - if (!argc) { - _brep_surface_help(&gib, 0, NULL); - return BRLCAD_OK; - } - - // TODO: add help flag - if (argc > 1 && BU_STR_EQUAL(argv[1], HELPFLAG)) { - argc--;argv++; - argc--;argv++; - _brep_surface_help(&gib, argc, argv); - return BRLCAD_OK; - } - - // Must have valid subcommand to process - if (bu_cmd_valid(_brep_surface_cmds, argv[0]) != BRLCAD_OK) { - bu_vls_printf(gib.vls, "invalid subcommand \"%s\" specified\n", argv[0]); - _brep_surface_help(&gib, 0, NULL); - return BRLCAD_ERROR; - } - - int ret; - if (bu_cmd(_brep_surface_cmds, argc, argv, 0, (void *)&gib, &ret) == BRLCAD_OK) { - return ret; - } - return BRLCAD_ERROR; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/brep/topology.cpp b/src/libged/brep/topology.cpp new file mode 100644 index 00000000000..89d0e14448a --- /dev/null +++ b/src/libged/brep/topology.cpp @@ -0,0 +1,307 @@ +/* T O P O L O G Y . C P P + * BRL-CAD + * + * Copyright (c) 2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/brep/topology.cpp + * + * NURBS topology editing support for brep objects + * + */ + +#include "common.h" + +#include "wdb.h" +#include "../ged_private.h" +#include "./ged_brep.h" + +using namespace brlcad; + +struct _ged_brep_itopo { + struct _ged_brep_info *gb; + struct bu_vls *vls; + const struct bu_cmdtab *cmds; +}; + +static int +_brep_topo_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps) +{ + struct _ged_brep_itopo *gb = (struct _ged_brep_itopo *)bs; + if (argc == 2 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + bu_vls_printf(gb->vls, "%s\n%s\n", us, ps); + return 1; + } + if (argc == 2 && BU_STR_EQUAL(argv[1], PURPOSEFLAG)) { + bu_vls_printf(gb->vls, "%s\n", ps); + return 1; + } + return 0; +} + +static int +_brep_cmd_topo_create_edge(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] topo e_create "; + const char *purpose_string = "create a new topology edge, given two vertices and a curve"; + if (_brep_topo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_itopo *gib = (struct _ged_brep_itopo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 3) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int v1 = atoi(argv[0]); + int v2 = atoi(argv[1]); + int c = atoi(argv[2]); + int edge = brep_edge_create(b_ip->brep, v1, v2, c); + + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create edge! id = %d", edge); + return BRLCAD_OK; +} + +static int +_brep_cmd_topo_create_face(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] topo f_create "; + const char *purpose_string = "create a new topology face, given a surface id"; + if (_brep_topo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_itopo *gib = (struct _ged_brep_itopo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int surface = atoi(argv[0]); + int face_id = brep_face_create(b_ip->brep, surface); + + if (face_id <0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create face\n"); + return BRLCAD_ERROR; + } + + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create face! id = %d", face_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_topo_reverse_face(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] topo f_rev "; + const char *purpose_string = "reverse a face"; + if (_brep_topo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_itopo *gib = (struct _ged_brep_itopo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int face = atoi(argv[0]); + bool res = brep_face_reverse(b_ip->brep, face); + + if (!res) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to reverse face\n"); + return BRLCAD_ERROR; + } + + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "reverse face!"); + return BRLCAD_OK; +} + +static int +_brep_cmd_topo_create_loop(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] topo l_create "; + const char *purpose_string = "create a new topology loop for a face"; + if (_brep_topo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_itopo *gib = (struct _ged_brep_itopo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 1) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int surface = atoi(argv[0]); + int loop_id = brep_loop_create(b_ip->brep, surface); + + if (loop_id <0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create loop\n"); + return BRLCAD_ERROR; + } + + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create loop! id = %d", loop_id); + return BRLCAD_OK; +} + +static int +_brep_cmd_topo_create_trim(void *bs, int argc, const char **argv) +{ + const char *usage_string = "brep [options] topo t_create "; + const char *purpose_string = "create a new topology trim for a loop"; + if (_brep_topo_msgs(bs, argc, argv, usage_string, purpose_string)) { + return BRLCAD_OK; + } + + struct _ged_brep_itopo *gib = (struct _ged_brep_itopo *)bs; + struct rt_brep_internal *b_ip = (struct rt_brep_internal *)gib->gb->intern.idb_ptr; + argc--;argv++; + if (argc < 4) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "not enough arguments\n"); + bu_vls_printf(gib->gb->gedp->ged_result_str, "%s\n", usage_string); + return BRLCAD_ERROR; + } + int loop_id = atoi(argv[0]); + int edge_id = atoi(argv[1]); + int orientation = atoi(argv[2]); + int para_curve_id = atoi(argv[3]); + int trim_id = brep_trim_create(b_ip->brep, loop_id, edge_id, orientation, para_curve_id); + + if (trim_id <0) { + bu_vls_printf(gib->gb->gedp->ged_result_str, "failed to create trim\n"); + return BRLCAD_ERROR; + } + + struct rt_wdb *wdbp = wdb_dbopen(gib->gb->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + + if (mk_brep(wdbp, gib->gb->solid_name.c_str(), (void *)b_ip->brep)) { + return BRLCAD_ERROR; + } + bu_vls_printf(gib->gb->gedp->ged_result_str, "create trim! id = %d", trim_id); + return BRLCAD_OK; +} + +static void +_brep_topo_help(struct _ged_brep_itopo *bs, int argc, const char **argv) +{ + struct _ged_brep_itopo *gb = (struct _ged_brep_itopo *)bs; + if (!argc || !argv) { + bu_vls_printf(gb->vls, "brep [options] topo [args]\n"); + bu_vls_printf(gb->vls, "Available subcommands:\n"); + const struct bu_cmdtab *ctp = NULL; + int ret; + const char *helpflag[2]; + helpflag[1] = PURPOSEFLAG; + for (ctp = gb->cmds; ctp->ct_name != (char *)NULL; ctp++) { + bu_vls_printf(gb->vls, " %s\t\t", ctp->ct_name); + helpflag[0] = ctp->ct_name; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } + } + else { + int ret; + const char *helpflag[2]; + helpflag[0] = argv[0]; + helpflag[1] = HELPFLAG; + bu_cmd(gb->cmds, 2, helpflag, 0, (void *)gb, &ret); + } +} + +const struct bu_cmdtab _brep_topo_cmds[] = { + { "e_create", _brep_cmd_topo_create_edge}, + { "f_create", _brep_cmd_topo_create_face}, + { "f_rev", _brep_cmd_topo_reverse_face}, + { "l_create", _brep_cmd_topo_create_loop}, + { "t_create", _brep_cmd_topo_create_trim}, + { (char *)NULL, NULL} +}; + +int brep_topo(struct _ged_brep_info *gb, int argc, const char **argv) +{ + struct _ged_brep_itopo gib; + gib.gb = gb; + gib.vls = gb->gedp->ged_result_str; + gib.cmds = _brep_topo_cmds; + + const ON_Brep *brep = ((struct rt_brep_internal *)(gb->intern.idb_ptr))->brep; + if (brep == NULL) { + bu_vls_printf(gib.vls, "not a brep object\n"); + return BRLCAD_ERROR; + } + + if (!argc) { + _brep_topo_help(&gib, 0, NULL); + return BRLCAD_OK; + } + + // TODO: add help flag + if (argc > 1 && BU_STR_EQUAL(argv[1], HELPFLAG)) { + argc--;argv++; + argc--;argv++; + _brep_topo_help(&gib, argc, argv); + return BRLCAD_OK; + } + + // Must have valid subcommand to process + if (bu_cmd_valid(_brep_topo_cmds, argv[0]) != BRLCAD_OK) { + bu_vls_printf(gib.vls, "invalid subcommand \"%s\" specified\n", argv[0]); + _brep_topo_help(&gib, 0, NULL); + return BRLCAD_ERROR; + } + + int ret; + if (bu_cmd(_brep_topo_cmds, argc, argv, 0, (void *)&gib, &ret) == BRLCAD_OK) { + return ret; + } + return BRLCAD_ERROR; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/close/CMakeLists.txt b/src/libged/close/CMakeLists.txt index 2a6635aa7c0..098720a97cd 100644 --- a/src/libged/close/CMakeLists.txt +++ b/src/libged/close/CMakeLists.txt @@ -7,7 +7,7 @@ include_directories( ) add_definitions(-DGED_PLUGIN) -ged_plugin_library(ged-close SHARED close.c) +ged_plugin_library(ged-close SHARED close.cpp) target_link_libraries(ged-close libged libbu) set_property(TARGET ged-close APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) VALIDATE_STYLE(ged-close close.c) @@ -15,7 +15,7 @@ PLUGIN_SETUP(ged-close ged) CMAKEFILES( CMakeLists.txt - close.c + close.cpp ) # Local Variables: diff --git a/src/libged/close/close.c b/src/libged/close/close.c deleted file mode 100644 index cbe03ce0479..00000000000 --- a/src/libged/close/close.c +++ /dev/null @@ -1,99 +0,0 @@ -/* C L O S E . C - * BRL-CAD - * - * Copyright (c) 2008-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libged/close.c - * - * The close command. - * - */ - -#include "common.h" - -#include - -#include "bu/cmd.h" - -#include "../ged_private.h" - - -int -ged_close_core(struct ged *gedp, int UNUSED(argc), const char **UNUSED(argv)) -{ - char *av[2]; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - - /* set result while we still have the info */ - bu_vls_sprintf(gedp->ged_result_str, "closed %s", gedp->dbip->dbi_filename); - - rt_new_material_head(MATER_NULL); - - av[0] = "zap"; - av[1] = (char *)0; - ged_exec(gedp, 1, (const char **)av); - - /* close current database */ - if (gedp->dbip) { - db_close(gedp->dbip); - } - gedp->dbip = NULL; - - /* Terminate any ged subprocesses */ - if (gedp != GED_NULL) { - for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_subp); i++) { - struct ged_subprocess *rrp = (struct ged_subprocess *)BU_PTBL_GET(&gedp->ged_subp, i); - if (!rrp->aborted) { - bu_terminate(bu_process_pid(rrp->p)); - rrp->aborted = 1; - } - bu_ptbl_rm(&gedp->ged_subp, (long *)rrp); - BU_PUT(rrp, struct ged_subprocess); - } - bu_ptbl_reset(&gedp->ged_subp); - } - - return BRLCAD_OK; -} - - -#ifdef GED_PLUGIN -#include "../include/plugin.h" - -struct ged_cmd_impl close_cmd_impl = {"close", ged_close_core, GED_CMD_DEFAULT}; -const struct ged_cmd close_cmd = { &close_cmd_impl }; - -const struct ged_cmd *close_cmds[] = { &close_cmd, NULL }; - -static const struct ged_plugin pinfo = { GED_API, close_cmds, 1 }; - -COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info(void) -{ - return &pinfo; -} -#endif /* GED_PLUGIN */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libged/close/close.cpp b/src/libged/close/close.cpp new file mode 100644 index 00000000000..ff48a8cab1a --- /dev/null +++ b/src/libged/close/close.cpp @@ -0,0 +1,124 @@ +/* C L O S E . C P P + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/close.cpp + * + * The close command. + * + */ + +#include "common.h" + +#include + +#include "bu/cmd.h" +#include "bv/lod.h" + +#include "../ged_private.h" + + +extern "C" int +ged_close_core(struct ged *gedp, int UNUSED(argc), const char **UNUSED(argv)) +{ + // If we don't have an open database, this is a no-op + if (!gedp->dbip) + return BRLCAD_OK; + + // If the caller has work to do first, trigger it + if (gedp->ged_pre_closedb_callback) + (*gedp->ged_pre_closedb_callback)(gedp, gedp->ged_db_callback_udata); + + /* set result while we still have the info */ + bu_vls_sprintf(gedp->ged_result_str, "closed %s", gedp->dbip->dbi_filename); + + rt_new_material_head(MATER_NULL); + + /* Clear any geometry displayed in application views. + * TODO - properly speaking, we should only be zapping geometry data here + * and not clearing all scene objects... */ + const char *av[2]; + av[0] = "zap"; + av[1] = (char *)0; + ged_exec(gedp, 1, (const char **)av); + + /* close current database */ + if (gedp->dbip) + db_close(gedp->dbip); + gedp->dbip = NULL; + + /* Clean up any old acceleration states, if present */ + const char *use_dbi_state = getenv("LIBGED_DBI_STATE"); + if (use_dbi_state && gedp->dbi_state) + delete gedp->dbi_state; + gedp->dbi_state = NULL; + if (gedp->ged_lod) + bv_mesh_lod_context_destroy(gedp->ged_lod); + gedp->ged_lod = NULL; + + /* Terminate any ged subprocesses */ + if (gedp != GED_NULL) { + for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_subp); i++) { + struct ged_subprocess *rrp = (struct ged_subprocess *)BU_PTBL_GET(&gedp->ged_subp, i); + if (!rrp->aborted) { + bu_terminate(bu_process_pid(rrp->p)); + rrp->aborted = 1; + } + bu_ptbl_rm(&gedp->ged_subp, (long *)rrp); + BU_PUT(rrp, struct ged_subprocess); + } + bu_ptbl_reset(&gedp->ged_subp); + } + + // If the caller has work to do after close, trigger it + if (gedp->ged_post_closedb_callback) + (*gedp->ged_post_closedb_callback)(gedp, gedp->ged_db_callback_udata); + + return BRLCAD_OK; +} + +extern "C" { +#ifdef GED_PLUGIN +#include "../include/plugin.h" + +struct ged_cmd_impl closedb_cmd_impl = {"closedb", ged_close_core, GED_CMD_DEFAULT}; +const struct ged_cmd closedb_cmd = { &closedb_cmd_impl }; + +struct ged_cmd_impl close_cmd_impl = {"close", ged_close_core, GED_CMD_DEFAULT}; +const struct ged_cmd close_cmd = { &close_cmd_impl }; + +const struct ged_cmd *close_cmds[] = { &closedb_cmd, &close_cmd, NULL }; + +static const struct ged_plugin pinfo = { GED_API, close_cmds, 2 }; + +COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info(void) +{ + return &pinfo; +} +#endif /* GED_PLUGIN */ +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/color/color.c b/src/libged/color/color.c index 4bb11fdadd2..61200ed0f3b 100644 --- a/src/libged/color/color.c +++ b/src/libged/color/color.c @@ -144,7 +144,10 @@ edcolor(struct ged *gedp, int argc, const char *argv[]) /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); - fp = bu_temp_file(tmpfil, MAXPATHLEN); + /* build temp file path */ + bu_dir(tmpfil, MAXPATHLEN, BU_DIR_TEMP, bu_temp_file_name(NULL, 0), NULL); + + fp = fopen(tmpfil, "w+"); if (fp == NULL) { bu_vls_printf(gedp->ged_result_str, "%s: could not create tmp file", argv[0]); return BRLCAD_ERROR; @@ -152,7 +155,7 @@ edcolor(struct ged *gedp, int argc, const char *argv[]) fprintf(fp, "%s", hdr); for (mp = rt_material_head(); mp != MATER_NULL; mp = mp->mt_forw) { - fprintf(fp, "%d\t%d\t%3d\t%3d\t%3d", + fprintf(fp, "%ld\t%ld\t%3d\t%3d\t%3d", mp->mt_low, mp->mt_high, mp->mt_r, mp->mt_g, mp->mt_b); fprintf(fp, "\n"); diff --git a/src/libged/concat/concat.cpp b/src/libged/concat/concat.cpp index b61d077fd43..9b9884cd47c 100644 --- a/src/libged/concat/concat.cpp +++ b/src/libged/concat/concat.cpp @@ -48,6 +48,7 @@ struct ged_concat_data { struct db_i *old_dbip; struct db_i *new_dbip; struct bu_vls affix; + long overwritten = 0; }; @@ -56,6 +57,7 @@ struct ged_concat_data { #define AUTO_SUFFIX 1<<2 #define CUSTOM_PREFIX 1<<3 #define CUSTOM_SUFFIX 1<<4 +#define OVERWRITE 1<<5 /** @@ -131,9 +133,9 @@ get_new_name(const char *name, } else { /* no custom suffix/prefix specified, use prefix */ if (num > 0) { - bu_vls_printf(&new_name, "_%ld", num); + bu_vls_printf(&new_name, "%ld_", num); } - bu_vls_strcpy(&new_name, name); + bu_vls_strcat(&new_name, name); } /* make sure it fits for v4 */ @@ -150,8 +152,8 @@ get_new_name(const char *name, } while (db_lookup(dbip, aname, LOOKUP_QUIET) != RT_DIR_NULL || (used_names.find(std::string(aname)) != used_names.end())); - /* if they didn't get what they asked for, warn them */ - if (num > 1) { + /* if they didn't get what they asked for, warn them (except when overwriting) */ + if (num > 1 && !(cc_data->copy_mode & OVERWRITE)) { if (cc_data->copy_mode & NO_AFFIX) { bu_log("WARNING: unable to import [%s] without an affix, imported as [%s]\n", name, bu_vls_addr(&new_name)); } else if (cc_data->copy_mode & CUSTOM_SUFFIX) { @@ -180,6 +182,9 @@ adjust_names(union tree *trp, std::string new_name; std::string old_name; + if (cc_data->copy_mode & OVERWRITE) /* we're overwriting conflicts, there's nothing to adjust */ + return; + if (trp == NULL) { return; } @@ -228,6 +233,8 @@ copy_object(struct ged *gedp, struct rt_comb_internal *comb; struct directory *new_dp; std::string new_name; + struct directory* oride_dp = NULL; + std::string owrite_backup; if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, @@ -275,6 +282,20 @@ copy_object(struct ged *gedp, if (!new_name.length()) { new_name = std::string(input_dp->d_namep); } + + /* if overwriting - + * move current to temp name before copying to avoid name collisions and data loss */ + if (cc_data->copy_mode & OVERWRITE) { + oride_dp = db_lookup(gedp->dbip, input_dp->d_namep, 0); + if (oride_dp) { /* obj exists and needs to be moved out of the way */ + db_rename(cc_data->old_dbip, oride_dp, new_name.c_str()); + /* remember the backup's name so we can delete it later */ + owrite_backup = new_name; + /* we've moved the orignal object out of the way. Reset new_name for the diradd */ + new_name = std::string(input_dp->d_namep); + } + } + if ((new_dp = db_diradd(curr_dbip, new_name.c_str(), RT_DIR_PHONY_ADDR, 0, input_dp->d_flags, (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, @@ -294,6 +315,19 @@ copy_object(struct ged *gedp, return BRLCAD_ERROR; } + /* if overwriting - + * we've added the new object, its safe to delete the original */ + if (oride_dp) { + _dl_eraseAllNamesFromDisplay(gedp, owrite_backup.c_str(), 0); + if (db_delete(gedp->dbip, oride_dp) != 0 || db_dirdelete(gedp->dbip, oride_dp) != 0) { + /* Abort processing on first error */ + bu_vls_printf(gedp->ged_result_str, "an error occurred while deleting %s\n", owrite_backup.c_str()); + return BRLCAD_ERROR; + } + db_update_nref(gedp->dbip, &rt_uniresource); + cc_data->overwritten++; + } + return BRLCAD_OK; } @@ -310,7 +344,7 @@ ged_concat_core(struct ged *gedp, int argc, const char *argv[]) char *colorTab; struct ged_concat_data cc_data; const char *oldfile; - static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]"; + static const char *usage = "[-u] [-t] [-c] [-s|-p] [-O] file.g [suffix|prefix]"; int importUnits = 0; int importTitle = 0; int importColorTable = 0; @@ -337,7 +371,7 @@ ged_concat_core(struct ged *gedp, int argc, const char *argv[]) /* process args */ bu_optind = 1; bu_opterr = 0; - while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) { + while ((c=bu_getopt(argc, (char * const *)argv, "utcspO")) != -1) { switch (c) { case 'u': importUnits = 1; @@ -354,6 +388,9 @@ ged_concat_core(struct ged *gedp, int argc, const char *argv[]) case 's': cc_data.copy_mode |= AUTO_SUFFIX; break; + case 'O': + cc_data.copy_mode |= OVERWRITE; + break; default: { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); bu_vls_free(&cc_data.affix); @@ -395,6 +432,8 @@ ged_concat_core(struct ged *gedp, int argc, const char *argv[]) cc_data.copy_mode |= CUSTOM_SUFFIX; } + } else if (cc_data.copy_mode & OVERWRITE) { + /* don't mess with affix */ } else { bu_vls_free(&cc_data.affix); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage); @@ -466,6 +505,10 @@ ged_concat_core(struct ged *gedp, int argc, const char *argv[]) /* Free all the directory entries, and close the input database */ db_close(newdbp); + if (cc_data.copy_mode & OVERWRITE) { + bu_vls_printf(gedp->ged_result_str, " [%ld] objects overwritten", cc_data.overwritten); + } + if (importColorTable) { if ((cp = bu_avs_get(&g_avs, "regionid_colortable")) != NULL) { colorTab = bu_strdup(cp); diff --git a/src/libged/dbi_state.cpp b/src/libged/dbi_state.cpp new file mode 100644 index 00000000000..62150a379a8 --- /dev/null +++ b/src/libged/dbi_state.cpp @@ -0,0 +1,3660 @@ +/* D B I _ S T A T E . C P P + * BRL-CAD + * + * Copyright (c) 1990-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup ged_db*/ +/** @{ */ +/** @file libged/dbi_state.cpp + * + * Maintain and manage an in-memory representation of the database hierarchy. + * Main utility of this is to make commonly needed hierarchy/attribute + * information available to applications without having to crack combs from + * disk during a standard tree walk. + */ + +#include "common.h" + +#include +#include +#include +#include +#include + +extern "C" { +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#include "lmdb.h" +} + +#include "./alphanum.h" + +#include "vmath.h" +#include "bu/app.h" +#include "bu/color.h" +#include "bu/path.h" +#include "bu/opt.h" +#include "bu/sort.h" +#include "bv/lod.h" +#include "raytrace.h" +#include "ged/defines.h" +#include "ged/view/state.h" +#include "./ged_private.h" + +// Subdirectory in BRL-CAD cache to Dbi state data +#define DBI_CACHEDIR ".Dbi" + +// Maximum database size. +#define CACHE_MAX_DB_SIZE 4294967296 + +// Define what format of the cache is current - if it doesn't match, we need +// to wipe and redo. +#define CACHE_CURRENT_FORMAT 1 + +/* There are various individual pieces of data in the cache associated with + * each object key. For lookup they use short suffix strings to distinguish + * them - we define those strings here to have consistent definitions for use + * in multiple functions. + * + * Changing any of these requires incrementing CACHE_CURRENT_FORMAT. */ +#define CACHE_OBJ_BOUNDS "bb" +#define CACHE_REGION_ID "rid" +#define CACHE_REGION_FLAG "rf" +#define CACHE_INHERIT_FLAG "if" +#define CACHE_COLOR "c" + +static void +dbi_dir(char *dir) +{ +#ifdef HAVE_WINDOWS_H + CreateDirectory(dir, NULL); +#else + /* mode: 775 */ + mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif +} + +struct ged_draw_cache { + MDB_env *env; + MDB_txn *txn; + MDB_dbi dbi; + struct bu_vls *fname; +}; + +static void +dbi_dirclear(const char *d) +{ + if (bu_file_directory(d)) { + char **filenames; + size_t nfiles = bu_file_list(d, "*", &filenames); + for (size_t i = 0; i < nfiles; i++) { + if (BU_STR_EQUAL(filenames[i], ".")) + continue; + if (BU_STR_EQUAL(filenames[i], "..")) + continue; + char cdir[MAXPATHLEN] = {0}; + bu_dir(cdir, MAXPATHLEN, d, filenames[i], NULL); + dbi_dirclear((const char *)cdir); + } + bu_argv_free(nfiles, filenames); + } + bu_file_delete(d); +} + +void +dbi_cache_clear(struct ged_draw_cache *c) +{ + if (!c) + return; + char dir[MAXPATHLEN]; + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, DBI_CACHEDIR, bu_vls_cstr(c->fname)); + dbi_dirclear((const char *)dir); +} + +struct ged_draw_cache * +dbi_cache_open(const char *name) +{ + // Hash the input filename to generate a key for uniqueness + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + struct bu_vls fname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&fname, "%s", bu_path_normalize(name)); + + XXH64_update(&h_state, bu_vls_cstr(&fname), bu_vls_strlen(&fname)*sizeof(char)); + XXH64_hash_t hash_val; + hash_val = XXH64_digest(&h_state); + unsigned long long hash = (unsigned long long)hash_val; + bu_path_component(&fname, bu_path_normalize(name), BU_PATH_BASENAME_EXTLESS); + bu_vls_printf(&fname, "_%llu", hash); + + // Set up the container + struct ged_draw_cache *c; + BU_GET(c, struct ged_draw_cache); + BU_GET(c->fname, struct bu_vls); + bu_vls_init(c->fname); + bu_vls_sprintf(c->fname, "%s", bu_vls_cstr(&fname)); + + // Base maximum readers on an estimate of how many threads + // we might want to fire off + size_t mreaders = std::thread::hardware_concurrency(); + if (!mreaders) + mreaders = 1; + int ncpus = bu_avail_cpus(); + if (ncpus > 0 && (size_t)ncpus > mreaders) + mreaders = (size_t)ncpus + 2; + + // Set up LMDB environments + if (mdb_env_create(&c->env)) + goto ged_context_fail; + if (mdb_env_set_maxreaders(c->env, mreaders)) + goto ged_context_close_fail; + if (mdb_env_set_mapsize(c->env, CACHE_MAX_DB_SIZE)) + goto ged_context_close_fail; + + // Ensure the necessary top level dirs are present + char dir[MAXPATHLEN]; + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, NULL); + if (!bu_file_exists(dir, NULL)) + dbi_dir(dir); + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, DBI_CACHEDIR, NULL); + if (!bu_file_exists(dir, NULL)) { + dbi_dir(dir); + } + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, DBI_CACHEDIR, "format", NULL); + if (!bu_file_exists(dir, NULL)) { + // Note a format, so we can detect if what's there isn't compatible + // with what this logic expects (in anticipation of future changes + // to the on-disk format). + FILE *fp = fopen(dir, "w"); + if (!fp) + goto ged_context_close_fail; + fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); + fclose(fp); + } else { + std::ifstream format_file(dir); + size_t disk_format_version = 0; + format_file >> disk_format_version; + format_file.close(); + if (disk_format_version != CACHE_CURRENT_FORMAT) { + bu_log("Old GED drawing info cache (%zd) found - clearing\n", disk_format_version); + dbi_cache_clear(c); + mdb_env_close(c->env); + bu_vls_free(&fname); + bu_vls_free(c->fname); + BU_PUT(c->fname, struct bu_vls); + BU_PUT(c, struct ged_draw_cache); + return dbi_cache_open(name); + } + FILE *fp = fopen(dir, "w"); + if (!fp) + goto ged_context_close_fail; + fprintf(fp, "%d\n", CACHE_CURRENT_FORMAT); + fclose(fp); + } + + // Create the specific LMDB cache dir, if not already present + bu_dir(dir, MAXPATHLEN, BU_DIR_CACHE, DBI_CACHEDIR, bu_vls_cstr(&fname), NULL); + if (!bu_file_exists(dir, NULL)) + dbi_dir(dir); + + // Need to call mdb_env_sync() at appropriate points. + if (mdb_env_open(c->env, dir, MDB_NOSYNC, 0664)) + goto ged_context_close_fail; + + // Success - return the context + return c; + + // If something went wrong, clean up and return NULL + ged_context_close_fail: + mdb_env_close(c->env); + ged_context_fail: + bu_vls_free(&fname); + bu_vls_free(c->fname); + BU_PUT(c->fname, struct bu_vls); + BU_PUT(c, struct ged_draw_cache); + return NULL; +} + +void +dbi_cache_close(struct ged_draw_cache *c) +{ + if (!c) + return; + mdb_env_close(c->env); + bu_vls_free(c->fname); + BU_PUT(c->fname, struct bu_vls); + BU_PUT(c, struct ged_draw_cache); +} + +static void +cache_write(struct ged_draw_cache *c, unsigned long long hash, const char *component, std::stringstream &s) +{ + if (!c || hash == 0 || !component) + return; + + // Prepare inputs for writing + MDB_val mdb_key; + MDB_val mdb_data[2]; + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + std::string buffer = s.str(); + + // As implemented this shouldn't be necessary, since all our keys are below + // the default size limit (511) + //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->i->lod_env)) + // return false; + + // Write out key/value to LMDB database, where the key is the hash + // and the value is the serialized LoD data + char *keycstr = bu_strdup(keystr.c_str()); + void *bdata = bu_calloc(buffer.length()+1, sizeof(char), "bdata"); + memcpy(bdata, buffer.data(), buffer.length()*sizeof(char)); + mdb_txn_begin(c->env, NULL, 0, &c->txn); + mdb_dbi_open(c->txn, NULL, 0, &c->dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keycstr; + mdb_data[0].mv_size = buffer.length()*sizeof(char); + mdb_data[0].mv_data = bdata; + mdb_data[1].mv_size = 0; + mdb_data[1].mv_data = NULL; + mdb_put(c->txn, c->dbi, &mdb_key, mdb_data, 0); + mdb_txn_commit(c->txn); + bu_free(keycstr, "keycstr"); + bu_free(bdata, "buffer data"); +} + +static size_t +cache_get(struct ged_draw_cache *c, void **data, unsigned long long hash, const char *component) +{ + if (!c || !data || hash == 0 || !component) + return 0; + + // Construct lookup key + MDB_val mdb_key; + MDB_val mdb_data[2]; + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + + // As implemented this shouldn't be necessary, since all our keys are below + // the default size limit (511) + //if (keystr.length()*sizeof(char) > mdb_env_get_maxkeysize(c->env)) + // return 0; + char *keycstr = bu_strdup(keystr.c_str()); + mdb_txn_begin(c->env, NULL, 0, &c->txn); + mdb_dbi_open(c->txn, NULL, 0, &c->dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keycstr; + int rc = mdb_get(c->txn, c->dbi, &mdb_key, &mdb_data[0]); + if (rc) { + bu_free(keycstr, "keycstr"); + (*data) = NULL; + return 0; + } + bu_free(keycstr, "keycstr"); + (*data) = mdb_data[0].mv_data; + + return mdb_data[0].mv_size; +} + +static void +cache_del(struct ged_draw_cache *c, unsigned long long hash, const char *component) +{ + if (!c || hash == 0 || !component) + return; + + // Construct lookup key + MDB_val mdb_key; + std::string keystr = std::to_string(hash) + std::string(":") + std::string(component); + + mdb_txn_begin(c->env, NULL, 0, &c->txn); + mdb_dbi_open(c->txn, NULL, 0, &c->dbi); + mdb_key.mv_size = keystr.length()*sizeof(char); + mdb_key.mv_data = (void *)keystr.c_str(); + mdb_del(c->txn, c->dbi, &mdb_key, NULL); + mdb_txn_commit(c->txn); +} + +static void +cache_done(struct ged_draw_cache *c) +{ + if (!c) + return; + mdb_txn_commit(c->txn); +} + + +// alphanum sort +bool alphanum_cmp(const std::string &a, const std::string &b) +{ + return alphanum_impl(a.c_str(), b.c_str(), NULL) < 0; +} + +struct walk_data { + DbiState *dbis = NULL; + std::unordered_map i_count; + mat_t *curr_mat = NULL; + unsigned long long phash = 0; +}; + +static void +populate_leaf(void *client_data, const char *name, matp_t c_m, int op) +{ + struct walk_data *d = (struct walk_data *)client_data; + struct db_i *dbip = d->dbis->dbip; + RT_CHECK_DBI(dbip); + + std::unordered_map &i_count = d->i_count; + XXH64_state_t h_state; + unsigned long long chash; + struct directory *dp = db_lookup(dbip, name, LOOKUP_QUIET); + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, name, strlen(name)*sizeof(char)); + chash = (unsigned long long)XXH64_digest(&h_state); + i_count[chash] += 1; + if (i_count[chash] > 1) { + // If we've got multiple instances of the same object in the tree, + // hash the string labeling the instance and map it to the correct + // parent comb so we can associate it with the tree contents + struct bu_vls iname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&iname, "%s@%llu", name, i_count[chash] - 1); + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, bu_vls_cstr(&iname), bu_vls_strlen(&iname)*sizeof(char)); + unsigned long long ihash = (unsigned long long)XXH64_digest(&h_state); + d->dbis->i_map[ihash] = chash; + d->dbis->i_str[ihash] = std::string(bu_vls_cstr(&iname)); + d->dbis->p_c[d->phash].insert(ihash); + d->dbis->p_v[d->phash].push_back(ihash); + if (dp == RT_DIR_NULL) { + // Invalid comb reference - goes into map + d->dbis->invalid_entry_map[ihash] = std::string(bu_vls_cstr(&iname)); + } else { + // In case this was previously invalid, remove + d->dbis->invalid_entry_map.erase(ihash); + } + bu_vls_free(&iname); + + // For the next stages, if we have an ihash use it + chash = ihash; + + } else { + + d->dbis->p_v[d->phash].push_back(chash); + d->dbis->p_c[d->phash].insert(chash); + if (dp == RT_DIR_NULL) { + // Invalid comb reference - goes into map + d->dbis->invalid_entry_map[chash] = std::string(name); + } else { + // In case this was previously invalid, remove + d->dbis->invalid_entry_map.erase(chash); + } + + } + + // If we have a non-IDN matrix, store it + if (c_m) { + for (int i = 0; i < 16; i++) + d->dbis->matrices[d->phash][chash].push_back(c_m[i]); + } + + // If we have a non-UNION op, store it + d->dbis->i_bool[d->phash][chash] = op; +} + +static void +populate_walk_tree(union tree *tp, void *d, int subtract_skip, int p_op, + void (*leaf_func)(void *, const char *, matp_t, int) + ) +{ + if (!tp) + return; + + RT_CK_TREE(tp); + + int op = p_op; + switch (tp->tr_op) { + case OP_SUBTRACT: + op = OP_SUBTRACT; + break; + case OP_INTERSECT: + op = OP_INTERSECT; + break; + }; + + + switch (tp->tr_op) { + case OP_SUBTRACT: + if (subtract_skip) + return; + /* fall through */ + case OP_UNION: + case OP_INTERSECT: + case OP_XOR: + populate_walk_tree(tp->tr_b.tb_right, d, subtract_skip, op, leaf_func); + /* fall through */ + case OP_NOT: + case OP_GUARD: + case OP_XNOP: + populate_walk_tree(tp->tr_b.tb_left, d, subtract_skip, OP_UNION, leaf_func); + break; + case OP_DB_LEAF: + (*leaf_func)(d, tp->tr_l.tl_name, tp->tr_l.tl_mat, op); + break; + default: + bu_log("unrecognized operator %d\n", tp->tr_op); + bu_bomb("draw walk\n"); + } +} + + +DbiState::DbiState(struct ged *ged_p) +{ + bu_vls_init(&path_string); + bu_vls_init(&hash_string); + BU_GET(res, struct resource); + rt_init_resource(res, 0, NULL); + shared_vs = new BViewState(this); + default_selected = new BSelectState(this); + selected_sets[std::string("default")] = default_selected; + gedp = ged_p; + if (!gedp) + return; + dbip = gedp->dbip; + if (!dbip) + return; + + // Set up cache + dcache = dbi_cache_open(dbip->dbi_filename); + + for (int i = 0; i < RT_DBNHASH; i++) { + struct directory *dp; + for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) { + update_dp(dp, 0); + } + } +} + + +DbiState::~DbiState() +{ + bu_vls_free(&path_string); + bu_vls_free(&hash_string); + std::unordered_map::iterator ss_it; + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + delete ss_it->second; + } + delete shared_vs; + rt_clean_resource_basic(NULL, res); + BU_PUT(res, struct resource); + + if (dcache) + dbi_cache_close(dcache); +} + + +void +DbiState::populate_maps(struct directory *dp, unsigned long long phash, int reset) +{ + if (!(dp->d_flags & RT_DIR_COMB)) + return; + std::unordered_map>::iterator pc_it; + std::unordered_map>::iterator pv_it; + pc_it = p_c.find(phash); + pv_it = p_v.find(phash); + if (pc_it == p_c.end() || pv_it != p_v.end() || reset) { + if (reset && pc_it != p_c.end()) { + pc_it->second.clear(); + } + if (reset && pv_it != p_v.end()) { + pv_it->second.clear(); + } + struct rt_db_internal in; + if (rt_db_get_internal(&in, dp, dbip, NULL, res) < 0) + return; + struct rt_comb_internal *comb = (struct rt_comb_internal *)in.idb_ptr; + if (!comb->tree) + return; + + std::unordered_map i_count; + struct walk_data d; + d.dbis = this; + d.phash = phash; + populate_walk_tree(comb->tree, (void *)&d, 0, OP_UNION, populate_leaf); + rt_db_free_internal(&in); + } +} + +unsigned long long +DbiState::path_hash(std::vector &path, size_t max_len) +{ + size_t mlen = (max_len) ? max_len : path.size(); + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, path.data(), mlen * sizeof(unsigned long long)); + return (unsigned long long)XXH64_digest(&h_state); +} + +static void +fp_path_split(std::vector &objs, const char *str) +{ + std::string s(str); + while (s.length() && s.c_str()[0] == '/') + s.erase(0, 1); //Remove leading slashes + + std::string nstr; + bool escaped = false; + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\\') { + if (escaped) { + nstr.push_back(s[i]); + escaped = false; + continue; + } + escaped = true; + continue; + } + if (s[i] == '/' && !escaped) { + if (nstr.length()) + objs.push_back(nstr); + nstr.clear(); + continue; + } + nstr.push_back(s[i]); + escaped = false; + } + if (nstr.length()) + objs.push_back(nstr); +} + +static std::string +name_deescape(std::string &name) +{ + std::string s(name); + std::string nstr; + + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\\') { + if ((i+1) < s.length()) + nstr.push_back(s[i+1]); + i++; + } else { + nstr.push_back(s[i]); + } + } + + return nstr; +} + +// This is a full (and more expensive) check to ensure +// a path has no cycles anywhere in it. +static bool +path_cyclic(std::vector &path) +{ + if (path.size() == 1) + return false; + int i = path.size() - 1; + while (i > 0) { + int j = i - 1; + while (j >= 0) { + if (path[i] == path[j]) + return true; + j--; + } + i--; + } + return false; +} + +// This version of the cyclic check assumes the path entries other than the +// last one are OK, and checks only against that last entry. +static bool +path_addition_cyclic(std::vector &path) +{ + if (path.size() == 1) + return false; + int new_entry = path.size() - 1; + int i = new_entry - 1; + while (i >= 0) { + if (path[new_entry] == path[i]) + return true; + i--; + } + return false; +} + + +static size_t +path_elements(std::vector &elements, const char *path) +{ + std::vector substrs; + fp_path_split(substrs, path); + for (size_t i = 0; i < substrs.size(); i++) { + std::string cleared = name_deescape(substrs[i]); + elements.push_back(cleared); + } + return elements.size(); +} + +std::vector +DbiState::digest_path(const char *path) +{ + // If no path, nothing to process + if (!path) + return std::vector(); + + // Digest the string into individual path elements + std::vector elements; + path_elements(elements, path); + + // Convert the string elements into hash elements + std::vector phe; + struct bu_vls hname = BU_VLS_INIT_ZERO; + XXH64_state_t h_state; + for (size_t i = 0; i < elements.size(); i++) { + XXH64_reset(&h_state, 0); + bu_vls_sprintf(&hname, "%s", elements[i].c_str()); + XXH64_update(&h_state, bu_vls_cstr(&hname), bu_vls_strlen(&hname)*sizeof(char)); + phe.push_back((unsigned long long)XXH64_digest(&h_state)); + } + bu_vls_free(&hname); + + // If we're cyclic, path is invalid + if (path_cyclic(phe)) + return std::vector(); + + // parent/child relationship validate + std::unordered_map>::iterator pc_it; + std::unordered_map::iterator i_it; + unsigned long long phash = phe[0]; + for (size_t i = 1; i < phe.size(); i++) { + pc_it = p_c.find(phash); + // The parent comb structure is stored only under its original name's hash - if + // we have a numbered instance from a comb tree as a parent, we may be able to + // map it to the correct entry with i_map. If not, we have an invalid path. + if (pc_it == p_c.end()) { + i_it = i_map.find(phash); + if (i_it == i_map.end()) + return std::vector(); + phash = i_it->second; + pc_it = p_c.find(phash); + if (pc_it == p_c.end()) + return std::vector(); + } + unsigned long long chash = phe[i]; + if (pc_it->second.find(chash) == pc_it->second.end()) { + bu_log("Invalid element path: %s\n", elements[i].c_str()); + return std::vector(); + } + phash = chash; + } + + return phe; +} + +bool +DbiState::valid_hash(unsigned long long phash) +{ + if (!phash) + return false; + + // First, see if the hash is an instance string + if (i_str.find(phash) != i_str.end()) + return true; + + // If we have potentially obsolete names, check those + // before trying the dp (which may no longer be invalid) + if (old_names.size() && old_names.find(phash) != old_names.end()) + return true; + + // If not, try the directory pointer + if (d_map.find(phash) != d_map.end()) + return true; + + // Last option - invalid string + if (invalid_entry_map.find(phash) != invalid_entry_map.end()) + return true; + + return false; +} + +bool +DbiState::valid_hash_path(std::vector &phashes) +{ + for (size_t i = 0; i < phashes.size(); i++) { + if (!valid_hash(phashes[i])) + return false; + } + return true; +} + +bool +DbiState::print_hash(struct bu_vls *opath, unsigned long long phash) +{ + if (!phash) + return false; + + // First, see if the hash is an instance string + if (i_str.find(phash) != i_str.end()) { + bu_vls_printf(opath, "%s", i_str[phash].c_str()); + return true; + } + + // If we have potentially obsolete names, check those + // before trying the dp (which may no longer be invalid) + if (old_names.size() && old_names.find(phash) != old_names.end()) { + bu_vls_printf(opath, "%s", old_names[phash].c_str()); + return true; + } + + // If not, try the directory pointer + if (d_map.find(phash) != d_map.end()) { + bu_vls_printf(opath, "%s", d_map[phash]->d_namep); + return true; + } + + // Last option - invalid string + if (invalid_entry_map.find(phash) != invalid_entry_map.end()) { + bu_vls_printf(opath, "%s", invalid_entry_map[phash].c_str()); + return true; + } + + bu_exit(EXIT_FAILURE, "DbiState::print_hash failure, dbi_state.cpp::%d - a hash not known to tha database's DbiState was passed in. This can happen when the dbip contents change and dbi_state->update() isn't called in the parent application after doing so.\n", __LINE__); + bu_vls_printf(opath, "\nERROR!!!\n"); + return false; +} + +void +DbiState::print_path(struct bu_vls *opath, std::vector &path, size_t pmax, int verbose) +{ + if (!opath || !path.size()) + return; + + bu_vls_trunc(opath, 0); + for (size_t i = 0; i < path.size(); i++) { + if (pmax && i == pmax) + break; + if (i > 0 && verbose) { + std::unordered_map>>::iterator m_it; + m_it = matrices.find(path[i-1]); + if (m_it != matrices.end()) { + std::unordered_map>::iterator mv_it; + mv_it = m_it->second.find(path[i]); + if (mv_it == m_it->second.end()) { + bu_vls_printf(opath, "[M]"); + } + } + } + if (!print_hash(opath, path[i])) + continue; + if (i < path.size() - 1 && (!pmax || i < pmax - 1)) + bu_vls_printf(opath, "/"); + } +} + +const char * +DbiState::pathstr(std::vector &path, size_t pmax) +{ + bu_vls_trunc(&path_string, 0); + print_path(&path_string, path, pmax); + return bu_vls_cstr(&path_string); +} + + +const char * +DbiState::hashstr(unsigned long long hash) +{ + bu_vls_trunc(&hash_string, 0); + print_hash(&hash_string, hash); + return bu_vls_cstr(&hash_string); +} + +unsigned int +DbiState::color_int(struct bu_color *c) +{ + if (!c) + return 0; + int r, g, b; + bu_color_to_rgb_ints(c, &r, &g, &b); + unsigned int colors = r + (g << 8) + (b << 16); + return colors; +} + +int +DbiState::int_color(struct bu_color *c, unsigned int cval) +{ + if (!c) + return 0; + + int r, g, b; + r = cval & 0xFF; + g = (cval >> 8) & 0xFF; + b = (cval >> 16) & 0xFF; + + unsigned char lrgb[3]; + lrgb[0] = (unsigned char)r; + lrgb[1] = (unsigned char)g; + lrgb[2] = (unsigned char)b; + + return bu_color_from_rgb_chars(c, lrgb); +} + +void +DbiState::clear_cache(struct directory *dp) +{ + if (!dp || !dcache) + return; + + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + unsigned long long hash = (unsigned long long)XXH64_digest(&h_state); + + cache_del(dcache, hash, CACHE_OBJ_BOUNDS); + cache_del(dcache, hash, CACHE_REGION_ID); + cache_del(dcache, hash, CACHE_REGION_FLAG); + cache_del(dcache, hash, CACHE_INHERIT_FLAG); + cache_del(dcache, hash, CACHE_COLOR); + + bboxes.erase(hash); + region_id.erase(hash); + c_inherit.erase(hash); + rgb.erase(hash); +} + +unsigned long long +DbiState::update_dp(struct directory *dp, int reset) +{ + if (dp->d_flags & DB_LS_HIDDEN) + return 0; + + // Set up to go from hash back to name + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + unsigned long long hash = (unsigned long long)XXH64_digest(&h_state); + d_map[hash] = dp; + + // Clear any (possibly) state bbox. bbox calculation + // can be expensive, so defer it until it's needed + bboxes.erase(hash); + + // Encode hierarchy info if this is a comb + if (dp->d_flags & RT_DIR_COMB) + populate_maps(dp, hash, reset); + + // Check for various drawing related attributes + // Ideally, if we have enough info, we'd like to avoid loading + // the avs. See if we can get away with it using dcache + struct bu_attribute_value_set c_avs = BU_AVS_INIT_ZERO; + bool loaded_avs = false; + region_id.erase(hash); + c_inherit.erase(hash); + rgb.erase(hash); + + // First, check the dcache for all remaining needed values + const char *b = NULL; + size_t bsize = 0; + + bool need_region_id_avs = true; + bool need_region_flag_avs = true; + bool need_color_inherit_avs = true; + bool need_cval_avs = true; + + int region_flag = 0; + int attr_region_id = -1; + int color_inherit = 0; + unsigned int cval = INT_MAX; + + bsize = cache_get(dcache, (void **)&b, hash, CACHE_REGION_ID); + if (bsize == sizeof(attr_region_id)) { + memcpy(&attr_region_id, b, sizeof(attr_region_id)); + need_region_id_avs = false; + } + cache_done(dcache); + + bsize = cache_get(dcache, (void **)&b, hash, CACHE_REGION_FLAG); + if (bsize == sizeof(region_flag)) { + memcpy(®ion_flag, b, sizeof(region_flag)); + need_region_flag_avs = false; + } + cache_done(dcache); + + bsize = cache_get(dcache, (void **)&b, hash, CACHE_INHERIT_FLAG); + if (bsize == sizeof(color_inherit)) { + memcpy(&color_inherit, b, sizeof(color_inherit)); + need_color_inherit_avs = false; + } + cache_done(dcache); + + bsize = cache_get(dcache, (void **)&b, hash, CACHE_COLOR); + if (bsize == sizeof(cval)) { + memcpy(&cval, b, sizeof(cval)); + need_cval_avs = false; + } + cache_done(dcache); + + + if (need_region_flag_avs) { + if (!loaded_avs) { + db5_get_attributes(dbip, &c_avs, dp); + loaded_avs = true; + } + // Check for region flag. + const char *region_flag_str = bu_avs_get(&c_avs, "region"); + if (region_flag_str && (BU_STR_EQUAL(region_flag_str, "R") || BU_STR_EQUAL(region_flag_str, "1"))) { + region_flag = 1; + } + + std::stringstream s; + s.write(reinterpret_cast(®ion_flag), sizeof(region_flag)); + cache_write(dcache, hash, CACHE_REGION_FLAG, s); + } + + + if (need_region_id_avs) { + if (!loaded_avs) { + db5_get_attributes(dbip, &c_avs, dp); + loaded_avs = true; + } + // Check for region id. For drawing purposes this needs to be a number. + const char *region_id_val = bu_avs_get(&c_avs, "region_id"); + if (region_id_val) + bu_opt_int(NULL, 1, ®ion_id_val, (void *)&attr_region_id); + + std::stringstream s; + s.write(reinterpret_cast(&attr_region_id), sizeof(attr_region_id)); + cache_write(dcache, hash, CACHE_REGION_ID, s); + } + + if (need_color_inherit_avs) { + if (!loaded_avs) { + db5_get_attributes(dbip, &c_avs, dp); + loaded_avs = true; + } + color_inherit = (BU_STR_EQUAL(bu_avs_get(&c_avs, "inherit"), "1")) ? 1 : 0; + + std::stringstream s; + s.write(reinterpret_cast(&color_inherit), sizeof(color_inherit)); + cache_write(dcache, hash, CACHE_INHERIT_FLAG, s); + } + + if (need_cval_avs) { + if (!loaded_avs) { + db5_get_attributes(dbip, &c_avs, dp); + loaded_avs = true; + } + // Color (note that the rt_material_head colors and a region_id may + // override this, as might a parent comb with color and the inherit + // flag both set. + rgb.erase(hash); + struct bu_color c = BU_COLOR_INIT_ZERO; + const char *color_val = bu_avs_get(&c_avs, "color"); + if (!color_val) + color_val = bu_avs_get(&c_avs, "rgb"); + if (color_val){ + bu_opt_color(NULL, 1, &color_val, (void *)&c); + cval = color_int(&c); + bu_log("have color: %u\n", cval); + } + + std::stringstream s; + s.write(reinterpret_cast(&cval), sizeof(cval)); + cache_write(dcache, hash, CACHE_COLOR, s); + } + + // If a region flag is set but a region_id is not, there is an implicit + // assumption that the region_id is to be regarded as 0. Not sure this + // will always be true, but right now region table based coloring works + // that way in existing BRL-CAD code (see the example m35.g model's + // all.g/component/power.train/r75 for an instance of this) + if (region_flag && attr_region_id == -1) + attr_region_id = 0; + + + if (attr_region_id != -1) + region_id[hash] = attr_region_id; + if (color_inherit) + c_inherit[hash] = color_inherit; + if (cval != INT_MAX) + rgb[hash] = cval; + + // Done with attributes + if (loaded_avs) { + bu_log("Had to load avs\n"); + bu_avs_free(&c_avs); + } + return hash; +} + +bool +DbiState::path_color(struct bu_color *c, std::vector &elements) +{ + // This may not be how we'll always want to do this, but at least for the + // moment (to duplicate observed MGED behavior) the first region_id seen + // along the path with an active color in rt_material_head trumps all other + // color values set by any other means. + if (rt_material_head() != MATER_NULL) { + std::unordered_map::iterator r_it; + int path_region_id; + for (size_t i = 0; i < elements.size(); i++) { + r_it = region_id.find(elements[i]); + if (r_it == region_id.end()) + continue; + path_region_id = r_it->second; + const struct mater *mp; + for (mp = rt_material_head(); mp != MATER_NULL; mp = mp->mt_forw) { + if (path_region_id > mp->mt_high || path_region_id < mp->mt_low) + continue; + unsigned char mt[3]; + mt[0] = mp->mt_r; + mt[1] = mp->mt_g; + mt[2] = mp->mt_b; + bu_color_from_rgb_chars(c, mt); + return true; + } + } + } + + // Next, check for an inherited color. If we have one (the behavior seen in MGED + // appears to require a comb with both inherit and a color value set to override + // lower colors) then we are done. + std::unordered_map::iterator ci_it; + std::unordered_map::iterator rgb_it; + for (size_t i = 0; i < elements.size(); i++) { + ci_it = c_inherit.find(elements[i]); + if (ci_it == c_inherit.end()) + continue; + rgb_it = rgb.find(elements[i]); + if (rgb_it == rgb.end()) + continue; + int_color(c, rgb_it->second); + return true; + } + + // If we don't have an inherited color, it works the other way around - the + // lowest set color wins. Note that a region flag doesn't automatically + // override a lower color level - i.e. there is no implicit inherit flag + // in a region being set on a comb. + std::vector::reverse_iterator v_it; + for (v_it = elements.rbegin(); v_it != elements.rend(); v_it++) { + rgb_it = rgb.find(*v_it); + if (rgb_it == rgb.end()) + continue; + int_color(c, rgb_it->second); + return true; + } + + // If we don't have anything else, default to red + unsigned char mt[3]; + mt[0] = 255; + mt[1] = 0; + mt[2] = 0; + bu_color_from_rgb_chars(c, mt); + return false; +} + +bool +DbiState::path_is_subtraction(std::vector &elements) +{ + if (elements.size() < 2) + return false; + + unsigned long long phash = elements[0]; + for (size_t i = 1; i < elements.size(); i++) { + unsigned long long chash = elements[i]; + std::unordered_map>::iterator i_it; + i_it = i_bool.find(phash); + if (i_it == i_bool.end()) + return false; + std::unordered_map::iterator ib_it; + ib_it = i_it->second.find(chash); + if (ib_it == i_it->second.end()) + return false; + + if (ib_it->second == OP_SUBTRACT) + return true; + + phash = chash; + } + + return false; +} + +db_op_t +DbiState::bool_op(unsigned long long phash, unsigned long long chash) +{ + if (!phash) + return DB_OP_UNION; + size_t op = i_bool[phash][chash]; + if (op == OP_SUBTRACT) { + return DB_OP_SUBTRACT; + } + if (op == OP_INTERSECT) + return DB_OP_INTERSECT; + return DB_OP_UNION; +} + +struct directory * +DbiState::get_hdp(unsigned long long phash) +{ + if (!phash) + return NULL; + + std::unordered_map::iterator d_it; + d_it = d_map.find(phash); + if (d_it != d_map.end()) { + return d_it->second; + } + + std::unordered_map::iterator i_it; + i_it = i_map.find(phash); + + if (i_it != i_map.end()) { + d_it = d_map.find(i_it->second); + if (d_it != d_map.end()) { + return d_it->second; + } + } + + return NULL; +} + +bool +DbiState::get_matrix(matp_t m, unsigned long long p_key, unsigned long long i_key) +{ + if (UNLIKELY(!m || p_key == 0 || i_key == 0)) + return false; + + std::unordered_map>>::iterator m_it; + std::unordered_map>::iterator mv_it; + m_it = matrices.find(p_key); + if (m_it == matrices.end()) + return false; + mv_it = m_it->second.find(i_key); + if (mv_it == m_it->second.end()) + return false; + + // If we got this far, we have an index into the matrices vector. Assign + // the result to m + std::vector &mv = mv_it->second; + for (size_t i = 0; i < 16; i++) + m[i] = mv[i]; + + return true; +} + +bool +DbiState::get_path_matrix(matp_t m, std::vector &elements) +{ + bool have_mat = false; + if (UNLIKELY(!m)) + return have_mat; + + MAT_IDN(m); + if (elements.size() < 2) + return have_mat; + + unsigned long long phash = elements[0]; + for (size_t i = 1; i < elements.size(); i++) { + unsigned long long chash = elements[i]; + mat_t nm; + MAT_IDN(nm); + bool got_mat = get_matrix(nm, phash, chash); + if (got_mat) { + mat_t cmat; + bn_mat_mul(cmat, m, nm); + MAT_COPY(m, cmat); + have_mat = true; + } + phash = chash; + } + + return have_mat; +} + +bool +DbiState::get_bbox(point_t *bbmin, point_t *bbmax, matp_t curr_mat, unsigned long long hash) +{ + + if (UNLIKELY(!bbmin || !bbmax || hash == 0)) + return false; + + bool ret = false; + std::unordered_map>::iterator pc_it; + std::unordered_set::iterator s_it; + unsigned long long key = hash; + // First, see if this is an instance we need to translate to its canonical + // .g database name + if (i_map.find(hash) != i_map.end()) + key = i_map[hash]; + + // See if we have a direct bbox lookup available + std::unordered_map>::iterator b_it; + b_it = bboxes.find(key); + if (b_it != bboxes.end()) { + point_t lbmin, lbmax; + lbmin[X] = b_it->second[0]; + lbmin[Y] = b_it->second[1]; + lbmin[Z] = b_it->second[2]; + lbmax[X] = b_it->second[3]; + lbmax[Y] = b_it->second[4]; + lbmax[Z] = b_it->second[5]; + + if (curr_mat) { + point_t tbmin, tbmax; + MAT4X3PNT(tbmin, curr_mat, lbmin); + VMOVE(lbmin, tbmin); + MAT4X3PNT(tbmax, curr_mat, lbmax); + VMOVE(lbmax, tbmax); + } + + VMINMAX(*bbmin, *bbmax, lbmin); + VMINMAX(*bbmin, *bbmax, lbmax); + return true; + } + + // We might have a comb. If that's the case, we need to work + // through the hierarchy to get the bboxes of the children. + pc_it = p_c.find(key); + if (pc_it != p_c.end()) { + // Have comb children - incorporate each one + for (s_it = pc_it->second.begin(); s_it != pc_it->second.end(); s_it++) { + unsigned long long child_hash = *s_it; + // See if we have a matrix for this case - if so, we need to + // incorporate it + mat_t nm; + MAT_IDN(nm); + bool have_mat = get_matrix(nm, key, child_hash); + if (have_mat) { + // Construct new "current" matrix + if (curr_mat) { + // If we already have a non-IDN matrix from parent + // path elements, we need to multiply the matrices + // to accumulate the position changes + mat_t om; + MAT_COPY(om, curr_mat); + bn_mat_mul(curr_mat, om, nm); + if (get_bbox(bbmin, bbmax, curr_mat, child_hash)) + ret = true; + MAT_COPY(curr_mat, om); + } else { + // If this is the first non-IDN matrix, we don't + // need to combine it with parent matrices + if (get_bbox(bbmin, bbmax, nm, child_hash)) + ret = true; + } + } else { + if (get_bbox(bbmin, bbmax, curr_mat, child_hash)) + ret = true; + } + } + } + + // When we have an object that is not a comb, look up its pre-calculated + // box and incorporate it into bmin/bmax. + point_t bmin, bmax; + bool have_bbox = false; + + // First, check the dcache + const char *b = NULL; + size_t bsize = cache_get(dcache, (void **)&b, hash, CACHE_OBJ_BOUNDS); + if (bsize) { + if (bsize != (sizeof(bmin) + sizeof(bmax))) { + bu_log("Incorrect data size found loading cached bounds data\n"); + } else { + memcpy(&bmin, b, sizeof(bmin)); + b += sizeof(bmin); + memcpy(&bmax, b, sizeof(bmax)); + //bu_log("cached: bmin: %f %f %f bbmax: %f %f %f\n", V3ARGS(bmin), V3ARGS(bmax)); + have_bbox = true; + } + } + cache_done(dcache); + + + // This calculation can be expensive. If we've already + // got it stashed as part of LoD processing, use that + // version. + struct directory *dp = get_hdp(hash); + if (!dp) + return false; + if (!have_bbox) { + if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && gedp->ged_lod) { + key = bv_mesh_lod_key_get(gedp->ged_lod, dp->d_namep); + if (key) { + struct bv_mesh_lod *lod = bv_mesh_lod_create(gedp->ged_lod, key); + if (lod) { + VMOVE(bmin, lod->bmin); + VMOVE(bmax, lod->bmax); + have_bbox = true; + + std::stringstream s; + s.write(reinterpret_cast(&bmin), sizeof(bmin)); + s.write(reinterpret_cast(&bmax), sizeof(bmax)); + cache_write(dcache, hash, CACHE_OBJ_BOUNDS, s); + } + } + } + } + + // No LoD - ask librt + if (!have_bbox) { + struct bg_tess_tol ttol = BG_TESS_TOL_INIT_ZERO; + struct bn_tol tol = BN_TOL_INIT_TOL; + mat_t m; + MAT_IDN(m); + int bret = rt_bound_instance(&bmin, &bmax, dp, dbip, &ttol, &tol, &m, res); + if (bret != -1) { + have_bbox = true; + + std::stringstream s; + s.write(reinterpret_cast(&bmin), sizeof(bmin)); + s.write(reinterpret_cast(&bmax), sizeof(bmax)); + cache_write(dcache, hash, CACHE_OBJ_BOUNDS, s); + } + } + + if (have_bbox) { + for (size_t j = 0; j < 3; j++) + bboxes[hash].push_back(bmin[j]); + for (size_t j = 0; j < 3; j++) + bboxes[hash].push_back(bmax[j]); + + VMINMAX(*bbmin, *bbmax, bmin); + VMINMAX(*bbmin, *bbmax, bmax); + ret = true; + } + + return ret; +} + +bool +DbiState::get_path_bbox(point_t *bbmin, point_t *bbmax, std::vector &elements) +{ + if (UNLIKELY(!bbmin || !bbmax || !elements.size())) + return false; + + // Everything but the last element should be a comb - we only need to + // assemble a matrix from the path (if there are any non-identity matrices) + // and call get_bbox on the last element. + bool have_mat = false; + mat_t start_mat; + MAT_IDN(start_mat); + for (size_t i = 0; i < elements.size() - 1; i++) { + mat_t nm; + MAT_IDN(nm); + bool got_mat = get_matrix(nm, elements[i], elements[i+1]); + if (got_mat) { + mat_t cmat; + bn_mat_mul(cmat, start_mat, nm); + MAT_COPY(start_mat, cmat); + have_mat = true; + } + } + if (have_mat) { + return get_bbox(bbmin, bbmax, start_mat, elements[elements.size() - 1]); + } + + return get_bbox(bbmin, bbmax, NULL, elements[elements.size() - 1]); +} + +BViewState * +DbiState::get_view_state(struct bview *v) +{ + if (!v->independent) + return shared_vs; + if (view_states.find(v) != view_states.end()) + return view_states[v]; + + BViewState *nv = new BViewState(this); + view_states[v] = nv; + return nv; +} + +std::vector +DbiState::get_selected_states(const char *sname) +{ + std::vector ret; + std::unordered_map::iterator ss_it; + + if (!sname || BU_STR_EQUIV(sname, "default")) { + ret.push_back(default_selected); + return ret; + } + + std::string sn(sname); + if (sn.find('*') != std::string::npos) { + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + if (bu_path_match(sname, ss_it->first.c_str(), 0)) { + ret.push_back(ss_it->second); + } + } + return ret; + } + + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + if (BU_STR_EQUIV(sname, ss_it->first.c_str())) { + ret.push_back(ss_it->second); + } + } + if (ret.size()) + return ret; + + BSelectState *ns = new BSelectState(this); + selected_sets[sn] = ns; + ret.push_back(ns); + return ret; +} + +BSelectState * +DbiState::find_selected_state(const char *sname) +{ + if (!sname || BU_STR_EQUIV(sname, "default")) { + return default_selected; + } + + std::unordered_map::iterator ss_it; + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + if (BU_STR_EQUIV(sname, ss_it->first.c_str())) { + return ss_it->second; + } + } + + return NULL; +} + +void +DbiState::put_selected_state(const char *sname) +{ + if (!sname || BU_STR_EQUIV(sname, "default")) { + default_selected->clear(); + return; + } + + std::unordered_map::iterator ss_it; + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + if (BU_STR_EQUIV(sname, ss_it->first.c_str())) { + delete ss_it->second; + selected_sets.erase(ss_it); + return; + } + } +} + +std::vector +DbiState::list_selection_sets() +{ + std::vector ret; + std::unordered_map::iterator ss_it; + for (ss_it = selected_sets.begin(); ss_it != selected_sets.end(); ss_it++) { + ret.push_back(ss_it->first); + } + std::sort(ret.begin(), ret.end(), &alphanum_cmp); + return ret; +} + +void +DbiState::gather_cyclic( + std::unordered_set &cyclic, + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + std::unordered_map>::iterator pc_it; + pc_it = p_c.find(c_hash); + + path_hashes.push_back(c_hash); + + if (!path_addition_cyclic(path_hashes)) { + /* Not cyclic - keep going */ + if (pc_it != p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + gather_cyclic(cyclic, *c_it, path_hashes); + } + } else { + cyclic.insert(c_hash); + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); +} + +static int +alphanum_sort(const void *a, const void *b, void *UNUSED(data)) { + struct directory *ga = *(struct directory **)a; + struct directory *gb = *(struct directory **)b; + return alphanum_impl(ga->d_namep, gb->d_namep, NULL); +} + +std::vector +DbiState::tops(bool show_cyclic) +{ + std::vector ret; + // First, get the standard tops results + struct directory **all_paths = NULL; + db_update_nref(gedp->dbip, &rt_uniresource); + int tops_cnt = db_ls(gedp->dbip, DB_LS_TOPS, NULL, &all_paths); + if (all_paths) { + bu_sort(all_paths, tops_cnt, sizeof(struct directory *), alphanum_sort, NULL); + + XXH64_state_t h_state; + for (int i = 0; i < tops_cnt; i++) { + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, all_paths[i]->d_namep, strlen(all_paths[i]->d_namep)*sizeof(char)); + unsigned long long hash = (unsigned long long)XXH64_digest(&h_state); + ret.push_back(hash); + } + bu_free(all_paths, "free db_ls output"); + } + + if (!show_cyclic) + return ret; + + // If we also want cyclic paths, use DbiState to try and speed things up. + // db_ls has that capability, but it has to unpack all the combs walking + // the tree to find the answer and that results in a slow check for large + // databases. + std::unordered_set cyclic_paths; + std::vector path_hashes; + for (size_t i = 0; i < ret.size(); i++) { + path_hashes.clear(); + gather_cyclic(cyclic_paths, ret[i], path_hashes); + } + std::unordered_set::iterator c_it; + for (c_it = cyclic_paths.begin(); c_it != cyclic_paths.end(); c_it++) { + ret.push_back(*c_it); + } + + return ret; +} + +unsigned long long +DbiState::update() +{ + unsigned long long ret = 0; + + if (!added.size() && !changed.size() && !removed.size()) { + changed_hashes.clear(); + old_names.clear(); + return ret; + } + + // If we got this far, SOMETHING changed + ret |= GED_DBISTATE_DB_CHANGE; + + std::unordered_set::iterator s_it; + std::unordered_set::iterator g_it; + + if (need_update_nref) { + db_update_nref(dbip, res); + need_update_nref = false; + } + + // dps -> hashes + XXH64_state_t h_state; + changed_hashes.clear(); + for(g_it = changed.begin(); g_it != changed.end(); g_it++) { + struct directory *dp = *g_it; + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + unsigned long long hash = (unsigned long long)XXH64_digest(&h_state); + changed_hashes.insert(hash); + } + + // Update the primary data structures + for(s_it = removed.begin(); s_it != removed.end(); s_it++) { + bu_log("removed: %llu\n", *s_it); + + // Combs with this key in their child set need to be updated to refer + // to it as an invalid entry. + std::unordered_map>::iterator pv_it; + for (pv_it = p_v.begin(); pv_it != p_v.end(); pv_it++) { + for (size_t i = 0; i < pv_it->second.size(); i++) { + if (i_map.find(pv_it->second[i]) != i_map.end()) { + invalid_entry_map[i_map[pv_it->second[i]]] = i_str[i_map[pv_it->second[i]]]; + } else { + invalid_entry_map[pv_it->second[i]] = old_names[*s_it]; + } + } + } + + d_map.erase(*s_it); + bboxes.erase(*s_it); + c_inherit.erase(*s_it); + rgb.erase(*s_it); + region_id.erase(*s_it); + matrices.erase(*s_it); + i_bool.erase(*s_it); + + // We do not clear the instance maps (i_map and i_str) since those containers do not + // guarantee uniqueness to one child object. To remove entries no longer + // used anywhere in the database, we have to confirm they are no longer needed on a global + // basis in a subsequent garbage-collect operation. + + // Entries with this hash as their key are erased. + p_c.erase(*s_it); + p_v.erase(*s_it); + } + + for(g_it = added.begin(); g_it != added.end(); g_it++) { + struct directory *dp = *g_it; + bu_log("added: %s\n", dp->d_namep); + unsigned long long hash = update_dp(dp, 0); + + // If this name was previously the source of an invalid reference, + // it is no longer. + invalid_entry_map.erase(hash); + } + + for(g_it = changed.begin(); g_it != changed.end(); g_it++) { + struct directory *dp = *g_it; + bu_log("changed: %s\n", dp->d_namep); + // Properties need to be updated - comb children, colors, matrices, + // bounding box for solids, etc. + update_dp(dp, 1); + } + + // Garbage collect i_map and i_str + std::unordered_map>::iterator sk_it; + std::unordered_set used; + for (sk_it = p_v.begin(); sk_it != p_v.end(); sk_it++) { + used.insert(sk_it->second.begin(), sk_it->second.end()); + } + std::vector unused; + std::unordered_map::iterator im_it; + for (im_it = i_map.begin(); im_it != i_map.end(); im_it++) { + if (used.find(im_it->first) != used.end()) + unused.push_back(im_it->first); + } + for (size_t i = 0; i < unused.size(); i++) { + i_map.erase(unused[i]); + i_str.erase(unused[i]); + } + + // For all associated view states, execute any necessary changes to + // view objects and lists + std::unordered_map> vmap; + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *v = (struct bview *)BU_PTBL_GET(views, i); + BViewState *bvs = gedp->dbi_state->get_view_state(v); + if (!bvs) + continue; + vmap[bvs].insert(v); + } + std::unordered_map>::iterator bv_it; + for (bv_it = vmap.begin(); bv_it != vmap.end(); bv_it++) { + bv_it->first->redraw(NULL, bv_it->second, 1); + } + + // Updates done, clear items stored by callbacks + added.clear(); + changed.clear(); + changed_hashes.clear(); + removed.clear(); + old_names.clear(); + + return ret; +} + +void +DbiState::print_leaves( + std::set &leaves, + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + std::unordered_map>::iterator pc_it; + path_hashes.push_back(c_hash); + + bool leaf = path_addition_cyclic(path_hashes); + + if (!leaf) { + /* Not cyclic - keep going */ + pc_it = p_c.find(c_hash); + if (pc_it == p_c.end()) { + leaf = true; + } + } + + if (!leaf) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + print_leaves(leaves, *c_it, path_hashes); + } + + // Print leaf + if (leaf) { + struct bu_vls p = BU_VLS_INIT_ZERO; + print_path(&p, path_hashes, 0, 1); + leaves.insert(std::string(bu_vls_cstr(&p))); + bu_vls_free(&p); + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); +} + +void +DbiState::print_dbi_state(struct bu_vls *outvls, bool report_view_states) +{ + struct bu_vls *o = outvls; + if (!o) { + BU_GET(o, struct bu_vls); + bu_vls_init(o); + } + + std::vector top_objs = tops(true); + std::set leaves; + // Report each path to its leaves (or to cyclic termination) + std::vector path_hashes; + for (size_t i = 0; i < top_objs.size(); i++) { + path_hashes.clear(); + print_leaves(leaves, top_objs[i], path_hashes); + } + + std::set::iterator l_it; + for (l_it = leaves.begin(); l_it != leaves.end(); l_it++) + bu_vls_printf(o, "%s\n", l_it->c_str()); + + if (report_view_states) { + if (gedp->ged_gvp) { + BViewState *vs = get_view_state(gedp->ged_gvp); + bu_vls_printf(o, "\nDefault:\n"); + vs->print_view_state(o); + } + if (view_states.size()) { + std::unordered_map::iterator v_it; + std::map> oviews; + for (v_it = view_states.begin(); v_it != view_states.end(); v_it++) { + if (v_it->first == gedp->ged_gvp) + continue; + std::string vname(bu_vls_cstr(&v_it->first->gv_name)); + oviews[vname].insert(v_it->second); + } + if (oviews.size()) { + bu_vls_printf(o, "\nViews:\n"); + std::map>::iterator o_it; + for (o_it = oviews.begin(); o_it != oviews.end(); o_it++) { + std::set &vset = o_it->second; + if (vset.size() > 1) { + std::cout << "Warning: " << vset.size() << " views with name " << o_it->first << "\n"; + } + std::set::iterator vs_it; + for (vs_it = vset.begin(); vs_it != vset.end(); vs_it++) { + bu_vls_printf(o, "\n%s:\n", o_it->first.c_str()); + (*vs_it)->print_view_state(o); + } + } + } + } + } + + if (!outvls) + std::cout << bu_vls_cstr(o) << "\n"; + + if (o != outvls) { + bu_vls_free(o); + BU_PUT(o, struct bu_vls); + } +} + +BViewState::BViewState(DbiState *s) +{ + dbis = s; +} + +// 0 = valid, 3 = need re-eval +int +BViewState::leaf_check( + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + if (!c_hash) + return 0; + + bool is_removed = (dbis->removed.find(c_hash) != dbis->removed.end()); + if (is_removed) + return 3; + + bool is_changed = (dbis->changed_hashes.find(c_hash) != dbis->changed_hashes.end()); + if (is_changed) + return 3; + + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(c_hash); + path_hashes.push_back(c_hash); + + if (!path_addition_cyclic(path_hashes)) { + /* Not cyclic - keep going */ + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + if (leaf_check(*c_it, path_hashes)) + return 3; + } + } + + return 0; +} + +// 0 = valid, 1 = invalid, 2 = invalid, remain "drawn", 3 == need re-eval +int +BViewState::check_status( + std::unordered_set *invalid_paths, + std::unordered_set *changed_paths, + unsigned long long path_hash, + std::vector &cpath, + bool leaf_expand + ) +{ + // If nothing was removed or changed, there's nothing to tell us anything + // is invalid - just return + if (dbis->removed.size() && !dbis->changed_hashes.size()) + return 0; + + bool parent_changed = false; + for (size_t j = 0; j < cpath.size(); j++) { + unsigned long long phash = (j > 0) ? cpath[j-1] : 0; + unsigned long long hash = cpath[j]; + if (phash && parent_changed) { + // Need to see if this is still a parent of the new comb. This step + // is why the draw update has to come AFTER the above primitive + // update passes, so the comb can give us the correct, current + // answer. + bool is_parent = false; + if (dbis->p_c.find(phash) != dbis->p_c.end() && dbis->p_c[phash].find(hash) != dbis->p_c[phash].end()) + is_parent = true; + // If not we're done, whether or not the parent dp was + // removed from the database. + if (!is_parent) { + if (invalid_paths) + (*invalid_paths).insert(path_hash); + if (changed_paths) + (*changed_paths).erase(path_hash); + return 1; + } + // If it's still in the comb tree, proceed with the evaluation. + } + + bool is_removed = (dbis->removed.find(hash) != dbis->removed.end()); + bool is_changed = (dbis->changed_hashes.find(hash) != dbis->changed_hashes.end()); + if (is_removed) { + if (is_removed && !j) { + // Top level removed - everything else is gone + if (invalid_paths) + (*invalid_paths).insert(path_hash); + if (changed_paths) + (*changed_paths).erase(path_hash); + return 1; + } + + if (is_removed && j != cpath.size()-1) { + // If removed is first and not a leaf, erase - if we got here + // the parent comb either wasn't changed at all or this + // particular instance is still there; either way the state + // here is not preservable, since the path is trying to refer + // to a tree path which no longer exists in the hierarchy. + if (invalid_paths) + (*invalid_paths).insert(path_hash); + if (changed_paths) + (*changed_paths).erase(path_hash); + return 1; + } + if (is_removed && j == cpath.size()-1) { + // If removed is a leaf and the comb instance is intact, + // leave "drawn" as invalid path. + if (changed_paths) + (*changed_paths).insert(path_hash); + return 2; + } + } + if (is_changed) { + bu_log("changed\n"); + if (j == cpath.size()-1) { + // Changed, but a leaf - stays drawn + if (changed_paths) + (*changed_paths).insert(path_hash); + return 0; + } + // Not a leaf - check child + parent_changed = true; + if (changed_paths) + (*changed_paths).insert(path_hash); + continue; + } + + // If we got here, reset the parent changed flag + parent_changed = false; + } + + // If we got through the whole path and leaf check is enabled, check if the + // leaf of the path is a comb. If it is, the presumption is that this path + // is part of the active set because it is an evaluated solid, and we will + // have to check its tree to see if anything below it changed. + if (leaf_expand) { + std::vector pitems = cpath; + unsigned long long lhash = pitems[pitems.size() - 1]; + pitems.pop_back(); + int ret = leaf_check(lhash, pitems); + if (ret == 3 && changed_paths) { + (*changed_paths).insert(path_hash); + } + } + + return 0; +} + +void +BViewState::add_path(const char *path) +{ + if (!path) + return; + + std::vector path_hashes = dbis->digest_path(path); + add_hpath(path_hashes); +} + +void +BViewState::add_hpath(std::vector &path_hashes) +{ + if (!path_hashes.size()) + return; + staged.push_back(path_hashes); +} + +void +BViewState::erase_path(int mode, int argc, const char **argv) +{ + if (!argc || !argv) + return; + + std::unordered_map>::iterator sm_it; + for (int i = 0; i < argc; i++) { + std::vector path_hashes = dbis->digest_path(argv[i]); + if (!path_hashes.size()) + continue; + unsigned long long c_hash = path_hashes[path_hashes.size() - 1]; + path_hashes.pop_back(); + erase_hpath(mode, c_hash, path_hashes, false); + } + + // Update info AFTER all paths are fully drawn + cache_collapsed(); +} + +void +BViewState::erase_hpath(int mode, unsigned long long c_hash, std::vector &path_hashes, bool cache_collapse) +{ + std::unordered_map>::iterator sm_it; + std::unordered_map>::iterator pc_it; + std::unordered_map>::iterator m_it; + pc_it = dbis->p_c.find(c_hash); + + path_hashes.push_back(c_hash); + + /* Cyclic - wasn't anything to draw */ + if (path_addition_cyclic(path_hashes)) + return; + + /* For some modes it's possible for combs to have evaluated objects, so + * check regardless of whether c_hash is a solid */ + if (mode == 3 || mode == 5 || pc_it == dbis->p_c.end()) { + unsigned long long phash = dbis->path_hash(path_hashes, 0); + sm_it = s_map.find(phash); + if (sm_it != s_map.end()) { + std::unordered_map::iterator s_it; + if (mode < 0) { + for (s_it = sm_it->second.begin(); s_it != sm_it->second.end(); s_it++) + bv_obj_put(s_it->second); + for (m_it = drawn_paths.begin(); m_it != drawn_paths.end(); m_it++) + m_it->second.erase(phash); + s_map.erase(phash); + } else { + s_it = sm_it->second.find(mode); + if (s_it != sm_it->second.end()) { + bv_obj_put(s_it->second); + sm_it->second.erase(s_it); + drawn_paths[mode].erase(phash); + s_map[phash].erase(mode); + } + } + + // In case phash is now gone from s_map check again + sm_it = s_map.find(phash); + + // IFF we have removed all of the drawn elements for this path, + // clear it from the active sets + if (sm_it == s_map.end() || !sm_it->second.size()) { + s_keys.erase(phash); + all_drawn_paths.erase(phash); + } + } + } + + /* If we do have a comb, keep going */ + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + erase_hpath(mode, *c_it, path_hashes, false); + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); + + // Update info on drawn paths + if (cache_collapse) + cache_collapsed(); +} + +unsigned long long +BViewState::path_hash(std::vector &path, size_t max_len) +{ + return dbis->path_hash(path, max_len); +} + +void +BViewState::depth_group_collapse( + std::vector> &collapsed, + std::unordered_set &d_paths, + std::unordered_set &p_d_paths, + std::map> &depth_groups + ) +{ + // Whittle down the mode depth groups until we find not-fully-drawn + // parents - when we find that, the children constitute non-collapsible + // paths based on what's drawn in this mode + while (depth_groups.size()) { + size_t plen = depth_groups.rbegin()->first; + if (plen == 1) + break; + std::unordered_set &pckeys = depth_groups.rbegin()->second; + + // For a given depth, group the paths by parent path. This results + // in path sub-groups which will define for us how "fully drawn" + // that particular parent comb instance is. + std::unordered_map> grouped_pckeys; + std::unordered_map pcomb; + std::unordered_set::iterator s_it; + for (s_it = pckeys.begin(); s_it != pckeys.end(); s_it++) { + std::vector &pc_path = s_keys[*s_it]; + unsigned long long ppathhash = dbis->path_hash(pc_path, plen - 1); + grouped_pckeys[ppathhash].insert(*s_it); + pcomb[ppathhash] = pc_path[plen-2]; + } + + // For each parent/child grouping, compare it against the .g ground + // truth set. If they match, fully drawn and we promote the path to + // the parent depth. If not, the paths do not collapse further and are + // added to drawn paths. + std::unordered_map>::iterator pg_it; + for (pg_it = grouped_pckeys.begin(); pg_it != grouped_pckeys.end(); pg_it++) { + + unsigned long long cpkey = *pg_it->second.begin(); + std::vector check_path = s_keys[cpkey]; + check_path.pop_back(); + + // As above, use the full path from the s_keys, but this time + // we're collecting the children. This is the set we need to compare + // against the .g ground truth to determine fully or partially drawn. + std::unordered_set g_children; + std::unordered_set &g_pckeys = pg_it->second; + for (s_it = g_pckeys.begin(); s_it != g_pckeys.end(); s_it++) { + std::vector &pc_path = s_keys[*s_it]; + g_children.insert(pc_path[plen-1]); + } + + // Do the check against the .g comb children info - the "ground truth" + // that defines what must be present for a fully drawn comb + bool is_fully_drawn = true; + std::unordered_set &ground_truth = dbis->p_c[pcomb[pg_it->first]]; + for (s_it = ground_truth.begin(); s_it != ground_truth.end(); s_it++) { + } + for (s_it = ground_truth.begin(); s_it != ground_truth.end(); s_it++) { + if (g_children.find(*s_it) == g_children.end()) { + is_fully_drawn = false; + break; + } + } + + // All the sub-paths in this grouping are fully drawn, whether + // or not they define a fully drawn parent, so stash their + // hashes + for (s_it = g_pckeys.begin(); s_it != g_pckeys.end(); s_it++) { + std::vector &path_hashes = s_keys[*s_it]; + unsigned long long thash = dbis->path_hash(path_hashes, plen); + d_paths.insert(thash); + } + + if (is_fully_drawn) { + // If fully drawn, depth_groups[plen-1] gets the first path in + // g_pckeys. The path is longer than that depth, but contains + // all the necessary information and using that approach avoids + // the need to duplicate paths. + depth_groups[plen - 1].insert(*g_pckeys.begin()); + } else { + // No further collapsing - add to final. We must make trimmed + // versions of the paths in case this depth holds promoted + // paths from deeper levels, since we are duplicating the full + // path contents. + for (s_it = g_pckeys.begin(); s_it != g_pckeys.end(); s_it++) { + std::vector trimmed = s_keys[*s_it]; + trimmed.resize(plen); + collapsed.push_back(trimmed); + + // Because we're not collapsing further, any paths above this + // path can be considered partially drawn. + while (trimmed.size() - 1) { + trimmed.pop_back(); + unsigned long long thash = dbis->path_hash(trimmed, 0); + p_d_paths.insert(thash); + } + } + } + } + + // Done with this depth + depth_groups.erase(plen); + } + + // If we collapsed all the way to top level objects, make sure to add them + // if they are still valid entries. If a toplevel entry is invalid, there + // is no parent comb to refer to it as an "invalid" object and it can no + // longer be drawn. + if (depth_groups.find(1) != depth_groups.end()) { + std::unordered_set &pckeys = depth_groups[1]; + std::unordered_set::iterator s_it; + for (s_it = pckeys.begin(); s_it != pckeys.end(); s_it++) { + std::vector trimmed = s_keys[*s_it]; + trimmed.resize(1); + collapsed.push_back(trimmed); + unsigned long long thash = dbis->path_hash(trimmed, 0); + d_paths.insert(thash); + } + } +} + +void +BViewState::cache_collapsed() +{ + // Group drawn paths by drawing mode type + std::unordered_map> mode_map; + std::unordered_map>::iterator sk_it; + for (sk_it = s_keys.begin(); sk_it != s_keys.end(); sk_it++) { + std::unordered_map>::iterator s_it; + s_it = s_map.find(sk_it->first); + if (s_it == s_map.end()) + continue; + std::unordered_map::iterator sm_it; + for (sm_it = s_it->second.begin(); sm_it != s_it->second.end(); sm_it++) + mode_map[sm_it->first].insert(sk_it->first); + } + + // Collapse each drawing mode until the leaf is a changed dp or not fully + // drawn. We must do this before the comb p_c relationships are updated in + // the context, since we want the answers for this collapse to be from the + // prior state, not the current state. + + // Reset containers + mode_collapsed.clear(); + drawn_paths.clear(); + partially_drawn_paths.clear(); + + // Each mode is initially processed separately, so we maintain + // awareness of the drawing state in various modes + std::unordered_map>::iterator mm_it; + for (mm_it = mode_map.begin(); mm_it != mode_map.end(); mm_it++) { + + std::map> depth_groups; + std::unordered_set &mode_keys = mm_it->second;; + std::unordered_set::iterator ms_it; + + // Group paths of the same depth. Depth == 1 paths are already + // top level objects and need no further processing. + for (ms_it = mode_keys.begin(); ms_it != mode_keys.end(); ms_it++) { + std::unordered_map>::iterator k_it; + k_it = s_keys.find(*ms_it); + if (k_it->second.size() == 1) { + mode_collapsed[mm_it->first].push_back(k_it->second); + unsigned long long dhash = dbis->path_hash(k_it->second, 0); + drawn_paths[mm_it->first].insert(dhash); + } else { + depth_groups[k_it->second.size()].insert(k_it->first); + } + } + + depth_group_collapse(mode_collapsed[mm_it->first], drawn_paths[mm_it->first], partially_drawn_paths[mm_it->first], depth_groups); + } + + + // Having processed all the modes, we now do the same thing without regards to + // drawing mode, to provide "who" with a mode-agnostic list of drawn paths. + all_collapsed.clear(); + std::map> all_depth_groups; + for (mm_it = mode_map.begin(); mm_it != mode_map.end(); mm_it++) { + // Group paths of the same depth. Depth == 1 paths are already + // top level objects and need no further processing. + std::unordered_set &mode_keys = mm_it->second;; + std::unordered_set::iterator ms_it; + for (ms_it = mode_keys.begin(); ms_it != mode_keys.end(); ms_it++) { + std::unordered_map>::iterator k_it; + k_it = s_keys.find(*ms_it); + if (k_it->second.size() == 1) { + all_collapsed.push_back(k_it->second); + unsigned long long dhash = dbis->path_hash(k_it->second, 0); + all_drawn_paths.insert(dhash); + } else { + // Populate mode-agnostic container + all_depth_groups[k_it->second.size()].insert(k_it->first); + } + } + } + + all_drawn_paths.clear(); + all_partially_drawn_paths.clear(); + depth_group_collapse(all_collapsed, all_drawn_paths, all_partially_drawn_paths, all_depth_groups); +} + +struct bv_scene_obj * +BViewState::scene_obj( + std::unordered_set &objs, + int curr_mode, + struct bv_obj_settings *vs, + matp_t m, + std::vector &path_hashes, + std::unordered_set &views, + struct bview *v + ) +{ + // Solid - scene object time + unsigned long long phash = dbis->path_hash(path_hashes, 0); + std::unordered_map>::iterator sm_it; + sm_it = s_map.find(phash); + struct bv_scene_obj *sp = NULL; + if (sm_it != s_map.end()) { + + // If we have user supplied settings, we need to do some checking + if (vs && !vs->mixed_modes) { + // If we're not allowed to mix modes, we need to erase any modes + // that don't match the current mode + std::vector phashes = path_hashes; + if (phashes.size()) { + unsigned long long c_hash = phashes[phashes.size() - 1]; + phashes.pop_back(); + std::unordered_set erase_modes; + std::unordered_map::iterator s_it; + for (s_it = sm_it->second.begin(); s_it != sm_it->second.end(); s_it++) { + if (s_it->first == curr_mode) + continue; + erase_modes.insert(s_it->first); + } + std::unordered_set::iterator e_it; + for (e_it = erase_modes.begin(); e_it != erase_modes.end(); e_it++) { + erase_hpath(*e_it, c_hash, phashes, false); + } + } + } + + if (s_map[phash].find(curr_mode) != s_map[phash].end()) { + // Already have scene object - check it against vs + // settings to see if we need to update + sp = s_map[phash][curr_mode]; + if (vs && vs->s_dmode == curr_mode) { + if (sp->s_soldash && vs->draw_non_subtract_only) { + if (sp->s_flag != DOWN) + sp->s_flag = DOWN; + } else { + if (sp->s_flag != UP) + sp->s_flag = UP; + } + if (bv_obj_settings_sync(sp->s_os, vs)) + objs.insert(sp); + } + + // Most view setting changes won't alter geometry, and adaptive + // drawing updating is handled via callbacks. However, adaptive + // plotting enablement/disablement changes which type of objects + // we need. Make sure we're synced. + std::unordered_set::iterator v_it; + if (sp->csg_obj) { + for (v_it = views.begin(); v_it != views.end(); v_it++) { + int have_adaptive = bv_obj_have_vo(sp, *v_it); + if ((*v_it)->gv_s->adaptive_plot_csg && !have_adaptive) { + bv_obj_stale(sp); + sp->curve_scale = -1; // Make sure a rework is triggered + objs.insert(sp); + } + if (!(*v_it)->gv_s->adaptive_plot_csg && have_adaptive && bv_clear_view_obj(sp, *v_it)) { + bv_obj_stale(sp); + objs.insert(sp); + } + } + } + if (sp->mesh_obj) { + for (v_it = views.begin(); v_it != views.end(); v_it++) { + int have_adaptive = bv_obj_have_vo(sp, *v_it); + if ((*v_it)->gv_s->adaptive_plot_mesh && !have_adaptive) { + bv_obj_stale(sp); + objs.insert(sp); + } + if (!(*v_it)->gv_s->adaptive_plot_mesh && have_adaptive && bv_clear_view_obj(sp, *v_it)) { + bv_obj_stale(sp); + objs.insert(sp); + } + } + } + + return NULL; + } + } + + // No pre-existing object - make a new one + sp = bv_obj_get(v, BV_DB_OBJS); + + // Find the leaf directory pointer + struct directory *dp = dbis->get_hdp(path_hashes[path_hashes.size()-1]); + if (!dp) { + bu_log("dbi_state.cpp:%d - dp lookup failed!\n", __LINE__); + return NULL; + } + + // Prepare draw data + struct rt_wdb *wdbp = wdb_dbopen(dbis->gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + struct draw_update_data_t *ud; + BU_GET(ud, struct draw_update_data_t); + ud->dbip = dbis->gedp->dbip; + ud->tol = &wdbp->wdb_tol; + ud->ttol = &wdbp->wdb_ttol; + ud->res = &rt_uniresource; // TODO - at some point this may be from the app or view... local_res is temporary, don't use it here + ud->mesh_c = dbis->gedp->ged_lod; + sp->dp = dp; + sp->s_i_data = (void *)ud; + + // Get color from path, unless we're overridden + struct bu_color c; + dbis->path_color(&c, path_hashes); + bu_color_to_rgb_chars(&c, sp->s_color); + if (vs && vs->color_override) { + // TODO - shouldn't be using s_color for the override... + sp->s_color[0] = vs->color[0]; + sp->s_color[1] = vs->color[1]; + sp->s_color[2] = vs->color[2]; + } + + // Set drawing mode + sp->s_os->s_dmode = curr_mode; + + // Tell scene object what the current matrix is + if (m) { + MAT_COPY(sp->s_mat, m); + } else { + dbis->get_path_matrix(sp->s_mat, path_hashes); + } + + // Assign the bounding box (needed for pre-adaptive-plot + // autoview) + dbis->get_path_bbox(&sp->bmin, &sp->bmax, path_hashes); + + // Adaptive also needs s_size and s_center to be set + sp->s_center[X] = (sp->bmin[X] + sp->bmax[X]) * 0.5; + sp->s_center[Y] = (sp->bmin[Y] + sp->bmax[Y]) * 0.5; + sp->s_center[Z] = (sp->bmin[Z] + sp->bmax[Z]) * 0.5; + sp->s_size = sp->bmax[X] - sp->bmin[X]; + V_MAX(sp->s_size, sp->bmax[Y] - sp->bmin[Y]); + V_MAX(sp->s_size, sp->bmax[Z] - sp->bmin[Z]); + sp->have_bbox = 1; + + // If we're drawing a subtraction and we're not overridden, set the + // appropriate flag for dashed line drawing + if (vs && !vs->draw_solid_lines_only) { + bool is_subtract = dbis->path_is_subtraction(path_hashes); + sp->s_soldash = (is_subtract) ? 1 : 0; + } + + // Set line width, if the user specified a non-default value + if (vs && vs->s_line_width) + sp->s_os->s_line_width = vs->s_line_width; + + // Set transparency + if (vs) + sp->s_os->transparency = vs->transparency; + + dbis->print_path(&sp->s_name, path_hashes); + s_map[phash][sp->s_os->s_dmode] = sp; + s_keys[phash] = path_hashes; + + // Final geometry generation is deferred + objs.insert(sp); + + return sp; +} + + +void +BViewState::walk_tree( + std::unordered_set &objs, + unsigned long long chash, + int curr_mode, + struct bview *v, + struct bv_obj_settings *vs, + matp_t m, + std::vector &path_hashes, + std::unordered_set &views, + unsigned long long *ret + ) +{ + size_t op = OP_UNION; + std::unordered_map>::iterator b_it; + b_it = dbis->i_bool.find(path_hashes[path_hashes.size() - 1]); + if (b_it != dbis->i_bool.end()) { + std::unordered_map::iterator bb_it; + bb_it = b_it->second.find(chash); + if (bb_it != b_it->second.end()) { + op = bb_it->second; + } + } + + if (op == OP_SUBTRACT && vs && vs->draw_solid_lines_only) + return; + + mat_t lm; + MAT_IDN(lm); + unsigned long long phash = path_hashes[path_hashes.size() - 1]; + dbis->get_matrix(lm, phash, chash); + + gather_paths(objs, chash, curr_mode, v, vs, m, lm, path_hashes, views, ret); +} + +// Note - by the time we are using gather_paths, any existing objects +// already defined are assumed to be updated/valid - only create +// missing objects. +void +BViewState::gather_paths( + std::unordered_set &objs, + unsigned long long c_hash, + int curr_mode, + struct bview *v, + struct bv_obj_settings *vs, + matp_t m, + matp_t lm, + std::vector &path_hashes, + std::unordered_set &views, + unsigned long long *ret + ) +{ + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(c_hash); + + struct directory *dp = dbis->get_hdp(c_hash); + path_hashes.push_back(c_hash); + + mat_t om, nm; + /* Update current matrix state to reflect the new branch of + * the tree. Either we have a local matrix, or we have an + * implicit IDN matrix. */ + MAT_COPY(om, m); + if (lm) { + MAT_COPY(nm, lm); + } else { + MAT_IDN(nm); + } + bn_mat_mul(m, om, nm); + + if (pc_it != dbis->p_c.end()) { + // Two things may prevent further processing of a comb - a hidden dp, or + // a cyclic path. + if (dp && !(dp->d_flags & RT_DIR_HIDDEN) && pc_it->second.size() && !path_addition_cyclic(path_hashes)) { + /* Keep going */ + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) { + walk_tree(objs, *c_it, curr_mode, v, vs, m, path_hashes, views, ret); + } + } else { + // Comb without children - (empty) scene object time + scene_obj(objs, curr_mode, vs, m, path_hashes, views, v); + } + } else { + // Solid - scene object time + struct bv_scene_obj *nobj = scene_obj(objs, curr_mode, vs, m, path_hashes, views, v); + if (nobj && ret) + (*ret) |= GED_DBISTATE_VIEW_CHANGE; + } + /* Done with branch - restore path, put back the old matrix state, + * and restore previous color settings */ + path_hashes.pop_back(); + MAT_COPY(m, om); +} + +void +BViewState::clear() +{ + s_map.clear(); + s_keys.clear(); + staged.clear(); + drawn_paths.clear(); + all_drawn_paths.clear(); + partially_drawn_paths.clear(); + mode_collapsed.clear(); + all_collapsed.clear(); +} + +std::vector +BViewState::list_drawn_paths(int mode, bool list_collapsed) +{ + std::unordered_map>>::iterator m_it; + std::vector ret; + if (mode == -1 && list_collapsed) { + struct bu_vls vpath = BU_VLS_INIT_ZERO; + for (size_t i = 0; i < all_collapsed.size(); i++) { + dbis->print_path(&vpath, all_collapsed[i]); + ret.push_back(std::string(bu_vls_cstr(&vpath))); + } + } + if (mode != -1 && list_collapsed) { + m_it = mode_collapsed.find(mode); + if (m_it == mode_collapsed.end()) + return ret; + struct bu_vls vpath = BU_VLS_INIT_ZERO; + for (size_t i = 0; i < m_it->second.size(); i++) { + dbis->print_path(&vpath, m_it->second[i]); + ret.push_back(std::string(bu_vls_cstr(&vpath))); + } + } + if (mode == -1 && !list_collapsed) { + struct bu_vls vpath = BU_VLS_INIT_ZERO; + std::unordered_map>::iterator k_it; + for (k_it = s_keys.begin(); k_it != s_keys.end(); k_it++) { + dbis->print_path(&vpath, k_it->second); + ret.push_back(std::string(bu_vls_cstr(&vpath))); + } + } + if (mode != -1 && !list_collapsed) { + struct bu_vls vpath = BU_VLS_INIT_ZERO; + std::unordered_map>::iterator sm_it; + for (sm_it = s_map.begin(); sm_it != s_map.end(); sm_it++) { + if (sm_it->second.find(mode) == sm_it->second.end()) + continue; + dbis->print_path(&vpath, s_keys[sm_it->first]); + ret.push_back(std::string(bu_vls_cstr(&vpath))); + } + } + + std::sort(ret.begin(), ret.end(), &alphanum_cmp); + + return ret; +} + +size_t +BViewState::count_drawn_paths(int mode, bool list_collapsed) +{ + std::unordered_map>>::iterator m_it; + std::vector ret; + if (mode == -1 && list_collapsed) + return all_collapsed.size(); + + if (mode != -1 && list_collapsed) { + m_it = mode_collapsed.find(mode); + if (m_it == mode_collapsed.end()) + return m_it->second.size(); + return 0; + } + + if (mode == -1 && !list_collapsed) + return s_keys.size(); + + if (mode != -1 && !list_collapsed) { + std::unordered_map>::iterator sm_it; + sm_it = s_map.find(mode); + if (sm_it != s_map.end()) + return sm_it->second.size(); + return 0; + } + + return 0; +} + +int +BViewState::is_hdrawn(int mode, unsigned long long phash) +{ + if (mode == -1) { + if (all_drawn_paths.find(phash) != all_drawn_paths.end()) + return 1; + if (all_partially_drawn_paths.find(phash) != all_partially_drawn_paths.end()) + return 2; + return 0; + } + + if (drawn_paths.find(mode) == drawn_paths.end()) + return 0; + + if (drawn_paths[mode].find(phash) != drawn_paths[mode].end()) + return 1; + if (partially_drawn_paths[mode].find(phash) != partially_drawn_paths[mode].end()) + return 2; + return 0; +} + +unsigned long long +BViewState::refresh(struct bview *v, int argc, const char **argv) +{ + if (!v) + return 0; + + bv_log(1, "BViewState::refresh"); + // We (well, callers) need to be able to tell if the redraw pass actually + // changed anything. + unsigned long long ret = 0; + + // Make sure the view knows how to update the oriented bounding box + v->gv_bounds_update = &bv_view_bounds; + + // If we have specific paths specified, the leaves of those paths + // denote which paths need refreshing. We need to process them + // and turn them to hashes, so we can check the s_keys hash vectors + // for the presence of "hashes of interest". + // + // Note - this is too aggressive, in that it will result in refreshing + // of objects that have the leaf in their paths but don't match the + // parent full path. However, checking the full parent path is more + // complicated without an n^2 order performance problem, so for the + // moment we punt and use the more aggressive redraw solution. + std::unordered_set active_hashes; + for (int i = 0; i < argc; i++) { + std::vector phashes = dbis->digest_path(argv[i]); + active_hashes.insert(phashes[phashes.size() - 1]); + } + + // Objects may be "drawn" in different ways - wireframes, shaded, + // evaluated. How they must be redrawn is mode dependent. + std::unordered_map> mode_map; + std::unordered_map>::iterator sk_it; + for (sk_it = s_keys.begin(); sk_it != s_keys.end(); sk_it++) { + std::unordered_map>::iterator s_it; + s_it = s_map.find(sk_it->first); + if (s_it == s_map.end()) + continue; + + // If we have specified objects, we only refresh if the path + // involves a hash of interest + if (active_hashes.size()) { + int active = 0; + for (size_t i = 0; i < sk_it->second.size(); i++) { + if (active_hashes.find(sk_it->second[i]) != active_hashes.end()) { + active = 1; + break; + } + } + if (!active) + continue; + } + + std::unordered_map::iterator sm_it; + for (sm_it = s_it->second.begin(); sm_it != s_it->second.end(); sm_it++) { + mode_map[sm_it->first].insert(sk_it->first); + } + } + + // Redo drawing based on current db info - color, matrix, and geometry + std::unordered_map>::iterator mm_it; + for (mm_it = mode_map.begin(); mm_it != mode_map.end(); mm_it++) { + std::unordered_set &mkeys = mm_it->second; + std::unordered_set::iterator k_it; + for (k_it = mkeys.begin(); k_it != mkeys.end(); k_it++) { + std::vector &cp = s_keys[*k_it]; + struct bv_scene_obj *s = NULL; + if (s_map.find(*k_it) != s_map.end()) { + if (s_map[*k_it].find(mm_it->first) != s_map[*k_it].end()) + s = s_map[*k_it][mm_it->first]; + } + if (!s) + continue; + struct bv_scene_obj *nso = bv_obj_get(v, BV_DB_OBJS); + bv_obj_sync(nso, s); + nso->s_i_data = s->s_i_data; + s->s_i_data = NULL; + s_map[*k_it].erase(mm_it->first); + ret = GED_DBISTATE_VIEW_CHANGE; + + // print path name, set view - otherwise empty + dbis->print_path(&nso->s_name, cp); + nso->s_v = v; + nso->dp = s->dp; + s_map[*k_it][mm_it->first] = nso; + + //bv_log(3, "refresh %s[%s]", bu_vls_cstr(&(nso->s_name)), bu_vls_cstr(&(v->gv_name))); + bu_log("refresh %s[%s]\n", bu_vls_cstr(&(nso->s_name)), bu_vls_cstr(&(v->gv_name))); + draw_scene(nso, v); + bv_obj_put(s); + } + } + + // Do selection sync + BSelectState *ss = dbis->find_selected_state(NULL); + if (ss) { + ss->draw_sync(); + ret = GED_DBISTATE_VIEW_CHANGE; + } + + return ret; +} + +unsigned long long +BViewState::redraw(struct bv_obj_settings *vs, std::unordered_set &views, int no_autoview) +{ + bv_log(1, "BViewState::redraw"); + // We (well, callers) need to be able to tell if the redraw pass actually + // changed anything. + unsigned long long ret = 0; + + if (!views.size()) + return 0; + + // Make sure the views know how to update the oriented bounding box + std::unordered_set::iterator v_it; + for (v_it = views.begin(); v_it != views.end(); v_it++) { + struct bview *v = *v_it; + v->gv_bounds_update = &bv_view_bounds; + } + + // For most operations on objects, we need only the current view (for + // independent views) or a single instance of any representative view (for + // shared state views). + struct bview *v = NULL; + if (views.size() == 1) + v = (*(views.begin())); + if (!v && views.size() > 1) { + // If we have multiple views, we want a non-independent view + for (v_it = views.begin(); v_it != views.end(); v_it++) { + struct bview *nv = *v_it; + if (nv->independent) + continue; + v = nv; + break; + } + } + + // The principle for redrawing will be that anything that was previously + // fully drawn should stay fully drawn, even if its tree structure has + // changed. + // + // In order to accommodate autoview requirements, final geometry + // drawing has to be delayed until after the initial scene objects are + // created. Make a set to track which objects we need to draw in the + // finalization stage. + std::unordered_set objs; + + + // First order of business is to go through already drawn solids, if any, + // and remove no-longer-valid paths. Keep still-valid paths to avoid the + // work of re-generating the scene objects. + std::unordered_set invalid_paths; + std::unordered_set changed_paths; + std::unordered_map>::iterator sk_it; + for (sk_it = s_keys.begin(); sk_it != s_keys.end(); sk_it++) { + // Work down from the root of each path looking for the first changed or + // removed entry. + std::vector &cpath = sk_it->second; + check_status(&invalid_paths, &changed_paths, sk_it->first, cpath, true); + } + + // Invalid path objects we remove completely + std::unordered_set::iterator iv_it; + for (iv_it = invalid_paths.begin(); iv_it != invalid_paths.end(); iv_it++) { + std::vector &phashes = s_keys[*iv_it]; + if (!phashes.size()) + continue; + unsigned long long c_hash = phashes[phashes.size() - 1]; + phashes.pop_back(); + erase_hpath(-1, c_hash, phashes, false); + } + + // Objects may be "drawn" in different ways - wireframes, shaded, evaluated. + // How they must be redrawn in the event of a database change is mode dependent, + // so after removing the invalid paths we categorize active paths according to + // which modes they are being visualized with. + std::unordered_map> mode_map; + for (sk_it = s_keys.begin(); sk_it != s_keys.end(); sk_it++) { + std::unordered_map>::iterator s_it; + s_it = s_map.find(sk_it->first); + if (s_it == s_map.end()) + continue; + std::unordered_map::iterator sm_it; + for (sm_it = s_it->second.begin(); sm_it != s_it->second.end(); sm_it++) { + mode_map[sm_it->first].insert(sk_it->first); + } + } + + // Changed paths we redo based on current db info - color, matrix, and + // geometry if the entry isn't invalid. This is the step that ensures any + // surviving solid objects in the drawing state are current for subsequent + // operations (and thus valid to reuse) + std::unordered_map>::iterator mm_it; + for (mm_it = mode_map.begin(); mm_it != mode_map.end(); mm_it++) { + for (iv_it = changed_paths.begin(); iv_it != changed_paths.end(); iv_it++) { + if (mm_it->second.find(*iv_it) == mm_it->second.end()) + continue; + std::vector &cp = s_keys[*iv_it]; + struct bv_scene_obj *s = NULL; + if (s_map.find(*iv_it) != s_map.end()) { + if (s_map[*iv_it].find(mm_it->first) != s_map[*iv_it].end()) { + ret = GED_DBISTATE_VIEW_CHANGE; + s = s_map[*iv_it][mm_it->first]; + } + } + if (dbis->invalid_entry_map.find(cp[cp.size() - 1]) != dbis->invalid_entry_map.end()) { + if (s) { + // Invalid - remove any scene object geometry + ret = GED_DBISTATE_VIEW_CHANGE; + bv_obj_reset(s); + s->s_v = v; + } else { + s = bv_obj_get(v, BV_DB_OBJS); + // print path name, set view - otherwise empty + dbis->print_path(&s->s_name, cp); + s->s_v = v; + s_map[*iv_it][mm_it->first] = s; + } + continue; + } + if (s) { + // Geometry is suspect - clear to prepare for regeneration + bv_obj_put(s); + s_map[*iv_it].erase(mm_it->first); + ret = GED_DBISTATE_VIEW_CHANGE; + } + } + } + + // Evaluate prior collapsed paths according to the same validity criteria, + // then re-expand them + std::unordered_map>>::iterator ms_it; + for (ms_it = mode_collapsed.begin(); ms_it != mode_collapsed.end(); ms_it++) { + std::unordered_set active_collapsed; + std::unordered_set draw_invalid_collapsed; + for (size_t i = 0; i < ms_it->second.size(); i++) { + std::vector &cpath = ms_it->second[i]; + int sret = check_status(NULL, NULL, 0, cpath, true); + if (sret == 2) + draw_invalid_collapsed.insert(i); + if (sret == 0) + active_collapsed.insert(i); + } + + // Expand active collapsed paths to solids, creating any missing path objects + // + // NOTE: We deliberately do NOT pass the supplied vs (if any) to these scene_obj/ + // gather_paths calls - user specified override settings should be applied only to + // staged paths specified by the user. Pre-existing geometry NOT specified by + // those commands does not get those settings applied during redraw. + std::unordered_set::iterator sz_it; + for (sz_it = active_collapsed.begin(); sz_it != active_collapsed.end(); sz_it++) { + std::vector cpath = ms_it->second[*sz_it]; + mat_t m; + MAT_IDN(m); + dbis->get_path_matrix(m, cpath); + if (ms_it->first == 3 || ms_it->first == 5) { + dbis->get_path_matrix(m, cpath); + scene_obj(objs, ms_it->first, NULL, m, cpath, views, v); + continue; + } + unsigned long long ihash = cpath[cpath.size() - 1]; + cpath.pop_back(); + gather_paths(objs, ihash, ms_it->first, v, NULL, m, NULL, cpath, views, &ret); + } + for (sz_it = draw_invalid_collapsed.begin(); sz_it != draw_invalid_collapsed.end(); sz_it++) { + std::vector cpath = ms_it->second[*sz_it]; + struct bv_scene_obj *s = bv_obj_get(v, BV_DB_OBJS); + // print path name, set view - otherwise empty + dbis->print_path(&s->s_name, cpath); + s->s_v = v; + s_map[ms_it->first][*iv_it] = s; + + // NOTE: Because there is no geometry to update, these scene objs + // are not added to objs + bu_log("invalid expand\n"); + } + } + + // Expand (or queue, depending on settings) any staged paths. + if (vs) { + for (size_t i = 0; i < staged.size(); i++) { + std::vector cpath = staged[i]; + // Validate this path - if the user has specified an invalid + // path, there's nothing else to do + if (!dbis->valid_hash_path(cpath)) + continue; + unsigned long long phash = dbis->path_hash(cpath, 0); + if (check_status(NULL, NULL, phash, cpath, false)) + continue; + mat_t m; + MAT_IDN(m); + dbis->get_path_matrix(m, cpath); + if ((vs->s_dmode == 3 || vs->s_dmode == 5)) { + dbis->get_path_matrix(m, cpath); + scene_obj(objs, vs->s_dmode, vs, m, cpath, views, v); + continue; + } + unsigned long long ihash = cpath[cpath.size() - 1]; + cpath.pop_back(); + gather_paths(objs, ihash, vs->s_dmode, v, vs, m, NULL, cpath, views, &ret); + } + } + // Staged paths are now added (as long as settings were supplied) - clear the queue + staged.clear(); + + // Do a preliminary autoview, unless suppressed, so any adaptive plotting + // routines have a rough idea of the correct dimensions to use + if (!no_autoview) { + for (v_it = views.begin(); v_it != views.end(); v_it++) { + bv_autoview(*v_it, BV_AUTOVIEW_SCALE_DEFAULT, 0); + } + } + + // Update geometry. draw_scene will avoid repeat creation of geometry + // when s is not adaptive, but if s IS adaptive we need unique geometry + // for each view even though the BViewState is shared - camera settings, + // which are unique to each bview, may differ and adaptive geometry must + // reflect that. + // + // Note that this is the ONLY situation where we must care about each + // view individually for shared state - the above uses of the first view + // work for the "top level" object used for adaptive cases, since shared + // views will be using a shared object pool for anything other than their + // view specific geometry sub-objects. + for (v_it = views.begin(); v_it != views.end(); v_it++) { + std::unordered_set::iterator o_it; + for (o_it = objs.begin(); o_it != objs.end(); o_it++) { + bv_log(3, "redraw %s[%s]", bu_vls_cstr(&((*(*o_it)).s_name)), bu_vls_cstr(&((*(*v_it)).gv_name))); + draw_scene(*o_it, *v_it); + } + } + + // We need to check if any drawn solids are selected. If so, we need + // to illuminate them. This is what ensures that newly drawn solids + // respect a previously selected set from the command line + BSelectState *ss = dbis->find_selected_state(NULL); + if (ss) { + if (invalid_paths.size() || changed_paths.size()) { + ss->refresh(); + ss->collapse(); + } + ss->draw_sync(); + ret = GED_DBISTATE_VIEW_CHANGE; + } + // Now that we have the finalized geometry, do a finishing autoview, + // unless suppressed + if (!no_autoview) { + for (v_it = views.begin(); v_it != views.end(); v_it++) { + bv_autoview(*v_it, BV_AUTOVIEW_SCALE_DEFAULT, 0); + } + } + + // Now that all path manipulations are finalized, update the + // sets of drawn paths + cache_collapsed(); + + return ret; +} + +void +BViewState::print_view_state(struct bu_vls *outvls) +{ + struct bu_vls *o = outvls; + if (!o) { + BU_GET(o, struct bu_vls); + bu_vls_init(o); + } + + bu_vls_printf(o, "Object count: %zd\n", s_keys.size()); + std::unordered_map>::iterator k_it; + for (k_it = s_keys.begin(); k_it != s_keys.end(); k_it++) { + std::vector &path = k_it->second; + struct bu_vls pstr = BU_VLS_INIT_ZERO; + dbis->print_path(&pstr, path, 0, 1); + bu_vls_printf(o, "%s\n", bu_vls_cstr(&pstr)); + bu_vls_free(&pstr); + } + + if (o != outvls) { + bu_vls_free(o); + BU_PUT(o, struct bu_vls); + } +} + +// Added dps present their own challenge, in terms of whether or not to +// automatically draw them. (I think this decision comes after the existing +// draw paths' removed/changed processing and the main .g reflecting maps are +// updated.) The cases: +// +// 1. Already part of a drawn invalid path - draw and expand, as path was +// drawn but is no longer invalid +// +// 2. Already part of a non-drawn invalid path - do not draw (? - could see +// a case for either behavior here, if the user wants to see the instances +// of the newly enabled part... this may have to be a user option) +// +// 2. Not part of any path, pre or post removed/changed draw states (i.e. +// a tops object) - draw + + + + +/* Handle selection status for various instances in the database */ + +BSelectState::BSelectState(DbiState *s) +{ + dbis = s; +} + +bool +BSelectState::select_path(const char *path, bool update) +{ + if (!path) + return false; + + std::vector path_hashes = dbis->digest_path(path); + if (!path_hashes.size()) + return false; + + bool ret = select_hpath(path_hashes); + if (update) + characterize(); + return ret; +} + +bool +BSelectState::select_hpath(std::vector &hpath) +{ + if (!hpath.size()) + return false; + + // If we're already selected, nothing to do + unsigned long long shash = dbis->path_hash(hpath, 0); + if (selected.find(shash) != selected.end()) + return true; + + // Validate that the specified path is current in the database. + for (size_t i = 1; i < hpath.size(); i++) { + unsigned long long phash = hpath[i-1]; + unsigned long long chash = hpath[i]; + if (dbis->p_c.find(phash) == dbis->p_c.end()) + return false; + if (dbis->p_c[phash].find(chash) == dbis->p_c[phash].end()) + return false; + } + + // If we're going to select this path, we need to clear out conflicting + // paths. We deliberately don't allow selection of multiple levels of + // a single path, to avoid unexpected and unintuitive behaviors. This + // means we have to clear any selection that is either a superset of this + // path or a child of it. + std::vector pitems = hpath; + pitems.pop_back(); + while (pitems.size()) { + unsigned long long phash = dbis->path_hash(pitems, 0); + selected.erase(phash); + active_paths.erase(phash); + pitems.pop_back(); + } + // Clear any active children of the selected path + pitems = hpath; + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(pitems[pitems.size() -1]); + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + clear_paths(*c_it, pitems); + } + + // Add to selected set + selected[shash] = hpath; + + // Note - with this lower level function, it is the caller's responsibility + // to call characterize to populate the path relationships - we deliberately + // do not do it here, so an application can do the work once per cycle + // rather than being forced to do it per path. + + return true; +} + +bool +BSelectState::deselect_path(const char *path, bool update) +{ + if (!path) + return false; + + std::vector path_hashes = dbis->digest_path(path); + if (!path_hashes.size()) + return false; + + bool ret = deselect_hpath(path_hashes); + if (update) + characterize(); + return ret; +} + +bool +BSelectState::deselect_hpath(std::vector &hpath) +{ + if (!hpath.size()) + return false; + + // For higher level paths, need to clear the illuminated solids + // below this path (if any) + std::vector pitems = hpath; + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(pitems[pitems.size() -1]); + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + clear_paths(*c_it, pitems); + } + + // Clear the selection itself + unsigned long long phash = dbis->path_hash(hpath, 0); + selected.erase(phash); + active_paths.erase(phash); + return true; + + // Note - with this lower level function, it is the caller's responsibility + // to call characterize to populate the path relationships - we deliberately + // do not do it here, so an application can do the work once per cycle + // rather than being forced to do it per path. +} + +bool +BSelectState::is_selected(unsigned long long hpath) +{ + if (!hpath) + return false; + + if (selected.find(hpath) == selected.end()) + return false; + + return true; +} + +bool +BSelectState::is_active(unsigned long long phash) +{ + if (!phash) + return false; + + if (active_paths.find(phash) == active_paths.end()) + return false; + + return true; +} + +bool +BSelectState::is_active_parent(unsigned long long phash) +{ + if (!phash) + return false; + + if (active_parents.find(phash) == active_parents.end()) + return false; + + return true; +} + +bool +BSelectState::is_parent_obj(unsigned long long hash) +{ + if (is_immediate_parent_obj(hash) || is_grand_parent_obj(hash)) + return true; + + return false; +} + +bool +BSelectState::is_immediate_parent_obj(unsigned long long hash) +{ + if (!hash) + return false; + + if (immediate_parents.find(hash) == immediate_parents.end()) + return false; + + return true; +} + +bool +BSelectState::is_grand_parent_obj(unsigned long long hash) +{ + + if (!hash) + return false; + + if (grand_parents.find(hash) == grand_parents.end()) + return false; + + return true; +} + +void +BSelectState::clear() +{ + selected.clear(); + active_paths.clear(); + characterize(); +} + +std::vector +BSelectState::list_selected_paths() +{ + std::unordered_map>::iterator s_it; + std::vector ret; + struct bu_vls vpath = BU_VLS_INIT_ZERO; + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + dbis->print_path(&vpath, s_it->second); + ret.push_back(std::string(bu_vls_cstr(&vpath))); + } + bu_vls_free(&vpath); + std::sort(ret.begin(), ret.end(), &alphanum_cmp); + return ret; +} + +void +BSelectState::add_paths( + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(c_hash); + + path_hashes.push_back(c_hash); + unsigned long long phash = dbis->path_hash(path_hashes, 0); + active_paths.insert(phash); + + if (!path_addition_cyclic(path_hashes)) { + /* Not cyclic - keep going */ + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + add_paths(*c_it, path_hashes); + } + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); +} + +void +BSelectState::clear_paths( + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(c_hash); + path_hashes.push_back(c_hash); + + unsigned long long phash = dbis->path_hash(path_hashes, 0); + selected.erase(phash); + active_paths.erase(phash); + + if (!path_addition_cyclic(path_hashes)) { + /* Not cyclic - keep going */ + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + clear_paths(*c_it, path_hashes); + } + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); +} + +void +BSelectState::expand_paths( + std::vector> &out_paths, + unsigned long long c_hash, + std::vector &path_hashes + ) +{ + std::unordered_map>::iterator pc_it; + pc_it = dbis->p_c.find(c_hash); + + path_hashes.push_back(c_hash); + + if (!path_addition_cyclic(path_hashes)) { + /* Not cyclic - keep going */ + if (pc_it != dbis->p_c.end()) { + std::unordered_set::iterator c_it; + for (c_it = pc_it->second.begin(); c_it != pc_it->second.end(); c_it++) + expand_paths(out_paths, *c_it, path_hashes); + } else { + out_paths.push_back(path_hashes); + } + } else { + out_paths.push_back(path_hashes); + } + + /* Done with branch - restore path */ + path_hashes.pop_back(); +} + +void +BSelectState::expand() +{ + // Given the current selection set, expand all the paths to + // their leaf solids and report those paths + std::vector> out_paths; + std::unordered_map>::iterator s_it; + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + std::vector seed_hashes = s_it->second; + unsigned long long shash = seed_hashes[seed_hashes.size() - 1]; + seed_hashes.pop_back(); + expand_paths(out_paths, shash, seed_hashes); + } + + // Update selected. + selected.clear(); + for (size_t i = 0; i < out_paths.size(); i++) { + unsigned long long phash = dbis->path_hash(out_paths[i], 0); + selected[phash] = out_paths[i]; + } + + characterize(); +} + +void +BSelectState::collapse() +{ + std::vector> collapsed; + std::map> depth_groups; + std::unordered_map>::iterator s_it; + std::unordered_set::iterator u_it; + + // Group paths of the same depth. Depth == 1 paths are already + // top level objects and need no further processing. + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + if (s_it->second.size() == 1) { + collapsed.push_back(s_it->second); + } else { + depth_groups[s_it->second.size()].insert(s_it->first); + } + } + + // Whittle down the mode depth groups until we find not-fully-drawn + // parents - when we find that, the children constitute non-collapsible + // paths based on what's drawn in this mode + while (depth_groups.size()) { + size_t plen = depth_groups.rbegin()->first; + if (plen == 1) + break; + std::unordered_set &pckeys = depth_groups.rbegin()->second; + + // For a given depth, group the paths by parent path. This results + // in path sub-groups which will define for us how "fully drawn" + // that particular parent comb instance is. + std::unordered_map> grouped_pckeys; + std::unordered_map pcomb; + for (u_it = pckeys.begin(); u_it != pckeys.end(); u_it++) { + std::vector &pc_path = selected[*u_it]; + unsigned long long ppathhash = dbis->path_hash(pc_path, plen - 1); + grouped_pckeys[ppathhash].insert(*u_it); + pcomb[ppathhash] = pc_path[plen-2]; + } + + // For each parent/child grouping, compare it against the .g ground + // truth set. If they match, fully drawn and we promote the path to + // the parent depth. If not, the paths do not collapse further and are + // added to drawn paths. + std::unordered_map>::iterator pg_it; + for (pg_it = grouped_pckeys.begin(); pg_it != grouped_pckeys.end(); pg_it++) { + + // As above, use the full path from selected, but this time + // we're collecting the children. This is the set we need to compare + // against the .g ground truth to determine fully or partially drawn. + std::unordered_set g_children; + std::unordered_set &g_pckeys = pg_it->second; + for (u_it = g_pckeys.begin(); u_it != g_pckeys.end(); u_it++) { + std::vector &pc_path = selected[*u_it]; + g_children.insert(pc_path[plen-1]); + } + + // Do the check against the .g comb children info - the "ground truth" + // that defines what must be present for a fully drawn comb + bool is_fully_selected = true; + std::unordered_set &ground_truth = dbis->p_c[pcomb[pg_it->first]]; + for (u_it = ground_truth.begin(); u_it != ground_truth.end(); u_it++) { + if (g_children.find(*u_it) == g_children.end()) { + is_fully_selected = false; + break; + } + } + + if (is_fully_selected) { + // If fully selected, depth_groups[plen-1] gets the first path in + // g_pckeys. The path is longer than that depth, but contains + // all the necessary information and using that approach avoids + // the need to duplicate paths. + depth_groups[plen - 1].insert(*g_pckeys.begin()); + } else { + // No further collapsing - add to final. We must make trimmed + // versions of the paths in case this depth holds promoted + // paths from deeper levels, since we are duplicating the full + // path contents. + for (u_it = g_pckeys.begin(); u_it != g_pckeys.end(); u_it++) { + std::vector trimmed = selected[*u_it]; + trimmed.resize(plen); + collapsed.push_back(trimmed); + } + } + } + + // Done with this depth + depth_groups.erase(plen); + } + + // If we collapsed all the way to top level objects, make sure to add them + // if they are still valid entries. If a toplevel entry is invalid, there + // is no parent comb to refer to it as an "invalid" object and it can no + // longer be drawn. + if (depth_groups.find(1) != depth_groups.end()) { + std::unordered_set &pckeys = depth_groups.rbegin()->second; + for (u_it = pckeys.begin(); u_it != pckeys.end(); u_it++) { + std::vector trimmed = selected[*u_it]; + trimmed.resize(1); + collapsed.push_back(trimmed); + } + } + + selected.clear(); + for (size_t i = 0; i < collapsed.size(); i++) { + unsigned long long phash = dbis->path_hash(collapsed[i], 0); + selected[phash] = collapsed[i]; + } + + characterize(); +} + +void +BSelectState::characterize() +{ + //bu_log("BSelectState::characterize\n"); + active_parents.clear(); + immediate_parents.clear(); + grand_parents.clear(); + + std::unordered_map>::iterator s_it; + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + std::vector seed_hashes = s_it->second; + unsigned long long shash = seed_hashes[seed_hashes.size() - 1]; + seed_hashes.pop_back(); + add_paths(shash, seed_hashes); + + // Stash the parent paths above this specific selection + std::vector pitems = s_it->second; + size_t c = s_it->second.size() - 1; + while (c > 0) { + pitems.pop_back(); + unsigned long long pphash = dbis->path_hash(s_it->second, c); + active_parents.insert(pphash); + c--; + } + } + + // Now, characterizing related objects. This is not just the immediate + // path parents - anything above the selected object is impacted. + + // Because we don't want to keep iterating over p_c, make a reverse map of children + // to parents + std::unordered_map> reverse_map; + std::unordered_map>::iterator pc_it; + for (pc_it = dbis->p_c.begin(); pc_it != dbis->p_c.end(); pc_it++) { + std::unordered_set::iterator sc_it; + for (sc_it = pc_it->second.begin(); sc_it != pc_it->second.end(); sc_it++) { + reverse_map[*sc_it].insert(pc_it->first); + } + } + + // Find the leaf children - they're the seeds + std::unordered_set active_children; + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + active_children.insert(s_it->second[s_it->second.size()-1]); + } + + // Find the immediate parents - they can be highlighted differently + std::unordered_set::iterator c_it, p_it; + std::unordered_map>::iterator r_it; + for (c_it = active_children.begin(); c_it != active_children.end(); c_it++) { + r_it = reverse_map.find(*c_it); + if (r_it == reverse_map.end()) + continue; + for (p_it = r_it->second.begin(); p_it != r_it->second.end(); p_it++) + immediate_parents.insert(*p_it); + } + + // Work our way up from the immediate parents - we want the higher levels to + // be known as active so they may indicate that active selections can be found + // below + std::queue gqueue; + for (p_it = immediate_parents.begin(); p_it != immediate_parents.end(); p_it++) { + gqueue.push(*p_it); + } + while (!gqueue.empty()) { + unsigned long long obj = gqueue.front(); + gqueue.pop(); + r_it = reverse_map.find(obj); + if (r_it == reverse_map.end()) + continue; + for (p_it = r_it->second.begin(); p_it != r_it->second.end(); p_it++) { + gqueue.push(*p_it); + grand_parents.insert(*p_it); + } + } +} + +void +BSelectState::refresh() +{ + // If the database may have changed, we need to revalidate selected + // paths are still current, and regenerate the active_paths set. + active_paths.clear(); + + // Unlike drawing, nothing fancy here - if a selected path is invalid, + // it's gone. + std::vector to_clear; + std::unordered_map>::iterator s_it; + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + std::vector &cpath = s_it->second; + for (size_t i = 1; i < cpath.size(); i++) { + unsigned long long phash = cpath[i-1]; + unsigned long long chash = cpath[i]; + if (dbis->p_c.find(phash) == dbis->p_c.end()) { + to_clear.push_back(s_it->first); + continue; + } + if (dbis->p_c[phash].find(chash) == dbis->p_c[phash].end()) { + to_clear.push_back(s_it->first); + continue; + } + } + } + + // Erase invalid paths + for (size_t i = 0; i < to_clear.size(); i++) { + selected.erase(to_clear[i]); + } + + // For all surviving selections, generate paths + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + std::vector seed_hashes = s_it->second; + unsigned long long shash = seed_hashes[seed_hashes.size() - 1]; + seed_hashes.pop_back(); + add_paths(shash, seed_hashes); + } +} + +bool +BSelectState::draw_sync() +{ + bool changed = false; + std::unordered_set vstates; + + struct bu_ptbl *views = bv_set_views(&dbis->gedp->ged_views); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *v = (struct bview *)BU_PTBL_GET(views, i); + BViewState *vs = dbis->get_view_state(v); + vstates.insert(vs); + } + + std::unordered_map>::iterator so_it; + std::unordered_map::iterator m_it; + std::unordered_set::iterator vs_it; + for (vs_it = vstates.begin(); vs_it != vstates.end(); vs_it++) { + for (so_it = (*vs_it)->s_map.begin(); so_it != (*vs_it)->s_map.end(); so_it++) { + char ill_state = is_active(so_it->first) ? UP : DOWN; + //bu_log("select ill_state: %s\n", (ill_state == UP) ? "up" : "down"); + for (m_it = so_it->second.begin(); m_it != so_it->second.end(); m_it++) { + struct bv_scene_obj *so = m_it->second; + int ill_changed = bv_illum_obj(so, ill_state); + if (ill_changed) + changed = true; + } + } + } + + return changed; +} + +unsigned long long +BSelectState::state_hash() +{ + std::unordered_map>::iterator s_it; + XXH64_state_t h_state; + XXH64_reset(&h_state, 0); + for (s_it = selected.begin(); s_it != selected.end(); s_it++) { + XXH64_update(&h_state, &s_it->first, sizeof(unsigned long long)); + } + return (unsigned long long)XXH64_digest(&h_state); +} + +/** @} */ +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libged/debugbu/debugbu.c b/src/libged/debugbu/debugbu.c index c4551cca41e..849875c4773 100644 --- a/src/libged/debugbu/debugbu.c +++ b/src/libged/debugbu/debugbu.c @@ -38,7 +38,6 @@ ged_debugbu_core(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[hex_code]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ diff --git a/src/libged/debuglib/debuglib.c b/src/libged/debuglib/debuglib.c index e008ada867a..72465007548 100644 --- a/src/libged/debuglib/debuglib.c +++ b/src/libged/debuglib/debuglib.c @@ -38,7 +38,6 @@ ged_debuglib_core(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[hex_code]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ diff --git a/src/libged/delay/delay.c b/src/libged/delay/delay.c index 023cd6a5e03..9f43116864a 100644 --- a/src/libged/delay/delay.c +++ b/src/libged/delay/delay.c @@ -40,7 +40,6 @@ ged_delay_core(struct ged *gedp, int argc, const char *argv[]) struct timeval tv; static const char *usage = "sec usec"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ diff --git a/src/libged/dir2ae/dir2ae.c b/src/libged/dir2ae/dir2ae.c index a270e8312d4..e8dfc8cbc92 100644 --- a/src/libged/dir2ae/dir2ae.c +++ b/src/libged/dir2ae/dir2ae.c @@ -41,7 +41,6 @@ ged_dir2ae_core(struct ged *gedp, int argc, const char *argv[]) int iflag; static const char *usage = "[-i] x y z"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ @@ -77,7 +76,7 @@ ged_dir2ae_core(struct ged *gedp, int argc, const char *argv[]) if (iflag) VSCALE(dir, dir, -1); - AZEL_FROM_V3DIR(az, el, dir); + bn_ae_vec(&az, &el, dir); bu_vls_printf(gedp->ged_result_str, "%lf %lf", az, el); return BRLCAD_OK; diff --git a/src/libged/display_list.c b/src/libged/display_list.c index 37da770b1c7..fa75f6b4144 100644 --- a/src/libged/display_list.c +++ b/src/libged/display_list.c @@ -686,7 +686,13 @@ solid_append_vlist(struct bv_scene_obj *sp, struct bv_vlist *vlist) void dl_add_path(int dashflag, struct bu_list *vhead, const struct db_full_path *pathp, struct db_tree_state *tsp, unsigned char *wireframe_color_override, struct _ged_client_data *dgcdp) { + if (!dgcdp || !dgcdp->v) + return; + struct bv_scene_obj *sp = bv_obj_get(dgcdp->v, BV_DB_OBJS); + if (!sp) + return; + struct ged_bv_data *bdata = (sp->s_u_data) ? (struct ged_bv_data *)sp->s_u_data : NULL; if (!bdata) { BU_GET(bdata, struct ged_bv_data); @@ -1000,6 +1006,9 @@ solid_copy_vlist(struct db_i *UNUSED(dbip), struct bv_scene_obj *sp, struct bv_v int invent_solid(struct ged *gedp, char *name, struct bu_list *vhead, long int rgb, int copy, fastf_t transparency, int dmode, int csoltab) { + if (!gedp || !gedp->ged_gvp) + return 0; + struct bu_list *hdlp = gedp->ged_gdp->gd_headDisplay; struct db_i *dbip = gedp->dbip; struct directory *dp; diff --git a/src/libged/dm/dm.c b/src/libged/dm/dm.c index 6e328ea91fa..1df8104a8fa 100644 --- a/src/libged/dm/dm.c +++ b/src/libged/dm/dm.c @@ -479,13 +479,23 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) struct _ged_dm_info *gd = (struct _ged_dm_info *)ds; struct ged *gedp = gd->gedp; struct bu_vls dm_name = BU_VLS_INIT_ZERO; + struct bu_vls view_name = BU_VLS_INIT_ZERO; - if (argc != 1 && argc != 2) { + struct bu_opt_desc d[3]; + BU_OPT(d[0], "d", "dm", "dm_name", &bu_opt_vls, &dm_name, "name of display manager to be created"); + BU_OPT(d[1], "V", "view", "view_name", &bu_opt_vls, &view_name, "view to associate with DM (defaults to gedp current view)"); + BU_OPT_NULL(d[2]); + + int ac = bu_opt_parse(NULL, argc, argv, d); + + if (!ac) { bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage_string); + bu_vls_free(&dm_name); + bu_vls_free(&view_name); return BRLCAD_ERROR; } - if (argc == 1) { + if (ac == 1 && !bu_vls_strlen(&dm_name)) { // No name - generate one bu_vls_sprintf(&dm_name, "%s-0", argv[0]); int exists = 0; @@ -519,11 +529,20 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) if (tries == DM_MAX_TRIES) { bu_vls_printf(gedp->ged_result_str, "unable to generate DM name"); bu_vls_free(&dm_name); + bu_vls_free(&view_name); return BRLCAD_ERROR; } } else { + if (ac == 2 && bu_vls_strlen(&dm_name) && !BU_STR_EQUAL(argv[1], bu_vls_cstr(&dm_name))) { + bu_vls_printf(gedp->ged_result_str, "Two different dm names specified: %s and %s\n", argv[1], bu_vls_cstr(&dm_name)); + bu_vls_free(&dm_name); + bu_vls_free(&view_name); + return BRLCAD_ERROR; + } + if (ac == 2) { + bu_vls_sprintf(&dm_name, "%s", argv[1]); + } // Have name - see if it already exists - bu_vls_sprintf(&dm_name, "%s", argv[1]); int exists = 0; struct bu_ptbl *views = bv_set_views(&gedp->ged_views); for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { @@ -539,19 +558,46 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) if (exists) { bu_vls_printf(gedp->ged_result_str, "DM %s already exists", bu_vls_cstr(&dm_name)); bu_vls_free(&dm_name); + bu_vls_free(&view_name); return BRLCAD_ERROR; } } - struct bview *target_view = (gedp->ged_gvp->dmp) ? NULL : gedp->ged_gvp; + struct bview *target_view = NULL; + if (bu_vls_strlen(&view_name)) { + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *tview = (struct bview *)BU_PTBL_GET(views, i); + if (!bu_vls_strcmp(&view_name, &tview->gv_name)) { + target_view = tview; + break; + } + } + } else { + target_view = (gedp->ged_gvp->dmp) ? NULL : gedp->ged_gvp; + } + if (!target_view) { BU_GET(target_view, struct bview); bv_init(target_view, &gedp->ged_views); bv_set_add_view(&gedp->ged_views, target_view); + // This view is being created by GED, so it needs to be cleaned + // up by GED as well + bu_ptbl_ins(&gedp->ged_free_views, (long *)target_view); + } + + if (target_view->dmp) { + bu_vls_printf(gedp->ged_result_str, "Target view %s of dm attach already has an associated dm\n", bu_vls_cstr(&target_view->gv_name)); + bu_vls_free(&dm_name); + bu_vls_free(&view_name); + return BRLCAD_ERROR; } // Make sure the view width and height are non-zero if we're in a - // "headless" mode without a graphical display + // "headless" mode without a graphical display. TODO - this + // either shouldn't be necessary or probably should come after + // dm_open has its chance to set up dm width and height (which + // should be used before the fallback) if (!target_view->gv_width) { target_view->gv_width = 512; } @@ -559,6 +605,8 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) target_view->gv_height = 512; } + // If the application has not provided a toolkit specific context, use the + // view itself as the context if (!gedp->ged_ctx) { gedp->ged_ctx = (void *)target_view; } @@ -567,6 +615,8 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) struct dm *dmp = dm_open(gedp->ged_ctx, gedp->ged_interp, argv[0], 1, &acmd); if (!dmp) { bu_vls_printf(gedp->ged_result_str, "failed to create DM %s", bu_vls_cstr(&dm_name)); + bu_vls_free(&dm_name); + bu_vls_free(&view_name); return BRLCAD_ERROR; } @@ -580,6 +630,9 @@ _dm_cmd_attach(void *ds, int argc, const char **argv) // We have the dmp - let the view know target_view->dmp = dmp; + bu_vls_free(&dm_name); + bu_vls_free(&view_name); + return BRLCAD_OK; } diff --git a/src/libged/dm/screengrab.c b/src/libged/dm/screengrab.c index 8c4d583a83d..984f0052dc6 100644 --- a/src/libged/dm/screengrab.c +++ b/src/libged/dm/screengrab.c @@ -59,7 +59,7 @@ image_mime(struct bu_vls *msg, size_t argc, const char **argv, void *set_mime) int ged_screen_grab_core(struct ged *gedp, int argc, const char *argv[]) { - + struct dm *dmp = NULL; int i; int print_help = 0; int bytes_per_pixel = 0; @@ -69,16 +69,17 @@ ged_screen_grab_core(struct ged *gedp, int argc, const char *argv[]) unsigned char *idata = NULL; struct icv_image *bif = NULL; /**< icv image container for saving images */ struct fb *fbp = NULL; + struct bu_vls dm_name = BU_VLS_INIT_ZERO; bu_mime_image_t type = BU_MIME_IMAGE_AUTO; - static char usage[] = "Usage: screengrab [-h] [-F] [--format fmt] [file.img]\n"; + static char usage[] = "Usage: screengrab [-h] [-F] [-D name] [--format fmt] [file.img]\n"; - struct bu_opt_desc d[4]; - BU_OPT(d[0], "h", "help", "", NULL, &print_help, "Print help and exit"); + struct bu_opt_desc d[5]; + BU_OPT(d[0], "h", "help", "", NULL, &print_help, "Print help and exit"); BU_OPT(d[1], "F", "fb", "", NULL, &grab_fb, "screengrab framebuffer instead of scene display"); - BU_OPT(d[2], "", "format", "fmt", &image_mime, &type, "output image file format"); - BU_OPT_NULL(d[3]); + BU_OPT(d[2], "D", "dm", "name", &bu_opt_vls, &dm_name, "name of DM to screengrab"); + BU_OPT(d[3], "", "format", "fmt", &image_mime, &type, "output image file format"); + BU_OPT_NULL(d[4]); - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -86,23 +87,6 @@ ged_screen_grab_core(struct ged *gedp, int argc, const char *argv[]) /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); - if (!gedp->ged_gvp) { - bu_vls_printf(gedp->ged_result_str, ": no current view set\n"); - return BRLCAD_ERROR; - } - - struct dm *dmp = (struct dm *)gedp->ged_gvp->dmp; - if (!dmp) { - bu_vls_printf(gedp->ged_result_str, ": no current display manager set\n"); - return BRLCAD_ERROR; - } - - /* must be wanting help */ - if (argc == 1) { - _ged_cmd_help(gedp, usage, d); - return GED_HELP; - } - argc-=(argc>0); argv+=(argc>0); /* done with command name argv[0] */ int opt_ret = bu_opt_parse(NULL, argc, argv, d); @@ -114,6 +98,35 @@ ged_screen_grab_core(struct ged *gedp, int argc, const char *argv[]) argc = opt_ret; + struct dm *cdmp = (gedp->ged_gvp) ? (struct dm *)gedp->ged_gvp->dmp : NULL; + + if (bu_vls_strlen(&dm_name) && gedp->ged_gvp) { + // We have a name - see if we can match it. + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + for (size_t j = 0; j < BU_PTBL_LEN(views); j++) { + if (dmp) + break; + struct bview *gdvp = (struct bview *)BU_PTBL_GET(views, j); + struct dm *ndmp = (struct dm *)gdvp->dmp; + if (!bu_vls_strcmp(dm_get_pathname(ndmp), &dm_name)) + dmp = ndmp; + } + if (!dmp) { + bu_vls_sprintf(gedp->ged_result_str, "DM %s specified, but not found in active set\n", bu_vls_cstr(&dm_name)); + bu_vls_free(&dm_name); + return BRLCAD_ERROR; + } + } + bu_vls_free(&dm_name); + + if (!dmp) + dmp = cdmp; + + if (!dmp) { + bu_vls_printf(gedp->ged_result_str, ": no current display manager set and no valid name specified\n"); + return BRLCAD_ERROR; + } + if (grab_fb) { fbp = dm_get_fb(dmp); if (!fbp) { diff --git a/src/libged/draw.cpp b/src/libged/draw.cpp index 2384c58fc4a..8730adcd951 100644 --- a/src/libged/draw.cpp +++ b/src/libged/draw.cpp @@ -41,8 +41,8 @@ #include "bu/opt.h" #include "bu/sort.h" #include "bv/defines.h" -#include "bg/lod.h" #include "bg/sat.h" +#include "bv/lod.h" #include "nmg.h" #include "rt/view.h" @@ -55,9 +55,9 @@ prim_tess(struct bv_scene_obj *s, struct rt_db_internal *ip) { struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; struct db_full_path *fp = (struct db_full_path *)s->s_path; + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)s->dp; const struct bn_tol *tol = d->tol; const struct bg_tess_tol *ttol = d->ttol; - struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); RT_CK_DB_INTERNAL(ip); RT_CK_DIR(dp); BN_CK_TOL(tol); @@ -75,7 +75,7 @@ prim_tess(struct bv_scene_obj *s, struct rt_db_internal *ip) } NMG_CK_REGION(r); - nmg_r_to_vlist(&s->s_vlist, r, NMG_VLIST_STYLE_POLYGON, &s->s_v->gv_objs.gv_vlfree); + nmg_r_to_vlist(&s->s_vlist, r, NMG_VLIST_STYLE_POLYGON, s->vlfree); nmg_km(m); s->current = 1; @@ -83,95 +83,101 @@ prim_tess(struct bv_scene_obj *s, struct rt_db_internal *ip) return 0; } +static void +draw_free_data(struct bv_scene_obj *s) +{ + /* Validate */ + if (!s) + return; + + if (s->s_path) { + struct db_full_path *sfp = (struct db_full_path *)s->s_path; + db_free_full_path(sfp); + BU_PUT(sfp, struct db_full_path); + } + + /* free drawing info */ + struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; + if (!d) + return; + BU_PUT(d, struct draw_update_data_t); + s->s_i_data = NULL; +} + + static int -csg_wireframe_update(struct bv_scene_obj *s, struct bview *v, int UNUSED(flag)) +csg_wireframe_update(struct bv_scene_obj *vo, struct bview *v, int flag) { /* Validate */ - if (!s || !v) + if (!vo || !v) return 0; - bool rework = false; - // Check bot threshold - //if (s->bot_threshold != s->s_v->gv_s->bot_threshold) - // rework = true; + if (!v->gv_s->adaptive_plot_csg) + return 0; + + bv_log(1, "csg_wireframe_update %s[%s]", bu_vls_cstr(&vo->s_name), bu_vls_cstr(&v->gv_name)); + + vo->csg_obj = 1; // If the object is not visible in the scene, don't change the data. This // check is useful in orthographic camera mode, where we zoom in on a // narrow subset of the model and far away objects are still rendered in // full detail. If we have a perspective matrix active don't make this // check, since far away objects outside the view obb will be visible. - //bu_log("min: %f %f %f max: %f %f %f\n", V3ARGS(s->bmin), V3ARGS(s->bmax)); - if (!(v->gv_perspective > SMALL_FASTF) && !bg_sat_aabb_obb(s->bmin, s->bmax, v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)) + //bu_log("min: %f %f %f max: %f %f %f\n", V3ARGS(vo->bmin), V3ARGS(vo->bmax)); + if (!(v->gv_perspective > SMALL_FASTF) && !bg_sat_aabb_obb(vo->bmin, vo->bmax, v->obb_center, v->obb_extent1, v->obb_extent2, v->obb_extent3)) return 0; + bool rework = (flag) ? true : false; + // Check point scale - if (!rework && !NEAR_EQUAL(s->curve_scale, s->s_v->gv_s->curve_scale, SMALL_FASTF)) + if (!rework && !NEAR_EQUAL(vo->curve_scale, vo->s_v->gv_s->curve_scale, SMALL_FASTF)) rework = true; // Check point scale - if (!rework && !NEAR_EQUAL(s->point_scale, s->s_v->gv_s->point_scale, SMALL_FASTF)) + if (!rework && !NEAR_EQUAL(vo->point_scale, vo->s_v->gv_s->point_scale, SMALL_FASTF)) rework = true; if (!rework) { // Check view scale - fastf_t delta = s->view_scale * 0.1/s->view_scale; - if (!NEAR_EQUAL(s->view_scale, v->gv_scale, delta)) + fastf_t delta = vo->view_scale * 0.1/vo->view_scale; + if (!NEAR_EQUAL(vo->view_scale, v->gv_scale, delta)) rework = true; } if (!rework) return 0; // We're going to redraw - sync with view - s->curve_scale = s->s_v->gv_s->curve_scale; - s->point_scale = s->s_v->gv_s->point_scale; - s->view_scale = v->gv_scale; + vo->curve_scale = v->gv_s->curve_scale; + vo->point_scale = v->gv_s->point_scale; + vo->view_scale = v->gv_scale; // Clear out existing vlists struct bu_list *p; - while (BU_LIST_WHILE(p, bu_list, &s->s_vlist)) { + while (BU_LIST_WHILE(p, bu_list, &vo->s_vlist)) { BU_LIST_DEQUEUE(p); struct bv_vlist *pv = (struct bv_vlist *)p; BU_FREE(pv, struct bv_vlist); } - struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; - struct db_full_path *fp = (struct db_full_path *)s->s_path; + struct draw_update_data_t *d = (struct draw_update_data_t *)vo->s_i_data; + struct db_full_path *fp = (struct db_full_path *)vo->s_path; + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)vo->dp; struct db_i *dbip = d->dbip; struct rt_db_internal dbintern; RT_DB_INTERNAL_INIT(&dbintern); struct rt_db_internal *ip = &dbintern; - int ret = rt_db_get_internal(ip, DB_FULL_PATH_CUR_DIR(fp), dbip, s->s_mat, d->res); + int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); if (ret < 0) return 0; if (ip->idb_meth->ft_adaptive_plot) { - ip->idb_meth->ft_adaptive_plot(&s->s_vlist, ip, d->tol, v, s->s_size); - s->s_type_flags |= BV_CSG_LOD; - s->s_dlist_stale = 1; + ip->idb_meth->ft_adaptive_plot(&vo->s_vlist, ip, d->tol, v, vo->s_size); + vo->s_type_flags |= BV_CSG_LOD; + bv_obj_stale(vo); } return 1; } -static void -draw_free_data(struct bv_scene_obj *s) -{ - /* Validate */ - if (!s) - return; - - if (s->s_path) { - struct db_full_path *sfp = (struct db_full_path *)s->s_path; - db_free_full_path(sfp); - BU_PUT(sfp, struct db_full_path); - } - - /* free drawing info */ - struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; - if (!d) - return; - BU_PUT(d, struct draw_update_data_t); - s->s_i_data = NULL; -} - struct ged_full_detail_clbk_data { struct db_i *dbip; struct directory *dp; @@ -245,125 +251,136 @@ bot_adaptive_plot(struct bv_scene_obj *s, struct bview *v) { if (!s || !v) return; - struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; - if (!d) - return; - struct db_i *dbip = d->dbip; - struct db_full_path *fp = (struct db_full_path *)s->s_path; - struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); - - // We need the key to look up the LoD data from the cache, and if we don't - // already have cache data for this bot we need to generate it. - unsigned long long key = bg_mesh_lod_key_get(d->mesh_c, dp->d_namep); - if (!key) { - // We don't have a key associated with the name. Get and check the BoT - // data itself, creating the LoD data if we don't already have it - struct rt_db_internal dbintern; - RT_DB_INTERNAL_INIT(&dbintern); - struct rt_db_internal *ip = &dbintern; - int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); - if (ret < 0) - return; - struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; - RT_BOT_CK_MAGIC(bot); - key = bg_mesh_lod_cache(d->mesh_c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); - bg_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); - rt_db_free_internal(&dbintern); - } - if (!key) - return; - // Once we have a valid key, proceed to create the necessary - // data structures and objects. - struct bv_mesh_lod *lod = bg_mesh_lod_create(d->mesh_c, key); - if (!lod) { - // Stale key? Clear it and try a regeneration - unsigned long long old_key = key; - bg_mesh_lod_clear_cache(d->mesh_c, key); - - // Load mesh and process - struct rt_db_internal dbintern; - RT_DB_INTERNAL_INIT(&dbintern); - struct rt_db_internal *ip = &dbintern; - int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); - if (ret < 0) + s->csg_obj = 0; + s->mesh_obj = 1; + + bv_log(1, "bot_adaptive_plot %s[%s]", bu_vls_cstr(&s->s_name), (v) ? bu_vls_cstr(&v->gv_name) : "NULL"); + + struct bv_scene_obj *vo = bv_obj_for_view(s, v); + + if (!vo) { + + vo = bv_obj_get_vo(s, v); + + vo->csg_obj = 0; + vo->mesh_obj = 1; + + struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; + if (!d || !d->mesh_c) return; - struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; - RT_BOT_CK_MAGIC(bot); - key = bg_mesh_lod_cache(d->mesh_c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); - bg_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); - rt_db_free_internal(&dbintern); - - // Sanity - if (old_key == key) { - bu_log("%s: LoD lookup by key failed, but regeneration generated the same key (?)\n", dp->d_namep); + struct db_i *dbip = d->dbip; + struct db_full_path *fp = (struct db_full_path *)s->s_path; + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)s->dp; + + if (!dp) return; + + // We need the key to look up the LoD data from the cache, and if we don't + // already have cache data for this bot we need to generate it. + unsigned long long key = bv_mesh_lod_key_get(d->mesh_c, dp->d_namep); + if (!key) { + // We don't have a key associated with the name. Get and check the BoT + // data itself, creating the LoD data if we don't already have it + struct rt_db_internal dbintern; + RT_DB_INTERNAL_INIT(&dbintern); + struct rt_db_internal *ip = &dbintern; + int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); + if (ret < 0) + return; + struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; + RT_BOT_CK_MAGIC(bot); + key = bv_mesh_lod_cache(d->mesh_c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); + bv_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); + rt_db_free_internal(&dbintern); } - unsigned long long new_key = bg_mesh_lod_key_get(d->mesh_c, dp->d_namep); - if (new_key == old_key) { - bu_log("%s: LoD regenerated with new key, but key lookup still returns old key (?)\n", dp->d_namep); + if (!key) return; + + // Once we have a valid key, proceed to create the necessary + // data structures and objects. + struct bv_mesh_lod *lod = bv_mesh_lod_create(d->mesh_c, key); + if (!lod) { + // Stale key? Clear it and try a regeneration + unsigned long long old_key = key; + bv_mesh_lod_clear_cache(d->mesh_c, key); + + // Load mesh and process + struct rt_db_internal dbintern; + RT_DB_INTERNAL_INIT(&dbintern); + struct rt_db_internal *ip = &dbintern; + int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); + if (ret < 0) + return; + struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; + RT_BOT_CK_MAGIC(bot); + key = bv_mesh_lod_cache(d->mesh_c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); + bv_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); + rt_db_free_internal(&dbintern); + + // Sanity + if (old_key == key) { + bu_log("%s: LoD lookup by key failed, but regeneration generated the same key (?)\n", dp->d_namep); + return; + } + unsigned long long new_key = bv_mesh_lod_key_get(d->mesh_c, dp->d_namep); + if (new_key == old_key) { + bu_log("%s: LoD regenerated with new key, but key lookup still returns old key (?)\n", dp->d_namep); + return; + } + + // If after all that we STILL don't get an LoD struct, give up + lod = bv_mesh_lod_create(d->mesh_c, key); + if (!lod) + return; } - // If after all that we STILL don't get an LoD struct, give up - lod = bg_mesh_lod_create(d->mesh_c, key); - if (!lod) - return; - } - struct bv_scene_obj *vo = bv_obj_get_child(s); - bv_set_view_obj(s, v, vo); - - // Most of the view properties (color, size, etc.) are inherited from - // the parent - bv_obj_sync(vo, s); - - // Assign the LoD information to the object's draw_data, and let - // the LoD know which object it is associated with. - vo->draw_data = (void *)lod; - lod->s = vo; - - // The object bounds are based on the LoD's calculations. Because the LoD - // cache stores only one cached data set per object, but full path - // instances in the scene can be placed with matrices, we must apply the - // s_mat transformation to the "baseline" LoD bbox info to get the correct - // box for the instance. - MAT4X3PNT(vo->bmin, s->s_mat, lod->bmin); - MAT4X3PNT(vo->bmax, s->s_mat, lod->bmax); - VMOVE(s->bmin, vo->bmin); - VMOVE(s->bmax, vo->bmax); - - // Record the necessary information for full detail information recovery. We - // don't duplicate the full mesh detail in the on-disk LoD storage, since we - // already have that info in the .g itself, but we need to know how to get at - // it when needed. The free callback will clean up, but we need to initialize - // the callback data here. - struct ged_full_detail_clbk_data *cbd; - BU_GET(cbd, ged_full_detail_clbk_data); - cbd->dbip = dbip; - cbd->dp = DB_FULL_PATH_CUR_DIR(fp); - cbd->res = &rt_uniresource; - cbd->intern = NULL; - bg_mesh_lod_detail_setup_clbk(lod, &bot_mesh_info_clbk, (void *)cbd); - bg_mesh_lod_detail_clear_clbk(lod, &bot_mesh_info_clear_clbk); - bg_mesh_lod_detail_free_clbk(lod, &bot_mesh_info_free_clbk); - - // LoD will need to re-check its level settings whenever the view changes - vo->s_update_callback = &bg_mesh_lod_view; - vo->s_free_callback = &bg_mesh_lod_free; - - // Initialize the LoD data to the current view - int level = bg_mesh_lod_view(vo, vo->s_v, 0); - if (level < 0) { - bu_log("Error loading info for initial LoD view\n"); - } + // Assign the LoD information to the object's draw_data, and let + // the LoD know which object it is associated with. + vo->draw_data = (void *)lod; + lod->s = vo; + + // The object bounds are based on the LoD's calculations. Because the LoD + // cache stores only one cached data set per object, but full path + // instances in the scene can be placed with matrices, we must apply the + // s_mat transformation to the "baseline" LoD bbox info to get the correct + // box for the instance. + MAT4X3PNT(vo->bmin, s->s_mat, lod->bmin); + MAT4X3PNT(vo->bmax, s->s_mat, lod->bmax); + VMOVE(s->bmin, vo->bmin); + VMOVE(s->bmax, vo->bmax); + + // Record the necessary information for full detail information recovery. We + // don't duplicate the full mesh detail in the on-disk LoD storage, since we + // already have that info in the .g itself, but we need to know how to get at + // it when needed. The free callback will clean up, but we need to initialize + // the callback data here. + struct ged_full_detail_clbk_data *cbd; + BU_GET(cbd, ged_full_detail_clbk_data); + cbd->dbip = dbip; + cbd->dp = dp; + cbd->res = &rt_uniresource; + cbd->intern = NULL; + bv_mesh_lod_detail_setup_clbk(lod, &bot_mesh_info_clbk, (void *)cbd); + bv_mesh_lod_detail_clear_clbk(lod, &bot_mesh_info_clear_clbk); + bv_mesh_lod_detail_free_clbk(lod, &bot_mesh_info_free_clbk); + + // LoD will need to re-check its level settings whenever the view changes + vo->s_update_callback = &bv_mesh_lod_view; + vo->s_free_callback = &bv_mesh_lod_free; + + // Initialize the LoD data to the current view + int level = bv_mesh_lod_view(vo, vo->s_v, 0); + if (level < 0) { + bu_log("Error loading info for initial LoD view\n"); + } - // Mark the object as a Mesh LoD so the drawing routine knows to handle it differently - vo->s_type_flags |= BV_MESH_LOD; + // Mark the object as a Mesh LoD so the drawing routine knows to handle it differently + vo->s_type_flags |= BV_MESH_LOD; + } - // Make the names unique - bu_vls_sprintf(&vo->s_name, "%s", bu_vls_cstr(&s->s_name)); - vo->s_path = NULL; // I don't think the vo objects will need the db_fullpath... - bu_vls_sprintf(&vo->s_uuid, "%s:%s", bu_vls_cstr(&v->gv_name), bu_vls_cstr(&s->s_uuid)); + bv_mesh_lod_view(vo, v, 0); + bv_obj_stale(vo); return; } @@ -374,138 +391,147 @@ brep_adaptive_plot(struct bv_scene_obj *s, struct bview *v) if (!s || !v) return; struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; - if (!d) + if (!d || !d->mesh_c) return; + bv_log(1, "brep_adaptive_plot %s[%s]", bu_vls_cstr(&s->s_name), (v) ? bu_vls_cstr(&v->gv_name) : "NULL"); - struct db_i *dbip = d->dbip; - struct db_full_path *fp = (struct db_full_path *)s->s_path; - struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); - const struct bn_tol *tol = d->tol; - const struct bg_tess_tol *ttol = d->ttol; - struct bv_mesh_lod *lod = NULL; - - // We need the key to look up the LoD data from the cache, and if we don't - // already have cache data for this brep we need to generate it. - unsigned long long key = bg_mesh_lod_key_get(d->mesh_c, dp->d_namep); - if (!key) { - // We don't have a key associated with the name. Get and check the - // Brep data itself, creating the mesh data and the corresponding LoD - // data if we don't already have it - struct bu_external ext = BU_EXTERNAL_INIT_ZERO; - if (db_get_external(&ext, dp, dbip)) - return; - key = bg_mesh_lod_custom_key((void *)ext.ext_buf, ext.ext_nbytes); - bu_free_external(&ext); - if (!key) + s->csg_obj = 0; + s->mesh_obj = 1; + + struct bv_scene_obj *vo = bv_obj_for_view(s, v); + + if (!vo) { + + vo = bv_obj_get_vo(s, v); + + vo->csg_obj = 0; + vo->mesh_obj = 1; + + struct db_i *dbip = d->dbip; + struct db_full_path *fp = (struct db_full_path *)s->s_path; + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)s->dp; + + if (!dp) return; - lod = bg_mesh_lod_create(d->mesh_c, key); - if (!lod) { - // Just in case we have a stale key... - bg_mesh_lod_clear_cache(d->mesh_c, key); - struct rt_db_internal dbintern; - RT_DB_INTERNAL_INIT(&dbintern); - struct rt_db_internal *ip = &dbintern; - int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); - if (ret < 0) + const struct bn_tol *tol = d->tol; + const struct bg_tess_tol *ttol = d->ttol; + struct bv_mesh_lod *lod = NULL; + + // We need the key to look up the LoD data from the cache, and if we don't + // already have cache data for this brep we need to generate it. + unsigned long long key = bv_mesh_lod_key_get(d->mesh_c, dp->d_namep); + if (!key) { + // We don't have a key associated with the name. Get and check the + // Brep data itself, creating the mesh data and the corresponding LoD + // data if we don't already have it + struct bu_external ext = BU_EXTERNAL_INIT_ZERO; + if (db_get_external(&ext, dp, dbip)) return; - struct rt_brep_internal *bi = (struct rt_brep_internal *)ip->idb_ptr; - RT_BREP_CK_MAGIC(bi); - - // Unlike a BoT, which has the mesh data already, we need to generate the - // mesh from the brep - int *faces = NULL; - int face_cnt = 0; - vect_t *normals = NULL; - point_t *pnts = NULL; - int pnt_cnt = 0; - - ret = brep_cdt_fast(&faces, &face_cnt, &normals, &pnts, &pnt_cnt, bi->brep, -1, ttol, tol); - if (ret != BRLCAD_OK) { - bu_free(faces, "faces"); - bu_free(normals, "normals"); - bu_free(pnts, "pnts"); + key = bv_mesh_lod_custom_key((void *)ext.ext_buf, ext.ext_nbytes); + bu_free_external(&ext); + if (!key) return; - } + lod = bv_mesh_lod_create(d->mesh_c, key); + if (!lod) { + // Just in case we have a stale key... + bv_mesh_lod_clear_cache(d->mesh_c, key); + + struct rt_db_internal dbintern; + RT_DB_INTERNAL_INIT(&dbintern); + struct rt_db_internal *ip = &dbintern; + int ret = rt_db_get_internal(ip, dp, dbip, NULL, d->res); + if (ret < 0) + return; + struct rt_brep_internal *bi = (struct rt_brep_internal *)ip->idb_ptr; + RT_BREP_CK_MAGIC(bi); + + // Unlike a BoT, which has the mesh data already, we need to generate the + // mesh from the brep + int *faces = NULL; + int face_cnt = 0; + vect_t *normals = NULL; + point_t *pnts = NULL; + int pnt_cnt = 0; + + ret = brep_cdt_fast(&faces, &face_cnt, &normals, &pnts, &pnt_cnt, bi->brep, -1, ttol, tol); + if (ret != BRLCAD_OK) { + bu_free(faces, "faces"); + bu_free(normals, "normals"); + bu_free(pnts, "pnts"); + return; + } - // Because we won't have the internal data to use for a full detail scenario, we set the ratio - // to 1 rather than .66 for breps... - key = bg_mesh_lod_cache(d->mesh_c, (const point_t *)pnts, pnt_cnt, normals, faces, face_cnt, key, 1); + // Because we won't have the internal data to use for a full detail scenario, we set the ratio + // to 1 rather than .66 for breps... + key = bv_mesh_lod_cache(d->mesh_c, (const point_t *)pnts, pnt_cnt, normals, faces, face_cnt, key, 1); - if (key) - bg_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); + if (key) + bv_mesh_lod_key_put(d->mesh_c, dp->d_namep, key); - rt_db_free_internal(&dbintern); + rt_db_free_internal(&dbintern); - bu_free(faces, "faces"); - bu_free(normals, "normals"); - bu_free(pnts, "pnts"); + bu_free(faces, "faces"); + bu_free(normals, "normals"); + bu_free(pnts, "pnts"); + } } - } - if (!key) - return; + if (!key) + return; - // Once we have a valid key, proceed to create the necessary - // data structures and objects. If the above didn't get us - // a valid mesh, no point in trying further - lod = bg_mesh_lod_create(d->mesh_c, key); - if (!lod) - return; + // Once we have a valid key, proceed to create the necessary + // data structures and objects. If the above didn't get us + // a valid mesh, no point in trying further + lod = bv_mesh_lod_create(d->mesh_c, key); + if (!lod) + return; - struct bv_scene_obj *vo = bv_obj_get_child(s); - bv_set_view_obj(s, v, vo); - - // Most of the view properties (color, size, etc.) are inherited from - // the parent - bv_obj_sync(vo, s); - - // Assign the LoD information to the object's draw_data, and let - // the LoD know which object it is associated with. - vo->draw_data = (void *)lod; - lod->s = vo; - - // The object bounds are based on the LoD's calculations. Because the LoD - // cache stores only one cached data set per object, but full path - // instances in the scene can be placed with matrices, we must apply the - // s_mat transformation to the "baseline" LoD bbox info to get the correct - // box for the instance. - MAT4X3PNT(vo->bmin, s->s_mat, lod->bmin); - MAT4X3PNT(vo->bmax, s->s_mat, lod->bmax); - VMOVE(s->bmin, vo->bmin); - VMOVE(s->bmax, vo->bmax); - - // Record the necessary information for full detail information recovery. We - // don't duplicate the full mesh detail in the on-disk LoD storage, since we - // already have that info in the .g itself, but we need to know how to get at - // it when needed. The free callback will clean up, but we need to initialize - // the callback data here. - struct ged_full_detail_clbk_data *cbd; - BU_GET(cbd, ged_full_detail_clbk_data); - cbd->dbip = dbip; - cbd->dp = DB_FULL_PATH_CUR_DIR(fp); - cbd->res = &rt_uniresource; - cbd->intern = NULL; - bg_mesh_lod_detail_setup_clbk(lod, &bot_mesh_info_clbk, (void *)cbd); - bg_mesh_lod_detail_clear_clbk(lod, &bot_mesh_info_clear_clbk); - bg_mesh_lod_detail_free_clbk(lod, &bot_mesh_info_free_clbk); - - // LoD will need to re-check its level settings whenever the view changes - vo->s_update_callback = &bg_mesh_lod_view; - vo->s_free_callback = &bg_mesh_lod_free; - - // Initialize the LoD data to the current view - int level = bg_mesh_lod_view(vo, vo->s_v, 0); - if (level < 0) { - bu_log("Error loading info for initial LoD view\n"); - } + // Assign the LoD information to the object's draw_data, and let + // the LoD know which object it is associated with. + vo->draw_data = (void *)lod; + lod->s = vo; + + // The object bounds are based on the LoD's calculations. Because the LoD + // cache stores only one cached data set per object, but full path + // instances in the scene can be placed with matrices, we must apply the + // s_mat transformation to the "baseline" LoD bbox info to get the correct + // box for the instance. + MAT4X3PNT(vo->bmin, s->s_mat, lod->bmin); + MAT4X3PNT(vo->bmax, s->s_mat, lod->bmax); + VMOVE(s->bmin, vo->bmin); + VMOVE(s->bmax, vo->bmax); + + // Record the necessary information for full detail information recovery. We + // don't duplicate the full mesh detail in the on-disk LoD storage, since we + // already have that info in the .g itself, but we need to know how to get at + // it when needed. The free callback will clean up, but we need to initialize + // the callback data here. + struct ged_full_detail_clbk_data *cbd; + BU_GET(cbd, ged_full_detail_clbk_data); + cbd->dbip = dbip; + cbd->dp = dp; + cbd->res = &rt_uniresource; + cbd->intern = NULL; + bv_mesh_lod_detail_setup_clbk(lod, &bot_mesh_info_clbk, (void *)cbd); + bv_mesh_lod_detail_clear_clbk(lod, &bot_mesh_info_clear_clbk); + bv_mesh_lod_detail_free_clbk(lod, &bot_mesh_info_free_clbk); + + // LoD will need to re-check its level settings whenever the view changes + vo->s_update_callback = &bv_mesh_lod_view; + vo->s_free_callback = &bv_mesh_lod_free; + + // Initialize the LoD data to the current view + int level = bv_mesh_lod_view(vo, vo->s_v, 0); + if (level < 0) { + bu_log("Error loading info for initial LoD view\n"); + } - // Mark the object as a Mesh LoD so the drawing routine knows to handle it differently - vo->s_type_flags |= BV_MESH_LOD; + // Mark the object as a Mesh LoD so the drawing routine knows to handle it differently + vo->s_type_flags |= BV_MESH_LOD; + } - // Make the names unique - bu_vls_sprintf(&vo->s_name, "%s", bu_vls_cstr(&s->s_name)); - vo->s_path = NULL; // I don't think the vo objects will need the db_fullpath... - bu_vls_sprintf(&vo->s_uuid, "%s:%s", bu_vls_cstr(&v->gv_name), bu_vls_cstr(&s->s_uuid)); + bv_mesh_lod_view(vo, vo->s_v, 0); + bv_obj_stale(vo); return; } @@ -514,9 +540,12 @@ brep_adaptive_plot(struct bv_scene_obj *s, struct bview *v) static void wireframe_plot(struct bv_scene_obj *s, struct bview *v, struct rt_db_internal *ip) { + bv_log(1, "wireframe_plot %s[%s]", bu_vls_cstr(&s->s_name), (v) ? bu_vls_cstr(&v->gv_name) : "NULL"); struct draw_update_data_t *d = (struct draw_update_data_t *)s->s_i_data; const struct bn_tol *tol = d->tol; const struct bg_tess_tol *ttol = d->ttol; + s->csg_obj = 1; + s->mesh_obj = 0; // Standard (view independent) wireframe if (!v || !v->gv_s->adaptive_plot_csg) { @@ -531,31 +560,31 @@ wireframe_plot(struct bv_scene_obj *s, struct bview *v, struct rt_db_internal *i // If we're adaptive, call the primitive's adaptive plotting, if any. if (ip->idb_meth->ft_adaptive_plot) { - struct bv_scene_obj *vo = bv_obj_get_child(s); - - // Make a copy of the draw info for vo. - struct draw_update_data_t *ld; - BU_GET(ld, struct draw_update_data_t); - ld->fp = (struct db_full_path *)s->s_path; - ld->dbip = d->dbip; - ld->tol = d->tol; - ld->ttol = d->ttol; - ld->mesh_c = d->mesh_c; - ld->res = d->res; - vo->s_i_data= (void *)ld; - - vo->s_update_callback = &csg_wireframe_update; - vo->s_free_callback = &draw_free_data; - - // Most of the view properties (color, size, etc.) are inherited from - // the parent - bv_obj_sync(vo, s); - - // Make the names unique - bu_vls_sprintf(&vo->s_name, "%s:%s", bu_vls_cstr(&v->gv_name), bu_vls_cstr(&s->s_name)); - vo->s_path = NULL; // I don't think the vo objects will need the db_fullpath... - bu_vls_sprintf(&vo->s_uuid, "%s:%s", bu_vls_cstr(&v->gv_name), bu_vls_cstr(&s->s_uuid)); + struct bv_scene_obj *vo = bv_obj_for_view(s, v); + if (!vo) { + vo = bv_obj_get_vo(s, v); + + // Make a copy of the draw info for vo. + struct draw_update_data_t *ld; + BU_GET(ld, struct draw_update_data_t); + ld->fp = (struct db_full_path *)s->s_path; + ld->dbip = d->dbip; + ld->tol = d->tol; + ld->ttol = d->ttol; + ld->mesh_c = d->mesh_c; + ld->res = d->res; + vo->s_i_data= (void *)ld; + + // We're adaptive - have to plot when the view changes. Set the + // callbacks + vo->s_update_callback = &csg_wireframe_update; + vo->s_free_callback = &draw_free_data; + + // Mark type as CSG LoD + vo->s_type_flags |= BV_CSG_LOD; + } + csg_wireframe_update(vo, v, 1); return; } @@ -582,9 +611,12 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) if (s->current && !v) return; + bv_log(1, "draw_scene %s[%s]", bu_vls_cstr(&s->s_name), (v) ? bu_vls_cstr(&v->gv_name) : "NULL"); + // If we're not adaptive, trigger the view insensitive drawing routines - if (v && !v->gv_s->adaptive_plot_csg && !v->gv_s->adaptive_plot_mesh) + if (v && !v->gv_s->adaptive_plot_csg && !v->gv_s->adaptive_plot_mesh) { return draw_scene(s, NULL); + } // If we have a scene object without drawing data, it is most likely // a container holding other objects we do need to draw. Iterate over @@ -628,18 +660,24 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) **************************************************************************/ struct db_i *dbip = d->dbip; struct db_full_path *fp = (struct db_full_path *)s->s_path; - struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); + if (fp && fp->fp_len <= 0) + return; + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)s->dp; + if (!dp) + return; // Adaptive BoTs have specialized LoD routines to help cope with very large // data sets, both for wireframe and shaded mode. - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && s->s_v->gv_s->adaptive_plot_mesh) { + if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && v && v->gv_s->adaptive_plot_mesh && + (s->s_os->s_dmode == 0 || s->s_os->s_dmode == 1)) { bot_adaptive_plot(s, v); return; } // Adaptive BReps have specialized LoD routines to manage shaded displays, which - // can involve slow and large mesh generations. - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BREP && s->s_v->gv_s->adaptive_plot_mesh && s->s_os->s_dmode == 1) { + // can involve slow and large mesh generations. BRep wireframes are based on the + // NURBS data, so this is used only for shaded mode + if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BREP && v && v->gv_s->adaptive_plot_mesh && s->s_os->s_dmode == 1) { brep_adaptive_plot(s, v); return; } @@ -653,7 +691,7 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) struct rt_db_internal dbintern; RT_DB_INTERNAL_INIT(&dbintern); struct rt_db_internal *ip = &dbintern; - int ret = rt_db_get_internal(ip, DB_FULL_PATH_CUR_DIR(fp), dbip, s->s_mat, d->res); + int ret = rt_db_get_internal(ip, dp, dbip, s->s_mat, d->res); if (ret < 0) return; @@ -683,7 +721,7 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) goto geom_done; break; case DB5_MINORTYPE_BRLCAD_BREP: - (void)rt_brep_plot_poly(&s->s_vlist, fp, ip, ttol, tol, NULL); + (void)rt_brep_plot_poly(&s->s_vlist, dp, ip, ttol, tol, NULL); goto geom_done; break; default: @@ -706,6 +744,8 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) if (prim_tess(s, ip) < 0) { wireframe_plot(s, v, ip); s->s_os->s_dmode = 0; + } else { + s->current = 1; } break; case 3: @@ -719,6 +759,8 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) if (prim_tess(s, ip) < 0) { wireframe_plot(s, v, ip); s->s_os->s_dmode = 0; + } else { + s->current = 1; } break; case 5: @@ -744,7 +786,6 @@ draw_scene(struct bv_scene_obj *s, struct bview *v) s->curve_scale = s->s_v->gv_s->curve_scale; s->point_scale = s->s_v->gv_s->point_scale; - s->current = 1; rt_db_free_internal(&dbintern); } diff --git a/src/libged/draw/draw.c b/src/libged/draw/draw.c index 1f02813fcb2..f6c32e98bea 100644 --- a/src/libged/draw/draw.c +++ b/src/libged/draw/draw.c @@ -98,7 +98,7 @@ plot_shaded( (void)rt_pg_plot_poly(&vhead, ip, tsp->ts_ttol, tsp->ts_tol); break; case DB5_MINORTYPE_BRLCAD_BREP: - (void)rt_brep_plot_poly(&vhead, pathp, ip, tsp->ts_ttol, + (void)rt_brep_plot_poly(&vhead, DB_FULL_PATH_CUR_DIR(pathp), ip, tsp->ts_ttol, tsp->ts_tol, NULL); } _ged_drawH_part2(0, &vhead, pathp, tsp, dgcdp); @@ -370,7 +370,7 @@ draw_nmg_region_start(struct db_tree_state *tsp, const struct db_full_path *path if (dgcdp->nmg_fast_wireframe_draw) { (void)rt_brep_plot(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } else { - (void)rt_brep_plot_poly(&vhead, pathp, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); + (void)rt_brep_plot_poly(&vhead, DB_FULL_PATH_CUR_DIR(pathp), &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } } goto out; @@ -491,7 +491,7 @@ draw_nmg_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, return (union tree *)NULL; } - } else if (curtree->tr_op != OP_NMG_TESS) { + } else if (curtree->tr_op != OP_TESS) { bu_vls_printf(dgcdp->gedp->ged_result_str, "Cannot use '-d' option when Boolean evaluation is required\n"); db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; @@ -711,6 +711,9 @@ _ged_drawtrees(struct ged *gedp, int argc, const char *argv[], int kind, struct case 4: shaded_mode_override = _GED_HIDDEN_LINE; break; + case 5: + shaded_mode_override = _GED_WIREFRAME_EVAL; + break; default: if (shaded_mode_override < 0) { shaded_mode_override = _GED_SHADED_MODE_UNSET; @@ -847,6 +850,15 @@ _ged_drawtrees(struct ged *gedp, int argc, const char *argv[], int kind, struct dgcdp = dgcdp_save; } + } else if (dgcdp.vs.s_dmode == _GED_WIREFRAME_EVAL) { + const char **eav = (const char **)bu_calloc(argc+1, sizeof(const char *), "av"); + eav[0] = "E"; + for (int ie = 0; ie < argc; ie++) { + eav[ie+1] = argv[ie]; + } + int eret = ged_exec(gedp, argc+1, eav); + bu_free(eav, "eav"); + return eret; } else { struct display_list **paths_to_draw; struct display_list *gdlp; @@ -951,7 +963,7 @@ _ged_drawtrees(struct ged *gedp, int argc, const char *argv[], int kind, struct &wdbp->wdb_initial_tree_state, enable_fastpath ? draw_nmg_region_start : 0, draw_nmg_region_end, - nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess, + nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : rt_booltree_leaf_tess, (void *)&dgcdp); } diff --git a/src/libged/draw/draw2.cpp b/src/libged/draw/draw2.cpp index 63695a55947..02bdb04b5a1 100644 --- a/src/libged/draw/draw2.cpp +++ b/src/libged/draw/draw2.cpp @@ -36,77 +36,16 @@ #include "bu/cmd.h" #include "bu/opt.h" #include "bu/sort.h" -#include "bg/lod.h" #include "nmg.h" #include "rt/view.h" -#include "ged/view/state.h" -#define ALPHANUM_IMPL -#include "../alphanum.h" -#include "../ged_private.h" - -/** - * This walker builds up scene size and bounding information. - */ -static void -_bound_fp(struct db_full_path *path, mat_t *curr_mat, void *client_data) -{ - struct directory *dp; - struct draw_data_t *dd = (struct draw_data_t *)client_data; - RT_CK_FULL_PATH(path); - RT_CK_DBI(dd->dbip); - - dp = DB_FULL_PATH_CUR_DIR(path); - if (!dp) - return; - if (dp->d_flags & RT_DIR_COMB) { - // Have a comb - keep going - struct rt_db_internal in; - struct rt_comb_internal *comb; - if (rt_db_get_internal(&in, dp, dd->dbip, NULL, dd->res) < 0) - return; - comb = (struct rt_comb_internal *)in.idb_ptr; - draw_walk_tree(path, comb->tree, curr_mat, _bound_fp, client_data, NULL); - rt_db_free_internal(&in); - // Use bbox to update sizing - if (dd->have_bbox) { - dd->g->s_size = dd->g->bmax[X] - dd->g->bmin[X]; - V_MAX(dd->g->s_size, dd->g->bmax[Y] - dd->g->bmin[Y]); - V_MAX(dd->g->s_size, dd->g->bmax[Z] - dd->g->bmin[Z]); - } - } else { - // If we're skipping subtractions there's no - // point in going further. - if (dd->skip_subtractions && dd->bool_op == 4) { - return; - } - - // On initialization we don't have any wireframes to establish sizes, and if - // we're adaptive we need some idea of object size to get a reasonable result. - // Try for a bounding box, if the method is available. Otherwise try the - // bounding the default plot. - point_t bmin, bmax; - int bbret = rt_bound_instance(&bmin, &bmax, DB_FULL_PATH_CUR_DIR(path), dd->dbip, dd->ttol, dd->tol, curr_mat, dd->res); - if (bbret >= 0) { - - // Got bounding box, use it to update sizing - fastf_t s_size = bmax[X] - bmin[X]; - V_MAX(s_size, bmax[Y] - bmin[Y]); - V_MAX(s_size, bmax[Z] - bmin[Z]); - - // Got bounding box, use it to update sizing - (*dd->s_size)[dp] = s_size; - VMINMAX(dd->min, dd->max, bmin); - VMINMAX(dd->min, dd->max, bmax); - VMINMAX(dd->g->bmin, dd->g->bmax, bmin); - VMINMAX(dd->g->bmin, dd->g->bmax, bmax); - dd->g->s_size = s_size; - dd->have_bbox = 1; - } - } +extern "C" { +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" } - +#include "ged/view/state.h" +#include "../ged_private.h" static int draw_opt_color(struct bu_vls *msg, size_t argc, const char **argv, void *data) @@ -121,355 +60,6 @@ draw_opt_color(struct bu_vls *msg, size_t argc, const char **argv, void *data) return ret; } -static int -alphanum_cmp(const void *a, const void *b, void *UNUSED(data)) { - struct bv_scene_group *ga = *(struct bv_scene_group **)a; - struct bv_scene_group *gb = *(struct bv_scene_group **)b; - return alphanum_impl(bu_vls_cstr(&ga->s_name), bu_vls_cstr(&gb->s_name), NULL); -} - -/* This function digests the paths into scene object sets. It does NOT trigger - * the routines that will actually produce the scene geometry and add it to the - * scene objects - it only prepares the inputs to be used for that process. */ -static int -ged_update_objs(struct ged *gedp, struct bview *v, struct bv_obj_settings *vs, int refresh, int argc, const char *argv[]) -{ - struct db_i *dbip = gedp->dbip; - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - struct resource *local_res; - BU_GET(local_res, struct resource); - rt_init_resource(local_res, 0, NULL); - - // If we have no active groups and no view objects, we are drawing into a - // blank canvas - unless options specifically disable it, if we are doing - // adaptive plotting we need to do a preliminary view characterization. - struct draw_data_t bounds_data; - std::map s_size; - bounds_data.bound_only = 1; - bounds_data.res = local_res; - bounds_data.have_bbox = 0; - bounds_data.dbip = dbip; - bounds_data.skip_subtractions = 1; - bounds_data.bool_op = 2; - bounds_data.v = v; - VSET(bounds_data.min, INFINITY, INFINITY, INFINITY); - VSET(bounds_data.max, -INFINITY, -INFINITY, -INFINITY); - bounds_data.s_size = &s_size; - - /* Validate that the supplied args are current, valid paths in the - * database. If one or more are not, bail */ - std::set fps; - std::vector fps_free; - std::set::iterator f_it; - for (size_t i = 0; i < (size_t)argc; ++i) { - struct db_full_path *fp; - BU_GET(fp, struct db_full_path); - db_full_path_init(fp); - int ret = db_string_to_path(fp, dbip, argv[i]); - if (ret < 0) { - // If that didn't work, there's one other thing we have to check - // for - a really strange path with the "/" character in it. - struct directory *fdp = db_lookup(dbip, argv[i], LOOKUP_QUIET); - if (fdp == RT_DIR_NULL) { - // Invalid path - db_free_full_path(fp); - BU_PUT(fp, struct db_full_path); - bu_vls_printf(gedp->ged_result_str, "Invalid path: %s\n", argv[i]); - continue; - } else { - // Object name contained forward slash (urk!) - db_free_full_path(fp); - db_full_path_init(fp); - db_add_node_to_full_path(fp, fdp); - } - } - fps.insert(fp); - fps_free.push_back(fp); - } - if (fps.size() != (size_t)argc) { - for (size_t i = 0; i < fps_free.size(); i++) { - db_free_full_path(fps_free[i]); - BU_PUT(fps_free[i], struct db_full_path); - } - return BRLCAD_ERROR; - } - // If we had no args, we're refreshing all drawn objects - if (!argc) { - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(sg, i); - struct db_full_path *fp = (struct db_full_path *)s->s_path; - fps.insert(fp); - } - } - - // As a preliminary step, check the already drawn paths to see if the - // proposed new path impacts them. If we need to set up for adaptive - // plotting, do initial bounds calculations to pave the way for an - // initial view setup. - std::map fp_g; - - for (f_it = fps.begin(); f_it != fps.end(); f_it++) { - struct bv_scene_group *g = NULL; - struct db_full_path *fp = *f_it; - - // Get the "seed" matrix from the path - everything we draw at or below - // the path will be positioned using it. We don't need the matrix - // itself in this stage, but if we can't get it the path isn't going to - // be workable anyway so we may as well check now and yank it if there - // is a problem. - mat_t mat; - MAT_IDN(mat); - if (!db_path_to_mat(dbip, fp, mat, 0, local_res)) { - continue; - } - - // Check all the current groups against the candidate. - std::set clear; - std::set::iterator g_it; - struct bv_obj_settings fpvs; - bv_obj_settings_sync(&fpvs, vs); - bool clear_invalid_only = false; - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - // If we already know we're clearing this one, don't check - // again - if (clear.find(cg) != clear.end()) { - continue; - } - - // Not already clearing, need to check - struct db_full_path *gfp = (struct db_full_path *)cg->s_path; - - // If we found an encompassing path, we don't need to do any more work - if (clear_invalid_only) { - continue; - } - - // Two conditions to check for here: - // 1. proposed draw path is a top match for existing path - if (db_full_path_match_top(fp, gfp)) { - // New path will replace the currently drawn path - clear it - clear.insert(cg); - if (refresh) - bv_obj_settings_sync(&fpvs, cg->s_os); - continue; - } - // 2. existing path is a top match encompassing the proposed path - if (db_full_path_match_top(gfp, fp)) { - // Already drawn - replace just the children of g that match this - // path to update their contents - g = cg; - if (refresh) - bv_obj_settings_sync(&fpvs, cg->s_os); - // We continue to weed out any other invalid paths in sg, even - // though cg should be the only path in sg that matches in this - // condition. However, we no longer need to do the top matches, - // so let the loop know - clear_invalid_only = true; - continue; - } - } - - // IFF we are just redrawing part or all of an already drawn path, we don't - // need to create a new scene object. Otherwise, we do. - if (g) { - // Remove children that match fp - we will be adding new versions - // to g to update them. If g has no children, it was probably an - // evaluated shape - in that case, replace it with a fresh instance. - if (!BU_PTBL_LEN(&g->children)) { - struct db_full_path *fpcpy; - BU_GET(fpcpy, struct db_full_path); - db_full_path_init(fpcpy); - db_dup_full_path(fpcpy, fp); - bv_obj_put(g); - g = bv_obj_get(v, BV_DB_OBJS); - db_path_to_vls(&g->s_name, fpcpy); - g->s_path = fpcpy; - bv_obj_settings_sync(g->s_os, &fpvs); - } else { - std::set sclear; - std::set::iterator s_it; - for (size_t i = 0; i < BU_PTBL_LEN(&g->children); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&g->children, i); - if (db_full_path_match_top((struct db_full_path *)s->s_path, fp)) { - sclear.insert(s); - } - } - for (s_it = sclear.begin(); s_it != sclear.end(); s_it++) { - struct bv_scene_obj *s = *s_it; - bv_obj_put(s); - } - } - } else { - // Create new scene object. Typically this will be a "parent" - // object and the actual per-solid wireframes or triangles will - // live in child objects below this object. However, in - // "evaluated" drawing modes the visualization in the scene is - // unique to this object and in those cases drawing information - // will be stored in this object directly. - struct db_full_path *fpcpy; - BU_GET(fpcpy, struct db_full_path); - db_full_path_init(fpcpy); - db_dup_full_path(fpcpy, fp); - g = bv_obj_get(v, BV_DB_OBJS); - db_path_to_vls(&g->s_name, fp); - g->s_path = fpcpy; - bv_obj_settings_sync(g->s_os, &fpvs); - } - - // If we're a blank slate, we're adaptive, and autoview isn't off - // we need to be building up some sense of the view and object - // sizes as we go, ahead of trying to draw anything. That means - // for each group we're going to be using mat and walking the tree - // of fp (or getting its box directly if fp is a solid with no - // parents) to build up bounding info. - mat_t cmat; - MAT_COPY(cmat, mat); - VSETALL(g->bmin, INFINITY); - VSETALL(g->bmax, -INFINITY); - bounds_data.g = g; - _bound_fp(fp, &cmat, (void *)&bounds_data); - - fp_g[fp] = g; - - if (clear.size()) { - // Clear anything superseded by the new path - for (g_it = clear.begin(); g_it != clear.end(); g_it++) { - struct bv_scene_group *cg = *g_it; - bv_obj_put(cg); - } - } - } - - // Initial setup is done, we now have the set of paths to walk to create - // the children objects. - std::map::iterator fpg_it; - for (fpg_it = fp_g.begin(); fpg_it != fp_g.end(); fpg_it++) { - struct db_full_path *fp = fpg_it->first; - struct bv_scene_group *g = fpg_it->second; - - // Seed initial matrix from the path - mat_t mat; - MAT_IDN(mat); - if (!db_path_to_mat(dbip, fp, mat, 0, local_res)) { - continue; - } - - // Get an initial color from the path, if we're not overridden - struct bu_color c; - if (!vs->color_override) { - unsigned char dc[3]; - dc[0] = 255; - dc[1] = 0; - dc[2] = 0; - bu_color_from_rgb_chars(&c, dc); - db_full_path_color(&c, fp, dbip, local_res); - } - - // Prepare tree walking data container - struct draw_data_t dd; - dd.dbip = gedp->dbip; - dd.v = v; - dd.tol = &wdbp->wdb_tol; - dd.ttol = &wdbp->wdb_ttol; - dd.mesh_c = gedp->ged_lod; - dd.color_inherit = 0; - dd.bound_only = 0; - dd.res = local_res; - dd.bool_op = 2; // Default to union - if (vs->color_override) { - bu_color_from_rgb_chars(&dd.c, vs->color); - } else { - HSET(dd.c.buc_rgb, c.buc_rgb[0], c.buc_rgb[1], c.buc_rgb[2], c.buc_rgb[3]); - } - dd.s_size = &s_size; - dd.vs = vs; - dd.g = g; - - // In drawing modes 3 (bigE) and 5 (points) we are producing an - // evaluated shape, rather than iterating to get the solids - if (vs->s_dmode == 3 || vs->s_dmode == 5) { - if (vs->color_override) { - VMOVE(g->s_color, vs->color); - } else { - bu_color_to_rgb_chars(&c, g->s_color); - } - // TODO - check object against default GED selection set - struct draw_update_data_t *ud; - BU_GET(ud, struct draw_update_data_t); - ud->fp = (struct db_full_path *)g->s_path; - ud->dbip = dd.dbip; - ud->tol = dd.tol; - ud->ttol = dd.ttol; - ud->res = &rt_uniresource; // TODO - at some point this may be from the app or view... local_res is temporary, don't use it here - ud->mesh_c = dd.mesh_c; - g->s_i_data = (void *)ud; - g->s_v = dd.v; - continue; - } - - // Walk the tree to build up the set of scene objects that will hold - // each instance's wireframe. These scene objects will be stored as - // children of g (which is the "who" level drawn object). - draw_gather_paths(fp, &mat, (void *)&dd); - } - rt_clean_resource_basic(NULL, local_res); - BU_PUT(local_res, struct resource); - - // Sort - bu_sort(BU_PTBL_BASEADDR(sg), BU_PTBL_LEN(sg), sizeof(struct bv_scene_group *), alphanum_cmp, NULL); - - // Clean up - for (size_t i = 0; i < fps_free.size(); i++) { - db_free_full_path(fps_free[i]); - BU_PUT(fps_free[i], struct db_full_path); - } - - // Scene objects are created and stored. The next step is to generate - // wireframes, triangles, etc. for each object based on current settings. - // It is then the job of the dm to display the scene objects supplied by - // the view. - return BRLCAD_OK; -} - -static int -ged_draw_view(struct bview *v, int bot_threshold, int no_autoview, int blank_slate) -{ - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - - /* Bot threshold is managed as a per-view setting internally. */ - if (bot_threshold >= 0) { - v->gv_s->bot_threshold = bot_threshold; - } - - // Make sure the view knows how to update the obb - v->gv_bounds_update = &bg_view_bounds; - - // Do an initial autoview so adaptive routines will have approximately - // the right starting point - if (blank_slate && !no_autoview) { - bv_autoview(v, BV_AUTOVIEW_SCALE_DEFAULT, 0); - } - - // Do the actual drawing - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(sg, i); - draw_scene(s, v); - } - - // Make sure what we've drawn is visible, unless we've a reason not to. - if (blank_slate && !no_autoview) { - bv_autoview(v, BV_AUTOVIEW_SCALE_DEFAULT, 0); - } - - // Scene objects are created and stored. The application may now call each - // object's update callback to generate wireframes, triangles, etc. for - // that object based on current settings. It is then the job of the dm to - // display the scene objects supplied by the view. - return BRLCAD_OK; -} - /* * Main drawing command control logic */ @@ -521,11 +111,25 @@ ged_draw2_core(struct ged *gedp, int argc, const char *argv[]) return BRLCAD_ERROR; } } + + // If we don't have a specified view, and the default view isn't a shared view, see if + // we can find a shared view in the view set. + if (!bu_vls_strlen(&cvls) && (!cv || cv->independent)) { + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *bv = (struct bview *)BU_PTBL_GET(views, i); + if (!bv->independent) { + cv = bv; + break; + } + } + } + bu_vls_free(&cvls); // We need a current view, either from gedp or from the options if (!cv) { - bu_vls_printf(gedp->ged_result_str, "No current GED view defined"); + bu_vls_printf(gedp->ged_result_str, "No view specified and no shared views found"); return BRLCAD_ERROR; } @@ -536,27 +140,25 @@ ged_draw2_core(struct ged *gedp, int argc, const char *argv[]) if (cv) bv_obj_settings_sync(&vs, &cv->gv_s->obj_s); - int drawing_modes[6] = {-1, 0, 0, 0, 0, 0}; - int refresh = 0; struct bu_opt_desc d[18]; BU_OPT(d[0], "h", "help", "", NULL, &print_help, "Print help and exit"); BU_OPT(d[1], "?", "", "", NULL, &print_help, ""); BU_OPT(d[2], "m", "mode", "#", &bu_opt_int, &drawing_modes[0], "0=wireframe;1=shaded bots;2=shaded;3=evaluated"); BU_OPT(d[3], "", "wireframe", "", NULL, &drawing_modes[1], "Draw using only wireframes (mode = 0)"); - BU_OPT(d[4], "", "shaded", "", NULL, &drawing_modes[2], "Shade bots and polysolids (mode = 1)"); + BU_OPT(d[4], "", "shaded", "", NULL, &drawing_modes[2], "Shade bots, breps and polysolids (mode = 1)"); BU_OPT(d[5], "", "shaded-all", "", NULL, &drawing_modes[3], "Shade all solids, not evaluated (mode = 2)"); BU_OPT(d[6], "E", "evaluate", "", NULL, &drawing_modes[4], "Wireframe with evaluate booleans (mode = 3)"); BU_OPT(d[7], "", "hidden-line", "", NULL, &drawing_modes[5], "Hidden line wireframes"); - BU_OPT(d[8], "t", "transparency", "#", &bu_opt_fastf_t, &vs.transparency, "Set transparency level in drawing: range 0 (clear) to 1 (opaque)"); - BU_OPT(d[9], "x", "", "#", &bu_opt_fastf_t, &vs.transparency, ""); - BU_OPT(d[10], "L", "", "#", &bu_opt_int, &bot_threshold, "Set face count level for drawing bounding boxes instead of BoT triangles (NOTE: passing this updates the global view setting - bot_threshold is a view property)."); - BU_OPT(d[11], "S", "no-subtract", "", NULL, &vs.draw_non_subtract_only, "Do not draw subtraction solids"); - BU_OPT(d[12], "", "no-dash", "", NULL, &vs.draw_solid_lines_only, "Use solid lines rather than dashed for subtraction solids"); - BU_OPT(d[13], "C", "color", "r/g/b", &draw_opt_color, &vs, "Override object colors"); - BU_OPT(d[14], "", "line-width", "#", &bu_opt_int, &vs.s_line_width, "Override default line width"); - BU_OPT(d[15], "R", "no-autoview", "", NULL, &no_autoview, "Do not calculate automatic view, even if initial scene is empty."); - BU_OPT(d[16], "", "refresh", "", NULL, &refresh, "Try to keep properties of existing drawn objects when updating."); + BU_OPT(d[8], "A", "add-mode", "", NULL, &vs.mixed_modes, "Don't erase other drawn modes for specified paths (allows simultaneous shaded and wireframe drawing for the same object)"); + BU_OPT(d[9], "t", "transparency", "#", &bu_opt_fastf_t, &vs.transparency, "Set transparency level in drawing: range 0 (clear) to 1 (opaque)"); + BU_OPT(d[10], "x", "", "#", &bu_opt_fastf_t, &vs.transparency, ""); + BU_OPT(d[11], "L", "", "#", &bu_opt_int, &bot_threshold, "Set face count level for drawing bounding boxes instead of BoT triangles (NOTE: passing this updates the global view setting - bot_threshold is a view property)."); + BU_OPT(d[12], "S", "no-subtract", "", NULL, &vs.draw_non_subtract_only, "Do not draw subtraction solids"); + BU_OPT(d[13], "", "no-dash", "", NULL, &vs.draw_solid_lines_only, "Use solid lines rather than dashed for subtraction solids"); + BU_OPT(d[14], "C", "color", "r/g/b", &draw_opt_color, &vs, "Override object colors"); + BU_OPT(d[15], "", "line-width", "#", &bu_opt_int, &vs.s_line_width, "Override default line width"); + BU_OPT(d[16], "R", "no-autoview", "", NULL, &no_autoview, "Do not calculate automatic view, even if initial scene is empty."); BU_OPT_NULL(d[17]); /* If no args, must be wanting help */ @@ -610,73 +212,64 @@ ged_draw2_core(struct ged *gedp, int argc, const char *argv[]) // Before we start doing anything with the object set, record if things are // starting out empty. int blank_slate = 0; + struct bu_ptbl *dobjs = bv_view_objs(cv, BV_DB_OBJS); + struct bu_ptbl *local_dobjs = bv_view_objs(cv, BV_DB_OBJS); struct bu_ptbl *vobjs = bv_view_objs(cv, BV_VIEW_OBJS); struct bu_ptbl *vlobjs = bv_view_objs(cv, BV_VIEW_OBJS | BV_LOCAL_OBJS); - if (!BU_PTBL_LEN(bv_view_objs(cv, BV_DB_OBJS)) && !BU_PTBL_LEN(vobjs) && !BU_PTBL_LEN(vlobjs)) { + if ((!dobjs || !BU_PTBL_LEN(dobjs)) && (!local_dobjs || !BU_PTBL_LEN(local_dobjs)) && + (!vobjs || !BU_PTBL_LEN(vobjs)) && (!vlobjs || !BU_PTBL_LEN(vlobjs))) { blank_slate = 1; } - // For the non-adaptive views, the object list is shared. We process the - // current list once to update the object set, but this step does not also - // update the geometries of the objects. Once we have the scene obj set, - // we must process it on a per-view basis in case the objects have view - // specific visualizations (such as in adaptive plotting.) - ged_update_objs(gedp, cv, &vs, refresh, argc, argv); - // Drawing can get complicated when we have multiple active views with // different settings. The simplest case is when the current or specified // view is an independent view - we just update it and return. if (cv->independent) { - return ged_draw_view(cv, bot_threshold, no_autoview, blank_slate); + BViewState *bvs = gedp->dbi_state->get_view_state(cv); + for (size_t i = 0; i < (size_t)argc; ++i) + bvs->add_path(argv[i]); + std::unordered_set vset; + vset.insert(cv); + bvs->redraw(&vs, vset, !(blank_slate && !no_autoview)); + return BRLCAD_OK; } // If we have multiple views, we have to handle each view. Most of the // time the work will be done in the first pass (when objects do not have // view specific geometry to generate) but this is not true when adaptive // plotting is enabled. + std::unordered_map> vmap; struct bu_ptbl *views = bv_set_views(&gedp->ged_views); for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { struct bview *v = (struct bview *)BU_PTBL_GET(views, i); - if (v->independent) { - // Independent views are handled individually by the above case - - // this logic doesn't reference them. + if (v->independent) continue; - } - ged_draw_view(v, bot_threshold, no_autoview, blank_slate); + BViewState *bvs = gedp->dbi_state->get_view_state(cv); + if (!bvs) + continue; + vmap[bvs].insert(v); + } + std::unordered_map>::iterator bv_it; + for (bv_it = vmap.begin(); bv_it != vmap.end(); bv_it++) { + for (size_t i = 0; i < (size_t)argc; ++i) + bv_it->first->add_path(argv[i]); + bv_it->first->redraw(&vs, bv_it->second, !(blank_slate && !no_autoview)); } return BRLCAD_OK; } static int -_ged_redraw_view(struct ged *gedp, struct bview *v, int argc, const char *argv[]) +_ged_redraw_view(struct ged *gedp, struct bview *v, int argc, const char **argv) { - if (!gedp || !v) + if (!gedp || !gedp->dbi_state || !v) return BRLCAD_ERROR; - - int ac = (v->independent) ? 5 : 3; - const char *av[7] = {NULL}; - av[0] = "draw"; - av[1] = "-R"; - av[2] = "--refresh"; - av[3] = (v->independent) ? "--view" : NULL; - av[4] = (v->independent) ? bu_vls_cstr(&v->gv_name) : NULL; - int oind = (v->independent) ? 5 : 3; - if (!argc) { - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - av[oind] = bu_vls_cstr(&cg->s_name); - ged_exec(gedp, ac, (const char **)av); - } - return BRLCAD_OK; - } else { - for (int i = 0; i < argc; i++) { - av[oind] = argv[i]; - ged_exec(gedp, ac, (const char **)av); - } - return BRLCAD_OK; - } + std::unordered_set vset; + BViewState *bvs = gedp->dbi_state->get_view_state(v); + if (!bvs) + return BRLCAD_ERROR; + bvs->refresh(v, argc, argv); + return BRLCAD_OK; } extern "C" int diff --git a/src/libged/echo/echo.c b/src/libged/echo/echo.c index a710311221c..8a86fe8e3ae 100644 --- a/src/libged/echo/echo.c +++ b/src/libged/echo/echo.c @@ -37,7 +37,6 @@ ged_echo_core(struct ged *gedp, int argc, const char *argv[]) { int i; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ diff --git a/src/libged/edit/CMakeLists.txt b/src/libged/edit/CMakeLists.txt index 8cb42158cf5..d6b06baa696 100644 --- a/src/libged/edit/CMakeLists.txt +++ b/src/libged/edit/CMakeLists.txt @@ -7,15 +7,17 @@ include_directories( ) add_definitions(-DGED_PLUGIN) -ged_plugin_library(ged-edit SHARED edit.c) +ged_plugin_library(ged-edit SHARED "edit.c;edit2.cpp") target_link_libraries(ged-edit libged libbu) set_property(TARGET ged-edit APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) -VALIDATE_STYLE(ged-edit edit.c) +VALIDATE_STYLE(ged-edit "edit.c;edit2.cpp") PLUGIN_SETUP(ged-edit ged) CMAKEFILES( CMakeLists.txt edit.c + edit2.cpp + ged_edit2.h ) # Local Variables: diff --git a/src/libged/edit/edit.c b/src/libged/edit/edit.c index 87c0b4e02b3..0a77b89b6ef 100644 --- a/src/libged/edit/edit.c +++ b/src/libged/edit/edit.c @@ -1961,6 +1961,8 @@ edit_strs_to_arg(struct ged *gedp, int *argc, const char **argv[], } +extern int ged_edit2_core(struct ged *gedp, int argc, const char *argv[]); + /** * A command line interface to the edit commands. Will handle any new * commands without modification. Validates as much as possible in a @@ -1970,6 +1972,10 @@ edit_strs_to_arg(struct ged *gedp, int *argc, const char **argv[], int ged_edit_core(struct ged *gedp, int argc, const char *argv[]) { + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) + return ged_edit2_core(gedp, argc, argv); + const char *const cmd_name = argv[0]; union edit_cmd subcmd; const char *subcmd_name = NULL; diff --git a/src/libged/edit/edit2.cpp b/src/libged/edit/edit2.cpp new file mode 100644 index 00000000000..8cfbdfd3f93 --- /dev/null +++ b/src/libged/edit/edit2.cpp @@ -0,0 +1,351 @@ +/* E D I T 2 . C P P + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/edit2.cpp + * + * Testing command for experimenting with editing routines. + * + * Among other things, we want the edit command to be aware of + * the GED selection state, if we have a default one set and + * the edit command doesn't explicitly specify an object or objects + * to operate on. + */ + +#include "common.h" + +#include +#include +#include + +#include +#include +#include + +#include "bu/cmd.h" +#include "bu/opt.h" + +#include "../ged_private.h" +#include "./ged_edit2.h" + +// Container to hold information about top level options and +// specified geometry options common to all the subcommands. +struct edit_info { + int verbosity; + struct directory *dp; +}; + + +// Rotate command +class cmd_rotate : public ged_subcmd { + public: + std::string usage() { return std::string("edit [options] [geometry] rotate X Y Z"); } + std::string purpose() { return std::string("rotate specified primitive or comb instance"); } + int exec(struct ged *, void *, int, const char **); +}; +static cmd_rotate edit_rotate_cmd; + +int +cmd_rotate::exec(struct ged *gedp, void *u_data, int argc, const char **argv) +{ + if (!gedp || !u_data || !argc || !argv) + return BRLCAD_ERROR; + + struct edit_info *einfo = (struct edit_info *)u_data; + if (einfo->dp == RT_DIR_NULL) + return BRLCAD_ERROR; + + argc--; argv++; + + if (argc < 3 || !argv) { + bu_vls_printf(gedp->ged_result_str, "%s\n", usage().c_str()); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + + +// Tra command +class cmd_tra : public ged_subcmd { + public: + std::string usage() { return std::string("edit [options] [geometry] tra X Y Z"); } + std::string purpose() { return std::string("translate specified primitive or comb instance relative to its current position"); } + int exec(struct ged *, void *, int, const char **); +}; +static cmd_tra edit_tra_cmd; + +int +cmd_tra::exec(struct ged *gedp, void *u_data, int argc, const char **argv) +{ + if (!gedp || !u_data || !argc || !argv) + return BRLCAD_ERROR; + + struct edit_info *einfo = (struct edit_info *)u_data; + if (einfo->dp == RT_DIR_NULL) + return BRLCAD_ERROR; + + argc--; argv++; + + if (argc < 3 || !argv) { + bu_vls_printf(gedp->ged_result_str, "%s\n", usage().c_str()); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + + +// Translate command +class cmd_translate : public ged_subcmd { + public: + std::string usage() { return std::string("edit [options] [geometry] translate X Y Z"); } + std::string purpose() { return std::string("translate specified primitive or comb instance to the specified absolute position"); } + int exec(struct ged *, void *, int, const char **); +}; +static cmd_translate edit_translate_cmd; + +int +cmd_translate::exec(struct ged *gedp, void *u_data, int argc, const char **argv) +{ + if (!gedp || !u_data || !argc || !argv) + return BRLCAD_ERROR; + + struct edit_info *einfo = (struct edit_info *)u_data; + if (einfo->dp == RT_DIR_NULL) + return BRLCAD_ERROR; + + argc--; argv++; + + if (argc < 3 || !argv) { + bu_vls_printf(gedp->ged_result_str, "%s\n", usage().c_str()); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + + +// Scale command +class cmd_scale : public ged_subcmd { + public: + std::string usage() { return std::string("edit [options] [geometry] scale_factor"); } + std::string purpose() { return std::string("scale specified primitive or comb instance by the specified factor (must be greater than 0)"); } + int exec(struct ged *, void *, int, const char **); +}; +static cmd_scale edit_scale_cmd; + +int +cmd_scale::exec(struct ged *gedp, void *u_data, int argc, const char **argv) +{ + if (!gedp || !u_data || !argc || !argv) + return BRLCAD_ERROR; + + struct edit_info *einfo = (struct edit_info *)u_data; + if (einfo->dp == RT_DIR_NULL) + return BRLCAD_ERROR; + + argc--; argv++; + + if (argc < 3 || !argv) { + bu_vls_printf(gedp->ged_result_str, "%s\n", usage().c_str()); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + + +extern "C" int +ged_edit2_core(struct ged *gedp, int argc, const char *argv[]) +{ + int help = 0; + int optend_pos = -1; + std::vector geom_objs; + struct edit_info einfo; + einfo.verbosity = 0; + einfo.dp = RT_DIR_NULL; + + // Clear results buffer + bu_vls_trunc(gedp->ged_result_str, 0); + + // If we don't have a context that allows us to edit, there's no point + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_READ_ONLY(gedp, BRLCAD_ERROR); + + // We know we're the edit command + argc--;argv++; + + // Set up our command map + std::map edit_cmds; + edit_cmds[std::string("rot")] = &edit_rotate_cmd; + edit_cmds[std::string("rotate")] = &edit_rotate_cmd; + edit_cmds[std::string("tra")] = &edit_tra_cmd; + edit_cmds[std::string("translate")] = &edit_translate_cmd; + edit_cmds[std::string("sca")] = &edit_scale_cmd; + edit_cmds[std::string("scale")] = &edit_scale_cmd; + + // See if we have any high level options set + struct bu_opt_desc d[3]; + BU_OPT(d[0], "h", "help", "", NULL, &help, "Print help"); + BU_OPT(d[1], "v", "verbose", "", NULL, &einfo.verbosity, "Verbose output"); + BU_OPT_NULL(d[2]); + + // Set up the edit container and initialize + struct bu_opt_desc *bdesc = (struct bu_opt_desc *)d; + + const char *bargs_help = "[options] subcommand [args]"; + if (!argc) { + _ged_subcmd2_help(gedp, bdesc, edit_cmds, "edit", bargs_help, 0, NULL); + return BRLCAD_OK; + } + + // High level options are only defined prior to the geometry specifier + std::vector gs; + for (int i = 0; i < argc; i++) { + // TODO - de-quote so we can support obj names matching options... + gs = gedp->dbi_state->digest_path(argv[i]); + if (gs.size()) { + optend_pos = i; + break; + } + } + + int acnt = (optend_pos >= 0) ? optend_pos : argc; + + int opt_ret = bu_opt_parse(NULL, acnt, argv, d); + + if (help || opt_ret < 0) { + if (optend_pos >= 0) { + argc = argc - optend_pos; + argv = &argv[optend_pos]; + _ged_subcmd2_help(gedp, bdesc, edit_cmds, "edit", bargs_help, argc, argv); + } else { + _ged_subcmd2_help(gedp, bdesc, edit_cmds, "edit", bargs_help, 0, NULL); + } + return BRLCAD_OK; + } + + // Must have a specifier + if (optend_pos == -1) { + bu_vls_printf(gedp->ged_result_str, ": no valid geometry specifier found, nothing to edit\n"); + _ged_subcmd2_help(gedp, bdesc, edit_cmds, "edit", bargs_help, 0, NULL); + return BRLCAD_ERROR; + } + + // There are some generic commands (rot, tra, etc.) that apply universally + // to all geometry, but the majority of editing operations are specific to + // each individual geometric primitive type. We first decode the specifier, + // to determine what operations we're able to support. + struct directory *dp = gedp->dbi_state->get_hdp(gs[0]); + if (!dp) { + bu_vls_printf(gedp->ged_result_str, ": geometry specifier lookup failed for %s\n", argv[0]); + return BRLCAD_ERROR; + } + + if (gs.size() > 1) { + bu_log("Comb instance specifier - only generic edit operations.\n"); + } else { + // TODO - once we have the object type, ask librt what subcommands and parameters are + // supported for this primitive. We can offer these in addition to the standard + // commands. + } + + // TODO - need to unpack and validate these prior to subcommand processing - this + // will be the same regardless of the specific edit operation, and we'll need + // directory pointers, combs, paths, etc rather than strings for actual editing + // to succeed. No point in having the subcommands all replicate that. + // + // We'll need to give some thought to the interaction between command line object + // specification and selection - the user may want to command line manipulate the + // selected object without writing to disk (say, for example, as a precision part + // of an otherwise interactive GUI editing session) and not expect that edit to + // be immediately written to disk, but if they specify the object on the command + // line explicitly it's possible they want to override the selection, discard any + // uncommitted changes, and instead do the specified command line operation. + // + // My current thought is that if a command line object is explicitly + // specified, and no options are supplied (say, -f to force a clearing of + // the state and write, or -S to indicate an operation on a temporary + // selection corresponding to the specified name in lieu of writing to + // disk) we abort in the case of a specified object and an active selection + // conflicting, with a note about how to proceed. Note that the situation + // is more complex than it might appear, since a primitive may be part of a + // selected comb tree and have implications that aren't immediately obvious + // - we'll have to implement something with the C++ state processing + // powerful enough to detect and report such situations intelligently, as + // well as rebuilding the selection state in the event of a forced edit + // invalidating temporary selection editing objects. + // + // Another option might be for libged to maintain an explicit set of + // temporary edit objects, and have the edit command track in-process + // edits independent of the selection command - that way, a user could + // also manually perform multiple intermediate edits on a specified object + // that isn't selected without being forced to have each step written to + // disk. This is potentially useful in situations like large bot objects + // where writing many copies to disk for multiple edits would be problematic + // without frequent garbage_collect runs on the .g file. The drawing layer + // could then handle such states consistently regardless of selection state - + // perhaps ghosting in the proposed new state unless the selection flag is + // set, and ghosting the saved-to-disk state when selection is active. + // + // For command line, if we do have temporary editing objects, the edit + // command should reject an edit on an object with an intermediate state + // active unless an explicit flag is set to make sure user intent is clear. + // If no flag, error out with message and options. If -i flag, edit the + // intermediate, non-disk temporary state. if -f/-w, apply the operation + // (if any) and then finalize and write the intermediate state to disk. If + // -F, erase the intermediate state and start over with the on-disk state - + // the equivalent to an MGED reset. + if (opt_ret > 0) { + for (int gcnt = 0; gcnt < opt_ret; gcnt++) { + geom_objs.push_back(std::string(argv[gcnt])); + } + } else { + // If nothing is specified, we need at least one selected geometry item or + // we have nothing to work on + std::vector ss = gedp->dbi_state->get_selected_states("default"); + if (ss.size()) { + geom_objs = ss[0]->list_selected_paths(); + } + } + + if (!geom_objs.size()) { + bu_vls_printf(gedp->ged_result_str, "Error: no geometry objects specified or selected\n"); + return BRLCAD_ERROR; + } + + // Jump the processing past any options specified + argc = argc - optend_pos; + argv = &argv[optend_pos]; + + // Execute the subcommand + return edit_cmds[std::string(argv[0])]->exec(gedp, &einfo, argc, argv); +} + + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/edit/ged_edit2.h b/src/libged/edit/ged_edit2.h new file mode 100644 index 00000000000..bb42a18be2c --- /dev/null +++ b/src/libged/edit/ged_edit2.h @@ -0,0 +1,64 @@ +/* G E D _ E D I T 2 . H + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file ged_edit2.h + * + * Private header for libged edit2 cmd. + * + */ + +#ifndef LIBGED_EDIT2_GED_PRIVATE_H +#define LIBGED_EDIT2_GED_PRIVATE_H + +#include "common.h" + +#include +#include +#include +#include + +#include "ged.h" + +__BEGIN_DECLS + +#define HELPFLAG "--print-help" +#define PURPOSEFLAG "--print-purpose" + +struct _ged_edit2_info { + struct ged *gedp = NULL; + int verbosity; + const struct bu_cmdtab *cmds = NULL; + struct bu_opt_desc *gopts = NULL; + std::vector geom_objs; // TODO - probably will pre-digest this at the top level into comb instances and directory pointers, since that should be the same for all commands... +}; + +__END_DECLS + +#endif /* LIBGED_EDIT2_GED_PRIVATE_H */ + +/** @} */ +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libged/erase/erase.c b/src/libged/erase/erase.c index 83c28aedb0f..20d9323bb7f 100644 --- a/src/libged/erase/erase.c +++ b/src/libged/erase/erase.c @@ -51,7 +51,6 @@ ged_erase_core(struct ged *gedp, int argc, const char *argv[]) static const char *usage = "[[-r] | [[-o] -A attribute=value]] [object(s)]"; const char *cmdName = argv[0]; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -122,6 +121,11 @@ ged_erase_core(struct ged *gedp, int argc, const char *argv[]) bu_vls_free(&vls); return BRLCAD_ERROR; } + if (!gedp->dbip) { + bu_vls_printf(gedp->ged_result_str, "Error: -A option requires an open database\n"); + bu_vls_free(&vls); + return BRLCAD_ERROR; + } bu_avs_init(&avs, (argc - last_opt)/2, "ged_erase_core avs"); i = 0; diff --git a/src/libged/erase/erase2.cpp b/src/libged/erase/erase2.cpp index 45ae20f2bcb..68bae8a02f8 100644 --- a/src/libged/erase/erase2.cpp +++ b/src/libged/erase/erase2.cpp @@ -31,302 +31,13 @@ #include #include +#include "bu/opt.h" #include "bu/sort.h" +#include "bv/view_sets.h" +#include "ged/database.h" +#include "ged/view.h" #include "ged/view/state.h" -#define ALPHANUM_IMPL -#include "../alphanum.h" -#include "../ged_private.h" - -#if 0 -static void -print_names(struct bu_ptbl *so, int depth) -{ - if (!so) - return; - for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { - struct bv_scene_group *s = (struct bv_scene_group *)BU_PTBL_GET(so, i) ; - bu_log("%*s%s\n", depth, " ", bu_vls_cstr(&s->s_name)); - print_names(&s->children, depth+2); - } -} -#endif - -void -fp_path_split(std::vector &objs, const char *str) -{ - std::string s(str); - size_t pos = 0; - if (s.c_str()[0] == '/') - s.erase(0, 1); //Remove leading slash - while ((pos = s.find_first_of("/", 0)) != std::string::npos) { - std::string ss = s.substr(0, pos); - objs.push_back(ss); - s.erase(0, pos + 1); - } - objs.push_back(s); -} - -bool -fp_path_top_match(std::vector &top, std::vector &candidate) -{ - for (size_t i = 0; i < top.size(); i++) { - if (i == candidate.size()) - return false; - if (top[i] != candidate[i]) - return false; - } - return true; -} - -// Need to process shallowest to deepest, so we properly split new scene groups -// generated from higher level paths that are in turn split by other deeper -// paths. -struct dfp_cmp { - bool operator() (struct db_full_path *fp, struct db_full_path *o) const { - // First, check length - if (fp->fp_len != o->fp_len) { - return (fp->fp_len < o->fp_len); - } - - // If length is the same, check the dp contents - for (size_t i = 0; i < fp->fp_len; i++) { - if (!BU_STR_EQUAL(fp->fp_names[i]->d_namep, o->fp_names[i]->d_namep)) { - return (bu_strcmp(fp->fp_names[i]->d_namep, o->fp_names[i]->d_namep) < 0); - } - } - return (bu_strcmp(fp->fp_names[fp->fp_len-1]->d_namep, o->fp_names[fp->fp_len-1]->d_namep) < 0); - } -}; - - -struct erase_data { - std::unordered_map *ngrps; - struct db_i *dbip; - struct db_full_path *fp; - struct bview *v; - std::unordered_map *cinst_map; -}; - -extern "C" void -path_add_children_walk_tree(struct db_full_path *path, union tree *tp, - int (*traverse_func) (std::unordered_map *, - struct db_i *, struct db_full_path *, struct db_full_path *, struct bview *), - void *client_data) -{ - struct bu_vls pvls = BU_VLS_INIT_ZERO; - struct bv_scene_group *g = NULL; - struct directory *dp; - struct db_full_path *nfp; - struct erase_data *ed = (struct erase_data *)client_data; - - if (!tp) - return; - - RT_CK_FULL_PATH(path); - RT_CHECK_DBI(ed->dbip); - RT_CK_TREE(tp); - - switch (tp->tr_op) { - case OP_NOT: - case OP_GUARD: - case OP_XNOP: - path_add_children_walk_tree(path, tp->tr_b.tb_left, traverse_func, client_data); - break; - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - path_add_children_walk_tree(path, tp->tr_b.tb_left, traverse_func, client_data); - path_add_children_walk_tree(path, tp->tr_b.tb_right, traverse_func, client_data); - break; - case OP_DB_LEAF: - if (UNLIKELY(ed->dbip->dbi_use_comb_instance_ids && ed->cinst_map)) - (*ed->cinst_map)[std::string(tp->tr_l.tl_name)]++; - if ((dp=db_lookup(ed->dbip, tp->tr_l.tl_name, LOOKUP_QUIET)) == RT_DIR_NULL) - return; - db_add_node_to_full_path(path, dp); - DB_FULL_PATH_SET_CUR_BOOL(path, tp->tr_op); - if (UNLIKELY(ed->dbip->dbi_use_comb_instance_ids && ed->cinst_map)) - DB_FULL_PATH_SET_CUR_COMB_INST(path, (*ed->cinst_map)[std::string(tp->tr_l.tl_name)]-1); - if (db_full_path_match_top(path, ed->fp)) { - if (DB_FULL_PATH_CUR_DIR(path) != DB_FULL_PATH_CUR_DIR(ed->fp)) - (*traverse_func)(ed->ngrps, ed->dbip, path, ed->fp, ed->v); - } else { - g = bv_obj_create(ed->v, BV_DB_OBJS); - BU_GET(g->s_path, struct db_full_path); - db_full_path_init((struct db_full_path *)g->s_path); - db_dup_full_path((struct db_full_path *)g->s_path, path); - db_path_to_vls(&pvls, path); - bu_vls_sprintf(&g->s_name, "%s", bu_vls_cstr(&pvls)); - BU_ALLOC(nfp, struct db_full_path); - db_full_path_init(nfp); - db_dup_full_path(nfp, path); - (*ed->ngrps)[g] = nfp; - } - DB_FULL_PATH_POP(path); - break; - default: - bu_log("path_add_children_walk_tree: unrecognized operator %d\n", tp->tr_op); - bu_bomb("path_add_children_walk_tree: unrecognized operator\n"); - } -} - -/* Return 1 if we did a split, 0 otherwise */ -int -path_add_children( - std::unordered_map *ngrps, - struct db_i *dbip, struct db_full_path *gfp, struct db_full_path *fp, struct bview *v) -{ - if (!gfp || !DB_FULL_PATH_CUR_DIR(gfp) || !dbip) - return 0; - - if (DB_FULL_PATH_CUR_DIR(gfp)->d_minor_type != DB5_MINORTYPE_BRLCAD_COMBINATION) - return 0; - - // Get the list of immediate children from gfp: - struct directory **children = NULL; - struct rt_db_internal in; - struct rt_comb_internal *comb; - if (rt_db_get_internal(&in, DB_FULL_PATH_CUR_DIR(gfp), dbip, NULL, &rt_uniresource) < 0) { - // Invalid comb - return 0; - } - comb = (struct rt_comb_internal *)in.idb_ptr; - - std::unordered_map comb_inst_map; - struct erase_data ed; - ed.ngrps = ngrps; - ed.dbip = dbip; - ed.fp = fp; - ed.v = v; - if (UNLIKELY(dbip->dbi_use_comb_instance_ids)) { - ed.cinst_map = &comb_inst_map; - } else { - ed.cinst_map = NULL; - } - - path_add_children_walk_tree(gfp, comb->tree, path_add_children, (void *)&ed); - - rt_db_free_internal(&in); - bu_free(children, "free children struct directory ptr array"); - - return 1; -} - -// For a given original drawn group and a set of splitting paths, find -// the new groups needed to hold the subset of solids that will still -// be drawn. -void -new_scene_grps(std::set *all, struct db_i *dbip, struct bv_scene_group *cg, std::set &spaths, struct bview *v) -{ - std::set sfp; - std::set::iterator s_it; - - // Turn splitting paths into db_full_paths so we can do depth ordered processing - for (s_it = spaths.begin(); s_it != spaths.end(); s_it++) { - struct db_full_path *fp = NULL; - BU_ALLOC(fp, struct db_full_path); - db_full_path_init(fp); - int ret = db_string_to_path(fp, dbip, s_it->c_str()); - if (ret < 0) { - // Invalid path - db_free_full_path(fp); - continue; - } - sfp.insert(fp); - } - - // Remove the children of cg from it's ptbl for later processing so we - // don't have to special case freeing cg - std::set sobjs; - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - sobjs.insert(s); - } - bu_ptbl_reset(&cg->children); - - // Seed our group set with the top level group - std::unordered_map ngrps; - { - struct db_full_path *gfp = (struct db_full_path *)cg->s_path; - ngrps[cg] = gfp; - } - - - // Now, work our way through sfp. For each sfp path, split everything - // in ngrps that matches it. - std::unordered_map::iterator g_it; - while (sfp.size()) { - struct db_full_path *fp = *sfp.begin(); - sfp.erase(sfp.begin()); - - std::set gclear; - std::unordered_map next_grps; - - for (g_it = ngrps.begin(); g_it != ngrps.end(); g_it++) { - struct bv_scene_group *ng = g_it->first; - struct db_full_path *gfp = g_it->second; - if (db_full_path_match_top(gfp, fp)) { - // Matches. Make new groups based on the children, and - // eliminate the gfp group - if (path_add_children(&next_grps, dbip, gfp, fp, v)) { - gclear.insert(ng); - } - } - } - - // Free up the replaced groups - std::set::iterator gc_it; - for (gc_it = gclear.begin(); gc_it != gclear.end(); gc_it++) { - struct bv_scene_group *ng = *gc_it; - db_free_full_path(ngrps[ng]); - ngrps.erase(ng); - bv_obj_put(ng); - } - - // Populate ngrps for the next round - for (g_it = next_grps.begin(); g_it != next_grps.end(); g_it++) { - ngrps[g_it->first] = g_it->second; - } - - } - - // All paths processed - ngrps should now contain the final set of groups to - // add to the view. Assign the solids - std::set::iterator sg_it; - for (sg_it = sobjs.begin(); sg_it != sobjs.end(); sg_it++) { - struct bv_scene_obj *sobj = *sg_it; - struct draw_update_data_t *ud = (struct draw_update_data_t *)sobj->s_i_data; - // Find the correct group - for (g_it = ngrps.begin(); g_it != ngrps.end(); g_it++) { - struct bv_scene_group *ng = g_it->first; - struct db_full_path *gfp = g_it->second; - if (db_full_path_match_top(gfp, ud->fp)) { - bu_ptbl_ins(&ng->children, (long *)sobj); - break; - } - } - } - - // Put the new groups in the view group set - for (g_it = ngrps.begin(); g_it != ngrps.end(); g_it++) { - struct bv_scene_group *ng = g_it->first; - all->insert(ng); - } - for (g_it = ngrps.begin(); g_it != ngrps.end(); g_it++) { - db_free_full_path(g_it->second); - BU_FREE(g_it->second, struct db_full_path); - } -} - -static int -alphanum_cmp(const void *a, const void *b, void *UNUSED(data)) { - struct bv_scene_group *ga = *(struct bv_scene_group **)a; - struct bv_scene_group *gb = *(struct bv_scene_group **)b; - return alphanum_impl(bu_vls_cstr(&ga->s_name), bu_vls_cstr(&gb->s_name), NULL); -} - /* * Erase objects from the scene. In many ways this is the most complex * operation we need to perform on a displayed set of objects. When subsets of @@ -340,7 +51,6 @@ ged_erase2_core(struct ged *gedp, int argc, const char *argv[]) static const char *usage = "[object(s)]"; const char *cmdName = argv[0]; struct bview *v = gedp->ged_gvp; - struct db_i *dbip = gedp->dbip; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); @@ -355,9 +65,11 @@ ged_erase2_core(struct ged *gedp, int argc, const char *argv[]) * if a specific view has in fact been specified. We do a preliminary * option check to figure this out */ struct bu_vls cvls = BU_VLS_INIT_ZERO; - struct bu_opt_desc vd[2]; + struct bu_opt_desc vd[3]; + int mode = -1; BU_OPT(vd[0], "V", "view", "name", &bu_opt_vls, &cvls, "specify view to draw on"); - BU_OPT_NULL(vd[1]); + BU_OPT(vd[1], "m", "mode", "#", &bu_opt_int, &mode, "erase objects drawn in the specified drawing mode"); + BU_OPT_NULL(vd[2]); int opt_ret = bu_opt_parse(NULL, argc, argv, vd); argc = opt_ret; if (bu_vls_strlen(&cvls)) { @@ -392,154 +104,11 @@ ged_erase2_core(struct ged *gedp, int argc, const char *argv[]) /* skip past cmd */ argc--; argv++; - // Check the supplied paths against the drawn paths. If they are equal or - // if the supplied path contains a drawn path, then we just completely - // eliminate the group. If the supplied path is a subset of a drawn path, - // we're removing only part of the group and have to split the drawn path. - // - // The operation we want to employ here is db_full_path_match_top, but at - // this stage of erase processing we don't know that either the supplied - // or the drawn paths are valid. Anything that is invalid is erased, but - // until it is we can't turn strings into paths reliably. So we use the - // bu_vls_strncmp function, and prepend a "/" character in the case whare a - // user supplies a name without the path prefix. - // - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - std::set all; - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - all.insert(cg); - } - bu_ptbl_reset(sg); - - // Make sure all the paths are unique and well formatted - std::set epaths; - std::set::iterator e_it; - struct bu_vls upath = BU_VLS_INIT_ZERO; - for (int i = 0; i < argc; ++i) { - bu_vls_sprintf(&upath, "%s", argv[i]); - if (argv[i][0] != '/') { - bu_vls_prepend(&upath, "/"); - } - epaths.insert(std::string(bu_vls_cstr(&upath))); - } - - std::set clear; - std::set::iterator c_it; - std::map> split; - std::map>::iterator g_it; - for (e_it = epaths.begin(); e_it != epaths.end(); e_it++) { - bu_vls_sprintf(&upath, "%s", e_it->c_str()); - std::vector u_objs; - fp_path_split(u_objs, bu_vls_cstr(&upath)); - for (c_it = all.begin(); c_it != all.end(); c_it++) { - struct bv_scene_group *cg = *c_it; - std::vector cg_objs; - fp_path_split(cg_objs, bu_vls_cstr(&cg->s_name)); - if (u_objs.size() > cg_objs.size()) { - if (fp_path_top_match(cg_objs, u_objs)) { - // The hard case - upath matches all of sname. We're - // erasing only a part of the drawn group, so we need to - // split it up into new groups. - split[cg].insert(std::string(bu_vls_cstr(&upath))); - - // We may be clearing multiple paths, but only one path per - // input path should end up split, so we can stop checking - // upath now that it's assigned. - break; - } - } else { - if (fp_path_top_match(u_objs, cg_objs)) { - // Easy case. Drawn path (s_name) is equal to or below - // hierarchy of specified upath, so it will be subsumed in - // upath - just clear it. This may happen to multiple - // paths, so we don't stop the check if we find a match. - clear.insert(cg); - } - } - } - } - bu_vls_free(&upath); - - // If any paths ended up in clear, there's no need to split them even if that - // would have been the consequence of another path specifier - for (c_it = clear.begin(); c_it != clear.end(); c_it++) { - split.erase(*c_it); - } - - // Do the straight-up removals - for (c_it = clear.begin(); c_it != clear.end(); c_it++) { - struct bv_scene_group *cg = *c_it; - all.erase(cg); - bv_obj_put(cg); - } - - // Now, the splits. - - // First step - remove the solid children corresponding to the removed - // paths so cg->children contains only the set of solids to be drawn (it - // will at that point be an invalid scene group but will be a suitable - // input for the next stage.) NOTE: we can't use db_full_path routines - // for this, since we want to be able to erase objects with no-longer-valid - // names and the full path routines validate against the .g database. - for (g_it = split.begin(); g_it != split.end(); g_it++) { - struct bv_scene_group *cg = &(*g_it->first); - std::vector cg_objs; - fp_path_split(cg_objs, bu_vls_cstr(&cg->s_name)); - std::set sclear; - std::set::iterator s_it; - std::set::iterator st_it; - for (st_it = g_it->second.begin(); st_it != g_it->second.end(); st_it++) { - bu_vls_sprintf(&upath, "%s", st_it->c_str()); - if (bu_vls_cstr(&upath)[0] != '/') { - bu_vls_prepend(&upath, "/"); - } - // Select the scene objects that contain upath in their hierarchy (i.e. s_name - // is a full subset of upath). These objects are removed. - std::vector u_objs; - fp_path_split(u_objs, bu_vls_cstr(&upath)); - bool match = fp_path_top_match(cg_objs, u_objs); - if (match) { - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - // For the solids in cg, any that are below upath in the hierarchy - // (that is, upath is a full subset of s_name) are being erased. - std::vector s_objs; - fp_path_split(s_objs, bu_vls_cstr(&s->s_name)); - bool smatch = fp_path_top_match(u_objs, s_objs); - if (smatch) - sclear.insert(s); - continue; - } - } - } - for (s_it = sclear.begin(); s_it != sclear.end(); s_it++) { - struct bv_scene_obj *s = *s_it; - bu_ptbl_rm(&cg->children, (long *)s); - bv_obj_put(s); - } - } - - - // Now, generate the new scene groups and assign the still-active solids to them. - for (g_it = split.begin(); g_it != split.end(); g_it++) { - struct bv_scene_group *cg = g_it->first; - std::set &spaths = g_it->second; - all.erase(cg); - new_scene_grps(&all, dbip, cg, spaths, v); - } - - - // Repopulate the sg tbl with the final results - for (c_it = all.begin(); c_it != all.end(); c_it++) { - struct bv_scene_group *ng = *c_it; - bu_ptbl_ins(sg, (long *)ng); - } - - - // Sort - bu_sort(BU_PTBL_BASEADDR(sg), BU_PTBL_LEN(sg), sizeof(struct bv_scene_group *), alphanum_cmp, NULL); + if (!gedp->dbi_state) + return BRLCAD_OK; + BViewState *bvs = gedp->dbi_state->get_view_state(v); + bvs->erase_path(mode, argc, argv); return BRLCAD_OK; } diff --git a/src/libged/eye_pos/eye_pos.c b/src/libged/eye_pos/eye_pos.c index 37122de5f63..8a0528dd2a6 100644 --- a/src/libged/eye_pos/eye_pos.c +++ b/src/libged/eye_pos/eye_pos.c @@ -38,8 +38,8 @@ ged_eye_pos_core(struct ged *gedp, int argc, const char *argv[]) point_t eye_pos; double scan[3]; static const char *usage = "x y z"; + double sval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -48,7 +48,7 @@ ged_eye_pos_core(struct ged *gedp, int argc, const char *argv[]) /* get eye position */ if (argc == 1) { - VSCALE(eye_pos, gedp->ged_gvp->gv_eye_pos, gedp->dbip->dbi_base2local); + VSCALE(eye_pos, gedp->ged_gvp->gv_eye_pos, sval); bn_encode_vect(gedp->ged_result_str, eye_pos, 1); return BRLCAD_OK; } @@ -83,7 +83,7 @@ ged_eye_pos_core(struct ged *gedp, int argc, const char *argv[]) VMOVE(eye_pos, scan); } - VSCALE(gedp->ged_gvp->gv_eye_pos, eye_pos, gedp->dbip->dbi_local2base); + VSCALE(gedp->ged_gvp->gv_eye_pos, eye_pos, sval); /* update perspective matrix */ mike_persp_mat(gedp->ged_gvp->gv_pmat, gedp->ged_gvp->gv_eye_pos); diff --git a/src/libged/facetize/CMakeLists.txt b/src/libged/facetize/CMakeLists.txt index fc8834d5b82..a8943d9b6ac 100644 --- a/src/libged/facetize/CMakeLists.txt +++ b/src/libged/facetize/CMakeLists.txt @@ -7,27 +7,24 @@ set(FACETIZE_INCLUDE_DIRS ) set(FACETIZE_LOCAL_INCLUDE_DIRS) -if(NOT "${IRMB_INCLUDE_DIRS}" EQUAL "") + +if (MANIFOLD_LIBRARIES) set(FACETIZE_LOCAL_INCLUDE_DIRS ${FACETIZE_LOCAL_INCLUDE_DIRS} - ${IRMB_INCLUDE_DIRS} + ${MANIFOLD_INCLUDE_DIRS} ) -endif(NOT "${IRMB_INCLUDE_DIRS}" EQUAL "") - -set(FACETIZE_LIBS libged libbu) - -if (NOT "${IRMB_LIBRARIES}" EQUAL "") - set(FACETIZE_LIBS ${FACETIZE_LIBS} ${IRMB_LIBRARIES}) -endif (NOT "${IRMB_LIBRARIES}" EQUAL "") - + add_definitions(-DUSE_MANIFOLD) +endif (MANIFOLD_LIBRARIES) # We want to include 3rd party libraries with -isystem - use # BRLCAD_LIB_INCLUDE_DIRS for that purpose BRLCAD_LIB_INCLUDE_DIRS(facetize FACETIZE_INCLUDE_DIRS FACETIZE_LOCAL_INCLUDE_DIRS) +set(FACETIZE_LIBS libged libbu ${MANIFOLD_LIBRARIES}) + add_definitions(-DGED_PLUGIN) ged_plugin_library(ged-facetize SHARED facetize.cpp facetize_log.c) target_link_libraries(ged-facetize ${FACETIZE_LIBS}) -set_property(TARGET ged-facetize APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) +set_property(TARGET ged-facetize APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H MANIFOLD_DLL_IMPORTS) VALIDATE_STYLE(ged-facetize facetize.cpp) PLUGIN_SETUP(ged-facetize ged) diff --git a/src/libged/facetize/facetize.cpp b/src/libged/facetize/facetize.cpp index b55859797d6..7b0ff8983b6 100644 --- a/src/libged/facetize/facetize.cpp +++ b/src/libged/facetize/facetize.cpp @@ -31,10 +31,11 @@ #include -#ifdef USE_IRMB -#include "irmb/irmb.h" +#ifdef USE_MANIFOLD +#include "manifold/manifold.h" #endif +#include "bu/app.h" #include "bu/env.h" #include "bu/exit.h" #include "bu/hook.h" @@ -47,6 +48,7 @@ #include "brep/cdt.h" #include "rt/geom.h" #include "rt/op.h" +#include "rt/conv.h" #include "rt/search.h" #include "raytrace.h" #include "analyze.h" @@ -60,7 +62,7 @@ #define FACETIZE_NMGBOOL 0x1 #define FACETIZE_SPSR 0x2 #define FACETIZE_CONTINUATION 0x4 -#define FACETIZE_IRMB 0x8 +#define FACETIZE_MANIFOLD 0x8 #define FACETIZE_SUCCESS 0 #define FACETIZE_FAILURE 1 @@ -137,11 +139,11 @@ _ged_facetize_attr(int method) static const char *nmg_flag = "facetize:NMG"; static const char *continuation_flag = "facetize:CM"; static const char *spsr_flag = "facetize:SPSR"; - static const char *irmb_flag = "facetize:IRMB"; + static const char *manifold_flag = "facetize:MANIFOLD"; if (method == FACETIZE_NMGBOOL) return nmg_flag; if (method == FACETIZE_CONTINUATION) return continuation_flag; if (method == FACETIZE_SPSR) return spsr_flag; - if (method == FACETIZE_IRMB) return irmb_flag; + if (method == FACETIZE_MANIFOLD) return manifold_flag; return NULL; } @@ -213,8 +215,8 @@ struct _ged_facetize_opts * _ged_facetize_opts_create() BU_GET(o->nmg_comb, struct bu_vls); bu_vls_init(o->nmg_comb); - BU_GET(o->irmb_comb, struct bu_vls); - bu_vls_init(o->irmb_comb); + BU_GET(o->manifold_comb, struct bu_vls); + bu_vls_init(o->manifold_comb); BU_GET(o->continuation_comb, struct bu_vls); bu_vls_init(o->continuation_comb); @@ -255,8 +257,8 @@ void _ged_facetize_opts_destroy(struct _ged_facetize_opts *o) bu_vls_free(o->nmg_comb); BU_PUT(o->nmg_comb, struct bu_vls); - bu_vls_free(o->irmb_comb); - BU_PUT(o->irmb_comb, struct bu_vls); + bu_vls_free(o->manifold_comb); + BU_PUT(o->manifold_comb, struct bu_vls); bu_vls_free(o->continuation_comb); BU_PUT(o->continuation_comb, struct bu_vls); @@ -566,7 +568,7 @@ _try_nmg_facetize(struct ged *gedp, int argc, const char **argv, int nmg_use_tnu facetize_region_end, nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : - nmg_booltree_leaf_tess, + rt_booltree_leaf_tess, (void *)&facetize_tree ); } else { @@ -1504,242 +1506,467 @@ _ged_nmg_obj(struct ged *gedp, int argc, const char **argv, const char *newname, return ret; } -#ifndef USE_IRMB -long - bool_meshes( - double **UNUSED(o_coords), int *UNUSED(o_clen), unsigned int **UNUSED(o_tris), int *UNUSED(o_tricnt), - int UNUSED(b_op), - double *UNUSED(a_coords), int UNUSED(a_clen), unsigned int *UNUSED(a_tris), int UNUSED(a_tricnt), - double *UNUSED(b_coords), int UNUSED(b_clen), unsigned int *UNUSED(b_tris), int UNUSED(b_tricnt) - ) - { - return -1; - } -#endif - -struct irmb_mesh { +struct manifold_mesh { int num_vertices; int num_faces; fastf_t *vertices; unsigned int *faces; }; +static +struct manifold_mesh * +bot_to_mmesh(struct rt_bot_internal *bot) +{ + struct manifold_mesh *omesh = NULL; + BU_GET(omesh, struct manifold_mesh); + omesh->num_vertices = bot->num_vertices; + omesh->num_faces = bot->num_faces; + omesh->faces = (unsigned int *)bu_calloc(bot->num_faces * 3, sizeof(unsigned int), "faces array"); + for (size_t i = 0; i < bot->num_faces * 3; i++) { + omesh->faces[i] = bot->faces[i]; + } + omesh->vertices = (fastf_t *)bu_calloc(bot->num_vertices * 3, sizeof(fastf_t), "vert array"); + for (size_t i = 0; i < bot->num_vertices * 3; i++) { + omesh->vertices[i] = bot->vertices[i]; + } + return omesh; +} + +#ifdef USE_MANIFOLD +// TODO - need to replace this with logic that uses Manifold's +// upstream examples to write out .glb files in the failure +// case. See, for example, +// +// https://github.com/elalish/manifold/pull/581#pullrequestreview-1702123678 +// https://github.com/elalish/manifold/blob/master/test/samples_test.cpp#L258-L269 + +/* Byte swaps a four byte value */ static void -irmb_subprocess(struct irmb_mesh **mesh, union tree *tp, struct db_i *dbip, int op, int *depth, int max_depth, - void (*traverse_func) (struct irmb_mesh **, struct directory *, struct db_i *, int, int *, int)) +lswap(unsigned int *v) { - struct directory *dp; - if (!tp) return; - RT_CHECK_DBI(dbip); - RT_CK_TREE(tp); - (*depth)++; - if (*depth > max_depth) { - (*depth)--; - return; - } - switch (tp->tr_op) { - case OP_NOT: - case OP_GUARD: - case OP_XNOP: - irmb_subprocess(mesh, tp->tr_b.tb_left, dbip, OP_UNION, depth, max_depth, traverse_func); - break; - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - irmb_subprocess(mesh, tp->tr_b.tb_left, dbip, OP_UNION, depth, max_depth, traverse_func); - irmb_subprocess(mesh, tp->tr_b.tb_right, dbip, tp->tr_op, depth, max_depth, traverse_func); - break; - case OP_DB_LEAF: - if ((dp=db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_QUIET)) == RT_DIR_NULL) { - (*depth)--; - return; - } else { - if (!(dp->d_flags & RT_DIR_HIDDEN)) { - traverse_func(mesh, dp, dbip, op, depth, max_depth); - } - (*depth)--; - break; - } + unsigned int r; - default: - bu_log("db_functree_subtree: unrecognized operator %d\n", tp->tr_op); - bu_bomb("db_functree_subtree: unrecognized operator\n"); - } - return; + r =*v; + *v = ((r & 0xff) << 24) | ((r & 0xff00) << 8) | ((r & 0xff0000) >> 8) + | ((r & 0xff000000) >> 24); } static void -irmb_process(struct irmb_mesh **mesh, struct directory *dp, struct db_i *dbip, int op, int *depth, int max_depth) +tris_to_stl(const char *name, double *vertices, unsigned int *faces, int tricnt) { - long irmb_ret = 0; - struct irmb_mesh *omesh = NULL; - struct irmb_mesh *bmesh = NULL; - if (!dp || !dbip) + char output_file[MAXPATHLEN]; + struct bu_vls fname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&fname, "%s.stl", name); + bu_dir(output_file, MAXPATHLEN, BU_DIR_CURR, bu_vls_cstr(&fname), NULL); + bu_vls_free(&fname); + int fd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (fd < 0) return; - struct rt_db_internal in; - if (rt_db_get_internal(&in, dp, dbip, NULL, &rt_uniresource) < 0) - return; - struct rt_db_internal *ip = ∈ + char buf[81]; /* need exactly 80 chars for header */ + memset(buf, 0, sizeof(buf)); + snprintf(buf, 80, "Manifold left input %s", name); + if (write(fd, &buf, 80) < 0) + perror("stl write failure\n"); + + /* Write out number of triangles */ + unsigned char tot_buffer[4]; + *(uint32_t *)tot_buffer = htonl((unsigned long)tricnt); + lswap((unsigned int *)tot_buffer); + if (write(fd, tot_buffer, 4) < 0) + perror("stl write failure\n"); + + /* Write out the vertex data for each triangle */ + point_t A, B, C; + vect_t BmA, CmA, norm; + unsigned long vi; + for (int i = 0; i < tricnt; i++) { + float flts[12]; + float *flt_ptr; + unsigned char vert_buffer[50]; + + vi = 3*faces[3*i]; + VSET(A, vertices[vi], vertices[vi+1], vertices[vi+2]); + vi = 3*faces[3*i+1]; + VSET(B, vertices[vi], vertices[vi+1], vertices[vi+2]); + vi = 3*faces[3*i+2]; + VSET(C, vertices[vi], vertices[vi+1], vertices[vi+2]); + + VSUB2(BmA, B, A); + VSUB2(CmA, C, A); + //if (bot->orientation != RT_BOT_CW) { + //VCROSS(norm, BmA, CmA); + VCROSS(norm, CmA, BmA); + VUNITIZE(norm); + + memset(vert_buffer, 0, sizeof(vert_buffer)); + + flt_ptr = flts; + VMOVE(flt_ptr, norm); + flt_ptr += 3; + VMOVE(flt_ptr, A); + flt_ptr += 3; + VMOVE(flt_ptr, B); + flt_ptr += 3; + VMOVE(flt_ptr, C); + + bu_cv_htonf(vert_buffer, (const unsigned char *)flts, 12); + for (int j = 0; j < 12; j++) { + lswap((unsigned int *)&vert_buffer[j*4]); + } + if (write(fd, vert_buffer, 50) < 0) + perror("stl write failure\n"); + } + + close(fd); +} +#endif + +#ifndef USE_MANIFOLD +long +bool_meshes( + double **UNUSED(o_coords), int *UNUSED(o_ccnt), unsigned int **UNUSED(o_tris), int *UNUSED(o_tricnt), + int UNUSED(b_op), + double *UNUSED(a_coords), int UNUSED(a_ccnt), unsigned int *UNUSED(a_tris), int UNUSED(a_tricnt), + double *UNUSED(b_coords), int UNUSED(b_ccnt), unsigned int *UNUSED(b_tris), int UNUSED(b_tricnt), + const char *UNUSED(lname), const char *UNUSED(rname)) +{ + return -1; +} +#else +long +bool_meshes( + double **o_coords, int *o_ccnt, unsigned int **o_tris, int *o_tricnt, + manifold::OpType b_op, + double *a_coords, int a_ccnt, unsigned int *a_tris, int a_tricnt, + double *b_coords, int b_ccnt, unsigned int *b_tris, int b_tricnt, + const char *lname, const char *rname) +{ + if (!o_coords || !o_ccnt || !o_tris || !o_tricnt) + return -1; + + manifold::Mesh a_mesh; + for (int i = 0; i < a_ccnt; i++) + a_mesh.vertPos.push_back(glm::vec3(a_coords[3*i], a_coords[3*i+1], a_coords[3*i+2])); + for (int i = 0; i < a_tricnt; i++) + a_mesh.triVerts.push_back(glm::vec3(a_tris[3*i], a_tris[3*i+1], a_tris[3*i+2])); + manifold::Mesh b_mesh; + for (int i = 0; i < b_ccnt; i++) + b_mesh.vertPos.push_back(glm::vec3(b_coords[3*i], b_coords[3*i+1], b_coords[3*i+2])); + for (int i = 0; i < b_tricnt; i++) + b_mesh.triVerts.push_back(glm::vec3(b_tris[3*i], b_tris[3*i+1], b_tris[3*i+2])); + + manifold::Manifold a_manifold(a_mesh); + if (a_manifold.Status() != manifold::Manifold::Error::NoError) { + bu_log("Error - a invalid\n"); + return -1; + } + manifold::Manifold b_manifold(b_mesh); + if (b_manifold.Status() != manifold::Manifold::Error::NoError) { + bu_log("Error - b invalid\n"); + return -1; + } + + manifold::Manifold result; + try { + result = a_manifold.Boolean(b_manifold, b_op); + if (result.Status() != manifold::Manifold::Error::NoError) { + bu_log("Error - bool result invalid\n"); + return -1; + } + } catch (...) { + bu_log("Manifold boolean library threw failure\n"); + const char *evar = getenv("GED_MANIFOLD_DEBUG"); + // write out the failing inputs to files to aid in debugging + if (evar && strlen(evar)) { + tris_to_stl(lname, a_coords, a_tris, a_tricnt); + tris_to_stl(rname, b_coords, b_tris, b_tricnt); + bu_exit(EXIT_FAILURE, "Exiting to avoid overwriting debug outputs from Manifold boolean failure."); + } + return -1; + } + manifold::Mesh rmesh = result.GetMesh(); + + (*o_coords) = (double *)calloc(rmesh.vertPos.size()*3, sizeof(double)); + (*o_tris) = (unsigned int *)calloc(rmesh.triVerts.size()*3, sizeof(unsigned int)); + for (size_t i = 0; i < rmesh.vertPos.size(); i++) { + (*o_coords)[3*i] = rmesh.vertPos[i].x; + (*o_coords)[3*i+1] = rmesh.vertPos[i].y; + (*o_coords)[3*i+2] = rmesh.vertPos[i].z; + } + for (size_t i = 0; i < rmesh.triVerts.size(); i++) { + (*o_tris)[3*i] = rmesh.triVerts[i].x; + (*o_tris)[3*i+1] = rmesh.triVerts[i].y; + (*o_tris)[3*i+2] = rmesh.triVerts[i].z; + } + *o_ccnt = (int)rmesh.vertPos.size(); + *o_tricnt = (int)rmesh.triVerts.size(); + + + int not_solid = bg_trimesh_solid2(*o_ccnt, *o_tricnt, (fastf_t *)*o_coords, (int *)*o_tris, NULL); + if (not_solid) { + *o_ccnt = 0; + *o_tricnt = 0; + bu_free(*o_coords, "coords"); + *o_coords = NULL; + bu_free(*o_tris, "tris"); + *o_tris = NULL; + bu_log("Error: Manifold boolean succeeded, but result reports as non-solid: failure."); + return -1; + } + + return rmesh.triVerts.size(); +} +#endif - bu_log("%d:%s\n", op, dp->d_namep); - // Translate op for IRMB - int irmb_op = 0; +static int +_manifold_do_bool( + union tree *tp, union tree *tl, union tree *tr, + int op, struct bu_list *UNUSED(vlfree), const struct bn_tol *tol, void *UNUSED(data)) +{ +#ifdef USE_MANIFOLD + struct rt_bot_internal *lbot = NULL; + struct rt_bot_internal *rbot = NULL; + struct manifold_mesh *lmesh = NULL; + struct manifold_mesh *rmesh = NULL; + struct manifold_mesh *omesh = NULL; + //struct _ged_facetize_opts *o = (struct _ged_facetize_opts *)data; + + // Translate op for MANIFOLD + manifold::OpType manifold_op = manifold::OpType::Add; switch (op) { case OP_UNION: - irmb_op = 0; + manifold_op = manifold::OpType::Add; break; case OP_INTERSECT: - irmb_op = 2; + manifold_op = manifold::OpType::Intersect; break; case OP_SUBTRACT: - irmb_op = 1; + manifold_op = manifold::OpType::Subtract; break; default: - irmb_op = 0; + manifold_op = manifold::OpType::Add; }; - // If we have a non-comb obj, get the NMG tessellation and do the operation - if (!(dp->d_flags & RT_DIR_COMB)) { + // We're either working with the results of CSG NMG tessellations, + // or we have prior manifold_mesh results - figure out which. + // If it's the NMG results, we need to make manifold_meshes for + // processing. + if (tl->tr_d.td_r) { + if (!BU_SETJUMP) { + /* try */ + lbot = (struct rt_bot_internal *)nmg_mdl_to_bot(tl->tr_d.td_r->m_p, &RTG.rtg_vlfree, tol); + } else { + /* catch */ + BU_UNSETJUMP; + lbot = NULL; + lmesh = NULL; + } BU_UNSETJUMP; - // 1. Make new triangle mesh with NMG of dp - if (!ip->idb_meth || !ip->idb_meth->ft_tessellate) { - bu_log("IRMB_ERROR(%s): NMG object tessellation support not available\n", dp->d_namep); - rt_db_free_internal(ip); - return; + if (lbot) { + lmesh = bot_to_mmesh(lbot); + // We created this locally if it wasn't originally a BoT - clean up + if (lbot->vertices) + bu_free(lbot->vertices, "verts"); + if (lbot->faces) + bu_free(lbot->faces, "faces"); + BU_FREE(lbot, struct rt_bot_internal); + lbot = NULL; } + } else { + lmesh = (struct manifold_mesh *)tl->tr_d.td_d; + } + if (tr->tr_d.td_r) { - // We need triangles. If we already have a bot we're good - otherwise, - // try to tessellate. - struct rt_bot_internal *bot = NULL; - if (ip->idb_type == ID_BOT) { - bot = (struct rt_bot_internal *)ip->idb_ptr; + if (!BU_SETJUMP) { + /* try */ + rbot = (struct rt_bot_internal *)nmg_mdl_to_bot(tr->tr_d.td_r->m_p, &RTG.rtg_vlfree, tol); } else { - struct rt_wdb *wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DEFAULT); - struct bn_tol *ntol = &(wdbp->wdb_tol); - struct bg_tess_tol *nttol = &(wdbp->wdb_ttol); - struct model *m = nmg_mm(); - struct nmgregion *r1 = (struct nmgregion *)NULL; - if (ip->idb_meth->ft_tessellate(&r1, m, ip, nttol, ntol) < 0) { - bu_log("ERROR(%s): tessellation failure\n", dp->d_namep); - rt_db_free_internal(ip); - return; - } - // NMG doesn't give us a bot by default - post-process it to get one. + /* catch */ + BU_UNSETJUMP; + rbot = NULL; + rmesh = NULL; + } BU_UNSETJUMP; + + if (rbot) { + rmesh = bot_to_mmesh(rbot); + // We created this locally if it wasn't originally a BoT - clean up + if (rbot->vertices) + bu_free(rbot->vertices, "verts"); + if (rbot->faces) + bu_free(rbot->faces, "faces"); + BU_FREE(rbot, struct rt_bot_internal); + rbot = NULL; + } + + } else { + rmesh = (struct manifold_mesh *)tr->tr_d.td_d; + } + int failed = 0; + if (!lmesh || !rmesh) { + failed = 1; + } else { + BU_GET(omesh, struct manifold_mesh); + int mret = bool_meshes( + (double **)&omesh->vertices, &omesh->num_vertices, &omesh->faces, &omesh->num_faces, + manifold_op, + (double *)lmesh->vertices, lmesh->num_vertices, lmesh->faces, lmesh->num_faces, + (double *)rmesh->vertices, rmesh->num_vertices, rmesh->faces, rmesh->num_faces, + tl->tr_d.td_name, + tr->tr_d.td_name + ); + + failed = (mret < 0) ? 1 : 0; + + if (failed) { + // TODO - we should be able to try an NMG boolean op here as a + // fallback, but we may need to translate one or both of the inputs + // into NMG + bu_free(omesh->faces, "faces"); + bu_free(omesh->vertices, "vertices"); + BU_PUT(omesh, struct manifold_mesh); + omesh = NULL; + } + } + + // Memory cleanup + if (tl->tr_d.td_r) { + nmg_km(tl->tr_d.td_r->m_p); + tl->tr_d.td_r = NULL; + } + if (tr->tr_d.td_r) { + nmg_km(tr->tr_d.td_r->m_p); + tr->tr_d.td_r = NULL; + } + if (tl->tr_d.td_d) { + struct manifold_mesh *km = (struct manifold_mesh *)tl->tr_d.td_d; + bu_free(km->faces, "faces"); + bu_free(km->vertices, "vertices"); + BU_PUT(km, struct manifold_mesh); + tl->tr_d.td_d = NULL; + } + if (tr->tr_d.td_d) { + struct manifold_mesh *km = (struct manifold_mesh *)tr->tr_d.td_d; + bu_free(km->faces, "faces"); + bu_free(km->vertices, "vertices"); + BU_PUT(km, struct manifold_mesh); + tr->tr_d.td_d = NULL; + } + + tp->tr_d.td_r = NULL; + + if (failed) { + tp->tr_d.td_d = NULL; + return -1; + } + + tp->tr_op = OP_TESS; + tp->tr_d.td_d = omesh; + return 0; +#else + if (!tp || !tl || !tr || op < 0 || !tol) + return -1; +#endif +} + +static struct manifold_mesh * +_try_manifold_facetize(struct ged *gedp, int argc, const char **argv, struct _ged_facetize_opts *o) +{ + int i; + union tree *ftree = NULL; + struct manifold_mesh *omesh = NULL; + + _ged_facetize_log_nmg(o); + + struct db_tree_state init_state; + struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + db_init_db_tree_state(&init_state, gedp->dbip, wdbp->wdb_resp); + /* Establish tolerances */ + init_state.ts_ttol = &wdbp->wdb_ttol; + init_state.ts_tol = &wdbp->wdb_tol; + init_state.ts_m = NULL; + union tree *facetize_tree = (union tree *)0; + + if (!BU_SETJUMP) { + /* try */ + i = db_walk_tree(gedp->dbip, argc, (const char **)argv, + 1, + &init_state, + 0, /* take all regions */ + facetize_region_end, + rt_booltree_leaf_tess, + (void *)&facetize_tree + ); + } else { + /* catch */ + BU_UNSETJUMP; + _ged_facetize_log_default(o); + return NULL; + } BU_UNSETJUMP; + + if (i < 0) { + /* Destroy NMG */ + _ged_facetize_log_default(o); + return NULL; + } + + if (facetize_tree) { + ftree = rt_booltree_evaluate(facetize_tree, &RTG.rtg_vlfree, &wdbp->wdb_tol, &rt_uniresource, &_manifold_do_bool, 0, (void *)o); + if (!ftree) { + _ged_facetize_log_default(o); + return NULL; + } + if (ftree->tr_d.td_d) { + omesh = (struct manifold_mesh *)ftree->tr_d.td_d; + _ged_facetize_log_default(o); + return omesh; + } else if (ftree->tr_d.td_r) { + // If we had only one NMG mesh, there was no bool + // operation - we need to set up a mesh + struct rt_bot_internal *bot = NULL; if (!BU_SETJUMP) { /* try */ - bot = (struct rt_bot_internal *)nmg_mdl_to_bot(m, &RTG.rtg_vlfree, ntol); + bot = (struct rt_bot_internal *)nmg_mdl_to_bot(ftree->tr_d.td_r->m_p, &RTG.rtg_vlfree, &wdbp->wdb_tol); } else { /* catch */ BU_UNSETJUMP; - bu_log("WARNING: triangulation failed!!!\n"); - rt_db_free_internal(ip); - return; + bot = NULL; + omesh = NULL; } BU_UNSETJUMP; - } - /* Sanity */ - if (!bot) { - rt_db_free_internal(ip); - return; - } - if (!bot->num_faces || !bot->num_vertices) { - if (ip->idb_type != ID_BOT) { - if (bot->vertices) - bu_free(bot->vertices, "verts"); - if (bot->faces) - bu_free(bot->faces, "faces"); - BU_FREE(bot, struct rt_bot_internal); - } - rt_db_free_internal(ip); - return; - } - BU_GET(bmesh, struct irmb_mesh); - bmesh->vertices = bot->vertices; - bmesh->num_vertices = bot->num_vertices; - bmesh->num_faces = bot->num_faces; - bmesh->faces = (unsigned int *)bu_calloc(bot->num_faces * 3, sizeof(unsigned int), "faces array"); - for (size_t i = 0; i < bot->num_faces * 3; i++) { - bmesh->faces[i] = bot->faces[i]; - } - bmesh->vertices = (fastf_t *)bu_calloc(bot->num_vertices * 3, sizeof(fastf_t), "vert array"); - for (size_t i = 0; i < bot->num_vertices * 3; i++) { - bmesh->vertices[i] = bot->vertices[i]; - } - // 2. Do the op between *mesh and the NMG output from dp - if (!(*mesh)->num_faces) { - if ((*mesh)->vertices) - bu_free((*mesh)->vertices, "verts"); - if ((*mesh)->faces) - bu_free((*mesh)->faces, "faces"); - BU_FREE(*mesh, struct irmb_mesh); - *mesh = bmesh; - } else { - BU_GET(omesh, struct irmb_mesh); - irmb_ret = bool_meshes( - (double **)&omesh->vertices, &omesh->num_vertices, &omesh->faces, &omesh->num_faces, - irmb_op, - (double *)(*mesh)->vertices, (*mesh)->num_vertices*3, (*mesh)->faces, (*mesh)->num_faces, - (double *)bmesh->vertices, bmesh->num_vertices*3, bmesh->faces, bmesh->num_faces - ); - bu_log("irmb: %ld\n", irmb_ret); - bu_free(bmesh->faces, "faces"); - bu_free(bmesh->vertices, "vertices"); - BU_PUT(bmesh, struct irmb_mesh); - - if (ip->idb_type != ID_BOT) { + + if (bot) { + omesh = bot_to_mmesh(bot); // We created this locally if it wasn't originally a BoT - clean up if (bot->vertices) bu_free(bot->vertices, "verts"); if (bot->faces) bu_free(bot->faces, "faces"); BU_FREE(bot, struct rt_bot_internal); + bot = NULL; } - // Free the previous state - if ((*mesh)->vertices) - bu_free((*mesh)->vertices, "verts"); - if ((*mesh)->faces) - bu_free((*mesh)->faces, "faces"); - BU_FREE(*mesh, struct irmb_mesh); - // Assign the new state as "current" - *mesh = omesh; - } - rt_db_free_internal(ip); - return; + } } - struct rt_comb_internal *comb = (struct rt_comb_internal *)ip->idb_ptr; - irmb_subprocess(mesh, comb->tree, dbip, OP_UNION, depth, max_depth, irmb_process); - rt_db_free_internal(ip); + _ged_facetize_log_default(o); + return omesh; } -// For IRMB, we do a tree walk. Each solid is individually triangulated, and +// For MANIFOLD, we do a tree walk. Each solid is individually triangulated, and // then the boolean op is applied with the result of the mesh generated thus // far. This is conceptually similar to how NMG does its processing, with the // main difference being that the external code is actually doing the mesh // boolean processing rather than libnmg. int -_ged_irmb_obj(struct ged *gedp, const char *objname, const char *newname, struct _ged_facetize_opts *opts) +_ged_manifold_obj(struct ged *gedp, int argc, const char **argv, const char *newname, struct _ged_facetize_opts *opts) { - int depth = 0; - struct irmb_mesh *mesh = NULL; - struct directory *dp = RT_DIR_NULL; int ret = BRLCAD_ERROR; - if (!gedp || !objname || !newname || !opts) - goto ged_irmb_obj_memfree; - - dp = db_lookup(gedp->dbip, objname, LOOKUP_QUIET); - if (!dp) - goto ged_irmb_obj_memfree; - - // Conceptually, we start off by unioning the "root" object of the - // tree with the initial world mesh, which is the empty mesh. - BU_GET(mesh, struct irmb_mesh); - mesh->num_vertices = 0; - mesh->num_faces = 0; - irmb_process(&mesh, dp, gedp->dbip, OP_UNION, &depth, 100); + struct manifold_mesh *mesh = NULL; + if (!gedp || !argc || !argv || !opts) + goto ged_manifold_obj_memfree; + mesh = _try_manifold_facetize(gedp, argc, argv, opts); + if (mesh && mesh->num_faces > 0) { struct rt_bot_internal *bot; BU_GET(bot, struct rt_bot_internal); @@ -1766,19 +1993,19 @@ _ged_irmb_obj(struct ged *gedp, const char *objname, const char *newname, struct ret = _write_bot(gedp, bot, newname, opts); } else { - goto ged_irmb_obj_memfree; + goto ged_manifold_obj_memfree; } -ged_irmb_obj_memfree: +ged_manifold_obj_memfree: if (mesh) { if (mesh->vertices) bu_free(mesh->vertices, "verts"); if (mesh->faces) bu_free(mesh->faces, "faces"); - BU_FREE(mesh, struct irmb_mesh); + BU_FREE(mesh, struct manifold_mesh); } if (!opts->quiet && ret != BRLCAD_OK) { - bu_log("IRMB: failed to generate %s\n", newname); + bu_log("MANIFOLD: failed to generate %s\n", newname); } return ret; @@ -1844,43 +2071,43 @@ _ged_facetize_objlist(struct ged *gedp, int argc, const char **argv, struct _ged while (!done_trying) { - if (flags & FACETIZE_NMGBOOL) { - opts->nmg_log_print_header = 1; + if (flags & FACETIZE_MANIFOLD) { if (argc == 1) { - bu_vls_sprintf(opts->nmg_log_header, "NMG: tessellating %s...\n", argv[0]); + bu_vls_sprintf(opts->nmg_log_header, "MANIFOLD: tessellating %s...\n", argv[0]); } else { - bu_vls_sprintf(opts->nmg_log_header, "NMG: tessellating %d objects with tolerances a=%g, r=%g, n=%g\n", argc, tol->abs, tol->rel, tol->norm); + bu_vls_sprintf(opts->nmg_log_header, "MANIFOLD: tessellating %d objects with tolerances a=%g, r=%g, n=%g\n", argc, tol->abs, tol->rel, tol->norm); } /* Let the user know what's going on, unless output is suppressed */ if (!opts->quiet) { bu_log("%s", bu_vls_addr(opts->nmg_log_header)); } - if (_ged_nmg_obj(gedp, argc, argv, newname, opts) == BRLCAD_OK) { + if (_ged_manifold_obj(gedp, argc, argv, newname, opts) == BRLCAD_OK) { ret = BRLCAD_OK; break; } else { - flags = flags & ~(FACETIZE_NMGBOOL); + flags = flags & ~(FACETIZE_MANIFOLD); continue; } } - if (flags & FACETIZE_IRMB) { + if (flags & FACETIZE_NMGBOOL) { + opts->nmg_log_print_header = 1; if (argc == 1) { - bu_vls_sprintf(opts->nmg_log_header, "IRMB: tessellating %s...\n", argv[0]); + bu_vls_sprintf(opts->nmg_log_header, "NMG: tessellating %s...\n", argv[0]); } else { - bu_vls_sprintf(opts->nmg_log_header, "IRMB: tessellating %d objects with tolerances a=%g, r=%g, n=%g\n", argc, tol->abs, tol->rel, tol->norm); + bu_vls_sprintf(opts->nmg_log_header, "NMG: tessellating %d objects with tolerances a=%g, r=%g, n=%g\n", argc, tol->abs, tol->rel, tol->norm); } /* Let the user know what's going on, unless output is suppressed */ if (!opts->quiet) { bu_log("%s", bu_vls_addr(opts->nmg_log_header)); } - if (_ged_irmb_obj(gedp, argv[0], newname, opts) == BRLCAD_OK) { + if (_ged_nmg_obj(gedp, argc, argv, newname, opts) == BRLCAD_OK) { ret = BRLCAD_OK; break; } else { - flags = flags & ~(FACETIZE_IRMB); + flags = flags & ~(FACETIZE_NMGBOOL); continue; } } @@ -2009,9 +2236,9 @@ _ged_methodcomb_add(struct ged *gedp, struct _ged_facetize_opts *opts, const cha struct bu_vls method_cname = BU_VLS_INIT_ZERO; if (!objname || method == FACETIZE_NULL) return BRLCAD_ERROR; - if (method == FACETIZE_IRMB && !bu_vls_strlen(opts->irmb_comb)) { - bu_vls_sprintf(opts->irmb_comb, "%s_IRMB-0", bu_vls_addr(opts->froot)); - bu_vls_incr(opts->irmb_comb, NULL, NULL, &_db_uniq_test, (void *)gedp); + if (method == FACETIZE_MANIFOLD && !bu_vls_strlen(opts->manifold_comb)) { + bu_vls_sprintf(opts->manifold_comb, "%s_MANIFOLD-0", bu_vls_addr(opts->froot)); + bu_vls_incr(opts->manifold_comb, NULL, NULL, &_db_uniq_test, (void *)gedp); } if (method == FACETIZE_NMGBOOL && !bu_vls_strlen(opts->nmg_comb)) { bu_vls_sprintf(opts->nmg_comb, "%s_NMGBOOL-0", bu_vls_addr(opts->froot)); @@ -2036,8 +2263,8 @@ _ged_methodcomb_add(struct ged *gedp, struct _ged_facetize_opts *opts, const cha case FACETIZE_SPSR: bu_vls_sprintf(&method_cname, "%s", bu_vls_addr(opts->spsr_comb)); break; - case FACETIZE_IRMB: - bu_vls_sprintf(&method_cname, "%s", bu_vls_addr(opts->irmb_comb)); + case FACETIZE_MANIFOLD: + bu_vls_sprintf(&method_cname, "%s", bu_vls_addr(opts->manifold_comb)); break; default: bu_vls_free(&method_cname); @@ -2154,23 +2381,23 @@ _ged_facetize_region_obj(struct ged *gedp, const char *oname, const char *sname, return BRLCAD_ERROR; } - if (cmethod == FACETIZE_IRMB) { + if (cmethod == FACETIZE_MANIFOLD) { /* We're staring a new object, so we want to write out the header in the * log file the first time we get an NMG logging event. (Re)set the flag * so the logger knows to do so. */ opts->nmg_log_print_header = 1; - bu_vls_sprintf(opts->nmg_log_header, "IRMB: tessellating %s (%d of %d) with tolerances a=%g, r=%g, n=%g\n", oname, ocnt, max_cnt, opts->tol->abs, opts->tol->rel, opts->tol->norm); + bu_vls_sprintf(opts->nmg_log_header, "MANIFOLD: tessellating %s (%d of %d) with tolerances a=%g, r=%g, n=%g\n", oname, ocnt, max_cnt, opts->tol->abs, opts->tol->rel, opts->tol->norm); /* Let the user know what's going on, unless output is suppressed */ if (!opts->quiet) { bu_log("%s", bu_vls_addr(opts->nmg_log_header)); } - ret = _ged_irmb_obj(gedp, oname, sname, opts); + ret = _ged_manifold_obj(gedp, 1, (const char **)&oname, sname, opts); if (ret != FACETIZE_FAILURE) { - if (_ged_methodcomb_add(gedp, opts, sname, FACETIZE_IRMB) != BRLCAD_OK && opts->verbosity > 1) { + if (_ged_methodcomb_add(gedp, opts, sname, FACETIZE_MANIFOLD) != BRLCAD_OK && opts->verbosity > 1) { bu_log("Error adding %s to methodology combination\n", sname); } } @@ -2341,6 +2568,10 @@ _ged_facetize_regions_resume(struct ged *gedp, int argc, const char **argv, stru bu_ptbl_reset(ar); + if (!cmethod && (methods & FACETIZE_MANIFOLD)) { + cmethod = FACETIZE_MANIFOLD; + methods = methods & ~(FACETIZE_MANIFOLD); + } if (!cmethod && (methods & FACETIZE_NMGBOOL)) { cmethod = FACETIZE_NMGBOOL; @@ -2765,16 +2996,17 @@ _ged_facetize_regions(struct ged *gedp, int argc, const char **argv, struct _ged ssize_t avail_mem = 0; bu_ptbl_reset(ar2); +#ifdef USE_MANIFOLD + if (!cmethod && (methods & FACETIZE_MANIFOLD)) { + cmethod = FACETIZE_MANIFOLD; + methods = methods & ~(FACETIZE_MANIFOLD); + } +#endif + if (!cmethod && (methods & FACETIZE_NMGBOOL)) { cmethod = FACETIZE_NMGBOOL; methods = methods & ~(FACETIZE_NMGBOOL); } -#ifdef USE_IRMB - if (!cmethod && (methods & FACETIZE_IRMB)) { - cmethod = FACETIZE_IRMB; - methods = methods & ~(FACETIZE_IRMB); - } -#endif if (!cmethod && (methods & FACETIZE_CONTINUATION)) { cmethod = FACETIZE_CONTINUATION; @@ -3199,8 +3431,8 @@ ged_facetize_core(struct ged *gedp, int argc, const char *argv[]) BU_OPT(d[17], "", "max-pnts", "#", &bu_opt_int, &(opts->max_pnts), "Maximum number of pnts to use when applying ray sampling methods."); BU_OPT(d[18], "B", "", "", NULL, &nonovlp_brep, "EXPERIMENTAL: non-overlapping facetization to BoT objects of union-only brep comb tree."); BU_OPT(d[19], "t", "threshold", "#", &bu_opt_fastf_t, &(opts->nonovlp_threshold), "EXPERIMENTAL: max ovlp threshold length."); -#ifdef USE_IRMB - BU_OPT(d[20], "", "IRMB", "", NULL, &(opts->irmb), "Use the experimental IRMB boolean evaluation"); +#ifdef USE_MANIFOLD + BU_OPT(d[20], "", "MANIFOLD", "", NULL, &(opts->manifold), "Use the experimental MANIFOLD boolean evaluation"); BU_OPT_NULL(d[21]); #else BU_OPT_NULL(d[20]); @@ -3256,12 +3488,13 @@ ged_facetize_core(struct ged *gedp, int argc, const char *argv[]) } /* Sort out which methods we can try */ - if (!opts->nmgbool && !opts->screened_poisson && !opts->continuation && !opts->irmb) { - /* Default to NMGBOOL and Continuation active */ + if (!opts->nmgbool && !opts->screened_poisson && !opts->continuation && !opts->manifold) { + /* Default to MANIFOLD, NMGBOOL and Continuation active */ + opts->method_flags |= FACETIZE_MANIFOLD; opts->method_flags |= FACETIZE_NMGBOOL; opts->method_flags |= FACETIZE_CONTINUATION; } else { - if (opts->irmb) opts->method_flags |= FACETIZE_IRMB; + if (opts->manifold) opts->method_flags |= FACETIZE_MANIFOLD; if (opts->nmgbool) opts->method_flags |= FACETIZE_NMGBOOL; if (opts->screened_poisson) opts->method_flags |= FACETIZE_SPSR; if (opts->continuation) opts->method_flags |= FACETIZE_CONTINUATION; @@ -3279,7 +3512,7 @@ ged_facetize_core(struct ged *gedp, int argc, const char *argv[]) } /* Check for a couple of non-valid combinations */ - if ((opts->method_flags == FACETIZE_SPSR || opts->method_flags == FACETIZE_CONTINUATION || opts->method_flags == FACETIZE_IRMB) && opts->nmg_use_tnurbs) { + if ((opts->method_flags == FACETIZE_SPSR || opts->method_flags == FACETIZE_CONTINUATION || opts->method_flags == FACETIZE_MANIFOLD) && opts->nmg_use_tnurbs) { bu_vls_printf(gedp->ged_result_str, "Note: Specified reconstruction method(s) do not all support TNURBS output\n"); ret = BRLCAD_ERROR; goto ged_facetize_memfree; diff --git a/src/libged/fb2pix/fb2pix.c b/src/libged/fb2pix/fb2pix.c index 10f1a175da0..c5b09682346 100644 --- a/src/libged/fb2pix/fb2pix.c +++ b/src/libged/fb2pix/fb2pix.c @@ -109,7 +109,6 @@ ged_fb2pix_core(struct ged *gedp, int argc, const char *argv[]) char usage[] = "Usage: fb-pix [-h -i -c] \n\ [-s squaresize] [-w width] [-n height] [file.pix]\n"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); if (!gedp->ged_gvp) { diff --git a/src/libged/fbclear/fbclear.c b/src/libged/fbclear/fbclear.c index 97402af2401..71806b96e63 100644 --- a/src/libged/fbclear/fbclear.c +++ b/src/libged/fbclear/fbclear.c @@ -52,7 +52,6 @@ ged_fbclear_core(struct ged *gedp, int argc, const char *argv[]) int ret; unsigned char clearColor[3] = {0.0, 0.0 ,0.0}; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); if (!gedp->ged_gvp || !gedp->ged_gvp->dmp) { diff --git a/src/libged/garbage_collect/garbage_collect.cpp b/src/libged/garbage_collect/garbage_collect.cpp index 6673bc1c516..b97d43db87a 100644 --- a/src/libged/garbage_collect/garbage_collect.cpp +++ b/src/libged/garbage_collect/garbage_collect.cpp @@ -156,12 +156,10 @@ ged_garbage_collect_core(struct ged *gedp, int argc, const char *argv[]) * will drawing without resize work?) */ ncmd = getenv("GED_TEST_NEW_CMD_FORMS"); if (BU_STR_EQUAL(ncmd, "1")) { - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - if (sg) { - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - who_objs.push_back(std::string(bu_vls_cstr(&cg->s_name))); - } + BViewState *bvs = gedp->dbi_state->get_view_state(gedp->ged_gvp); + std::vector wpaths = bvs->list_drawn_paths(-1, false); + for (size_t i = 0; i < wpaths.size(); i++) { + who_objs.push_back(wpaths[i]); } } else { struct display_list *gdlp; @@ -234,11 +232,10 @@ ged_garbage_collect_core(struct ged *gedp, int argc, const char *argv[]) // If we got this far, we need to close the current database, open the new // one, and verify the data - av[0] = "close"; + av[0] = "closedb"; av[1] = NULL; ged_exec(gedp, 1, (const char **)av); - - av[0] = "open"; + av[0] = "opendb"; av[1] = bu_vls_cstr(&working_file); av[2] = NULL; if (ged_exec(gedp, 2, (const char **)av) != BRLCAD_OK) { @@ -275,14 +272,14 @@ ged_garbage_collect_core(struct ged *gedp, int argc, const char *argv[]) } if (ret == BRLCAD_ERROR) { bu_vls_printf(gedp->ged_result_str, "ERROR: %s has incorrect data! Something is very wrong. Aborting garbage collect, database unchanged\n", bu_vls_cstr(&working_file)); - av[0] = "close"; + av[0] = "closedb"; av[1] = NULL; ged_exec(gedp, 1, (const char **)av); goto gc_cleanup; } // Done verifying - av[0] = "close"; + av[0] = "closedb"; av[1] = NULL; ged_exec(gedp, 1, (const char **)av); @@ -310,13 +307,13 @@ ged_garbage_collect_core(struct ged *gedp, int argc, const char *argv[]) // *Gulp* - here we go. Swap the new file in for the old bu_file_delete(bu_vls_cstr(&fpath)); if (std::rename(bu_vls_cstr(&working_file), bu_vls_cstr(&fpath))) { - bu_vls_printf(gedp->ged_result_str, "ERROR: %s cannot be renamed to %s!\nSomething is very wrong, aborting - user needs to manually restore %s to its original name/location.\n", bu_vls_cstr(&working_file), bu_vls_cstr(&fpath), bu_vls_cstr(&bkup_file)); + bu_vls_printf(gedp->ged_result_str, "ERROR: %s cannot be renamed to %s: %s!\nSomething is very wrong, aborting - user needs to manually restore %s to its original name/location.\n", bu_vls_cstr(&working_file), bu_vls_cstr(&fpath), strerror(errno), bu_vls_cstr(&bkup_file)); ret = BRLCAD_ERROR; goto gc_cleanup; } // Open the renamed, garbage collected file - av[0] = "open"; + av[0] = "opendb"; av[1] = bu_vls_cstr(&fpath); av[2] = NULL; if (ged_exec(gedp, 2, (const char **)av) != BRLCAD_OK) { diff --git a/src/libged/ged.c b/src/libged/ged.c deleted file mode 100644 index edadf56f396..00000000000 --- a/src/libged/ged.c +++ /dev/null @@ -1,487 +0,0 @@ -/* G E D . C - * BRL-CAD - * - * Copyright (c) 2000-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @addtogroup libged */ -/** @{ */ -/** @file libged/ged.c - * - * A quasi-object-oriented database interface. - * - * A database object contains the attributes and methods for - * controlling a BRL-CAD database. - * - * Also include routines to allow libwdb to use librt's import/export - * interface, rather than having to know about the database formats directly. - * - */ -/** @} */ - -#include "common.h" - -#include -#include -#include - - -#include "bu/sort.h" -#include "vmath.h" -#include "bn.h" -#include "rt/geom.h" -#include "raytrace.h" -#include "bv/plot3.h" - -#include "bv/defines.h" - -#include "./ged_private.h" -#include "./qray.h" - -#define FREE_BV_SCENE_OBJ(p, fp) { \ - BU_LIST_APPEND(fp, &((p)->l)); \ - BV_FREE_VLIST(&RTG.rtg_vlfree, &((p)->s_vlist)); } - - -/* TODO: Ew. Globals. Make this go away... */ -struct ged *_ged_current_gedp; -vect_t _ged_eye_model; -mat_t _ged_viewrot; - -/* FIXME: this function should not exist. passing pointers as strings - * indicates a failure in design and lazy coding. - */ -int -ged_decode_dbip(const char *dbip_string, struct db_i **dbipp) -{ - if (sscanf(dbip_string, "%p", (void **)dbipp) != 1) { - return BRLCAD_ERROR; - } - - /* Could core dump */ - RT_CK_DBI(*dbipp); - - return BRLCAD_OK; -} - - -void -ged_close(struct ged *gedp) -{ - if (gedp == GED_NULL) - return; - - if (gedp->dbip) { - db_close(gedp->dbip); - gedp->dbip = NULL; - } - - /* Terminate any ged subprocesses */ - if (gedp != GED_NULL) { - for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_subp); i++) { - struct ged_subprocess *rrp = (struct ged_subprocess *)BU_PTBL_GET(&gedp->ged_subp, i); - if (!rrp->aborted) { - bu_terminate(bu_process_pid(rrp->p)); - rrp->aborted = 1; - } - bu_ptbl_rm(&gedp->ged_subp, (long *)rrp); - BU_PUT(rrp, struct ged_subprocess); - } - bu_ptbl_reset(&gedp->ged_subp); - } - - ged_free(gedp); - BU_PUT(gedp, struct ged); - gedp = NULL; -} - -void -ged_free(struct ged *gedp) -{ - if (gedp == GED_NULL) - return; - - bu_vls_free(&gedp->go_name); - - gedp->ged_gvp = NULL; - bv_set_free(&gedp->ged_views); - - - if (gedp->ged_gdp != GED_DRAWABLE_NULL) { - - for (size_t i = 0; i < BU_PTBL_LEN(&gedp->free_solids); i++) { - // TODO - FREE_BV_SCENE_OBJ macro is stashing on the free_scene_obj list, not - // BU_PUT-ing the solid objects themselves - is that what we expect - // when doing ged_free? I.e., is ownership of the free solid list - // with the struct ged or with the application as a whole? We're - // BU_PUT-ing gedp->ged_views.free_scene_obj - above why just that one? -#if 0 - struct bv_scene_obj *sp = (struct bv_scene_obj *)BU_PTBL_GET(&gedp->free_solids, i); - RT_FREE_VLIST(&(sp->s_vlist)); -#endif - } - bu_ptbl_free(&gedp->free_solids); - - if (gedp->ged_gdp->gd_headDisplay) - BU_PUT(gedp->ged_gdp->gd_headDisplay, struct bu_vls); - if (gedp->ged_gdp->gd_headVDraw) - BU_PUT(gedp->ged_gdp->gd_headVDraw, struct bu_vls); - qray_free(gedp->ged_gdp); - BU_PUT(gedp->ged_gdp, struct ged_drawable); - } - - if (gedp->ged_log) { - bu_vls_free(gedp->ged_log); - BU_PUT(gedp->ged_log, struct bu_vls); - } - - if (gedp->ged_results) { - ged_results_free(gedp->ged_results); - BU_PUT(gedp->ged_results, struct ged_results); - } - - if (gedp->ged_result_str) { - bu_vls_free(gedp->ged_result_str); - BU_PUT(gedp->ged_result_str, struct bu_vls); - } - - ged_selection_sets_destroy(gedp->ged_selection_sets); - gedp->ged_selection_sets = NULL; - gedp->ged_cset = NULL; - - BU_PUT(gedp->ged_cbs, struct ged_callback_state); - - bu_ptbl_free(&gedp->ged_subp); - - if (gedp->ged_fbs) - BU_PUT(gedp->ged_fbs, struct fbserv_obj); -} - -void -ged_init(struct ged *gedp) -{ - if (gedp == GED_NULL) - return; - - gedp->dbip = NULL; - - // TODO - rename to ged_name - bu_vls_init(&gedp->go_name); - - // View related containers - bv_set_init(&gedp->ged_views); - - /* TODO: If we're init-ing the list here, does that mean the gedp has - * ownership of all solid objects created and stored here, and should we - * then free them when ged_free is called? (don't appear to be currently, - * just calling FREE_BV_SCENE_OBJ which doesn't de-allocate... */ - BU_PTBL_INIT(&gedp->free_solids); - - /* In principle we should be establishing an initial view here, - * but Archer won't tolerate it. */ - gedp->ged_gvp = GED_VIEW_NULL; - - /* Create a non-opened fbserv */ - BU_GET(gedp->ged_fbs, struct fbserv_obj); - gedp->ged_fbs->fbs_listener.fbsl_fd = -1; - gedp->fbs_is_listening = NULL; - gedp->fbs_listen_on_port = NULL; - gedp->fbs_open_server_handler = NULL; - gedp->fbs_close_server_handler = NULL; - gedp->fbs_open_client_handler = NULL; - gedp->fbs_close_client_handler = NULL; - - gedp->ged_subprocess_init_callback = NULL; - gedp->ged_subprocess_end_callback = NULL; - - BU_GET(gedp->ged_gdp, struct ged_drawable); - BU_GET(gedp->ged_gdp->gd_headDisplay, struct bu_list); - BU_LIST_INIT(gedp->ged_gdp->gd_headDisplay); - BU_GET(gedp->ged_gdp->gd_headVDraw, struct bu_list); - BU_LIST_INIT(gedp->ged_gdp->gd_headVDraw); - - gedp->ged_gdp->gd_uplotOutputMode = PL_OUTPUT_MODE_BINARY; - qray_init(gedp->ged_gdp); - - gedp->ged_selection_sets = ged_selection_sets_create(gedp); - gedp->ged_cset = ged_selection_sets_get(gedp->ged_selection_sets, "default"); // default set - - BU_GET(gedp->ged_log, struct bu_vls); - bu_vls_init(gedp->ged_log); - - BU_GET(gedp->ged_results, struct ged_results); - (void)_ged_results_init(gedp->ged_results); - - BU_PTBL_INIT(&gedp->ged_subp); - - /* For now, we're keeping the string... will go once no one uses it */ - BU_GET(gedp->ged_result_str, struct bu_vls); - bu_vls_init(gedp->ged_result_str); - - /* Initialize callbacks */ - BU_GET(gedp->ged_cbs, struct ged_callback_state); - gedp->ged_refresh_handler = NULL; - gedp->ged_refresh_clientdata = NULL; - gedp->ged_output_handler = NULL; - gedp->ged_create_vlist_scene_obj_callback = NULL; - gedp->ged_create_vlist_display_list_callback = NULL; - gedp->ged_destroy_vlist_callback = NULL; - gedp->ged_create_io_handler = NULL; - gedp->ged_delete_io_handler = NULL; - gedp->ged_io_data = NULL; - - /* ? */ - gedp->ged_output_script = NULL; - gedp->ged_internal_call = 0; - - gedp->ged_ctx = NULL; - gedp->ged_interp = NULL; -} - - -struct ged * -ged_open(const char *dbtype, const char *filename, int existing_only) -{ - struct ged *gedp; - struct rt_wdb *wdbp; - struct mater *save_materp = MATER_NULL; - - if (filename == NULL) - return GED_NULL; - - save_materp = rt_material_head(); - rt_new_material_head(MATER_NULL); - - if (BU_STR_EQUAL(dbtype, "db")) { - struct db_i *dbip; - - if ((dbip = _ged_open_dbip(filename, existing_only)) == DBI_NULL) { - /* Restore RT's material head */ - rt_new_material_head(save_materp); - - return GED_NULL; - } - - RT_CK_DBI(dbip); - - wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); - } else if (BU_STR_EQUAL(dbtype, "file")) { - wdbp = wdb_fopen(filename); - } else { - struct db_i *dbip; - - /* FIXME: this call should not exist. passing pointers as - * strings indicates a failure in design and lazy coding. - */ - if (sscanf(filename, "%p", (void **)&dbip) != 1) { - /* Restore RT's material head */ - rt_new_material_head(save_materp); - - return GED_NULL; - } - - if (dbip == DBI_NULL) { - int i; - - BU_ALLOC(dbip, struct db_i); - dbip->dbi_eof = (b_off_t)-1L; - dbip->dbi_fp = NULL; - dbip->dbi_mf = NULL; - dbip->dbi_read_only = 0; - - /* Initialize fields */ - for (i = 0; i dbi_Head[i] = RT_DIR_NULL; - } - - dbip->dbi_local2base = 1.0; /* mm */ - dbip->dbi_base2local = 1.0; - dbip->dbi_title = bu_strdup("Untitled BRL-CAD Database"); - dbip->dbi_uses = 1; - dbip->dbi_filename = NULL; - dbip->dbi_filepath = NULL; - dbip->dbi_version = 5; - - bu_ptbl_init(&dbip->dbi_clients, 128, "dbi_clients[]"); - bu_ptbl_init(&dbip->dbi_changed_clbks , 8, "dbi_changed_clbks]"); - bu_ptbl_init(&dbip->dbi_update_nref_clbks, 8, "dbi_update_nref_clbks"); - - dbip->dbi_use_comb_instance_ids = 0; - const char *need_comb_inst = getenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS"); - if (BU_STR_EQUAL(need_comb_inst, "1")) { - dbip->dbi_use_comb_instance_ids = 1; - } - dbip->dbi_magic = DBI_MAGIC; /* Now it's valid */ - } - - /* Could core dump */ - RT_CK_DBI(dbip); - - if (BU_STR_EQUAL(dbtype, "disk")) - wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); - else if (BU_STR_EQUAL(dbtype, "disk_append")) - wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK_APPEND_ONLY); - else if (BU_STR_EQUAL(dbtype, "inmem")) - wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM); - else if (BU_STR_EQUAL(dbtype, "inmem_append")) - wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM_APPEND_ONLY); - else { - /* Restore RT's material head */ - rt_new_material_head(save_materp); - - bu_log("wdb_open %s target type not recognized", dbtype); - return GED_NULL; - } - } - - BU_GET(gedp, struct ged); - GED_INIT(gedp, wdbp); - BU_ALLOC(gedp->ged_gvp, struct bview); - bv_init(gedp->ged_gvp, &gedp->ged_views); - - return gedp; -} - - -/** - * @brief - * Open/Create the database and build the in memory directory. - */ -struct db_i * -_ged_open_dbip(const char *filename, int existing_only) -{ - struct db_i *dbip = DBI_NULL; - - /* open database */ - if (((dbip = db_open(filename, DB_OPEN_READWRITE)) == DBI_NULL) && - ((dbip = db_open(filename, DB_OPEN_READONLY)) == DBI_NULL)) { - - /* - * Check to see if we can access the database - */ - if (bu_file_exists(filename, NULL) && !bu_file_readable(filename)) { - bu_log("_ged_open_dbip: %s is not readable", filename); - - return DBI_NULL; - } - - if (existing_only) - return DBI_NULL; - - /* db_create does a db_dirbuild */ - if ((dbip = db_create(filename, 5)) == DBI_NULL) { - bu_log("_ged_open_dbip: failed to create %s\n", filename); - - return DBI_NULL; - } - - return dbip; - } - - /* --- Scan geometry database and build in-memory directory --- */ - if (db_dirbuild(dbip) < 0) { - db_close(dbip); - bu_log("_ged_open_dbip: db_dirbuild failed on database file %s", filename); - dbip = DBI_NULL; - } - - return dbip; -} - -/* Callback wrapper functions */ - -void -ged_refresh_cb(struct ged *gedp) -{ - if (gedp->ged_refresh_handler != GED_REFRESH_FUNC_NULL) { - gedp->ged_cbs->ged_refresh_handler_cnt++; - if (gedp->ged_cbs->ged_refresh_handler_cnt > 1) { - bu_log("Warning - recursive call of gedp->ged_refresh_handler!\n"); - } - (*gedp->ged_refresh_handler)(gedp->ged_refresh_clientdata); - gedp->ged_cbs->ged_refresh_handler_cnt--; - } -} - -void -ged_output_handler_cb(struct ged *gedp, char *str) -{ - if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) { - gedp->ged_cbs->ged_output_handler_cnt++; - if (gedp->ged_cbs->ged_output_handler_cnt > 1) { - bu_log("Warning - recursive call of gedp->ged_output_handler!\n"); - } - (*gedp->ged_output_handler)(gedp, str); - gedp->ged_cbs->ged_output_handler_cnt--; - } -} - -void -ged_create_vlist_solid_cb(struct ged *gedp, struct bv_scene_obj *s) -{ - if (gedp->ged_create_vlist_scene_obj_callback != GED_CREATE_VLIST_SOLID_FUNC_NULL) { - gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt++; - if (gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt > 1) { - bu_log("Warning - recursive call of gedp->ged_create_vlist_scene_obj_callback!\n"); - } - (*gedp->ged_create_vlist_scene_obj_callback)(s); - gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt--; - } -} - -void -ged_create_vlist_display_list_cb(struct ged *gedp, struct display_list *dl) -{ - if (gedp->ged_create_vlist_display_list_callback != GED_CREATE_VLIST_DISPLAY_LIST_FUNC_NULL) { - gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt++; - if (gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt > 1) { - bu_log("Warning - recursive call of gedp->ged_create_vlist_callback!\n"); - } - (*gedp->ged_create_vlist_display_list_callback)(dl); - gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt--; - } -} - -void -ged_destroy_vlist_cb(struct ged *gedp, unsigned int i, int j) -{ - if (gedp->ged_destroy_vlist_callback != GED_DESTROY_VLIST_FUNC_NULL) { - gedp->ged_cbs->ged_destroy_vlist_callback_cnt++; - if (gedp->ged_cbs->ged_destroy_vlist_callback_cnt > 1) { - bu_log("Warning - recursive call of gedp->ged_destroy_vlist_callback!\n"); - } - (*gedp->ged_destroy_vlist_callback)(i, j); - gedp->ged_cbs->ged_destroy_vlist_callback_cnt--; - } -} - -#if 0 -int -ged_io_handler_cb(struct ged *, ged_io_handler_callback_t *cb, void *, int) -{ - if ( -} -#endif - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libged/ged.cpp b/src/libged/ged.cpp new file mode 100644 index 00000000000..0e9d40e8afe --- /dev/null +++ b/src/libged/ged.cpp @@ -0,0 +1,502 @@ +/* G E D . C P P + * BRL-CAD + * + * Copyright (c) 2000-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup libged */ +/** @{ */ +/** @file libged/ged.cpp + * + * A quasi-object-oriented database interface. + * + * A database object contains the attributes and methods for + * controlling a BRL-CAD database. + * + * Also include routines to allow libwdb to use librt's import/export + * interface, rather than having to know about the database formats directly. + * + */ +/** @} */ + +#include "common.h" + +#include +#include +#include + + +#include "bu/sort.h" +#include "vmath.h" +#include "bn.h" +#include "rt/geom.h" +#include "raytrace.h" +#include "bv/lod.h" +#include "bv/plot3.h" + +#include "bv/defines.h" + +#include "./ged_private.h" +extern "C" { +#include "./qray.h" +} + +#define FREE_BV_SCENE_OBJ(p, fp) { \ + BU_LIST_APPEND(fp, &((p)->l)); \ + BV_FREE_VLIST(&RTG.rtg_vlfree, &((p)->s_vlist)); } + + +/* TODO: Ew. Globals. Make this go away... */ +struct ged *_ged_current_gedp; +vect_t _ged_eye_model; +mat_t _ged_viewrot; + +void +ged_close(struct ged *gedp) +{ + if (gedp == GED_NULL) + return; + + if (gedp->dbip) { + db_close(gedp->dbip); + gedp->dbip = NULL; + } + + if (gedp->ged_lod) + bv_mesh_lod_context_destroy(gedp->ged_lod); + + /* Terminate any ged subprocesses */ + if (gedp != GED_NULL) { + for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_subp); i++) { + struct ged_subprocess *rrp = (struct ged_subprocess *)BU_PTBL_GET(&gedp->ged_subp, i); + if (!rrp->aborted) { + bu_terminate(bu_process_pid(rrp->p)); + rrp->aborted = 1; + } + bu_ptbl_rm(&gedp->ged_subp, (long *)rrp); + BU_PUT(rrp, struct ged_subprocess); + } + bu_ptbl_reset(&gedp->ged_subp); + } + + ged_free(gedp); + BU_PUT(gedp, struct ged); + gedp = NULL; +} + +void +ged_free(struct ged *gedp) +{ + if (gedp == GED_NULL) + return; + + bu_vls_free(&gedp->go_name); + + gedp->ged_gvp = NULL; + + for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_free_views); i++) { + struct bview *gdvp = (struct bview *)BU_PTBL_GET(&gedp->ged_free_views, i); + bv_free(gdvp); + bu_free((void *)gdvp, "bv"); + } + bu_ptbl_free(&gedp->ged_free_views); + bv_set_free(&gedp->ged_views); + + if (gedp->ged_gdp != GED_DRAWABLE_NULL) { + + for (size_t i = 0; i < BU_PTBL_LEN(&gedp->free_solids); i++) { + // TODO - FREE_BV_SCENE_OBJ macro is stashing on the free_scene_obj list, not + // BU_PUT-ing the solid objects themselves - is that what we expect + // when doing ged_free? I.e., is ownership of the free solid list + // with the struct ged or with the application as a whole? We're + // BU_PUT-ing gedp->ged_views.free_scene_obj - above why just that one? +#if 0 + struct bv_scene_obj *sp = (struct bv_scene_obj *)BU_PTBL_GET(&gedp->free_solids, i); + RT_FREE_VLIST(&(sp->s_vlist)); +#endif + } + bu_ptbl_free(&gedp->free_solids); + + if (gedp->ged_gdp->gd_headDisplay) + BU_PUT(gedp->ged_gdp->gd_headDisplay, struct bu_vls); + if (gedp->ged_gdp->gd_headVDraw) + BU_PUT(gedp->ged_gdp->gd_headVDraw, struct bu_vls); + qray_free(gedp->ged_gdp); + BU_PUT(gedp->ged_gdp, struct ged_drawable); + } + + if (gedp->ged_log) { + bu_vls_free(gedp->ged_log); + BU_PUT(gedp->ged_log, struct bu_vls); + } + + if (gedp->ged_results) { + ged_results_free(gedp->ged_results); + BU_PUT(gedp->ged_results, struct ged_results); + } + + if (gedp->ged_result_str) { + bu_vls_free(gedp->ged_result_str); + BU_PUT(gedp->ged_result_str, struct bu_vls); + } + + BU_PUT(gedp->ged_cbs, struct ged_callback_state); + + bu_ptbl_free(&gedp->ged_subp); + + if (gedp->ged_fbs) + BU_PUT(gedp->ged_fbs, struct fbserv_obj); +} + +void +ged_init(struct ged *gedp) +{ + if (gedp == GED_NULL) + return; + + gedp->dbip = NULL; + + // TODO - rename to ged_name + bu_vls_init(&gedp->go_name); + + // View related containers + bv_set_init(&gedp->ged_views); + BU_PTBL_INIT(&gedp->ged_free_views); + + /* TODO: If we're init-ing the list here, does that mean the gedp has + * ownership of all solid objects created and stored here, and should we + * then free them when ged_free is called? (don't appear to be currently, + * just calling FREE_BV_SCENE_OBJ which doesn't de-allocate... */ + BU_PTBL_INIT(&gedp->free_solids); + + /* In principle we should be establishing an initial view here, + * but Archer won't tolerate it. */ + gedp->ged_gvp = GED_VIEW_NULL; + + /* Create a non-opened fbserv */ + BU_GET(gedp->ged_fbs, struct fbserv_obj); + gedp->ged_fbs->fbs_listener.fbsl_fd = -1; + gedp->fbs_is_listening = NULL; + gedp->fbs_listen_on_port = NULL; + gedp->fbs_open_server_handler = NULL; + gedp->fbs_close_server_handler = NULL; + gedp->fbs_open_client_handler = NULL; + gedp->fbs_close_client_handler = NULL; + + gedp->ged_pre_opendb_callback = NULL; + gedp->ged_post_opendb_callback = NULL; + gedp->ged_pre_closedb_callback = NULL; + gedp->ged_post_closedb_callback = NULL; + gedp->ged_db_callback_udata = NULL; + + gedp->ged_subprocess_init_callback = NULL; + gedp->ged_subprocess_end_callback = NULL; + + BU_GET(gedp->ged_gdp, struct ged_drawable); + BU_GET(gedp->ged_gdp->gd_headDisplay, struct bu_list); + BU_LIST_INIT(gedp->ged_gdp->gd_headDisplay); + BU_GET(gedp->ged_gdp->gd_headVDraw, struct bu_list); + BU_LIST_INIT(gedp->ged_gdp->gd_headVDraw); + + gedp->ged_gdp->gd_uplotOutputMode = PL_OUTPUT_MODE_BINARY; + qray_init(gedp->ged_gdp); + + BU_GET(gedp->ged_log, struct bu_vls); + bu_vls_init(gedp->ged_log); + + BU_GET(gedp->ged_results, struct ged_results); + (void)_ged_results_init(gedp->ged_results); + + BU_PTBL_INIT(&gedp->ged_subp); + + /* For now, we're keeping the string... will go once no one uses it */ + BU_GET(gedp->ged_result_str, struct bu_vls); + bu_vls_init(gedp->ged_result_str); + + /* Initialize callbacks */ + BU_GET(gedp->ged_cbs, struct ged_callback_state); + gedp->ged_refresh_handler = NULL; + gedp->ged_refresh_clientdata = NULL; + gedp->ged_output_handler = NULL; + gedp->ged_create_vlist_scene_obj_callback = NULL; + gedp->ged_create_vlist_display_list_callback = NULL; + gedp->ged_destroy_vlist_callback = NULL; + gedp->ged_create_io_handler = NULL; + gedp->ged_delete_io_handler = NULL; + gedp->ged_io_data = NULL; + + /* ? */ + gedp->ged_output_script = NULL; + gedp->ged_internal_call = 0; + + gedp->dbi_state = NULL; + + gedp->ged_ctx = NULL; + gedp->ged_interp = NULL; +} + + +struct ged * +ged_open(const char *dbtype, const char *filename, int existing_only) +{ + struct ged *gedp; + struct rt_wdb *wdbp; + struct mater *save_materp = MATER_NULL; + + if (filename == NULL) + return GED_NULL; + + save_materp = rt_material_head(); + rt_new_material_head(MATER_NULL); + + if (BU_STR_EQUAL(dbtype, "db")) { + struct db_i *dbip; + + if ((dbip = _ged_open_dbip(filename, existing_only)) == DBI_NULL) { + /* Restore RT's material head */ + rt_new_material_head(save_materp); + + return GED_NULL; + } + + RT_CK_DBI(dbip); + + wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); + } else if (BU_STR_EQUAL(dbtype, "file")) { + wdbp = wdb_fopen(filename); + } else { + struct db_i *dbip; + + /* FIXME: this call should not exist. passing pointers as + * strings indicates a failure in design and lazy coding. + */ + if (sscanf(filename, "%p", (void **)&dbip) != 1) { + /* Restore RT's material head */ + rt_new_material_head(save_materp); + + return GED_NULL; + } + + if (dbip == DBI_NULL) { + int i; + + BU_ALLOC(dbip, struct db_i); + dbip->dbi_eof = (b_off_t)-1L; + dbip->dbi_fp = NULL; + dbip->dbi_mf = NULL; + dbip->dbi_read_only = 0; + + /* Initialize fields */ + for (i = 0; i dbi_Head[i] = RT_DIR_NULL; + } + + dbip->dbi_local2base = 1.0; /* mm */ + dbip->dbi_base2local = 1.0; + dbip->dbi_title = bu_strdup("Untitled BRL-CAD Database"); + dbip->dbi_uses = 1; + dbip->dbi_filename = NULL; + dbip->dbi_filepath = NULL; + dbip->dbi_version = 5; + + bu_ptbl_init(&dbip->dbi_clients, 128, "dbi_clients[]"); + bu_ptbl_init(&dbip->dbi_changed_clbks , 8, "dbi_changed_clbks]"); + bu_ptbl_init(&dbip->dbi_update_nref_clbks, 8, "dbi_update_nref_clbks"); + + dbip->dbi_use_comb_instance_ids = 0; + const char *need_comb_inst = getenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS"); + if (BU_STR_EQUAL(need_comb_inst, "1")) { + dbip->dbi_use_comb_instance_ids = 1; + } + dbip->dbi_magic = DBI_MAGIC; /* Now it's valid */ + } + + /* Could core dump */ + RT_CK_DBI(dbip); + + if (BU_STR_EQUAL(dbtype, "disk")) + wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); + else if (BU_STR_EQUAL(dbtype, "disk_append")) + wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK_APPEND_ONLY); + else if (BU_STR_EQUAL(dbtype, "inmem")) + wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM); + else if (BU_STR_EQUAL(dbtype, "inmem_append")) + wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM_APPEND_ONLY); + else { + /* Restore RT's material head */ + rt_new_material_head(save_materp); + + bu_log("wdb_open %s target type not recognized", dbtype); + return GED_NULL; + } + } + + BU_GET(gedp, struct ged); + GED_INIT(gedp, wdbp); +#if 0 + // Archer doesn't tolerate populating the GEDP with an initial view at the + // moment. Probably should fix that, as there are lots of ged commands + // that only work correctly with a view present... + BU_ALLOC(gedp->ged_gvp, struct bview); + bv_init(gedp->ged_gvp, &gedp->ged_views); + bv_set_add_view(&gedp->ged_views, gedp->ged_gvp); + bu_ptbl_ins(&gedp->ged_free_views, (long *)gedp->ged_gvp); +#endif + + db_update_nref(gedp->dbip, &rt_uniresource); + + gedp->ged_lod = bv_mesh_lod_context_create(filename); + + const char *use_dbi_state = getenv("LIBGED_DBI_STATE"); + if (use_dbi_state) { + gedp->dbi_state = new DbiState(gedp); + } else { + gedp->dbi_state = NULL; + } + + return gedp; +} + + +/** + * @brief + * Open/Create the database and build the in memory directory. + */ +struct db_i * +_ged_open_dbip(const char *filename, int existing_only) +{ + struct db_i *dbip = DBI_NULL; + + /* open database */ + if (((dbip = db_open(filename, DB_OPEN_READWRITE)) == DBI_NULL) && + ((dbip = db_open(filename, DB_OPEN_READONLY)) == DBI_NULL)) { + + /* + * Check to see if we can access the database + */ + if (bu_file_exists(filename, NULL) && !bu_file_readable(filename)) { + bu_log("_ged_open_dbip: %s is not readable", filename); + + return DBI_NULL; + } + + if (existing_only) + return DBI_NULL; + + /* db_create does a db_dirbuild */ + if ((dbip = db_create(filename, BRLCAD_DB_FORMAT_LATEST)) == DBI_NULL) { + bu_log("_ged_open_dbip: failed to create %s\n", filename); + + return DBI_NULL; + } + + return dbip; + } + + /* --- Scan geometry database and build in-memory directory --- */ + if (db_dirbuild(dbip) < 0) { + db_close(dbip); + bu_log("_ged_open_dbip: db_dirbuild failed on database file %s", filename); + dbip = DBI_NULL; + } + + return dbip; +} + +/* Callback wrapper functions */ + +void +ged_refresh_cb(struct ged *gedp) +{ + if (gedp->ged_refresh_handler != GED_REFRESH_FUNC_NULL) { + gedp->ged_cbs->ged_refresh_handler_cnt++; + if (gedp->ged_cbs->ged_refresh_handler_cnt > 1) { + bu_log("Warning - recursive call of gedp->ged_refresh_handler!\n"); + } + (*gedp->ged_refresh_handler)(gedp->ged_refresh_clientdata); + gedp->ged_cbs->ged_refresh_handler_cnt--; + } +} + +void +ged_output_handler_cb(struct ged *gedp, char *str) +{ + if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) { + gedp->ged_cbs->ged_output_handler_cnt++; + if (gedp->ged_cbs->ged_output_handler_cnt > 1) { + bu_log("Warning - recursive call of gedp->ged_output_handler!\n"); + } + (*gedp->ged_output_handler)(gedp, str); + gedp->ged_cbs->ged_output_handler_cnt--; + } +} + +void +ged_create_vlist_solid_cb(struct ged *gedp, struct bv_scene_obj *s) +{ + if (gedp->ged_create_vlist_scene_obj_callback != GED_CREATE_VLIST_SOLID_FUNC_NULL) { + gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt++; + if (gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt > 1) { + bu_log("Warning - recursive call of gedp->ged_create_vlist_scene_obj_callback!\n"); + } + (*gedp->ged_create_vlist_scene_obj_callback)(s); + gedp->ged_cbs->ged_create_vlist_scene_obj_callback_cnt--; + } +} + +void +ged_create_vlist_display_list_cb(struct ged *gedp, struct display_list *dl) +{ + if (gedp->ged_create_vlist_display_list_callback != GED_CREATE_VLIST_DISPLAY_LIST_FUNC_NULL) { + gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt++; + if (gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt > 1) { + bu_log("Warning - recursive call of gedp->ged_create_vlist_callback!\n"); + } + (*gedp->ged_create_vlist_display_list_callback)(dl); + gedp->ged_cbs->ged_create_vlist_display_list_callback_cnt--; + } +} + +void +ged_destroy_vlist_cb(struct ged *gedp, unsigned int i, int j) +{ + if (gedp->ged_destroy_vlist_callback != GED_DESTROY_VLIST_FUNC_NULL) { + gedp->ged_cbs->ged_destroy_vlist_callback_cnt++; + if (gedp->ged_cbs->ged_destroy_vlist_callback_cnt > 1) { + bu_log("Warning - recursive call of gedp->ged_destroy_vlist_callback!\n"); + } + (*gedp->ged_destroy_vlist_callback)(i, j); + gedp->ged_cbs->ged_destroy_vlist_callback_cnt--; + } +} + +#if 0 +int +ged_io_handler_cb(struct ged *, ged_io_handler_callback_t *cb, void *, int) +{ + if ( +} +#endif + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/ged_private.h b/src/libged/ged_private.h index 67175ae9083..a5a10abb59f 100644 --- a/src/libged/ged_private.h +++ b/src/libged/ged_private.h @@ -68,6 +68,7 @@ __BEGIN_DECLS #define _GED_BOOL_EVAL 3 #define _GED_HIDDEN_LINE 4 #define _GED_SHADED_MODE_EVAL 5 +#define _GED_WIREFRAME_EVAL 6 #define _GED_DRAW_WIREFRAME 1 #define _GED_DRAW_NMG_POLY 3 @@ -201,7 +202,7 @@ struct draw_data_t { int color_inherit; int bool_op; struct resource *res; - struct bg_mesh_lod_context *mesh_c; + struct bv_mesh_lod_context *mesh_c; /* To avoid the need for multiple subtree walking * functions, we also set up to support a bounding @@ -215,7 +216,6 @@ struct draw_data_t { std::map *s_size; #endif }; -GED_EXPORT void draw_scene(struct bv_scene_obj *s, struct bview *v); GED_EXPORT void draw_walk_tree(struct db_full_path *path, union tree *tp, mat_t *curr_mat, void (*traverse_func) (struct db_full_path *path, mat_t *, void *), void *client_data, void *comb_inst_map); @@ -665,7 +665,7 @@ struct _ged_facetize_opts { int triangulate; int make_nmg; int nmgbool; - int irmb; + int manifold; int screened_poisson; int continuation; int method_flags; @@ -691,7 +691,7 @@ struct _ged_facetize_opts { int fnull; struct bu_vls *froot; - struct bu_vls *irmb_comb; + struct bu_vls *manifold_comb; struct bu_vls *nmg_comb; struct bu_vls *continuation_comb; struct bu_vls *spsr_comb; @@ -719,6 +719,27 @@ _ged_subcmd_exec(struct ged *gedp, struct bu_opt_desc *gopts, const struct bu_cm int help, int cmd_pos); +// TODO: alternative approach to the command structure supported by +// _ged_subcmd_help - if we successfully migrate all the uses of the above +// functions, rename this from subcmd2 to subcmd... +// +// Prototyping with edit/edit2.cpp +#ifdef __cplusplus + +#include +#include + +class ged_subcmd { + public: + virtual std::string usage() { return std::string(""); } + virtual std::string purpose() { return std::string(""); } + virtual int exec(struct ged *, void *, int, const char **) { return BRLCAD_ERROR; } +}; + +GED_EXPORT extern int +_ged_subcmd2_help(struct ged *gedp, struct bu_opt_desc *gopts, std::map &subcmds, const char *cmdname, const char *cmdargs, int argc, const char **argv); + +#endif __END_DECLS diff --git a/src/libged/ged_util.c b/src/libged/ged_util.c deleted file mode 100644 index 7300b2445a9..00000000000 --- a/src/libged/ged_util.c +++ /dev/null @@ -1,2329 +0,0 @@ -/* G E D _ U T I L . C - * BRL-CAD - * - * Copyright (c) 2000-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @addtogroup libged */ -/** @{ */ -/** @file libged/ged_util.c - * - * Utility routines for common operations in libged. - * - */ -/** @} */ - -#include "common.h" - -#include -#include - -#ifdef HAVE_SYS_TYPES_H -# include -#endif - -#include "bio.h" -#include "bresource.h" - - -#include "bu/app.h" -#include "bu/cmd.h" -#include "bu/file.h" -#include "bu/opt.h" -#include "bu/path.h" -#include "bu/sort.h" -#include "bu/str.h" -#include "bu/units.h" -#include "bu/vls.h" -#include "bv.h" - -#include "ged.h" -#include "./ged_private.h" - -int -_ged_subcmd_help(struct ged *gedp, struct bu_opt_desc *gopts, const struct bu_cmdtab *cmds, const char *cmdname, const char *cmdargs, void *gd, int argc, const char **argv) -{ - if (!gedp || !gopts || !cmds || !cmdname) - return BRLCAD_ERROR; - - if (!argc || !argv || BU_STR_EQUAL(argv[0], "help")) { - bu_vls_printf(gedp->ged_result_str, "%s %s\n", cmdname, cmdargs); - if (gopts) { - char *option_help = bu_opt_describe(gopts, NULL); - if (option_help) { - bu_vls_printf(gedp->ged_result_str, "Options:\n%s\n", option_help); - bu_free(option_help, "help str"); - } - } - bu_vls_printf(gedp->ged_result_str, "Available subcommands:\n"); - const struct bu_cmdtab *ctp = NULL; - int ret; - const char *helpflag[2]; - helpflag[1] = PURPOSEFLAG; - size_t maxcmdlen = 0; - for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { - maxcmdlen = (maxcmdlen > strlen(ctp->ct_name)) ? maxcmdlen : strlen(ctp->ct_name); - } - for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { - bu_vls_printf(gedp->ged_result_str, " %s%*s", ctp->ct_name, (int)(maxcmdlen - strlen(ctp->ct_name)) + 2, " "); - if (!BU_STR_EQUAL(ctp->ct_name, "help")) { - helpflag[0] = ctp->ct_name; - bu_cmd(cmds, 2, helpflag, 0, gd, &ret); - } else { - bu_vls_printf(gedp->ged_result_str, "print help and exit\n"); - } - } - } else { - int ret; - const char **helpargv = (const char **)bu_calloc((size_t)argc+1, sizeof(char *), "help argv"); - helpargv[0] = argv[0]; - helpargv[1] = HELPFLAG; - for (int i = 1; i < argc; i++) { - helpargv[i+1] = argv[i]; - } - bu_cmd(cmds, argc+1, helpargv, 0, gd, &ret); - bu_free((void *)helpargv, "help argv"); - return ret; - } - - return BRLCAD_OK; -} - -int -_ged_subcmd_exec(struct ged *gedp, struct bu_opt_desc *gopts, const struct bu_cmdtab *cmds, const char *cmdname, const char *cmdargs, void *gd, int argc, const char **argv, int help, int cmd_pos) -{ - if (!gedp || !gopts || !cmds || !cmdname) - return BRLCAD_ERROR; - - if (help) { - if (cmd_pos >= 0) { - argc = argc - cmd_pos; - argv = &argv[cmd_pos]; - _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, argc, argv); - } else { - _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, 0, NULL); - } - return BRLCAD_OK; - } - - // Must have a subcommand - if (cmd_pos == -1) { - bu_vls_printf(gedp->ged_result_str, ": no valid subcommand specified\n"); - _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, 0, NULL); - return BRLCAD_ERROR; - } - - int ret; - if (bu_cmd(cmds, argc, argv, 0, (void *)gd, &ret) == BRLCAD_OK) { - return ret; - } else { - bu_vls_printf(gedp->ged_result_str, "subcommand %s not defined", argv[0]); - } - - - return BRLCAD_OK; -} - -void -ged_push_scene_obj(struct ged *gedp, struct bv_scene_obj *sp) -{ - BV_FREE_VLIST(&RTG.rtg_vlfree, &(sp->s_vlist)); - if (sp->s_u_data) { - struct ged_bv_data *bdata = (struct ged_bv_data *)sp->s_u_data; - bdata->s_fullpath.fp_len = 0; // Don't free memory, but implicitly clear contents - } - bu_ptbl_ins(&gedp->free_solids, (long *)sp); -} - -struct bv_scene_obj * -ged_pop_scene_obj(struct ged *gedp) -{ - struct bv_scene_obj *sp = NULL; - if (BU_PTBL_LEN(&gedp->free_solids)) { - sp = (struct bv_scene_obj *)BU_PTBL_GET(&gedp->free_solids, (BU_PTBL_LEN(&gedp->free_solids) - 1)); - bu_ptbl_rm(&gedp->free_solids, (long *)sp); - } else { - BU_ALLOC(sp, struct bv_scene_obj); // from GET_BV_SCENE_OBJ in bv/defines.h - struct ged_bv_data *bdata; - BU_GET(bdata, struct ged_bv_data); - db_full_path_init(&bdata->s_fullpath); - sp->s_u_data = (void *)bdata; - } - return sp; -} - -int -scene_bounding_sph(struct bu_ptbl *so, vect_t *min, vect_t *max, int pflag) -{ - struct bv_scene_obj *sp; - vect_t minus, plus; - int is_empty = 1; - - VSETALL((*min), INFINITY); - VSETALL((*max), -INFINITY); - - /* calculate the bounding for of all solids being displayed */ - for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { - struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(so, i); - if (BU_PTBL_LEN(&g->children)) { - for (size_t j = 0; j < BU_PTBL_LEN(&g->children); j++) { - sp = (struct bv_scene_obj *)BU_PTBL_GET(&g->children, j); - minus[X] = sp->s_center[X] - sp->s_size; - minus[Y] = sp->s_center[Y] - sp->s_size; - minus[Z] = sp->s_center[Z] - sp->s_size; - VMIN((*min), minus); - plus[X] = sp->s_center[X] + sp->s_size; - plus[Y] = sp->s_center[Y] + sp->s_size; - plus[Z] = sp->s_center[Z] + sp->s_size; - VMAX((*max), plus); - - is_empty = 0; - } - } else { - // If we're an evaluated object, the group itself has the - // necessary info. - minus[X] = g->s_center[X] - g->s_size; - minus[Y] = g->s_center[Y] - g->s_size; - minus[Z] = g->s_center[Z] - g->s_size; - VMIN((*min), minus); - plus[X] = g->s_center[X] + g->s_size; - plus[Y] = g->s_center[Y] + g->s_size; - plus[Z] = g->s_center[Z] + g->s_size; - VMAX((*max), plus); - } - } - if (!pflag) { - bu_log("todo - handle pflag\n"); - } - - return is_empty; -} - - -int -_ged_results_init(struct ged_results *results) -{ - if (UNLIKELY(!results)) - return BRLCAD_ERROR; - BU_ALLOC(results->results_tbl, struct bu_ptbl); - BU_PTBL_INIT(results->results_tbl); - return BRLCAD_OK; -} - - -int -_ged_results_add(struct ged_results *results, const char *result_string) -{ - /* If there isn't a string, we can live with that */ - if (UNLIKELY(!result_string)) - return BRLCAD_OK; - - /* If we have nowhere to insert into and we *do* have a string, trouble */ - if (UNLIKELY(!results)) - return BRLCAD_ERROR; - if (UNLIKELY(!(results->results_tbl))) - return BRLCAD_ERROR; - if (UNLIKELY(!(BU_PTBL_IS_INITIALIZED(results->results_tbl)))) - return BRLCAD_ERROR; - - /* We're good to go - copy the string and stuff it in. */ - bu_ptbl_ins(results->results_tbl, (long *)bu_strdup(result_string)); - - return BRLCAD_OK; -} - -size_t -ged_results_count(struct ged_results *results) -{ - if (UNLIKELY(!results)) return 0; - if (UNLIKELY(!(results->results_tbl))) return 0; - return (size_t)BU_PTBL_LEN(results->results_tbl); -} - -const char * -ged_results_get(struct ged_results *results, size_t index) -{ - return (const char *)BU_PTBL_GET(results->results_tbl, index); -} - -void -ged_results_clear(struct ged_results *results) -{ - int i = 0; - if (UNLIKELY(!results)) return; - if (UNLIKELY(!(results->results_tbl))) return; - - /* we clean up everything except the ged_results structure itself */ - for (i = (int)BU_PTBL_LEN(results->results_tbl) - 1; i >= 0; i--) { - char *rstring = (char *)BU_PTBL_GET(results->results_tbl, i); - if (rstring) - bu_free(rstring, "free results string"); - } - bu_ptbl_reset(results->results_tbl); -} - -void -ged_results_free(struct ged_results *results) { - if (UNLIKELY(!results)) return; - if (UNLIKELY(!(results->results_tbl))) return; - - ged_results_clear(results); - bu_ptbl_free(results->results_tbl); - bu_free(results->results_tbl, "done with results ptbl"); -} - -/*********************************************************/ -/* comparison functions for bu_sort */ -/*********************************************************/ - -/** - * Given two pointers to pointers to directory entries, do a string - * compare on the respective names and return that value. - */ -int -cmpdirname(const void *a, const void *b, void *UNUSED(arg)) -{ - struct directory **dp1, **dp2; - - dp1 = (struct directory **)a; - dp2 = (struct directory **)b; - return bu_strcmp((*dp1)->d_namep, (*dp2)->d_namep); -} - -/** - * Given two pointers to pointers to directory entries, compare - * the dp->d_len sizes. - */ -int -cmpdlen(const void *a, const void *b, void *UNUSED(arg)) -{ - int cmp = 0; - struct directory **dp1, **dp2; - - dp1 = (struct directory **)a; - dp2 = (struct directory **)b; - if ((*dp1)->d_len > (*dp2)->d_len) cmp = 1; - if ((*dp1)->d_len < (*dp2)->d_len) cmp = -1; - return cmp; -} - -/*********************************************************/ -/* _ged_vls_col_pr4v */ -/*********************************************************/ - - -void -_ged_vls_col_pr4v(struct bu_vls *vls, - struct directory **list_of_names, - size_t num_in_list, - int no_decorate, - int ssflag) -{ - size_t lines, i, j, k, this_one; - size_t namelen; - size_t maxnamelen; /* longest name in list */ - size_t cwidth; /* column width */ - size_t numcol; /* number of columns */ - - if (!ssflag) { - bu_sort((void *)list_of_names, - (unsigned)num_in_list, (unsigned)sizeof(struct directory *), - cmpdirname, NULL); - } else { - bu_sort((void *)list_of_names, - (unsigned)num_in_list, (unsigned)sizeof(struct directory *), - cmpdlen, NULL); - } - - /* - * Traverse the list of names, find the longest name and set the - * the column width and number of columns accordingly. If the - * longest name is greater than 80 characters, the number of - * columns will be one. - */ - maxnamelen = 0; - for (k = 0; k < num_in_list; k++) { - namelen = strlen(list_of_names[k]->d_namep); - if (namelen > maxnamelen) - maxnamelen = namelen; - } - - if (maxnamelen <= 16) - maxnamelen = 16; - cwidth = maxnamelen + 4; - - if (cwidth > 80) - cwidth = 80; - numcol = GED_TERMINAL_WIDTH / cwidth; - - /* - * For the number of (full and partial) lines that will be needed, - * print in vertical format. - */ - lines = (num_in_list + (numcol - 1)) / numcol; - for (i = 0; i < lines; i++) { - for (j = 0; j < numcol; j++) { - this_one = j * lines + i; - bu_vls_printf(vls, "%s", list_of_names[this_one]->d_namep); - namelen = strlen(list_of_names[this_one]->d_namep); - - /* - * Region and ident checks here.... Since the code has - * been modified to push and sort on pointers, the - * printing of the region and ident flags must be delayed - * until now. There is no way to make the decision on - * where to place them before now. - */ - if (!no_decorate && list_of_names[this_one]->d_flags & RT_DIR_COMB) { - bu_vls_putc(vls, '/'); - namelen++; - } - - if (!no_decorate && list_of_names[this_one]->d_flags & RT_DIR_REGION) { - bu_vls_putc(vls, 'R'); - namelen++; - } - - /* - * Size check (partial lines), and line termination. Note - * that this will catch the end of the lines that are full - * too. - */ - if (this_one + lines >= num_in_list) { - bu_vls_putc(vls, '\n'); - break; - } else { - /* - * Pad to next boundary as there will be another entry - * to the right of this one. - */ - while (namelen++ < cwidth) - bu_vls_putc(vls, ' '); - } - } - } -} - -/*********************************************************/ - -struct directory ** -_ged_getspace(struct db_i *dbip, - size_t num_entries) -{ - struct directory **dir_basep; - - if (num_entries == 0) - num_entries = db_directory_size(dbip); - - /* Allocate and cast num_entries worth of pointers */ - dir_basep = (struct directory **) bu_calloc((num_entries+1), sizeof(struct directory *), "_ged_getspace *dir[]"); - return dir_basep; -} - - -void -_ged_cmd_help(struct ged *gedp, const char *usage, struct bu_opt_desc *d) -{ - struct bu_vls str = BU_VLS_INIT_ZERO; - char *option_help; - - bu_vls_sprintf(&str, "%s", usage); - - if ((option_help = bu_opt_describe(d, NULL))) { - bu_vls_printf(&str, "Options:\n%s\n", option_help); - bu_free(option_help, "help str"); - } - - bu_vls_vlscat(gedp->ged_result_str, &str); - bu_vls_free(&str); -} - -// TODO - replace with bu_opt_incr_long -int -_ged_vopt(struct bu_vls *UNUSED(msg), size_t UNUSED(argc), const char **UNUSED(argv), void *set_var) -{ - int *v_set = (int *)set_var; - if (v_set) { - (*v_set) = (*v_set) + 1; - } - return 0; -} - -/* Sort the argv array to list existing objects first and everything else at - * the end. Returns the number of argv entries where db_lookup failed */ -int -_ged_sort_existing_objs(struct ged *gedp, int argc, const char *argv[], struct directory **dpa) -{ - int i = 0; - int exist_cnt = 0; - int nonexist_cnt = 0; - struct directory *dp; - const char **exists = (const char **)bu_calloc(argc, sizeof(const char *), "obj exists array"); - const char **nonexists = (const char **)bu_calloc(argc, sizeof(const char *), "obj nonexists array"); - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - for (i = 0; i < argc; i++) { - dp = db_lookup(gedp->dbip, argv[i], LOOKUP_QUIET); - if (dp == RT_DIR_NULL) { - nonexists[nonexist_cnt] = argv[i]; - nonexist_cnt++; - } else { - exists[exist_cnt] = argv[i]; - if (dpa) dpa[exist_cnt] = dp; - exist_cnt++; - } - } - for (i = 0; i < exist_cnt; i++) { - argv[i] = exists[i]; - } - for (i = 0; i < nonexist_cnt; i++) { - argv[i + exist_cnt] = nonexists[i]; - } - - bu_free((void *)exists, "exists array"); - bu_free((void *)nonexists, "nonexists array"); - - return nonexist_cnt; -} - - - -/** - * Returns - * 0 on success - * !0 on failure - */ -static int -_ged_densities_from_file(struct analyze_densities **dens, char **den_src, struct ged *gedp, const char *name, int fault_tolerant) -{ - struct analyze_densities *densities; - struct bu_mapped_file *dfile = NULL; - struct bu_vls msgs = BU_VLS_INIT_ZERO; - char *buf = NULL; - int ret = 0; - int ecnt = 0; - - if (gedp == GED_NULL || gedp->dbip == NULL || !dens) { - return BRLCAD_ERROR; - } - - if (!bu_file_exists(name, NULL)) { - bu_vls_printf(gedp->ged_result_str, "Could not find density file - %s\n", name); - return BRLCAD_ERROR; - } - - dfile = bu_open_mapped_file(name, "densities file"); - if (!dfile) { - bu_vls_printf(gedp->ged_result_str, "Could not open density file - %s\n", name); - return BRLCAD_ERROR; - } - - buf = (char *)(dfile->buf); - - (void)analyze_densities_create(&densities); - - ret = analyze_densities_load(densities, buf, &msgs, &ecnt); - - if (!fault_tolerant && ecnt > 0) { - bu_vls_printf(gedp->ged_result_str, "Problem reading densities file %s:\n%s\n", name, bu_vls_cstr(&msgs)); - if (densities) { - analyze_densities_destroy(densities); - } - bu_vls_free(&msgs); - bu_close_mapped_file(dfile); - return BRLCAD_ERROR; - } - - bu_vls_free(&msgs); - bu_close_mapped_file(dfile); - - (*dens) = densities; - if (ret > 0) { - if (den_src) { - (*den_src) = bu_strdup(name); - } - } else { - if (ret == 0 && densities) { - analyze_densities_destroy(densities); - } - } - - return (ret == 0) ? BRLCAD_ERROR : BRLCAD_OK; -} - -/** - * Load density information. - * - * Returns - * 0 on success - * !0 on failure - */ -int -_ged_read_densities(struct analyze_densities **dens, char **den_src, struct ged *gedp, const char *filename, int fault_tolerant) -{ - struct bu_vls d_path_dir = BU_VLS_INIT_ZERO; - - if (gedp == GED_NULL || gedp->dbip == DBI_NULL || !dens) { - return BRLCAD_ERROR; - } - - /* If we've explicitly been given a file, read that */ - if (filename) { - return _ged_densities_from_file(dens, den_src, gedp, filename, fault_tolerant); - } - - /* If we don't have an explicitly specified file, see if we have definitions in - * the database itself. */ - if (gedp->dbip != DBI_NULL) { - int ret = 0; - int ecnt = 0; - struct bu_vls msgs = BU_VLS_INIT_ZERO; - struct directory *dp; - struct rt_db_internal intern; - struct rt_binunif_internal *bip; - struct analyze_densities *densities; - char *buf; - - dp = db_lookup(gedp->dbip, GED_DB_DENSITY_OBJECT, LOOKUP_QUIET); - - if (dp != (struct directory *)NULL) { - - if (rt_db_get_internal(&intern, dp, gedp->dbip, NULL, &rt_uniresource) < 0) { - bu_vls_printf(_ged_current_gedp->ged_result_str, "could not import %s\n", dp->d_namep); - return BRLCAD_ERROR; - } - - if ((intern.idb_major_type & DB5_MAJORTYPE_BINARY_MASK) == 0) - return BRLCAD_ERROR; - - bip = (struct rt_binunif_internal *)intern.idb_ptr; - - RT_CHECK_BINUNIF (bip); - - (void)analyze_densities_create(&densities); - - buf = (char *)bu_calloc(bip->count+1, sizeof(char), "density buffer"); - memcpy(buf, bip->u.int8, bip->count); - rt_db_free_internal(&intern); - - ret = analyze_densities_load(densities, buf, &msgs, &ecnt); - - bu_free((void *)buf, "density buffer"); - - if (!fault_tolerant && ecnt > 0) { - bu_vls_printf(gedp->ged_result_str, "Problem reading densities from .g file:\n%s\n", bu_vls_cstr(&msgs)); - bu_vls_free(&msgs); - if (densities) { - analyze_densities_destroy(densities); - } - return BRLCAD_ERROR; - } - - bu_vls_free(&msgs); - - (*dens) = densities; - if (ret > 0) { - if (den_src) { - (*den_src) = bu_strdup(gedp->dbip->dbi_filename); - } - } else { - if (ret == 0 && densities) { - analyze_densities_destroy(densities); - } - } - return (ret == 0) ? BRLCAD_ERROR : BRLCAD_OK; - } - } - - /* If we don't have an explicitly specified file and the database doesn't have any information, see if we - * have .density files in either the current database directory or HOME. */ - - /* Try .g path first */ - if (bu_path_component(&d_path_dir, gedp->dbip->dbi_filename, BU_PATH_DIRNAME)) { - - bu_vls_printf(&d_path_dir, "/.density"); - - if (bu_file_exists(bu_vls_cstr(&d_path_dir), NULL)) { - int ret = _ged_densities_from_file(dens, den_src, gedp, bu_vls_cstr(&d_path_dir), fault_tolerant); - bu_vls_free(&d_path_dir); - return ret; - } - } - - /* Try HOME */ - if (bu_dir(NULL, 0, BU_DIR_HOME, NULL)) { - - bu_vls_sprintf(&d_path_dir, "%s/.density", bu_dir(NULL, 0, BU_DIR_HOME, NULL)); - - if (bu_file_exists(bu_vls_cstr(&d_path_dir), NULL)) { - int ret = _ged_densities_from_file(dens, den_src, gedp, bu_vls_cstr(&d_path_dir), fault_tolerant); - bu_vls_free(&d_path_dir); - return ret; - } - } - - return BRLCAD_ERROR; -} - -int -ged_dbcopy(struct ged *from_gedp, struct ged *to_gedp, const char *from, const char *to, int fflag) -{ - struct directory *from_dp; - struct bu_external external; - - GED_CHECK_DATABASE_OPEN(from_gedp, BRLCAD_ERROR); - GED_CHECK_DATABASE_OPEN(to_gedp, BRLCAD_ERROR); - GED_CHECK_READ_ONLY(to_gedp, BRLCAD_ERROR); - - /* initialize result */ - bu_vls_trunc(from_gedp->ged_result_str, 0); - bu_vls_trunc(to_gedp->ged_result_str, 0); - - GED_DB_LOOKUP(from_gedp, from_dp, from, LOOKUP_NOISY, BRLCAD_ERROR & GED_QUIET); - - if (!fflag && db_lookup(to_gedp->dbip, to, LOOKUP_QUIET) != RT_DIR_NULL) { - bu_vls_printf(from_gedp->ged_result_str, "%s already exists.", to); - return BRLCAD_ERROR; - } - - if (db_get_external(&external, from_dp, from_gedp->dbip)) { - bu_vls_printf(from_gedp->ged_result_str, "Database read error, aborting\n"); - return BRLCAD_ERROR; - } - - struct rt_wdb *wdbp = wdb_dbopen(to_gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - if (wdb_export_external(wdbp, &external, to, - from_dp->d_flags, from_dp->d_minor_type) < 0) { - bu_free_external(&external); - bu_vls_printf(from_gedp->ged_result_str, - "Failed to write new object (%s) to database - aborting!!\n", - to); - return BRLCAD_ERROR; - } - - bu_free_external(&external); - - /* Need to do something extra for _GLOBAL */ - if (db_version(to_gedp->dbip) > 4 && BU_STR_EQUAL(to, DB5_GLOBAL_OBJECT_NAME)) { - struct directory *to_dp; - struct bu_attribute_value_set avs; - const char *val; - - GED_DB_LOOKUP(to_gedp, to_dp, to, LOOKUP_NOISY, BRLCAD_ERROR & GED_QUIET); - - bu_avs_init_empty(&avs); - if (db5_get_attributes(to_gedp->dbip, &avs, to_dp)) { - bu_vls_printf(from_gedp->ged_result_str, "Cannot get attributes for object %s\n", to_dp->d_namep); - return BRLCAD_ERROR; - } - - if ((val = bu_avs_get(&avs, "title")) != NULL) - to_gedp->dbip->dbi_title = bu_strdup(val); - - if ((val = bu_avs_get(&avs, "units")) != NULL) { - double loc2mm; - - if ((loc2mm = bu_mm_value(val)) > 0) { - to_gedp->dbip->dbi_local2base = loc2mm; - to_gedp->dbip->dbi_base2local = 1.0 / loc2mm; - } - } - - if ((val = bu_avs_get(&avs, "regionid_colortable")) != NULL) { - rt_color_free(); - db5_import_color_table((char *)val); - } - - bu_avs_free(&avs); - } - - return BRLCAD_OK; -} - - -int -ged_rot_args(struct ged *gedp, int argc, const char *argv[], char *coord, mat_t rmat) -{ - vect_t rvec; - static const char *usage = "[-m|-v] x y z"; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - GED_CHECK_VIEW(gedp, BRLCAD_ERROR); - GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - /* must be wanting help */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return GED_HELP; - } - - /* process possible coord flag */ - if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') { - *coord = argv[1][1]; - --argc; - ++argv; - } else - *coord = gedp->ged_gvp->gv_coord; - - if (argc != 2 && argc != 4) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - - if (argc == 2) { - if (bn_decode_vect(rvec, argv[1]) != 3) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - } else { - double scan[3]; - - if (sscanf(argv[1], "%lf", &scan[X]) < 1) { - bu_vls_printf(gedp->ged_result_str, "ged_eye: bad X value %s\n", argv[1]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[2], "%lf", &scan[Y]) < 1) { - bu_vls_printf(gedp->ged_result_str, "ged_eye: bad Y value %s\n", argv[2]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[3], "%lf", &scan[Z]) < 1) { - bu_vls_printf(gedp->ged_result_str, "ged_eye: bad Z value %s\n", argv[3]); - return BRLCAD_ERROR; - } - - /* convert from double to fastf_t */ - VMOVE(rvec, scan); - } - - VSCALE(rvec, rvec, -1.0); - bn_mat_angles(rmat, rvec[X], rvec[Y], rvec[Z]); - - return BRLCAD_OK; -} - -int -ged_arot_args(struct ged *gedp, int argc, const char *argv[], mat_t rmat) -{ - point_t pt = VINIT_ZERO; - vect_t axisv; - double axis[3]; /* not fastf_t due to sscanf */ - double angle; /* not fastf_t due to sscanf */ - static const char *usage = "x y z angle"; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - GED_CHECK_VIEW(gedp, BRLCAD_ERROR); - GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - /* must be wanting help */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return GED_HELP; - } - - if (argc != 5) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - - if (sscanf(argv[1], "%lf", &axis[X]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad X value - %s\n", argv[0], argv[1]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[2], "%lf", &axis[Y]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad Y value - %s\n", argv[0], argv[2]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[3], "%lf", &axis[Z]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad Z value - %s\n", argv[0], argv[3]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[4], "%lf", &angle) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad angle - %s\n", argv[0], argv[4]); - return BRLCAD_ERROR; - } - - VUNITIZE(axis); - VMOVE(axisv, axis); - bn_mat_arb_rot(rmat, pt, axisv, angle*DEG2RAD); - - return BRLCAD_OK; -} - -int -ged_tra_args(struct ged *gedp, int argc, const char *argv[], char *coord, vect_t tvec) -{ - static const char *usage = "[-m|-v] x y z"; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - GED_CHECK_VIEW(gedp, BRLCAD_ERROR); - GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - /* must be wanting help */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return GED_HELP; - } - - /* process possible coord flag */ - if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') { - *coord = argv[1][1]; - --argc; - ++argv; - } else - *coord = gedp->ged_gvp->gv_coord; - - if (argc != 2 && argc != 4) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - - if (argc == 2) { - if (bn_decode_vect(tvec, argv[1]) != 3) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - } else { - double scan[3]; - - if (sscanf(argv[1], "%lf", &scan[X]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad X value %s\n", argv[0], argv[1]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[2], "%lf", &scan[Y]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad Y value %s\n", argv[0], argv[2]); - return BRLCAD_ERROR; - } - - if (sscanf(argv[3], "%lf", &scan[Z]) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad Z value %s\n", argv[0], argv[3]); - return BRLCAD_ERROR; - } - - /* convert from double to fastf_t */ - VMOVE(tvec, scan); - } - - return BRLCAD_OK; -} - -int -ged_scale_args(struct ged *gedp, int argc, const char *argv[], fastf_t *sf1, fastf_t *sf2, fastf_t *sf3) -{ - static const char *usage = "sf (or) sfx sfy sfz"; - int ret = BRLCAD_OK, args_read; - double scan; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - GED_CHECK_VIEW(gedp, BRLCAD_ERROR); - GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - - if (!sf1 || !sf2 || !sf3) { - bu_vls_printf(gedp->ged_result_str, "%s: invalid input state", argv[0]); - return BRLCAD_ERROR; - } - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - /* must be wanting help */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return GED_HELP; - } - - if (argc != 2 && argc != 4) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; - } - - if (argc == 2) { - if (!sf1 || bu_sscanf(argv[1], "%lf", &scan) != 1) { - bu_vls_printf(gedp->ged_result_str, "\nbad scale factor '%s'", argv[1]); - return BRLCAD_ERROR; - } - *sf1 = scan; - } else { - args_read = bu_sscanf(argv[1], "%lf", &scan); - if (!sf1 || args_read != 1) { - bu_vls_printf(gedp->ged_result_str, "\nbad x scale factor '%s'", argv[1]); - ret = BRLCAD_ERROR; - } - *sf1 = scan; - - args_read = bu_sscanf(argv[2], "%lf", &scan); - if (!sf2 || args_read != 1) { - bu_vls_printf(gedp->ged_result_str, "\nbad y scale factor '%s'", argv[2]); - ret = BRLCAD_ERROR; - } - *sf2 = scan; - - args_read = bu_sscanf(argv[3], "%lf", &scan); - if (!sf3 || args_read != 1) { - bu_vls_printf(gedp->ged_result_str, "\nbad z scale factor '%s'", argv[3]); - ret = BRLCAD_ERROR; - } - *sf3 = scan; - } - return ret; -} - -size_t -ged_who_argc(struct ged *gedp) -{ - const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); - if (BU_STR_EQUAL(cmd2, "1")) { - if (!gedp || !gedp->ged_gvp) - return 0; - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - return BU_PTBL_LEN(sg); - } - - struct display_list *gdlp = NULL; - size_t visibleCount = 0; - - if (!gedp || !gedp->ged_gdp || !gedp->ged_gdp->gd_headDisplay) - return 0; - - for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { - visibleCount++; - } - - return visibleCount; -} - - -/** - * Build a command line vector of the tops of all objects in view. - * - * Returns the number of items displayed. - * - * FIXME: crazy inefficient for massive object lists. needs to work - * with preallocated memory. - */ -int -ged_who_argv(struct ged *gedp, char **start, const char **end) -{ - char **vp = start; - const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); - if (BU_STR_EQUAL(cmd2, "1")) { - if (!gedp || !gedp->ged_gvp) - return 0; - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - if ((vp != NULL) && ((const char **)vp < end)) { - *vp++ = bu_strdup(bu_vls_cstr(&g->s_name)); - } else { - bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() ran out of space at %s\n", bu_vls_cstr(&g->s_name)); - break; - } - } - return (int)BU_PTBL_LEN(sg); - } - - struct display_list *gdlp; - - if (!gedp || !gedp->ged_gdp || !gedp->ged_gdp->gd_headDisplay) - return 0; - - if (UNLIKELY(!start || !end)) { - bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() called with NULL args\n"); - return 0; - } - - for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { - if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) - continue; - - if ((vp != NULL) && ((const char **)vp < end)) { - *vp++ = bu_strdup(bu_vls_addr(&gdlp->dl_path)); - } else { - bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() ran out of space at %s\n", ((struct directory *)gdlp->dl_dp)->d_namep); - break; - } - } - - if ((vp != NULL) && ((const char **)vp < end)) { - *vp = (char *) 0; - } - - return vp-start; -} - -void -_ged_do_list(struct ged *gedp, struct directory *dp, int verbose) -{ - int id; - struct rt_db_internal intern; - - RT_CK_DBI(gedp->dbip); - - if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { - /* this is the _GLOBAL object */ - struct bu_attribute_value_set avs; - struct bu_attribute_value_pair *avp; - - bu_vls_strcat(gedp->ged_result_str, dp->d_namep); - bu_vls_strcat(gedp->ged_result_str, ": global attributes object\n"); - bu_avs_init_empty(&avs); - if (db5_get_attributes(gedp->dbip, &avs, dp)) { - bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for %s\n", dp->d_namep); - return; - } -/* !!! left off here*/ - for (BU_AVS_FOR(avp, &avs)) { - if (BU_STR_EQUAL(avp->name, "units")) { - double conv; - const char *str; - - conv = atof(avp->value); - bu_vls_strcat(gedp->ged_result_str, "\tunits: "); - - str = bu_units_string(conv); - if (str == NULL) { - bu_vls_strcat(gedp->ged_result_str, "Unrecognized units\n"); - } else { - bu_vls_strcat(gedp->ged_result_str, str); - bu_vls_putc(gedp->ged_result_str, '\n'); - } - } else { - bu_vls_putc(gedp->ged_result_str, '\t'); - bu_vls_strcat(gedp->ged_result_str, avp->name); - bu_vls_strcat(gedp->ged_result_str, ": "); - bu_vls_strcat(gedp->ged_result_str, avp->value); - bu_vls_putc(gedp->ged_result_str, '\n'); - } - } - } else { - - if ((id = rt_db_get_internal(&intern, dp, gedp->dbip, - (fastf_t *)NULL, &rt_uniresource)) < 0) { - bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal(%s) failure\n", dp->d_namep); - rt_db_free_internal(&intern); - return; - } - - bu_vls_printf(gedp->ged_result_str, "%s: ", dp->d_namep); - - if (!OBJ[id].ft_describe || - OBJ[id].ft_describe(gedp->ged_result_str, - &intern, - verbose, - gedp->dbip->dbi_base2local) < 0) - bu_vls_printf(gedp->ged_result_str, "%s: describe error\n", dp->d_namep); - rt_db_free_internal(&intern); - } -} - -/** - * Once the vlist has been created, perform the common tasks - * in handling the drawn solid. - * - * This routine must be prepared to run in parallel. - */ -void -_ged_drawH_part2(int dashflag, struct bu_list *vhead, const struct db_full_path *pathp, struct db_tree_state *tsp, struct _ged_client_data *dgcdp) -{ - - if (dgcdp->vs.color_override) { - unsigned char wcolor[3]; - - wcolor[0] = (unsigned char)dgcdp->vs.color[0]; - wcolor[1] = (unsigned char)dgcdp->vs.color[1]; - wcolor[2] = (unsigned char)dgcdp->vs.color[2]; - dl_add_path(dashflag, vhead, pathp, tsp, wcolor, dgcdp); - } else { - dl_add_path(dashflag, vhead, pathp, tsp, NULL, dgcdp); - } -} - -void -_ged_cvt_vlblock_to_solids(struct ged *gedp, struct bv_vlblock *vbp, const char *name, int copy) -{ - size_t i; - char shortname[32] = {0}; - char namebuf[64] = {0}; - - bu_strlcpy(shortname, name, sizeof(shortname)); - - for (i = 0; i < vbp->nused; i++) { - if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) - continue; - snprintf(namebuf, 64, "%s%lx", shortname, vbp->rgb[i]); - invent_solid(gedp, namebuf, &vbp->head[i], vbp->rgb[i], copy, 1.0, 0, 0); - } -} - -#define WIN_EDITOR "\"c:/Program Files/Windows NT/Accessories/wordpad\"" -#define MAC_EDITOR "/Applications/TextEdit.app/Contents/MacOS/TextEdit" -#define EMACS_EDITOR "emacs" -#define NANO_EDITOR "nano" -#define VIM_EDITOR "vim" -#define VI_EDITOR "vi" - -int -_ged_editit(const char *editstring, const char *filename) -{ -#ifdef HAVE_UNISTD_H - int xpid = 0; - int status = 0; -#endif - int pid = 0; - char **avtmp = (char **)NULL; - const char *terminal = (char *)NULL; - const char *terminal_opt = (char *)NULL; - const char *editor = (char *)NULL; - const char *editor_opt = (char *)NULL; - const char *file = (const char *)filename; - -#if defined(SIGINT) && defined(SIGQUIT) - void (*s2)(int); - void (*s3)(int); -#endif - - if (!file) { - bu_log("INTERNAL ERROR: editit filename missing\n"); - return 0; - } - - char *editstring_cpy = NULL; - - /* convert the edit string into pieces suitable for arguments to execlp */ - - if (editstring != NULL) { - editstring_cpy = bu_strdup(editstring); - avtmp = (char **)bu_calloc(5, sizeof(char *), "ged_editit: editstring args"); - bu_argv_from_string(avtmp, 4, editstring_cpy); - - if (avtmp[0] && !BU_STR_EQUAL(avtmp[0], "(null)")) - terminal = avtmp[0]; - if (avtmp[1] && !BU_STR_EQUAL(avtmp[1], "(null)")) - terminal_opt = avtmp[1]; - if (avtmp[2] && !BU_STR_EQUAL(avtmp[2], "(null)")) - editor = avtmp[2]; - if (avtmp[3] && !BU_STR_EQUAL(avtmp[3], "(null)")) - editor_opt = avtmp[3]; - } else { - editor = getenv("EDITOR"); - - /* still unset? try windows */ - if (!editor || editor[0] == '\0') { - if (bu_file_exists(WIN_EDITOR, NULL)) { - editor = WIN_EDITOR; - } - } - - /* still unset? try mac os x */ - if (!editor || editor[0] == '\0') { - if (bu_file_exists(MAC_EDITOR, NULL)) { - editor = MAC_EDITOR; - } - } - - /* still unset? try emacs */ - if (!editor || editor[0] == '\0') { - editor = bu_which(EMACS_EDITOR); - } - - /* still unset? try nano */ - if (!editor || editor[0] == '\0') { - editor = bu_which(NANO_EDITOR); - } - - /* still unset? try vim */ - if (!editor || editor[0] == '\0') { - editor = bu_which(VIM_EDITOR); - } - - /* still unset? As a last resort, go with vi - - * vi is part of the POSIX standard, which is as - * close as we can get currently to an editor - * that should always be present: - * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html */ - if (!editor || editor[0] == '\0') { - editor = bu_which(VI_EDITOR); - } - } - - if (!editor) { - bu_log("INTERNAL ERROR: editit editor missing\n"); - return 0; - } - - /* print a message to let the user know they need to quit their - * editor before the application will come back to life. - */ - { - size_t length; - struct bu_vls str = BU_VLS_INIT_ZERO; - struct bu_vls sep = BU_VLS_INIT_ZERO; - char *editor_basename; - - if (terminal && editor_opt) { - bu_log("Invoking [%s %s %s] via %s\n\n", editor, editor_opt, file, terminal); - } else if (terminal) { - bu_log("Invoking [%s %s] via %s\n\n", editor, file, terminal); - } else if (editor_opt) { - bu_log("Invoking [%s %s %s]\n\n", editor, editor_opt, file); - } else { - bu_log("Invoking [%s %s]\n\n", editor, file); - } - editor_basename = bu_path_basename(editor, NULL); - bu_vls_sprintf(&str, "\nNOTE: You must QUIT %s before %s will respond and continue.\n", editor_basename, bu_getprogname()); - for (length = bu_vls_strlen(&str) - 2; length > 0; length--) { - bu_vls_putc(&sep, '*'); - } - bu_log("%s%s%s\n\n", bu_vls_addr(&sep), bu_vls_addr(&str), bu_vls_addr(&sep)); - bu_vls_free(&str); - bu_vls_free(&sep); - bu_free(editor_basename, "editor_basename free"); - } - -#if defined(SIGINT) && defined(SIGQUIT) - s2 = signal(SIGINT, SIG_IGN); - s3 = signal(SIGQUIT, SIG_IGN); -#endif - -#ifdef HAVE_UNISTD_H - if ((pid = fork()) < 0) { - perror("fork"); - return 0; - } -#endif - - if (pid == 0) { - /* Don't call bu_log() here in the child! */ - -#if defined(SIGINT) && defined(SIGQUIT) - /* deja vu */ - (void)signal(SIGINT, SIG_DFL); - (void)signal(SIGQUIT, SIG_DFL); -#endif - - { - -#if defined(_WIN32) && !defined(__CYGWIN__) - char buffer[RT_MAXLINE + 1] = {0}; - STARTUPINFO si = {0}; - PROCESS_INFORMATION pi = {0}; - si.cb = sizeof(STARTUPINFO); - si.lpReserved = NULL; - si.lpReserved2 = NULL; - si.cbReserved2 = 0; - si.lpDesktop = NULL; - si.dwFlags = 0; - - snprintf(buffer, RT_MAXLINE, "%s %s", editor, file); - - CreateProcess(NULL, buffer, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); - WaitForSingleObject(pi.hProcess, INFINITE); - return 1; -#else - char *editor_basename = bu_path_basename(editor, NULL); - if (BU_STR_EQUAL(editor_basename, "TextEdit")) { - /* close stdout/stderr so we don't get blather from TextEdit about service registration failure */ - close(fileno(stdout)); - close(fileno(stderr)); - } - bu_free(editor_basename, "editor_basename free"); - - if (!terminal && !editor_opt) { - (void)execlp(editor, editor, file, NULL); - } else if (!terminal) { - (void)execlp(editor, editor, editor_opt, file, NULL); - } else if (terminal && !terminal_opt) { - (void)execlp(terminal, terminal, editor, file, NULL); - } else if (terminal && !editor_opt) { - (void)execlp(terminal, terminal, terminal_opt, editor, file, NULL); - } else { - (void)execlp(terminal, terminal, terminal_opt, editor, editor_opt, file, NULL); - } -#endif - /* should not reach */ - perror(editor); - bu_exit(1, NULL); - } - } - -#ifdef HAVE_UNISTD_H - /* wait for the editor to terminate */ - while ((xpid = wait(&status)) >= 0) { - if (xpid == pid) { - break; - } - } -#endif - -#if defined(SIGINT) && defined(SIGQUIT) - (void)signal(SIGINT, s2); - (void)signal(SIGQUIT, s3); -#endif - - if (editstring != NULL) { - bu_free((void *)avtmp, "ged_editit: avtmp"); - bu_free(editstring_cpy, "editstring copy"); - } - - return 1; -} - -void -_ged_rt_set_eye_model(struct ged *gedp, - vect_t eye_model) -{ - if (gedp->ged_gvp->gv_s->gv_zclip || gedp->ged_gvp->gv_perspective > 0) { - vect_t temp; - - VSET(temp, 0.0, 0.0, 1.0); - MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp); - } else { - /* not doing zclipping, so back out of geometry */ - int i; - vect_t direction; - vect_t extremum[2]; - double t_in; - vect_t diag1; - vect_t diag2; - point_t ecenter; - - VSET(eye_model, -gedp->ged_gvp->gv_center[MDX], - -gedp->ged_gvp->gv_center[MDY], -gedp->ged_gvp->gv_center[MDZ]); - - for (i = 0; i < 3; ++i) { - extremum[0][i] = INFINITY; - extremum[1][i] = -INFINITY; - } - - const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); - if (BU_STR_EQUAL(cmd2, "1")) { - struct bu_ptbl *db_objs = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - (void)scene_bounding_sph(db_objs, &(extremum[0]), &(extremum[1]), 1); - } else { - (void)dl_bounding_sph(gedp->ged_gdp->gd_headDisplay, &(extremum[0]), &(extremum[1]), 1); - } - - VMOVEN(direction, gedp->ged_gvp->gv_rotation + 8, 3); - for (i = 0; i < 3; ++i) - if (NEAR_ZERO(direction[i], 1e-10)) - direction[i] = 0.0; - - VSUB2(diag1, extremum[1], extremum[0]); - VADD2(ecenter, extremum[1], extremum[0]); - VSCALE(ecenter, ecenter, 0.5); - VSUB2(diag2, ecenter, eye_model); - t_in = MAGNITUDE(diag1) + MAGNITUDE(diag2); - VJOIN1(eye_model, eye_model, t_in, direction); - } -} - -void -_ged_rt_output_handler2(void *clientData, int type) -{ - struct ged_subprocess *rrtp = (struct ged_subprocess *)clientData; - int count = 0; - int retcode = 0; - int read_failed_stderr = 0; - int read_failed_stdout = 0; - char line[RT_MAXLINE+1] = {0}; - - if ((rrtp == (struct ged_subprocess *)NULL) || (rrtp->gedp == (struct ged *)NULL)) - return; - - BU_CKMAG(rrtp, GED_CMD_MAGIC, "ged subprocess"); - - struct ged *gedp = rrtp->gedp; - - /* Get data from rt */ - if (rrtp->stderr_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { - read_failed_stderr = 1; - } - if (rrtp->stdout_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDOUT, RT_MAXLINE) <= 0) { - read_failed_stdout = 1; - } - - if (read_failed_stderr || read_failed_stdout) { - int aborted; - - /* Done watching for output, undo subprocess I/O hooks. */ - if (type != -1 && gedp->ged_delete_io_handler) { - - if (rrtp->stdin_active || rrtp->stdout_active || rrtp->stderr_active) { - // If anyone else is still listening, we're not done yet. - if (rrtp->stdin_active) { - (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDIN); - return; - } - if (rrtp->stdout_active) { - (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDOUT); - return; - } - if (rrtp->stderr_active) { - (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDERR); - return; - } - } - - return; - } - - /* Either EOF has been sent or there was a read error. - * there is no need to block indefinitely */ - retcode = bu_process_wait(&aborted, rrtp->p, 120); - - if (aborted) - bu_log("Raytrace aborted.\n"); - else if (retcode) - bu_log("Raytrace failed.\n"); - else - bu_log("Raytrace complete.\n"); - - if (gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) - gedp->ged_gdp->gd_rtCmdNotify(aborted); - - if (rrtp->end_clbk) - rrtp->end_clbk(aborted, rrtp->end_clbk_data); - - /* free rrtp */ - bu_ptbl_rm(&gedp->ged_subp, (long *)rrtp); - BU_PUT(rrtp, struct ged_subprocess); - - return; - } - - /* for feelgoodedness */ - line[count] = '\0'; - - /* handle (i.e., probably log to stderr) the resulting line */ - if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) - ged_output_handler_cb(gedp, line); - else - bu_vls_printf(gedp->ged_result_str, "%s", line); - -} - -void -_ged_rt_output_handler(void *clientData, int mask) -{ - const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); - if (BU_STR_EQUAL(cmd2, "1")) { - _ged_rt_output_handler2(clientData, mask); - return; - } - struct ged_subprocess *rrtp = (struct ged_subprocess *)clientData; - int count = 0; - int retcode = 0; - int read_failed_stderr = 0; - int read_failed_stdout = 0; - char line[RT_MAXLINE+1] = {0}; - - if ((rrtp == (struct ged_subprocess *)NULL) || (rrtp->gedp == (struct ged *)NULL)) - return; - - BU_CKMAG(rrtp, GED_CMD_MAGIC, "ged subprocess"); - - struct ged *gedp = rrtp->gedp; - - /* Get data from rt */ - if (rrtp->stderr_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { - read_failed_stderr = 1; - } - if (rrtp->stdout_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDOUT, RT_MAXLINE) <= 0) { - read_failed_stdout = 1; - } - - if (read_failed_stderr || read_failed_stdout) { - int aborted; - - /* Done watching for output, undo subprocess I/O hooks. */ - if (gedp->ged_delete_io_handler) { - if (rrtp->stderr_active) - (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDERR); - if (rrtp->stdout_active) - (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDOUT); - } - - - /* Either EOF has been sent or there was a read error. - * there is no need to block indefinitely */ - retcode = bu_process_wait(&aborted, rrtp->p, 120); - - if (aborted) - bu_log("Raytrace aborted.\n"); - else if (retcode) - bu_log("Raytrace failed.\n"); - else - bu_log("Raytrace complete.\n"); - - if (gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) - gedp->ged_gdp->gd_rtCmdNotify(aborted); - - if (rrtp->end_clbk) - rrtp->end_clbk(aborted, rrtp->end_clbk_data); - - /* free rrtp */ - bu_ptbl_rm(&gedp->ged_subp, (long *)rrtp); - BU_PUT(rrtp, struct ged_subprocess); - - return; - } - - /* for feelgoodedness */ - line[count] = '\0'; - - /* handle (i.e., probably log to stderr) the resulting line */ - if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) - ged_output_handler_cb(gedp, line); - else - bu_vls_printf(gedp->ged_result_str, "%s", line); - -} - -void -_ged_rt_write(struct ged *gedp, - FILE *fp, - vect_t eye_model, - int argc, - const char **argv) -{ - quat_t quat; - - /* Double-precision IEEE floating point only guarantees 15-17 - * digits of precision; single-precision only 6-9 significant - * decimal digits. Using a %.15e precision specifier makes our - * printed value dip into unreliable territory (1+15 digits). - * Looking through our history, %.14e seems to be safe as the - * value prior to printing quaternions was %.9e, although anything - * from 9->14 "should" be safe as it's above our calculation - * tolerance and above single-precision capability. - */ - fprintf(fp, "viewsize %.14e;\n", gedp->ged_gvp->gv_size); - quat_mat2quat(quat, gedp->ged_gvp->gv_rotation); - fprintf(fp, "orientation %.14e %.14e %.14e %.14e;\n", V4ARGS(quat)); - fprintf(fp, "eye_pt %.14e %.14e %.14e;\n", - eye_model[X], eye_model[Y], eye_model[Z]); - - fprintf(fp, "start 0; clean;\n"); - - /* If no objects were specified, activate all objects currently displayed. - * Otherwise, simply draw the specified objects. If the caller passed - * -1 in argc it means the objects are specified on the command line. - * (TODO - we shouldn't be doing that anywhere for this; long command - * strings make Windows unhappy. Once all the callers have been - * adjusted to pass the object lists for itemization via pipes below, - * remove the -1 case.) */ - if (argc >= 0) { - if (!argc) { - const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); - if (BU_STR_EQUAL(cmd2, "1")) { - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - fprintf(fp, "draw %s;\n", bu_vls_cstr(&g->s_name)); - } - } else { - struct display_list *gdlp; - for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { - if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) - continue; - fprintf(fp, "draw %s;\n", bu_vls_addr(&gdlp->dl_path)); - } - } - } else { - int i = 0; - while (i < argc) { - fprintf(fp, "draw %s;\n", argv[i++]); - } - } - - fprintf(fp, "prep;\n"); - } - - dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); - - dl_write_animate(gedp->ged_gdp->gd_headDisplay, fp); - - dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); - - fprintf(fp, "end;\n"); -} - -int -_ged_run_rt(struct ged *gedp, int cmd_len, const char **gd_rt_cmd, int argc, const char **argv) -{ - FILE *fp_in; - vect_t eye_model; - struct ged_subprocess *run_rtp; - struct bu_process *p = NULL; - - bu_process_exec(&p, gd_rt_cmd[0], cmd_len, gd_rt_cmd, 0, 0); - - if (bu_process_pid(p) == -1) { - bu_vls_printf(gedp->ged_result_str, "\nunable to successfully launch subprocess: "); - for (int i = 0; i < cmd_len; i++) { - bu_vls_printf(gedp->ged_result_str, "%s ", gd_rt_cmd[i]); - } - bu_vls_printf(gedp->ged_result_str, "\n"); - return BRLCAD_ERROR; - } - - if (gedp->ged_subprocess_init_callback) { - (*gedp->ged_subprocess_init_callback)(bu_process_pid(p), gedp->ged_subprocess_clbk_context); - } - - fp_in = bu_process_open(p, BU_PROCESS_STDIN); - - _ged_rt_set_eye_model(gedp, eye_model); - _ged_rt_write(gedp, fp_in, eye_model, argc, argv); - - bu_process_close(p, BU_PROCESS_STDIN); - - BU_GET(run_rtp, struct ged_subprocess); - run_rtp->magic = GED_CMD_MAGIC; - run_rtp->stdin_active = 0; - run_rtp->stdout_active = 0; - run_rtp->stderr_active = 0; - run_rtp->end_clbk = gedp->ged_subprocess_end_callback; - run_rtp->end_clbk_data = gedp->ged_subprocess_clbk_context; - bu_ptbl_ins(&gedp->ged_subp, (long *)run_rtp); - - run_rtp->p = p; - run_rtp->aborted = 0; - run_rtp->gedp = gedp; - - /* If we know how, set up hooks so the parent process knows to watch for output. */ - if (gedp->ged_create_io_handler) { - (*gedp->ged_create_io_handler)(run_rtp, BU_PROCESS_STDERR, _ged_rt_output_handler, (void *)run_rtp); - } - return BRLCAD_OK; -} - -/* - * Add an instance of object 'objp' to combination 'name'. - * If the combination does not exist, it is created. - * region_flag is 1 (region), or 0 (group). - * - * Preserves the GIFT semantics. - */ -struct directory * -_ged_combadd(struct ged *gedp, - struct directory *objp, - char *combname, - int region_flag, /* true if adding region */ - db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ - int ident, /* "Region ID" */ - int air /* Air code */) -{ - int ac = 1; - const char *av[2]; - - av[0] = objp->d_namep; - av[1] = NULL; - - if (_ged_combadd2(gedp, combname, ac, av, region_flag, relation, ident, air, NULL, 1) & BRLCAD_ERROR) - return RT_DIR_NULL; - - /* Done changing stuff - update nref. */ - db_update_nref(gedp->dbip, &rt_uniresource); - - return db_lookup(gedp->dbip, combname, LOOKUP_QUIET); -} - - -/* - * Add an instance of object 'objp' to combination 'name'. - * If the combination does not exist, it is created. - * region_flag is 1 (region), or 0 (group). - * - * Preserves the GIFT semantics. - */ -int -_ged_combadd2(struct ged *gedp, - char *combname, - int argc, - const char *argv[], - int region_flag, /* true if adding region */ - db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ - int ident, /* "Region ID" */ - int air, /* Air code */ - matp_t m, /* Matrix */ - int validate /* 1 to check if new members exist, 0 to just add them */) -{ - struct directory *dp; - struct directory *objp; - struct rt_db_internal intern; - struct rt_comb_internal *comb; - union tree *tp; - struct rt_tree_array *tree_list; - size_t node_count; - size_t actual_count; - size_t curr_count; - int i; - - if (argc < 1) - return BRLCAD_ERROR; - - /* - * Check to see if we have to create a new combination - */ - if ((dp = db_lookup(gedp->dbip, combname, LOOKUP_QUIET)) == RT_DIR_NULL) { - int flags; - - if (region_flag) - flags = RT_DIR_REGION | RT_DIR_COMB; - else - flags = RT_DIR_COMB; - - RT_DB_INTERNAL_INIT(&intern); - intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; - intern.idb_type = ID_COMBINATION; - intern.idb_meth = &OBJ[ID_COMBINATION]; - - GED_DB_DIRADD(gedp, dp, combname, -1, 0, flags, (void *)&intern.idb_type, 0); - - BU_ALLOC(comb, struct rt_comb_internal); - RT_COMB_INTERNAL_INIT(comb); - - intern.idb_ptr = (void *)comb; - - if (region_flag) { - struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - comb->region_flag = 1; - comb->region_id = ident; - comb->aircode = air; - comb->los = wdbp->wdb_los_default; - comb->GIFTmater = wdbp->wdb_mat_default; - bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", ident); - if (air) - bu_vls_printf(gedp->ged_result_str, "air=%d, ", air); - bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", - wdbp->wdb_los_default, - wdbp->wdb_mat_default); - } else { - comb->region_flag = 0; - } - - goto addmembers; - } else if (!(dp->d_flags & RT_DIR_COMB)) { - bu_vls_printf(gedp->ged_result_str, "%s exists, but is not a combination\n", dp->d_namep); - return BRLCAD_ERROR; - } - - /* combination exists, add a new member */ - GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, 0); - - comb = (struct rt_comb_internal *)intern.idb_ptr; - RT_CK_COMB(comb); - - if (region_flag && !comb->region_flag) { - bu_vls_printf(gedp->ged_result_str, "%s: not a region\n", dp->d_namep); - return BRLCAD_ERROR; - } - -addmembers: - if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) { - db_non_union_push(comb->tree, &rt_uniresource); - if (db_ck_v4gift_tree(comb->tree) < 0) { - bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for editing\n"); - rt_db_free_internal(&intern); - return BRLCAD_ERROR; - } - } - - /* make space for an extra leaf */ - curr_count = db_tree_nleaves(comb->tree); - node_count = curr_count + argc; - tree_list = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list"); - - /* flatten tree */ - if (comb->tree) { - actual_count = argc + (struct rt_tree_array *)db_flatten_tree(tree_list, comb->tree, OP_UNION, 1, &rt_uniresource) - tree_list; - BU_ASSERT(actual_count == node_count); - comb->tree = TREE_NULL; - } - - for (i = 0; i < argc; ++i) { - if (validate) { - objp = db_lookup(gedp->dbip, argv[i], LOOKUP_NOISY); - if (objp == RT_DIR_NULL) { - bu_vls_printf(gedp->ged_result_str, "skip member %s\n", argv[i]); - continue; - } - } - - /* insert new member at end */ - switch (relation) { - case DB_OP_INTERSECT: - tree_list[curr_count].tl_op = OP_INTERSECT; - break; - case DB_OP_SUBTRACT: - tree_list[curr_count].tl_op = OP_SUBTRACT; - break; - default: - if (relation != DB_OP_UNION) { - bu_vls_printf(gedp->ged_result_str, "unrecognized relation (assume UNION)\n"); - } - tree_list[curr_count].tl_op = OP_UNION; - break; - } - - /* make new leaf node, and insert at end of list */ - BU_GET(tp, union tree); - RT_TREE_INIT(tp); - tree_list[curr_count].tl_tree = tp; - tp->tr_l.tl_op = OP_DB_LEAF; - tp->tr_l.tl_name = bu_strdup(argv[i]); - if (m) { - tp->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "mat copy"); - MAT_COPY(tp->tr_l.tl_mat, m); - } else { - tp->tr_l.tl_mat = (matp_t)NULL; - } - - ++curr_count; - } - - /* rebuild the tree */ - comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, &rt_uniresource); - - /* and finally, write it out */ - GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, 0); - - bu_free((char *)tree_list, "combadd: tree_list"); - - /* Done changing stuff - update nref. */ - db_update_nref(gedp->dbip, &rt_uniresource); - - return BRLCAD_OK; -} - -void -_ged_wait_status(struct bu_vls *logstr, - int status) -{ - int sig = status & 0x7f; - int core = status & 0x80; - int ret = status >> 8; - - if (status == 0) { - bu_vls_printf(logstr, "Normal exit\n"); - return; - } - - bu_vls_printf(logstr, "Abnormal exit x%x", status); - - if (core) - bu_vls_printf(logstr, ", core dumped"); - - if (sig) - bu_vls_printf(logstr, ", terminating signal = %d", sig); - else - bu_vls_printf(logstr, ", return (exit) code = %d", ret); -} - -struct directory ** -_ged_build_dpp(struct ged *gedp, - const char *path) { - struct directory *dp; - struct directory **dpp; - int i; - char *begin; - char *end; - char *newstr; - char *list; - int ac; - const char **av; - const char **av_orig = NULL; - struct bu_vls vls = BU_VLS_INIT_ZERO; - - /* - * First, build an array of the object's path components. - * We store the list in av_orig below. - */ - newstr = bu_strdup(path); - begin = newstr; - while ((end = strchr(begin, '/')) != NULL) { - *end = '\0'; - bu_vls_printf(&vls, "%s ", begin); - begin = end + 1; - } - bu_vls_printf(&vls, "%s ", begin); - free((void *)newstr); - - list = bu_vls_addr(&vls); - - if (bu_argv_from_tcl_list(list, &ac, &av_orig) != 0) { - bu_vls_printf(gedp->ged_result_str, "-1"); - bu_vls_free(&vls); - return (struct directory **)NULL; - } - - /* skip first element if empty */ - av = av_orig; - if (*av[0] == '\0') { - --ac; - ++av; - } - - /* ignore last element if empty */ - if (*av[ac-1] == '\0') - --ac; - - /* - * Next, we build an array of directory pointers that - * correspond to the object's path. - */ - dpp = (struct directory **)bu_calloc((size_t)ac+1, sizeof(struct directory *), "_ged_build_dpp: directory pointers"); - for (i = 0; i < ac; ++i) { - if ((dp = db_lookup(gedp->dbip, av[i], 0)) != RT_DIR_NULL) - dpp[i] = dp; - else { - /* object is not currently being displayed */ - bu_vls_printf(gedp->ged_result_str, "-1"); - - bu_free((void *)dpp, "_ged_build_dpp: directory pointers"); - bu_free((char *)av_orig, "free av_orig"); - bu_vls_free(&vls); - return (struct directory **)NULL; - } - } - - dpp[i] = RT_DIR_NULL; - - bu_free((char *)av_orig, "free av_orig"); - bu_vls_free(&vls); - return dpp; -} - -/* - * This routine walks through the directory entry list and mallocs enough - * space for pointers to hold: - * a) all of the entries if called with an argument of 0, or - * b) the number of entries specified by the argument if > 0. - */ -struct directory ** -_ged_dir_getspace(struct db_i *dbip, - size_t num_entries) -{ - size_t i; - struct directory **dir_basep; - struct directory *dp; - - if (num_entries == 0) { - /* Set num_entries to the number of entries */ - for (i = 0; i < RT_DBNHASH; i++) - for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) - num_entries++; - } - - /* Allocate and cast num_entries worth of pointers */ - dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *), - "dir_getspace *dir[]"); - return dir_basep; -} - -int -_ged_set_metaball(struct ged *gedp, struct rt_metaball_internal *mbip, const char *attribute, fastf_t sf) -{ - RT_METABALL_CK_MAGIC(mbip); - - switch (attribute[0]) { - case 'm': - case 'M': - if (sf <= METABALL_METABALL) - mbip->method = METABALL_METABALL; - else if (sf >= METABALL_BLOB) - mbip->method = METABALL_BLOB; - else - mbip->method = (int)sf; - - break; - case 't': - case 'T': - if (sf < 0) - mbip->threshold = -sf; - else - mbip->threshold = sf; - - break; - default: - bu_vls_printf(gedp->ged_result_str, "bad metaball attribute - %s", attribute); - return BRLCAD_ERROR; - } - - return BRLCAD_OK; -} - -int -_ged_select_botpts(struct ged *gedp, struct rt_bot_internal *botip, double vx, double vy, double vwidth, double vheight, double vminz, int rflag) -{ - size_t i; - fastf_t vr = 0.0; - fastf_t vmin_x = 0.0; - fastf_t vmin_y = 0.0; - fastf_t vmax_x = 0.0; - fastf_t vmax_y = 0.0; - - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - GED_CHECK_VIEW(gedp, BRLCAD_ERROR); - - if (rflag) { - vr = vwidth; - } else { - vmin_x = vx; - vmin_y = vy; - - if (vwidth > 0) - vmax_x = vx + vwidth; - else { - vmin_x = vx + vwidth; - vmax_x = vx; - } - - if (vheight > 0) - vmax_y = vy + vheight; - else { - vmin_y = vy + vheight; - vmax_y = vy; - } - } - - if (rflag) { - for (i = 0; i < botip->num_vertices; i++) { - point_t vloc; - point_t vpt; - vect_t diff; - fastf_t mag; - - MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]); - - if (vpt[Z] < vminz) - continue; - - VSET(vloc, vx, vy, vpt[Z]); - VSUB2(diff, vpt, vloc); - mag = MAGNITUDE(diff); - - if (mag > vr) - continue; - - bu_vls_printf(gedp->ged_result_str, "%zu ", i); - } - } else { - for (i = 0; i < botip->num_vertices; i++) { - point_t vpt; - - MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]); - - if (vpt[Z] < vminz) - continue; - - if (vmin_x <= vpt[X] && vpt[X] <= vmax_x && - vmin_y <= vpt[Y] && vpt[Y] <= vmax_y) { - bu_vls_printf(gedp->ged_result_str, "%zu ", i); - } - } - } - - return BRLCAD_OK; -} - -/* - * Returns point mbp_i. - */ -struct wdb_metaball_pnt * -_ged_get_metaball_pt_i(struct rt_metaball_internal *mbip, int mbp_i) -{ - int i = 0; - struct wdb_metaball_pnt *curr_mbpp; - - for (BU_LIST_FOR(curr_mbpp, wdb_metaball_pnt, &mbip->metaball_ctrl_head)) { - if (i == mbp_i) - return curr_mbpp; - - ++i; - } - - return (struct wdb_metaball_pnt *)NULL; -} - - -#define GED_METABALL_SCALE(_d, _scale) \ - if ((_scale) < 0.0) \ - (_d) = -(_scale); \ - else \ - (_d) *= (_scale); - -int -_ged_scale_metaball(struct ged *gedp, struct rt_metaball_internal *mbip, const char *attribute, fastf_t sf, int rflag) -{ - int mbp_i; - struct wdb_metaball_pnt *mbpp; - - RT_METABALL_CK_MAGIC(mbip); - - if (!rflag && sf > 0) - sf = -sf; - - switch (attribute[0]) { - case 'f': - case 'F': - if (sscanf(attribute+1, "%d", &mbp_i) != 1) - mbp_i = 0; - - if ((mbpp = _ged_get_metaball_pt_i(mbip, mbp_i)) == (struct wdb_metaball_pnt *)NULL) - return BRLCAD_ERROR; - - BU_CKMAG(mbpp, WDB_METABALLPT_MAGIC, "wdb_metaball_pnt"); - GED_METABALL_SCALE(mbpp->fldstr, sf); - - break; - case 's': - case 'S': - if (sscanf(attribute+1, "%d", &mbp_i) != 1) - mbp_i = 0; - - if ((mbpp = _ged_get_metaball_pt_i(mbip, mbp_i)) == (struct wdb_metaball_pnt *)NULL) - return BRLCAD_ERROR; - - BU_CKMAG(mbpp, WDB_METABALLPT_MAGIC, "wdb_metaball_pnt"); - GED_METABALL_SCALE(mbpp->sweat, sf); - - break; - default: - bu_vls_printf(gedp->ged_result_str, "bad metaball attribute - %s", attribute); - return BRLCAD_ERROR; - } - - return BRLCAD_OK; -} - -#if 0 - -// TODO - need to generalize the path specifier parsing per notes in TODO. This is a first -// cut at recasting what search is using now, which doesn't implement the full resolving logic. - -int -_ged_characterize_pathspec(struct bu_vls *normalized, struct ged *gedp, const char *pathspec) -{ - struct bu_vls np = BU_VLS_INIT_ZERO; - int flags = 0; - - // Start with nothing - if we get a valid answer we'll print it - if (normalized) { - bu_vls_trunc(normalized, 0); - } - - if (!pathspec) - return GED_PATHSPEC_INVALID; - - if (BU_STR_EQUAL(pathspec, "/")) - return flags; - - if (BU_STR_EQUAL(pathspec, ".")) { - flags |= GED_PATHSPEC_LOCAL; - return flags; - } - - if (BU_STR_EQUAL(pathspec, "|")) { - flags |= GED_PATHSPEC_FLAT; - return flags; - } - - bu_vls_sprintf(&np, "%s", pathspec); - if (bu_vls_cstr(&np)[0] == '|') { - flags |= GED_PATHSPEC_FLAT; - bu_vls_nibble(&np, 1); - } - if (BU_STR_EQUAL(bu_vls_cstr(&np), "/")) { - bu_vls_free(&np); - return flags; - } - - if (BU_STR_EQUAL(bu_vls_cstr(&np), ".")) { - flags |= GED_PATHSPEC_LOCAL; - bu_vls_free(&np); - return flags; - } - - if (bu_vls_cstr(&np)[0] != '/') - flags |= GED_PATHSPEC_LOCAL; - - const char *bu_norm = bu_path_normalize(bu_vls_cstr(&np)); - - if (bu_norm && !BU_STR_EQUAL(bu_norm , "/")) { - struct bu_vls tmp = BU_VLS_INIT_ZERO; - char *tbasename = bu_path_basename(bu_vls_cstr(&np), NULL); - bu_vls_sprintf(&tmp, "%s", tbasename); - bu_free(tbasename, "free bu_path_basename string (caller's responsibility per bu/log.h)"); - bu_vls_sprintf(&np, "%s", bu_vls_cstr(&tmp)); - bu_vls_free(&tmp); - } else { - bu_vls_sprintf(&np, "%s", "/"); - } - - // If we've gotten this far, normalizing to nothing is considered invalid. - if (!bu_vls_strlen(&np)) { - bu_vls_free(&np); - return GED_PATHSPEC_INVALID; - } - - // If we reduced to the root fullpath, we're done - if (BU_STR_EQUAL(bu_vls_cstr(&np), "/")) { - bu_vls_free(&np); - return flags; - } - - /* We've handled the toplevel special cases. If we got here, we have a specific - * path - now the only question is whether that path is valid */ - flags |= GED_PATHSPEC_SPECIFIC; - struct directory *path_dp = db_lookup(gedp->dbip, bu_vls_cstr(&np), LOOKUP_QUIET); - if (path_dp == RT_DIR_NULL) { - flags = GED_PATHSPEC_INVALID; - } else { - if (normalized) - bu_vls_sprintf(normalized, "%s", bu_vls_cstr(&np)); - } - bu_vls_free(&np); - - return flags; -} - -#endif - - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libged/ged_util.cpp b/src/libged/ged_util.cpp new file mode 100644 index 00000000000..5335443e57a --- /dev/null +++ b/src/libged/ged_util.cpp @@ -0,0 +1,2488 @@ +/* G E D _ U T I L . C + * BRL-CAD + * + * Copyright (c) 2000-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup libged */ +/** @{ */ +/** @file libged/ged_util.c + * + * Utility routines for common operations in libged. + * + */ +/** @} */ + +#include "common.h" + +#include +#include + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include "bio.h" +#include "bresource.h" + + +#include "bu/app.h" +#include "bu/cmd.h" +#include "bu/file.h" +#include "bu/opt.h" +#include "bu/path.h" +#include "bu/sort.h" +#include "bu/str.h" +#include "bu/units.h" +#include "bu/vls.h" +#include "bv.h" + +#include "ged.h" +#include "./ged_private.h" + +int +_ged_subcmd_help(struct ged *gedp, struct bu_opt_desc *gopts, const struct bu_cmdtab *cmds, const char *cmdname, const char *cmdargs, void *gd, int argc, const char **argv) +{ + if (!gedp || !gopts || !cmds || !cmdname) + return BRLCAD_ERROR; + + if (!argc || !argv || BU_STR_EQUAL(argv[0], "help")) { + bu_vls_printf(gedp->ged_result_str, "%s %s\n", cmdname, cmdargs); + if (gopts) { + char *option_help = bu_opt_describe(gopts, NULL); + if (option_help) { + bu_vls_printf(gedp->ged_result_str, "Options:\n%s\n", option_help); + bu_free(option_help, "help str"); + } + } + bu_vls_printf(gedp->ged_result_str, "Available subcommands:\n"); + const struct bu_cmdtab *ctp = NULL; + int ret; + const char *helpflag[2]; + helpflag[1] = PURPOSEFLAG; + size_t maxcmdlen = 0; + + // It's possible for a command table to associate multiple strings with + // the same function, for compatibility or convenience. In those + // instances, rather than repeat the same line, we instead group all + // strings leading to the same subcommand together. + std::vector uniq_cmds; + std::map> cmd_strings; + std::map cmd_labels; + for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { + cmd_strings[ctp->ct_func].insert(std::string(ctp->ct_name)); + } + std::map>::iterator c_it; + for (c_it = cmd_strings.begin(); c_it != cmd_strings.end(); c_it++) { + std::set::iterator s_it; + std::string label; + for (s_it = c_it->second.begin(); s_it != c_it->second.end(); s_it++) { + if (s_it != c_it->second.begin()) + label.append(std::string(",")); + label.append(*s_it); + } + cmd_labels[c_it->first] = label; + } + std::map::iterator l_it; + for (l_it = cmd_labels.begin(); l_it != cmd_labels.end(); l_it++) + maxcmdlen = (maxcmdlen > l_it->second.length()) ? maxcmdlen : l_it->second.length(); + + std::set processed_funcs; + + for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { + if (processed_funcs.find(ctp->ct_func) != processed_funcs.end()) + continue; + processed_funcs.insert(ctp->ct_func); + std::string &lbl = cmd_labels[ctp->ct_func]; + bu_vls_printf(gedp->ged_result_str, " %s%*s", lbl.c_str(), (int)(maxcmdlen - lbl.length()) + 2, " "); + if (!BU_STR_EQUAL(ctp->ct_name, "help")) { + helpflag[0] = ctp->ct_name; + bu_cmd(cmds, 2, helpflag, 0, gd, &ret); + } else { + bu_vls_printf(gedp->ged_result_str, "print help and exit\n"); + } + } + } else { + int ret; + const char **helpargv = (const char **)bu_calloc((size_t)argc+1, sizeof(char *), "help argv"); + helpargv[0] = argv[0]; + helpargv[1] = HELPFLAG; + for (int i = 1; i < argc; i++) { + helpargv[i+1] = argv[i]; + } + bu_cmd(cmds, argc+1, helpargv, 0, gd, &ret); + bu_free((void *)helpargv, "help argv"); + return ret; + } + + return BRLCAD_OK; +} + +int +_ged_subcmd_exec(struct ged *gedp, struct bu_opt_desc *gopts, const struct bu_cmdtab *cmds, const char *cmdname, const char *cmdargs, void *gd, int argc, const char **argv, int help, int cmd_pos) +{ + if (!gedp || !gopts || !cmds || !cmdname) + return BRLCAD_ERROR; + + if (help) { + if (cmd_pos >= 0) { + argc = argc - cmd_pos; + argv = &argv[cmd_pos]; + _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, argc, argv); + } else { + _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, 0, NULL); + } + return BRLCAD_OK; + } + + // Must have a subcommand + if (cmd_pos == -1) { + bu_vls_printf(gedp->ged_result_str, ": no valid subcommand specified\n"); + _ged_subcmd_help(gedp, gopts, cmds, cmdname, cmdargs, gd, 0, NULL); + return BRLCAD_ERROR; + } + + int ret; + if (bu_cmd(cmds, argc, argv, 0, (void *)gd, &ret) == BRLCAD_OK) { + return ret; + } else { + bu_vls_printf(gedp->ged_result_str, "subcommand %s not defined", argv[0]); + } + + + return BRLCAD_OK; +} + +int +_ged_subcmd2_help(struct ged *gedp, struct bu_opt_desc *gopts, std::map &subcmds, const char *cmdname, const char *cmdargs, int argc, const char **argv) +{ + if (!gedp || !gopts || !cmdname) + return BRLCAD_ERROR; + + if (!argc || !argv || BU_STR_EQUAL(argv[0], "help")) { + bu_vls_printf(gedp->ged_result_str, "%s %s\n", cmdname, cmdargs); + if (gopts) { + char *option_help = bu_opt_describe(gopts, NULL); + if (option_help) { + bu_vls_printf(gedp->ged_result_str, "Options:\n%s\n", option_help); + bu_free(option_help, "help str"); + } + } + bu_vls_printf(gedp->ged_result_str, "Available subcommands:\n"); + + // It's possible for a command table to associate multiple strings with + // the same function, for compatibility or convenience. In those + // instances, rather than repeat the same line, we instead group all + // strings leading to the same subcommand together. + + // Group the strings referencing the same method + std::map> cmd_strings; + std::map::iterator cm_it; + for (cm_it = subcmds.begin(); cm_it != subcmds.end(); cm_it++) + cmd_strings[cm_it->second].insert(cm_it->first); + + // Generate the labels to be printed + std::map cmd_labels; + std::map>::iterator c_it; + for (c_it = cmd_strings.begin(); c_it != cmd_strings.end(); c_it++) { + std::set::iterator s_it; + std::string label; + for (s_it = c_it->second.begin(); s_it != c_it->second.end(); s_it++) { + if (s_it != c_it->second.begin()) + label.append(std::string(",")); + label.append(*s_it); + } + cmd_labels[c_it->first] = label; + } + + // Find the maximum label length we need to accommodate when printing + std::map::iterator l_it; + size_t maxcmdlen = 0; + for (l_it = cmd_labels.begin(); l_it != cmd_labels.end(); l_it++) + maxcmdlen = (maxcmdlen > l_it->second.length()) ? maxcmdlen : l_it->second.length(); + + // Generate the help table + std::set processed_funcs; + for (cm_it = subcmds.begin(); cm_it != subcmds.end(); cm_it++) { + // We're only going to print one line per unique, even if the + // command has multiple aliases in the table + if (processed_funcs.find(cm_it->second) != processed_funcs.end()) + continue; + processed_funcs.insert(cm_it->second); + + // Unseen command - print + std::string &lbl = cmd_labels[cm_it->second]; + bu_vls_printf(gedp->ged_result_str, " %s%*s", lbl.c_str(), (int)(maxcmdlen - lbl.length()) + 2, " "); + bu_vls_printf(gedp->ged_result_str, "%s\n", cm_it->second->purpose().c_str()); + } + } else { + + std::map::iterator cm_it = subcmds.find(std::string(cmdname)); + if (cm_it == subcmds.end()) + return BRLCAD_ERROR; + bu_vls_printf(gedp->ged_result_str, "%s", cm_it->second->usage().c_str()); + return BRLCAD_OK; + + } + + return BRLCAD_OK; +} + + + +void +ged_push_scene_obj(struct ged *gedp, struct bv_scene_obj *sp) +{ + BV_FREE_VLIST(&RTG.rtg_vlfree, &(sp->s_vlist)); + if (sp->s_u_data) { + struct ged_bv_data *bdata = (struct ged_bv_data *)sp->s_u_data; + bdata->s_fullpath.fp_len = 0; // Don't free memory, but implicitly clear contents + } + bu_ptbl_ins(&gedp->free_solids, (long *)sp); +} + +struct bv_scene_obj * +ged_pop_scene_obj(struct ged *gedp) +{ + struct bv_scene_obj *sp = NULL; + if (BU_PTBL_LEN(&gedp->free_solids)) { + sp = (struct bv_scene_obj *)BU_PTBL_GET(&gedp->free_solids, (BU_PTBL_LEN(&gedp->free_solids) - 1)); + bu_ptbl_rm(&gedp->free_solids, (long *)sp); + } else { + BU_ALLOC(sp, struct bv_scene_obj); // from GET_BV_SCENE_OBJ in bv/defines.h + struct ged_bv_data *bdata; + BU_GET(bdata, struct ged_bv_data); + db_full_path_init(&bdata->s_fullpath); + sp->s_u_data = (void *)bdata; + } + return sp; +} + +/* NOTE - caller must initialize vmin and vmax to INFINITY and -INFINITY + * respectively (we don't do it here so callers may run this routine + * repeatedly over different tables to accumulate bounds. */ +static int +scene_bounding_sph(struct bu_ptbl *so, vect_t *vmin, vect_t *vmax, int pflag) +{ + struct bv_scene_obj *sp; + vect_t minus, plus; + int is_empty = 1; + + /* calculate the bounding for of all solids being displayed */ + for (size_t i = 0; i < BU_PTBL_LEN(so); i++) { + struct bv_scene_group *g = (struct bv_scene_group *)BU_PTBL_GET(so, i); + if (BU_PTBL_LEN(&g->children)) { + for (size_t j = 0; j < BU_PTBL_LEN(&g->children); j++) { + sp = (struct bv_scene_obj *)BU_PTBL_GET(&g->children, j); + minus[X] = sp->s_center[X] - sp->s_size; + minus[Y] = sp->s_center[Y] - sp->s_size; + minus[Z] = sp->s_center[Z] - sp->s_size; + VMIN((*vmin), minus); + plus[X] = sp->s_center[X] + sp->s_size; + plus[Y] = sp->s_center[Y] + sp->s_size; + plus[Z] = sp->s_center[Z] + sp->s_size; + VMAX((*vmax), plus); + + is_empty = 0; + } + } else { + // If we're an evaluated object, the group itself has the + // necessary info. + minus[X] = g->s_center[X] - g->s_size; + minus[Y] = g->s_center[Y] - g->s_size; + minus[Z] = g->s_center[Z] - g->s_size; + VMIN((*vmin), minus); + plus[X] = g->s_center[X] + g->s_size; + plus[Y] = g->s_center[Y] + g->s_size; + plus[Z] = g->s_center[Z] + g->s_size; + VMAX((*vmax), plus); + } + } + if (!pflag) { + bu_log("todo - handle pflag\n"); + } + + return is_empty; +} + + +int +_ged_results_init(struct ged_results *results) +{ + if (UNLIKELY(!results)) + return BRLCAD_ERROR; + BU_ALLOC(results->results_tbl, struct bu_ptbl); + BU_PTBL_INIT(results->results_tbl); + return BRLCAD_OK; +} + + +int +_ged_results_add(struct ged_results *results, const char *result_string) +{ + /* If there isn't a string, we can live with that */ + if (UNLIKELY(!result_string)) + return BRLCAD_OK; + + /* If we have nowhere to insert into and we *do* have a string, trouble */ + if (UNLIKELY(!results)) + return BRLCAD_ERROR; + if (UNLIKELY(!(results->results_tbl))) + return BRLCAD_ERROR; + if (UNLIKELY(!(BU_PTBL_IS_INITIALIZED(results->results_tbl)))) + return BRLCAD_ERROR; + + /* We're good to go - copy the string and stuff it in. */ + bu_ptbl_ins(results->results_tbl, (long *)bu_strdup(result_string)); + + return BRLCAD_OK; +} + +size_t +ged_results_count(struct ged_results *results) +{ + if (UNLIKELY(!results)) return 0; + if (UNLIKELY(!(results->results_tbl))) return 0; + return (size_t)BU_PTBL_LEN(results->results_tbl); +} + +const char * +ged_results_get(struct ged_results *results, size_t index) +{ + return (const char *)BU_PTBL_GET(results->results_tbl, index); +} + +void +ged_results_clear(struct ged_results *results) +{ + int i = 0; + if (UNLIKELY(!results)) return; + if (UNLIKELY(!(results->results_tbl))) return; + + /* we clean up everything except the ged_results structure itself */ + for (i = (int)BU_PTBL_LEN(results->results_tbl) - 1; i >= 0; i--) { + char *rstring = (char *)BU_PTBL_GET(results->results_tbl, i); + if (rstring) + bu_free(rstring, "free results string"); + } + bu_ptbl_reset(results->results_tbl); +} + +void +ged_results_free(struct ged_results *results) { + if (UNLIKELY(!results)) return; + if (UNLIKELY(!(results->results_tbl))) return; + + ged_results_clear(results); + bu_ptbl_free(results->results_tbl); + bu_free(results->results_tbl, "done with results ptbl"); +} + +/*********************************************************/ +/* comparison functions for bu_sort */ +/*********************************************************/ + +/** + * Given two pointers to pointers to directory entries, do a string + * compare on the respective names and return that value. + */ +int +cmpdirname(const void *a, const void *b, void *UNUSED(arg)) +{ + struct directory **dp1, **dp2; + + dp1 = (struct directory **)a; + dp2 = (struct directory **)b; + return bu_strcmp((*dp1)->d_namep, (*dp2)->d_namep); +} + +/** + * Given two pointers to pointers to directory entries, compare + * the dp->d_len sizes. + */ +int +cmpdlen(const void *a, const void *b, void *UNUSED(arg)) +{ + int cmp = 0; + struct directory **dp1, **dp2; + + dp1 = (struct directory **)a; + dp2 = (struct directory **)b; + if ((*dp1)->d_len > (*dp2)->d_len) cmp = 1; + if ((*dp1)->d_len < (*dp2)->d_len) cmp = -1; + return cmp; +} + +/*********************************************************/ +/* _ged_vls_col_pr4v */ +/*********************************************************/ + + +void +_ged_vls_col_pr4v(struct bu_vls *vls, + struct directory **list_of_names, + size_t num_in_list, + int no_decorate, + int ssflag) +{ + size_t lines, i, j, k, this_one; + size_t namelen; + size_t maxnamelen; /* longest name in list */ + size_t cwidth; /* column width */ + size_t numcol; /* number of columns */ + + if (!ssflag) { + bu_sort((void *)list_of_names, + (unsigned)num_in_list, (unsigned)sizeof(struct directory *), + cmpdirname, NULL); + } else { + bu_sort((void *)list_of_names, + (unsigned)num_in_list, (unsigned)sizeof(struct directory *), + cmpdlen, NULL); + } + + /* + * Traverse the list of names, find the longest name and set the + * the column width and number of columns accordingly. If the + * longest name is greater than 80 characters, the number of + * columns will be one. + */ + maxnamelen = 0; + for (k = 0; k < num_in_list; k++) { + namelen = strlen(list_of_names[k]->d_namep); + if (namelen > maxnamelen) + maxnamelen = namelen; + } + + if (maxnamelen <= 16) + maxnamelen = 16; + cwidth = maxnamelen + 4; + + if (cwidth > 80) + cwidth = 80; + numcol = GED_TERMINAL_WIDTH / cwidth; + + /* + * For the number of (full and partial) lines that will be needed, + * print in vertical format. + */ + lines = (num_in_list + (numcol - 1)) / numcol; + for (i = 0; i < lines; i++) { + for (j = 0; j < numcol; j++) { + this_one = j * lines + i; + bu_vls_printf(vls, "%s", list_of_names[this_one]->d_namep); + namelen = strlen(list_of_names[this_one]->d_namep); + + /* + * Region and ident checks here.... Since the code has + * been modified to push and sort on pointers, the + * printing of the region and ident flags must be delayed + * until now. There is no way to make the decision on + * where to place them before now. + */ + if (!no_decorate && list_of_names[this_one]->d_flags & RT_DIR_COMB) { + bu_vls_putc(vls, '/'); + namelen++; + } + + if (!no_decorate && list_of_names[this_one]->d_flags & RT_DIR_REGION) { + bu_vls_putc(vls, 'R'); + namelen++; + } + + /* + * Size check (partial lines), and line termination. Note + * that this will catch the end of the lines that are full + * too. + */ + if (this_one + lines >= num_in_list) { + bu_vls_putc(vls, '\n'); + break; + } else { + /* + * Pad to next boundary as there will be another entry + * to the right of this one. + */ + while (namelen++ < cwidth) + bu_vls_putc(vls, ' '); + } + } + } +} + +/*********************************************************/ + +struct directory ** +_ged_getspace(struct db_i *dbip, + size_t num_entries) +{ + struct directory **dir_basep; + + if (num_entries == 0) + num_entries = db_directory_size(dbip); + + /* Allocate and cast num_entries worth of pointers */ + dir_basep = (struct directory **) bu_calloc((num_entries+1), sizeof(struct directory *), "_ged_getspace *dir[]"); + return dir_basep; +} + + +void +_ged_cmd_help(struct ged *gedp, const char *usage, struct bu_opt_desc *d) +{ + struct bu_vls str = BU_VLS_INIT_ZERO; + char *option_help; + + bu_vls_sprintf(&str, "%s", usage); + + if ((option_help = bu_opt_describe(d, NULL))) { + bu_vls_printf(&str, "Options:\n%s\n", option_help); + bu_free(option_help, "help str"); + } + + bu_vls_vlscat(gedp->ged_result_str, &str); + bu_vls_free(&str); +} + +// TODO - replace with bu_opt_incr_long +int +_ged_vopt(struct bu_vls *UNUSED(msg), size_t UNUSED(argc), const char **UNUSED(argv), void *set_var) +{ + int *v_set = (int *)set_var; + if (v_set) { + (*v_set) = (*v_set) + 1; + } + return 0; +} + +/* Sort the argv array to list existing objects first and everything else at + * the end. Returns the number of argv entries where db_lookup failed */ +int +_ged_sort_existing_objs(struct ged *gedp, int argc, const char *argv[], struct directory **dpa) +{ + int i = 0; + int exist_cnt = 0; + int nonexist_cnt = 0; + struct directory *dp; + const char **exists = (const char **)bu_calloc(argc, sizeof(const char *), "obj exists array"); + const char **nonexists = (const char **)bu_calloc(argc, sizeof(const char *), "obj nonexists array"); + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + for (i = 0; i < argc; i++) { + dp = db_lookup(gedp->dbip, argv[i], LOOKUP_QUIET); + if (dp == RT_DIR_NULL) { + nonexists[nonexist_cnt] = argv[i]; + nonexist_cnt++; + } else { + exists[exist_cnt] = argv[i]; + if (dpa) dpa[exist_cnt] = dp; + exist_cnt++; + } + } + for (i = 0; i < exist_cnt; i++) { + argv[i] = exists[i]; + } + for (i = 0; i < nonexist_cnt; i++) { + argv[i + exist_cnt] = nonexists[i]; + } + + bu_free((void *)exists, "exists array"); + bu_free((void *)nonexists, "nonexists array"); + + return nonexist_cnt; +} + + + +/** + * Returns + * 0 on success + * !0 on failure + */ +static int +_ged_densities_from_file(struct analyze_densities **dens, char **den_src, struct ged *gedp, const char *name, int fault_tolerant) +{ + struct analyze_densities *densities; + struct bu_mapped_file *dfile = NULL; + struct bu_vls msgs = BU_VLS_INIT_ZERO; + char *buf = NULL; + int ret = 0; + int ecnt = 0; + + if (gedp == GED_NULL || gedp->dbip == NULL || !dens) { + return BRLCAD_ERROR; + } + + if (!bu_file_exists(name, NULL)) { + bu_vls_printf(gedp->ged_result_str, "Could not find density file - %s\n", name); + return BRLCAD_ERROR; + } + + dfile = bu_open_mapped_file(name, "densities file"); + if (!dfile) { + bu_vls_printf(gedp->ged_result_str, "Could not open density file - %s\n", name); + return BRLCAD_ERROR; + } + + buf = (char *)(dfile->buf); + + (void)analyze_densities_create(&densities); + + ret = analyze_densities_load(densities, buf, &msgs, &ecnt); + + if (!fault_tolerant && ecnt > 0) { + bu_vls_printf(gedp->ged_result_str, "Problem reading densities file %s:\n%s\n", name, bu_vls_cstr(&msgs)); + if (densities) { + analyze_densities_destroy(densities); + } + bu_vls_free(&msgs); + bu_close_mapped_file(dfile); + return BRLCAD_ERROR; + } + + bu_vls_free(&msgs); + bu_close_mapped_file(dfile); + + (*dens) = densities; + if (ret > 0) { + if (den_src) { + (*den_src) = bu_strdup(name); + } + } else { + if (ret == 0 && densities) { + analyze_densities_destroy(densities); + } + } + + return (ret == 0) ? BRLCAD_ERROR : BRLCAD_OK; +} + +/** + * Load density information. + * + * Returns + * 0 on success + * !0 on failure + */ +int +_ged_read_densities(struct analyze_densities **dens, char **den_src, struct ged *gedp, const char *filename, int fault_tolerant) +{ + struct bu_vls d_path_dir = BU_VLS_INIT_ZERO; + + if (gedp == GED_NULL || gedp->dbip == DBI_NULL || !dens) { + return BRLCAD_ERROR; + } + + /* If we've explicitly been given a file, read that */ + if (filename) { + return _ged_densities_from_file(dens, den_src, gedp, filename, fault_tolerant); + } + + /* If we don't have an explicitly specified file, see if we have definitions in + * the database itself. */ + if (gedp->dbip != DBI_NULL) { + int ret = 0; + int ecnt = 0; + struct bu_vls msgs = BU_VLS_INIT_ZERO; + struct directory *dp; + struct rt_db_internal intern; + struct rt_binunif_internal *bip; + struct analyze_densities *densities; + char *buf; + + dp = db_lookup(gedp->dbip, GED_DB_DENSITY_OBJECT, LOOKUP_QUIET); + + if (dp != (struct directory *)NULL) { + + if (rt_db_get_internal(&intern, dp, gedp->dbip, NULL, &rt_uniresource) < 0) { + bu_vls_printf(_ged_current_gedp->ged_result_str, "could not import %s\n", dp->d_namep); + return BRLCAD_ERROR; + } + + if ((intern.idb_major_type & DB5_MAJORTYPE_BINARY_MASK) == 0) + return BRLCAD_ERROR; + + bip = (struct rt_binunif_internal *)intern.idb_ptr; + + RT_CHECK_BINUNIF (bip); + + (void)analyze_densities_create(&densities); + + buf = (char *)bu_calloc(bip->count+1, sizeof(char), "density buffer"); + memcpy(buf, bip->u.int8, bip->count); + rt_db_free_internal(&intern); + + ret = analyze_densities_load(densities, buf, &msgs, &ecnt); + + bu_free((void *)buf, "density buffer"); + + if (!fault_tolerant && ecnt > 0) { + bu_vls_printf(gedp->ged_result_str, "Problem reading densities from .g file:\n%s\n", bu_vls_cstr(&msgs)); + bu_vls_free(&msgs); + if (densities) { + analyze_densities_destroy(densities); + } + return BRLCAD_ERROR; + } + + bu_vls_free(&msgs); + + (*dens) = densities; + if (ret > 0) { + if (den_src) { + (*den_src) = bu_strdup(gedp->dbip->dbi_filename); + } + } else { + if (ret == 0 && densities) { + analyze_densities_destroy(densities); + } + } + return (ret == 0) ? BRLCAD_ERROR : BRLCAD_OK; + } + } + + /* If we don't have an explicitly specified file and the database doesn't have any information, see if we + * have .density files in either the current database directory or HOME. */ + + /* Try .g path first */ + if (bu_path_component(&d_path_dir, gedp->dbip->dbi_filename, BU_PATH_DIRNAME)) { + + bu_vls_printf(&d_path_dir, "/.density"); + + if (bu_file_exists(bu_vls_cstr(&d_path_dir), NULL)) { + int ret = _ged_densities_from_file(dens, den_src, gedp, bu_vls_cstr(&d_path_dir), fault_tolerant); + bu_vls_free(&d_path_dir); + return ret; + } + } + + /* Try HOME */ + if (bu_dir(NULL, 0, BU_DIR_HOME, NULL)) { + + bu_vls_sprintf(&d_path_dir, "%s/.density", bu_dir(NULL, 0, BU_DIR_HOME, NULL)); + + if (bu_file_exists(bu_vls_cstr(&d_path_dir), NULL)) { + int ret = _ged_densities_from_file(dens, den_src, gedp, bu_vls_cstr(&d_path_dir), fault_tolerant); + bu_vls_free(&d_path_dir); + return ret; + } + } + + return BRLCAD_ERROR; +} + +int +ged_dbcopy(struct ged *from_gedp, struct ged *to_gedp, const char *from, const char *to, int fflag) +{ + struct directory *from_dp; + struct bu_external external; + + GED_CHECK_DATABASE_OPEN(from_gedp, BRLCAD_ERROR); + GED_CHECK_DATABASE_OPEN(to_gedp, BRLCAD_ERROR); + GED_CHECK_READ_ONLY(to_gedp, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(from_gedp->ged_result_str, 0); + bu_vls_trunc(to_gedp->ged_result_str, 0); + + GED_DB_LOOKUP(from_gedp, from_dp, from, LOOKUP_NOISY, BRLCAD_ERROR & GED_QUIET); + + if (!fflag && db_lookup(to_gedp->dbip, to, LOOKUP_QUIET) != RT_DIR_NULL) { + bu_vls_printf(from_gedp->ged_result_str, "%s already exists.", to); + return BRLCAD_ERROR; + } + + if (db_get_external(&external, from_dp, from_gedp->dbip)) { + bu_vls_printf(from_gedp->ged_result_str, "Database read error, aborting\n"); + return BRLCAD_ERROR; + } + + struct rt_wdb *wdbp = wdb_dbopen(to_gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + if (wdb_export_external(wdbp, &external, to, + from_dp->d_flags, from_dp->d_minor_type) < 0) { + bu_free_external(&external); + bu_vls_printf(from_gedp->ged_result_str, + "Failed to write new object (%s) to database - aborting!!\n", + to); + return BRLCAD_ERROR; + } + + bu_free_external(&external); + + /* Need to do something extra for _GLOBAL */ + if (db_version(to_gedp->dbip) > 4 && BU_STR_EQUAL(to, DB5_GLOBAL_OBJECT_NAME)) { + struct directory *to_dp; + struct bu_attribute_value_set avs; + const char *val; + + GED_DB_LOOKUP(to_gedp, to_dp, to, LOOKUP_NOISY, BRLCAD_ERROR & GED_QUIET); + + bu_avs_init_empty(&avs); + if (db5_get_attributes(to_gedp->dbip, &avs, to_dp)) { + bu_vls_printf(from_gedp->ged_result_str, "Cannot get attributes for object %s\n", to_dp->d_namep); + return BRLCAD_ERROR; + } + + if ((val = bu_avs_get(&avs, "title")) != NULL) + to_gedp->dbip->dbi_title = bu_strdup(val); + + if ((val = bu_avs_get(&avs, "units")) != NULL) { + double loc2mm; + + if ((loc2mm = bu_mm_value(val)) > 0) { + to_gedp->dbip->dbi_local2base = loc2mm; + to_gedp->dbip->dbi_base2local = 1.0 / loc2mm; + } + } + + if ((val = bu_avs_get(&avs, "regionid_colortable")) != NULL) { + rt_color_free(); + db5_import_color_table((char *)val); + } + + bu_avs_free(&avs); + } + + return BRLCAD_OK; +} + + +int +ged_rot_args(struct ged *gedp, int argc, const char *argv[], char *coord, mat_t rmat) +{ + vect_t rvec; + static const char *usage = "[-m|-v] x y z"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + /* process possible coord flag */ + if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') { + *coord = argv[1][1]; + --argc; + ++argv; + } else + *coord = gedp->ged_gvp->gv_coord; + + if (argc != 2 && argc != 4) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if (argc == 2) { + if (bn_decode_vect(rvec, argv[1]) != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + } else { + double scan[3]; + + if (sscanf(argv[1], "%lf", &scan[X]) < 1) { + bu_vls_printf(gedp->ged_result_str, "ged_eye: bad X value %s\n", argv[1]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[2], "%lf", &scan[Y]) < 1) { + bu_vls_printf(gedp->ged_result_str, "ged_eye: bad Y value %s\n", argv[2]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[3], "%lf", &scan[Z]) < 1) { + bu_vls_printf(gedp->ged_result_str, "ged_eye: bad Z value %s\n", argv[3]); + return BRLCAD_ERROR; + } + + /* convert from double to fastf_t */ + VMOVE(rvec, scan); + } + + VSCALE(rvec, rvec, -1.0); + bn_mat_angles(rmat, rvec[X], rvec[Y], rvec[Z]); + + return BRLCAD_OK; +} + +int +ged_arot_args(struct ged *gedp, int argc, const char *argv[], mat_t rmat) +{ + point_t pt = VINIT_ZERO; + vect_t axisv; + double axis[3]; /* not fastf_t due to sscanf */ + double angle; /* not fastf_t due to sscanf */ + static const char *usage = "x y z angle"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if (sscanf(argv[1], "%lf", &axis[X]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad X value - %s\n", argv[0], argv[1]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[2], "%lf", &axis[Y]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad Y value - %s\n", argv[0], argv[2]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[3], "%lf", &axis[Z]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad Z value - %s\n", argv[0], argv[3]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[4], "%lf", &angle) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad angle - %s\n", argv[0], argv[4]); + return BRLCAD_ERROR; + } + + VUNITIZE(axis); + VMOVE(axisv, axis); + bn_mat_arb_rot(rmat, pt, axisv, angle*DEG2RAD); + + return BRLCAD_OK; +} + +int +ged_tra_args(struct ged *gedp, int argc, const char *argv[], char *coord, vect_t tvec) +{ + static const char *usage = "[-m|-v] x y z"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + /* process possible coord flag */ + if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') { + *coord = argv[1][1]; + --argc; + ++argv; + } else + *coord = gedp->ged_gvp->gv_coord; + + if (argc != 2 && argc != 4) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if (argc == 2) { + if (bn_decode_vect(tvec, argv[1]) != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + } else { + double scan[3]; + + if (sscanf(argv[1], "%lf", &scan[X]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad X value %s\n", argv[0], argv[1]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[2], "%lf", &scan[Y]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad Y value %s\n", argv[0], argv[2]); + return BRLCAD_ERROR; + } + + if (sscanf(argv[3], "%lf", &scan[Z]) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad Z value %s\n", argv[0], argv[3]); + return BRLCAD_ERROR; + } + + /* convert from double to fastf_t */ + VMOVE(tvec, scan); + } + + return BRLCAD_OK; +} + +int +ged_scale_args(struct ged *gedp, int argc, const char *argv[], fastf_t *sf1, fastf_t *sf2, fastf_t *sf3) +{ + static const char *usage = "sf (or) sfx sfy sfz"; + int ret = BRLCAD_OK, args_read; + double scan; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + + if (!sf1 || !sf2 || !sf3) { + bu_vls_printf(gedp->ged_result_str, "%s: invalid input state", argv[0]); + return BRLCAD_ERROR; + } + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 2 && argc != 4) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if (argc == 2) { + if (!sf1 || bu_sscanf(argv[1], "%lf", &scan) != 1) { + bu_vls_printf(gedp->ged_result_str, "\nbad scale factor '%s'", argv[1]); + return BRLCAD_ERROR; + } + *sf1 = scan; + } else { + args_read = bu_sscanf(argv[1], "%lf", &scan); + if (!sf1 || args_read != 1) { + bu_vls_printf(gedp->ged_result_str, "\nbad x scale factor '%s'", argv[1]); + ret = BRLCAD_ERROR; + } + *sf1 = scan; + + args_read = bu_sscanf(argv[2], "%lf", &scan); + if (!sf2 || args_read != 1) { + bu_vls_printf(gedp->ged_result_str, "\nbad y scale factor '%s'", argv[2]); + ret = BRLCAD_ERROR; + } + *sf2 = scan; + + args_read = bu_sscanf(argv[3], "%lf", &scan); + if (!sf3 || args_read != 1) { + bu_vls_printf(gedp->ged_result_str, "\nbad z scale factor '%s'", argv[3]); + ret = BRLCAD_ERROR; + } + *sf3 = scan; + } + return ret; +} + +size_t +ged_who_argc(struct ged *gedp) +{ + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) { + if (!gedp || !gedp->ged_gvp || !gedp->dbi_state) + return 0; + BViewState *bvs = gedp->dbi_state->get_view_state(gedp->ged_gvp); + if (bvs) + return bvs->count_drawn_paths(-1, true); + return 0; + } + + struct display_list *gdlp = NULL; + size_t visibleCount = 0; + + if (!gedp || !gedp->ged_gdp || !gedp->ged_gdp->gd_headDisplay) + return 0; + + for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { + visibleCount++; + } + + return visibleCount; +} + + +/** + * Build a command line vector of the tops of all objects in view. + * + * Returns the number of items displayed. + * + * FIXME: crazy inefficient for massive object lists. needs to work + * with preallocated memory. + */ +int +ged_who_argv(struct ged *gedp, char **start, const char **end) +{ + char **vp = start; + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) { + if (!gedp || !gedp->ged_gvp || !gedp->dbi_state) + return 0; + BViewState *bvs = gedp->dbi_state->get_view_state(gedp->ged_gvp); + if (bvs) { + std::vector drawn_paths = bvs->list_drawn_paths(-1, true); + for (size_t i = 0; i < drawn_paths.size(); i++) { + if ((vp != NULL) && ((const char **)vp < end)) { + *vp++ = bu_strdup(drawn_paths[i].c_str()); + } else { + bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() ran out of space at %s\n", drawn_paths[i].c_str()); + break; + } + } + } else { + return 0; + } + } + + struct display_list *gdlp; + + if (!gedp || !gedp->ged_gdp || !gedp->ged_gdp->gd_headDisplay) + return 0; + + if (UNLIKELY(!start || !end)) { + bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() called with NULL args\n"); + return 0; + } + + for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { + if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) + continue; + + if ((vp != NULL) && ((const char **)vp < end)) { + *vp++ = bu_strdup(bu_vls_addr(&gdlp->dl_path)); + } else { + bu_vls_printf(gedp->ged_result_str, "INTERNAL ERROR: ged_who_argv() ran out of space at %s\n", ((struct directory *)gdlp->dl_dp)->d_namep); + break; + } + } + + if ((vp != NULL) && ((const char **)vp < end)) { + *vp = (char *) 0; + } + + return vp-start; +} + +void +_ged_do_list(struct ged *gedp, struct directory *dp, int verbose) +{ + int id; + struct rt_db_internal intern; + + RT_CK_DBI(gedp->dbip); + + if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { + /* this is the _GLOBAL object */ + struct bu_attribute_value_set avs; + struct bu_attribute_value_pair *avp; + + bu_vls_strcat(gedp->ged_result_str, dp->d_namep); + bu_vls_strcat(gedp->ged_result_str, ": global attributes object\n"); + bu_avs_init_empty(&avs); + if (db5_get_attributes(gedp->dbip, &avs, dp)) { + bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for %s\n", dp->d_namep); + return; + } +/* !!! left off here*/ + for (BU_AVS_FOR(avp, &avs)) { + if (BU_STR_EQUAL(avp->name, "units")) { + double conv; + const char *str; + + conv = atof(avp->value); + bu_vls_strcat(gedp->ged_result_str, "\tunits: "); + + str = bu_units_string(conv); + if (str == NULL) { + bu_vls_strcat(gedp->ged_result_str, "Unrecognized units\n"); + } else { + bu_vls_strcat(gedp->ged_result_str, str); + bu_vls_putc(gedp->ged_result_str, '\n'); + } + } else { + bu_vls_putc(gedp->ged_result_str, '\t'); + bu_vls_strcat(gedp->ged_result_str, avp->name); + bu_vls_strcat(gedp->ged_result_str, ": "); + bu_vls_strcat(gedp->ged_result_str, avp->value); + bu_vls_putc(gedp->ged_result_str, '\n'); + } + } + } else { + + if ((id = rt_db_get_internal(&intern, dp, gedp->dbip, + (fastf_t *)NULL, &rt_uniresource)) < 0) { + bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal(%s) failure\n", dp->d_namep); + rt_db_free_internal(&intern); + return; + } + + bu_vls_printf(gedp->ged_result_str, "%s: ", dp->d_namep); + + if (!OBJ[id].ft_describe || + OBJ[id].ft_describe(gedp->ged_result_str, + &intern, + verbose, + gedp->dbip->dbi_base2local) < 0) + bu_vls_printf(gedp->ged_result_str, "%s: describe error\n", dp->d_namep); + rt_db_free_internal(&intern); + } +} + +/** + * Once the vlist has been created, perform the common tasks + * in handling the drawn solid. + * + * This routine must be prepared to run in parallel. + */ +void +_ged_drawH_part2(int dashflag, struct bu_list *vhead, const struct db_full_path *pathp, struct db_tree_state *tsp, struct _ged_client_data *dgcdp) +{ + + if (dgcdp->vs.color_override) { + unsigned char wcolor[3]; + + wcolor[0] = (unsigned char)dgcdp->vs.color[0]; + wcolor[1] = (unsigned char)dgcdp->vs.color[1]; + wcolor[2] = (unsigned char)dgcdp->vs.color[2]; + dl_add_path(dashflag, vhead, pathp, tsp, wcolor, dgcdp); + } else { + dl_add_path(dashflag, vhead, pathp, tsp, NULL, dgcdp); + } +} + +void +_ged_cvt_vlblock_to_solids(struct ged *gedp, struct bv_vlblock *vbp, const char *name, int copy) +{ + size_t i; + char shortname[32] = {0}; + char namebuf[64] = {0}; + + bu_strlcpy(shortname, name, sizeof(shortname)); + + for (i = 0; i < vbp->nused; i++) { + if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) + continue; + snprintf(namebuf, 64, "%s%lx", shortname, vbp->rgb[i]); + invent_solid(gedp, namebuf, &vbp->head[i], vbp->rgb[i], copy, 1.0, 0, 0); + } +} + +#define WIN_EDITOR "c:/Program Files/Windows NT/Accessories/wordpad.exe" +#define MAC_EDITOR "/Applications/TextEdit.app/Contents/MacOS/TextEdit" +#define EMACS_EDITOR "emacs" +#define NANO_EDITOR "nano" +#define VIM_EDITOR "vim" +#define VI_EDITOR "vi" + +int +_ged_editit(const char *editstring, const char *filename) +{ +#ifdef HAVE_UNISTD_H + int xpid = 0; + int status = 0; +#endif + int pid = 0; + char **avtmp = (char **)NULL; + const char *terminal = (char *)NULL; + const char *terminal_opt = (char *)NULL; + const char *editor = (char *)NULL; + const char *editor_opt = (char *)NULL; + const char *file = (const char *)filename; + +#if defined(SIGINT) && defined(SIGQUIT) + void (*s2)(int); + void (*s3)(int); +#endif + + if (!file) { + bu_log("INTERNAL ERROR: editit filename missing\n"); + return 0; + } + + char *editstring_cpy = NULL; + + /* convert the edit string into pieces suitable for arguments to execlp */ + + if (editstring != NULL) { + editstring_cpy = bu_strdup(editstring); + avtmp = (char **)bu_calloc(5, sizeof(char *), "ged_editit: editstring args"); + bu_argv_from_string(avtmp, 4, editstring_cpy); + + if (avtmp[0] && !BU_STR_EQUAL(avtmp[0], "(null)")) + terminal = avtmp[0]; + if (avtmp[1] && !BU_STR_EQUAL(avtmp[1], "(null)")) + terminal_opt = avtmp[1]; + if (avtmp[2] && !BU_STR_EQUAL(avtmp[2], "(null)")) + editor = avtmp[2]; + if (avtmp[3] && !BU_STR_EQUAL(avtmp[3], "(null)")) + editor_opt = avtmp[3]; + } else { + editor = getenv("EDITOR"); + + /* still unset? try windows */ + if (!editor || editor[0] == '\0') { + if (bu_file_exists(WIN_EDITOR, NULL)) { + editor = WIN_EDITOR; + } + } + + /* still unset? try mac os x */ + if (!editor || editor[0] == '\0') { + if (bu_file_exists(MAC_EDITOR, NULL)) { + editor = MAC_EDITOR; + } + } + + /* still unset? try emacs */ + if (!editor || editor[0] == '\0') { + editor = bu_which(EMACS_EDITOR); + } + + /* still unset? try nano */ + if (!editor || editor[0] == '\0') { + editor = bu_which(NANO_EDITOR); + } + + /* still unset? try vim */ + if (!editor || editor[0] == '\0') { + editor = bu_which(VIM_EDITOR); + } + + /* still unset? As a last resort, go with vi - + * vi is part of the POSIX standard, which is as + * close as we can get currently to an editor + * that should always be present: + * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html */ + if (!editor || editor[0] == '\0') { + editor = bu_which(VI_EDITOR); + } + } + + if (!editor) { + bu_log("INTERNAL ERROR: editit editor missing\n"); + return 0; + } + + /* print a message to let the user know they need to quit their + * editor before the application will come back to life. + */ + { + size_t length; + struct bu_vls str = BU_VLS_INIT_ZERO; + struct bu_vls sep = BU_VLS_INIT_ZERO; + char *editor_basename; + + if (terminal && editor_opt) { + bu_log("Invoking [%s %s %s] via %s\n\n", editor, editor_opt, file, terminal); + } else if (terminal) { + bu_log("Invoking [%s %s] via %s\n\n", editor, file, terminal); + } else if (editor_opt) { + bu_log("Invoking [%s %s %s]\n\n", editor, editor_opt, file); + } else { + bu_log("Invoking [%s %s]\n\n", editor, file); + } + editor_basename = bu_path_basename(editor, NULL); + bu_vls_sprintf(&str, "\nNOTE: You must QUIT %s before %s will respond and continue.\n", editor_basename, bu_getprogname()); + for (length = bu_vls_strlen(&str) - 2; length > 0; length--) { + bu_vls_putc(&sep, '*'); + } + bu_log("%s%s%s\n\n", bu_vls_addr(&sep), bu_vls_addr(&str), bu_vls_addr(&sep)); + bu_vls_free(&str); + bu_vls_free(&sep); + bu_free(editor_basename, "editor_basename free"); + } + +#if defined(SIGINT) && defined(SIGQUIT) + s2 = signal(SIGINT, SIG_IGN); + s3 = signal(SIGQUIT, SIG_IGN); +#endif + +#ifdef HAVE_UNISTD_H + if ((pid = fork()) < 0) { + perror("fork"); + return 0; + } +#endif + + if (pid == 0) { + /* Don't call bu_log() here in the child! */ + +#if defined(SIGINT) && defined(SIGQUIT) + /* deja vu */ + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); +#endif + + { + +#if defined(_WIN32) && !defined(__CYGWIN__) + char buffer[RT_MAXLINE + 1] = {0}; + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + si.cb = sizeof(STARTUPINFO); + si.lpReserved = NULL; + si.lpReserved2 = NULL; + si.cbReserved2 = 0; + si.lpDesktop = NULL; + si.dwFlags = 0; + + snprintf(buffer, RT_MAXLINE, "%s %s", editor, file); + + CreateProcess(NULL, buffer, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); + WaitForSingleObject(pi.hProcess, INFINITE); + return 1; +#else + char *editor_basename = bu_path_basename(editor, NULL); + if (BU_STR_EQUAL(editor_basename, "TextEdit")) { + /* close stdout/stderr so we don't get blather from TextEdit about service registration failure */ + close(fileno(stdout)); + close(fileno(stderr)); + } + bu_free(editor_basename, "editor_basename free"); + + if (!terminal && !editor_opt) { + (void)execlp(editor, editor, file, NULL); + } else if (!terminal) { + (void)execlp(editor, editor, editor_opt, file, NULL); + } else if (terminal && !terminal_opt) { + (void)execlp(terminal, terminal, editor, file, NULL); + } else if (terminal && !editor_opt) { + (void)execlp(terminal, terminal, terminal_opt, editor, file, NULL); + } else { + (void)execlp(terminal, terminal, terminal_opt, editor, editor_opt, file, NULL); + } +#endif + /* should not reach */ + perror(editor); + bu_exit(1, NULL); + } + } + +#ifdef HAVE_UNISTD_H + /* wait for the editor to terminate */ + while ((xpid = wait(&status)) >= 0) { + if (xpid == pid) { + break; + } + } +#endif + +#if defined(SIGINT) && defined(SIGQUIT) + (void)signal(SIGINT, s2); + (void)signal(SIGQUIT, s3); +#endif + + if (editstring != NULL) { + bu_free((void *)avtmp, "ged_editit: avtmp"); + bu_free(editstring_cpy, "editstring copy"); + } + + return 1; +} + +void +_ged_rt_set_eye_model(struct ged *gedp, + vect_t eye_model) +{ + if (gedp->ged_gvp->gv_s->gv_zclip || gedp->ged_gvp->gv_perspective > 0) { + vect_t temp; + + VSET(temp, 0.0, 0.0, 1.0); + MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp); + } else { + /* not doing zclipping, so back out of geometry */ + int i; + vect_t direction; + vect_t extremum[2]; + double t_in; + vect_t diag1; + vect_t diag2; + point_t ecenter; + + VSET(eye_model, -gedp->ged_gvp->gv_center[MDX], + -gedp->ged_gvp->gv_center[MDY], -gedp->ged_gvp->gv_center[MDZ]); + + for (i = 0; i < 3; ++i) { + extremum[0][i] = INFINITY; + extremum[1][i] = -INFINITY; + } + + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) { + VSETALL(extremum[0], INFINITY); + VSETALL(extremum[1], -INFINITY); + struct bu_ptbl *db_objs = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); + if (db_objs) + (void)scene_bounding_sph(db_objs, &(extremum[0]), &(extremum[1]), 1); + struct bu_ptbl *local_db_objs = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS | BV_LOCAL_OBJS); + if (local_db_objs) + (void)scene_bounding_sph(local_db_objs, &(extremum[0]), &(extremum[1]), 1); + } else { + (void)dl_bounding_sph(gedp->ged_gdp->gd_headDisplay, &(extremum[0]), &(extremum[1]), 1); + } + + VMOVEN(direction, gedp->ged_gvp->gv_rotation + 8, 3); + for (i = 0; i < 3; ++i) + if (NEAR_ZERO(direction[i], 1e-10)) + direction[i] = 0.0; + + VSUB2(diag1, extremum[1], extremum[0]); + VADD2(ecenter, extremum[1], extremum[0]); + VSCALE(ecenter, ecenter, 0.5); + VSUB2(diag2, ecenter, eye_model); + t_in = MAGNITUDE(diag1) + MAGNITUDE(diag2); + VJOIN1(eye_model, eye_model, t_in, direction); + } +} + +void +_ged_rt_output_handler2(void *clientData, int type) +{ + struct ged_subprocess *rrtp = (struct ged_subprocess *)clientData; + int count = 0; + int retcode = 0; + int read_failed_stderr = 0; + int read_failed_stdout = 0; + char line[RT_MAXLINE+1] = {0}; + + if ((rrtp == (struct ged_subprocess *)NULL) || (rrtp->gedp == (struct ged *)NULL)) + return; + + BU_CKMAG(rrtp, GED_CMD_MAGIC, "ged subprocess"); + + struct ged *gedp = rrtp->gedp; + + /* Get data from rt */ + if (rrtp->stderr_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { + read_failed_stderr = 1; + } + if (rrtp->stdout_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDOUT, RT_MAXLINE) <= 0) { + read_failed_stdout = 1; + } + + if (read_failed_stderr || read_failed_stdout) { + int aborted; + + /* Done watching for output, undo subprocess I/O hooks. */ + if (type != -1 && gedp->ged_delete_io_handler) { + + if (rrtp->stdin_active || rrtp->stdout_active || rrtp->stderr_active) { + // If anyone else is still listening, we're not done yet. + if (rrtp->stdin_active) { + (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDIN); + return; + } + if (rrtp->stdout_active) { + (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDOUT); + return; + } + if (rrtp->stderr_active) { + (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDERR); + return; + } + } + + return; + } + + /* Either EOF has been sent or there was a read error. + * there is no need to block indefinitely */ + retcode = bu_process_wait(&aborted, rrtp->p, 120); + + if (aborted) + bu_log("Raytrace aborted.\n"); + else if (retcode) + bu_log("Raytrace failed.\n"); + else + bu_log("Raytrace complete.\n"); + + if (gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) + gedp->ged_gdp->gd_rtCmdNotify(aborted); + + if (rrtp->end_clbk) + rrtp->end_clbk(aborted, rrtp->end_clbk_data); + + /* free rrtp */ + bu_ptbl_rm(&gedp->ged_subp, (long *)rrtp); + BU_PUT(rrtp, struct ged_subprocess); + + return; + } + + /* for feelgoodedness */ + line[count] = '\0'; + + /* handle (i.e., probably log to stderr) the resulting line */ + if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) + ged_output_handler_cb(gedp, line); + else + bu_vls_printf(gedp->ged_result_str, "%s", line); + +} + +void +_ged_rt_output_handler(void *clientData, int mask) +{ + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) { + _ged_rt_output_handler2(clientData, mask); + return; + } + struct ged_subprocess *rrtp = (struct ged_subprocess *)clientData; + int count = 0; + int retcode = 0; + int read_failed_stderr = 0; + int read_failed_stdout = 0; + char line[RT_MAXLINE+1] = {0}; + + if ((rrtp == (struct ged_subprocess *)NULL) || (rrtp->gedp == (struct ged *)NULL)) + return; + + BU_CKMAG(rrtp, GED_CMD_MAGIC, "ged subprocess"); + + struct ged *gedp = rrtp->gedp; + + /* Get data from rt */ + if (rrtp->stderr_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { + read_failed_stderr = 1; + } + if (rrtp->stdout_active && bu_process_read((char *)line, &count, rrtp->p, BU_PROCESS_STDOUT, RT_MAXLINE) <= 0) { + read_failed_stdout = 1; + } + + if (read_failed_stderr || read_failed_stdout) { + int aborted; + + /* Done watching for output, undo subprocess I/O hooks. */ + if (gedp->ged_delete_io_handler) { + if (rrtp->stderr_active) + (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDERR); + if (rrtp->stdout_active) + (*gedp->ged_delete_io_handler)(rrtp, BU_PROCESS_STDOUT); + } + + + /* Either EOF has been sent or there was a read error. + * there is no need to block indefinitely */ + retcode = bu_process_wait(&aborted, rrtp->p, 120); + + if (aborted) + bu_log("Raytrace aborted.\n"); + else if (retcode) + bu_log("Raytrace failed.\n"); + else + bu_log("Raytrace complete.\n"); + + if (gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) + gedp->ged_gdp->gd_rtCmdNotify(aborted); + + if (rrtp->end_clbk) + rrtp->end_clbk(aborted, rrtp->end_clbk_data); + + /* free rrtp */ + bu_ptbl_rm(&gedp->ged_subp, (long *)rrtp); + BU_PUT(rrtp, struct ged_subprocess); + + return; + } + + /* for feelgoodedness */ + line[count] = '\0'; + + /* handle (i.e., probably log to stderr) the resulting line */ + if (gedp->ged_output_handler != (void (*)(struct ged *, char *))0) + ged_output_handler_cb(gedp, line); + else + bu_vls_printf(gedp->ged_result_str, "%s", line); + +} + +void +_ged_rt_write(struct ged *gedp, + FILE *fp, + vect_t eye_model, + int argc, + const char **argv) +{ + quat_t quat; + + /* Double-precision IEEE floating point only guarantees 15-17 + * digits of precision; single-precision only 6-9 significant + * decimal digits. Using a %.15e precision specifier makes our + * printed value dip into unreliable territory (1+15 digits). + * Looking through our history, %.14e seems to be safe as the + * value prior to printing quaternions was %.9e, although anything + * from 9->14 "should" be safe as it's above our calculation + * tolerance and above single-precision capability. + */ + fprintf(fp, "viewsize %.14e;\n", gedp->ged_gvp->gv_size); + quat_mat2quat(quat, gedp->ged_gvp->gv_rotation); + fprintf(fp, "orientation %.14e %.14e %.14e %.14e;\n", V4ARGS(quat)); + fprintf(fp, "eye_pt %.14e %.14e %.14e;\n", + eye_model[X], eye_model[Y], eye_model[Z]); + + fprintf(fp, "start 0; clean;\n"); + + /* If no objects were specified, activate all objects currently displayed. + * Otherwise, simply draw the specified objects. If the caller passed + * -1 in argc it means the objects are specified on the command line. + * (TODO - we shouldn't be doing that anywhere for this; long command + * strings make Windows unhappy. Once all the callers have been + * adjusted to pass the object lists for itemization via pipes below, + * remove the -1 case.) */ + if (argc >= 0) { + if (!argc) { + const char *cmd2 = getenv("GED_TEST_NEW_CMD_FORMS"); + if (BU_STR_EQUAL(cmd2, "1")) { + BViewState *bvs = gedp->dbi_state->get_view_state(gedp->ged_gvp); + if (bvs) { + std::vector drawn_paths = bvs->list_drawn_paths(-1, true); + for (size_t i = 0; i < drawn_paths.size(); i++) { + fprintf(fp, "draw %s;\n", drawn_paths[i].c_str()); + } + } + } else { + struct display_list *gdlp; + for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { + if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) + continue; + fprintf(fp, "draw %s;\n", bu_vls_addr(&gdlp->dl_path)); + } + } + } else { + int i = 0; + while (i < argc) { + fprintf(fp, "draw %s;\n", argv[i++]); + } + } + + fprintf(fp, "prep;\n"); + } + + dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); + + dl_write_animate(gedp->ged_gdp->gd_headDisplay, fp); + + dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); + + fprintf(fp, "end;\n"); +} + +int +_ged_run_rt(struct ged *gedp, int cmd_len, const char **gd_rt_cmd, int argc, const char **argv) +{ + FILE *fp_in; + vect_t eye_model; + struct ged_subprocess *run_rtp; + struct bu_process *p = NULL; + + bu_process_exec(&p, gd_rt_cmd[0], cmd_len, gd_rt_cmd, 0, 0); + + if (bu_process_pid(p) == -1) { + bu_vls_printf(gedp->ged_result_str, "\nunable to successfully launch subprocess: "); + for (int i = 0; i < cmd_len; i++) { + bu_vls_printf(gedp->ged_result_str, "%s ", gd_rt_cmd[i]); + } + bu_vls_printf(gedp->ged_result_str, "\n"); + return BRLCAD_ERROR; + } + + if (gedp->ged_subprocess_init_callback) { + (*gedp->ged_subprocess_init_callback)(bu_process_pid(p), gedp->ged_subprocess_clbk_context); + } + + fp_in = bu_process_open(p, BU_PROCESS_STDIN); + + _ged_rt_set_eye_model(gedp, eye_model); + _ged_rt_write(gedp, fp_in, eye_model, argc, argv); + + bu_process_close(p, BU_PROCESS_STDIN); + + BU_GET(run_rtp, struct ged_subprocess); + run_rtp->magic = GED_CMD_MAGIC; + run_rtp->stdin_active = 0; + run_rtp->stdout_active = 0; + run_rtp->stderr_active = 0; + run_rtp->end_clbk = gedp->ged_subprocess_end_callback; + run_rtp->end_clbk_data = gedp->ged_subprocess_clbk_context; + bu_ptbl_ins(&gedp->ged_subp, (long *)run_rtp); + + run_rtp->p = p; + run_rtp->aborted = 0; + run_rtp->gedp = gedp; + + /* If we know how, set up hooks so the parent process knows to watch for output. */ + if (gedp->ged_create_io_handler) { + (*gedp->ged_create_io_handler)(run_rtp, BU_PROCESS_STDERR, _ged_rt_output_handler, (void *)run_rtp); + } + return BRLCAD_OK; +} + + +struct rt_object_selections * +ged_get_object_selections(struct ged *gedp, const char *object_name) +{ + struct rt_object_selections *obj_selections; + + obj_selections = (struct rt_object_selections *)bu_hash_get(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name)); + + if (!obj_selections) { + BU_ALLOC(obj_selections, struct rt_object_selections); + obj_selections->sets = bu_hash_create(0); + (void)bu_hash_set(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name), (void *)obj_selections); + } + + return obj_selections; +} + + +struct rt_selection_set * +ged_get_selection_set(struct ged *gedp, const char *object_name, const char *selection_name) +{ + struct rt_object_selections *obj_selections; + struct rt_selection_set *set; + + obj_selections = ged_get_object_selections(gedp, object_name); + set = (struct rt_selection_set *)bu_hash_get(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name)); + if (!set) { + BU_ALLOC(set, struct rt_selection_set); + BU_PTBL_INIT(&set->selections); + bu_hash_set(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name), (void *)set); + } + + return set; +} + + +/* + * Add an instance of object 'objp' to combination 'name'. + * If the combination does not exist, it is created. + * region_flag is 1 (region), or 0 (group). + * + * Preserves the GIFT semantics. + */ +struct directory * +_ged_combadd(struct ged *gedp, + struct directory *objp, + char *combname, + int region_flag, /* true if adding region */ + db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ + int ident, /* "Region ID" */ + int air /* Air code */) +{ + int ac = 1; + const char *av[2]; + + av[0] = objp->d_namep; + av[1] = NULL; + + if (_ged_combadd2(gedp, combname, ac, av, region_flag, relation, ident, air, NULL, 1) & BRLCAD_ERROR) + return RT_DIR_NULL; + + /* Done changing stuff - update nref. */ + db_update_nref(gedp->dbip, &rt_uniresource); + + return db_lookup(gedp->dbip, combname, LOOKUP_QUIET); +} + + +/* + * Add an instance of object 'objp' to combination 'name'. + * If the combination does not exist, it is created. + * region_flag is 1 (region), or 0 (group). + * + * Preserves the GIFT semantics. + */ +int +_ged_combadd2(struct ged *gedp, + char *combname, + int argc, + const char *argv[], + int region_flag, /* true if adding region */ + db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ + int ident, /* "Region ID" */ + int air, /* Air code */ + matp_t m, /* Matrix */ + int validate /* 1 to check if new members exist, 0 to just add them */) +{ + struct directory *dp; + struct directory *objp; + struct rt_db_internal intern; + struct rt_comb_internal *comb; + union tree *tp; + struct rt_tree_array *tree_list; + size_t node_count; + size_t actual_count; + size_t curr_count; + int i; + + if (argc < 1) + return BRLCAD_ERROR; + + /* + * Check to see if we have to create a new combination + */ + if ((dp = db_lookup(gedp->dbip, combname, LOOKUP_QUIET)) == RT_DIR_NULL) { + int flags; + + if (region_flag) + flags = RT_DIR_REGION | RT_DIR_COMB; + else + flags = RT_DIR_COMB; + + RT_DB_INTERNAL_INIT(&intern); + intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; + intern.idb_type = ID_COMBINATION; + intern.idb_meth = &OBJ[ID_COMBINATION]; + + GED_DB_DIRADD(gedp, dp, combname, -1, 0, flags, (void *)&intern.idb_type, 0); + + BU_ALLOC(comb, struct rt_comb_internal); + RT_COMB_INTERNAL_INIT(comb); + + intern.idb_ptr = (void *)comb; + + if (region_flag) { + struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); + comb->region_flag = 1; + comb->region_id = ident; + comb->aircode = air; + comb->los = wdbp->wdb_los_default; + comb->GIFTmater = wdbp->wdb_mat_default; + bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", ident); + if (air) + bu_vls_printf(gedp->ged_result_str, "air=%d, ", air); + bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", + wdbp->wdb_los_default, + wdbp->wdb_mat_default); + } else { + comb->region_flag = 0; + } + + goto addmembers; + } else if (!(dp->d_flags & RT_DIR_COMB)) { + bu_vls_printf(gedp->ged_result_str, "%s exists, but is not a combination\n", dp->d_namep); + return BRLCAD_ERROR; + } + + /* combination exists, add a new member */ + GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, 0); + + comb = (struct rt_comb_internal *)intern.idb_ptr; + RT_CK_COMB(comb); + + if (region_flag && !comb->region_flag) { + bu_vls_printf(gedp->ged_result_str, "%s: not a region\n", dp->d_namep); + return BRLCAD_ERROR; + } + +addmembers: + if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) { + db_non_union_push(comb->tree, &rt_uniresource); + if (db_ck_v4gift_tree(comb->tree) < 0) { + bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for editing\n"); + rt_db_free_internal(&intern); + return BRLCAD_ERROR; + } + } + + /* make space for an extra leaf */ + curr_count = db_tree_nleaves(comb->tree); + node_count = curr_count + argc; + tree_list = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list"); + + /* flatten tree */ + if (comb->tree) { + actual_count = argc + (struct rt_tree_array *)db_flatten_tree(tree_list, comb->tree, OP_UNION, 1, &rt_uniresource) - tree_list; + BU_ASSERT(actual_count == node_count); + comb->tree = TREE_NULL; + } + + for (i = 0; i < argc; ++i) { + if (validate) { + objp = db_lookup(gedp->dbip, argv[i], LOOKUP_NOISY); + if (objp == RT_DIR_NULL) { + bu_vls_printf(gedp->ged_result_str, "skip member %s\n", argv[i]); + continue; + } + } + + /* insert new member at end */ + switch (relation) { + case DB_OP_INTERSECT: + tree_list[curr_count].tl_op = OP_INTERSECT; + break; + case DB_OP_SUBTRACT: + tree_list[curr_count].tl_op = OP_SUBTRACT; + break; + default: + if (relation != DB_OP_UNION) { + bu_vls_printf(gedp->ged_result_str, "unrecognized relation (assume UNION)\n"); + } + tree_list[curr_count].tl_op = OP_UNION; + break; + } + + /* make new leaf node, and insert at end of list */ + BU_GET(tp, union tree); + RT_TREE_INIT(tp); + tree_list[curr_count].tl_tree = tp; + tp->tr_l.tl_op = OP_DB_LEAF; + tp->tr_l.tl_name = bu_strdup(argv[i]); + if (m) { + tp->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "mat copy"); + MAT_COPY(tp->tr_l.tl_mat, m); + } else { + tp->tr_l.tl_mat = (matp_t)NULL; + } + + ++curr_count; + } + + /* rebuild the tree */ + comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, &rt_uniresource); + + /* and finally, write it out */ + GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, 0); + + bu_free((char *)tree_list, "combadd: tree_list"); + + /* Done changing stuff - update nref. */ + db_update_nref(gedp->dbip, &rt_uniresource); + + return BRLCAD_OK; +} + +void +_ged_wait_status(struct bu_vls *logstr, + int status) +{ + int sig = status & 0x7f; + int core = status & 0x80; + int ret = status >> 8; + + if (status == 0) { + bu_vls_printf(logstr, "Normal exit\n"); + return; + } + + bu_vls_printf(logstr, "Abnormal exit x%x", status); + + if (core) + bu_vls_printf(logstr, ", core dumped"); + + if (sig) + bu_vls_printf(logstr, ", terminating signal = %d", sig); + else + bu_vls_printf(logstr, ", return (exit) code = %d", ret); +} + +struct directory ** +_ged_build_dpp(struct ged *gedp, + const char *path) { + struct directory *dp; + struct directory **dpp; + int i; + char *begin; + char *end; + char *newstr; + char *list; + int ac; + const char **av; + const char **av_orig = NULL; + struct bu_vls vls = BU_VLS_INIT_ZERO; + + /* + * First, build an array of the object's path components. + * We store the list in av_orig below. + */ + newstr = bu_strdup(path); + begin = newstr; + while ((end = strchr(begin, '/')) != NULL) { + *end = '\0'; + bu_vls_printf(&vls, "%s ", begin); + begin = end + 1; + } + bu_vls_printf(&vls, "%s ", begin); + free((void *)newstr); + + list = bu_vls_addr(&vls); + + if (bu_argv_from_tcl_list(list, &ac, &av_orig) != 0) { + bu_vls_printf(gedp->ged_result_str, "-1"); + bu_vls_free(&vls); + return (struct directory **)NULL; + } + + /* skip first element if empty */ + av = av_orig; + if (*av[0] == '\0') { + --ac; + ++av; + } + + /* ignore last element if empty */ + if (*av[ac-1] == '\0') + --ac; + + /* + * Next, we build an array of directory pointers that + * correspond to the object's path. + */ + dpp = (struct directory **)bu_calloc((size_t)ac+1, sizeof(struct directory *), "_ged_build_dpp: directory pointers"); + for (i = 0; i < ac; ++i) { + if ((dp = db_lookup(gedp->dbip, av[i], 0)) != RT_DIR_NULL) + dpp[i] = dp; + else { + /* object is not currently being displayed */ + bu_vls_printf(gedp->ged_result_str, "-1"); + + bu_free((void *)dpp, "_ged_build_dpp: directory pointers"); + bu_free((char *)av_orig, "free av_orig"); + bu_vls_free(&vls); + return (struct directory **)NULL; + } + } + + dpp[i] = RT_DIR_NULL; + + bu_free((char *)av_orig, "free av_orig"); + bu_vls_free(&vls); + return dpp; +} + +/* + * This routine walks through the directory entry list and mallocs enough + * space for pointers to hold: + * a) all of the entries if called with an argument of 0, or + * b) the number of entries specified by the argument if > 0. + */ +struct directory ** +_ged_dir_getspace(struct db_i *dbip, + size_t num_entries) +{ + size_t i; + struct directory **dir_basep; + struct directory *dp; + + if (num_entries == 0) { + /* Set num_entries to the number of entries */ + for (i = 0; i < RT_DBNHASH; i++) + for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) + num_entries++; + } + + /* Allocate and cast num_entries worth of pointers */ + dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *), + "dir_getspace *dir[]"); + return dir_basep; +} + +int +_ged_set_metaball(struct ged *gedp, struct rt_metaball_internal *mbip, const char *attribute, fastf_t sf) +{ + RT_METABALL_CK_MAGIC(mbip); + + switch (attribute[0]) { + case 'm': + case 'M': + if (sf <= METABALL_METABALL) + mbip->method = METABALL_METABALL; + else if (sf >= METABALL_BLOB) + mbip->method = METABALL_BLOB; + else + mbip->method = (int)sf; + + break; + case 't': + case 'T': + if (sf < 0) + mbip->threshold = -sf; + else + mbip->threshold = sf; + + break; + default: + bu_vls_printf(gedp->ged_result_str, "bad metaball attribute - %s", attribute); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + +int +_ged_select_botpts(struct ged *gedp, struct rt_bot_internal *botip, double vx, double vy, double vwidth, double vheight, double vminz, int rflag) +{ + size_t i; + fastf_t vr = 0.0; + fastf_t vmin_x = 0.0; + fastf_t vmin_y = 0.0; + fastf_t vmax_x = 0.0; + fastf_t vmax_y = 0.0; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + + if (rflag) { + vr = vwidth; + } else { + vmin_x = vx; + vmin_y = vy; + + if (vwidth > 0) + vmax_x = vx + vwidth; + else { + vmin_x = vx + vwidth; + vmax_x = vx; + } + + if (vheight > 0) + vmax_y = vy + vheight; + else { + vmin_y = vy + vheight; + vmax_y = vy; + } + } + + if (rflag) { + for (i = 0; i < botip->num_vertices; i++) { + point_t vloc; + point_t vpt; + vect_t diff; + fastf_t mag; + + MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]); + + if (vpt[Z] < vminz) + continue; + + VSET(vloc, vx, vy, vpt[Z]); + VSUB2(diff, vpt, vloc); + mag = MAGNITUDE(diff); + + if (mag > vr) + continue; + + bu_vls_printf(gedp->ged_result_str, "%zu ", i); + } + } else { + for (i = 0; i < botip->num_vertices; i++) { + point_t vpt; + + MAT4X3PNT(vpt, gedp->ged_gvp->gv_model2view, &botip->vertices[i*3]); + + if (vpt[Z] < vminz) + continue; + + if (vmin_x <= vpt[X] && vpt[X] <= vmax_x && + vmin_y <= vpt[Y] && vpt[Y] <= vmax_y) { + bu_vls_printf(gedp->ged_result_str, "%zu ", i); + } + } + } + + return BRLCAD_OK; +} + +/* + * Returns point mbp_i. + */ +struct wdb_metaball_pnt * +_ged_get_metaball_pt_i(struct rt_metaball_internal *mbip, int mbp_i) +{ + int i = 0; + struct wdb_metaball_pnt *curr_mbpp; + + for (BU_LIST_FOR(curr_mbpp, wdb_metaball_pnt, &mbip->metaball_ctrl_head)) { + if (i == mbp_i) + return curr_mbpp; + + ++i; + } + + return (struct wdb_metaball_pnt *)NULL; +} + + +#define GED_METABALL_SCALE(_d, _scale) \ + if ((_scale) < 0.0) \ + (_d) = -(_scale); \ + else \ + (_d) *= (_scale); + +int +_ged_scale_metaball(struct ged *gedp, struct rt_metaball_internal *mbip, const char *attribute, fastf_t sf, int rflag) +{ + int mbp_i; + struct wdb_metaball_pnt *mbpp; + + RT_METABALL_CK_MAGIC(mbip); + + if (!rflag && sf > 0) + sf = -sf; + + switch (attribute[0]) { + case 'f': + case 'F': + if (sscanf(attribute+1, "%d", &mbp_i) != 1) + mbp_i = 0; + + if ((mbpp = _ged_get_metaball_pt_i(mbip, mbp_i)) == (struct wdb_metaball_pnt *)NULL) + return BRLCAD_ERROR; + + BU_CKMAG(mbpp, WDB_METABALLPT_MAGIC, "wdb_metaball_pnt"); + GED_METABALL_SCALE(mbpp->fldstr, sf); + + break; + case 's': + case 'S': + if (sscanf(attribute+1, "%d", &mbp_i) != 1) + mbp_i = 0; + + if ((mbpp = _ged_get_metaball_pt_i(mbip, mbp_i)) == (struct wdb_metaball_pnt *)NULL) + return BRLCAD_ERROR; + + BU_CKMAG(mbpp, WDB_METABALLPT_MAGIC, "wdb_metaball_pnt"); + GED_METABALL_SCALE(mbpp->sweat, sf); + + break; + default: + bu_vls_printf(gedp->ged_result_str, "bad metaball attribute - %s", attribute); + return BRLCAD_ERROR; + } + + return BRLCAD_OK; +} + +#if 0 + +// TODO - need to generalize the path specifier parsing per notes in TODO. This is a first +// cut at recasting what search is using now, which doesn't implement the full resolving logic. + +int +_ged_characterize_pathspec(struct bu_vls *normalized, struct ged *gedp, const char *pathspec) +{ + struct bu_vls np = BU_VLS_INIT_ZERO; + int flags = 0; + + // Start with nothing - if we get a valid answer we'll print it + if (normalized) { + bu_vls_trunc(normalized, 0); + } + + if (!pathspec) + return GED_PATHSPEC_INVALID; + + if (BU_STR_EQUAL(pathspec, "/")) + return flags; + + if (BU_STR_EQUAL(pathspec, ".")) { + flags |= GED_PATHSPEC_LOCAL; + return flags; + } + + if (BU_STR_EQUAL(pathspec, "|")) { + flags |= GED_PATHSPEC_FLAT; + return flags; + } + + bu_vls_sprintf(&np, "%s", pathspec); + if (bu_vls_cstr(&np)[0] == '|') { + flags |= GED_PATHSPEC_FLAT; + bu_vls_nibble(&np, 1); + } + if (BU_STR_EQUAL(bu_vls_cstr(&np), "/")) { + bu_vls_free(&np); + return flags; + } + + if (BU_STR_EQUAL(bu_vls_cstr(&np), ".")) { + flags |= GED_PATHSPEC_LOCAL; + bu_vls_free(&np); + return flags; + } + + if (bu_vls_cstr(&np)[0] != '/') + flags |= GED_PATHSPEC_LOCAL; + + const char *bu_norm = bu_path_normalize(bu_vls_cstr(&np)); + + if (bu_norm && !BU_STR_EQUAL(bu_norm , "/")) { + struct bu_vls tmp = BU_VLS_INIT_ZERO; + char *tbasename = bu_path_basename(bu_vls_cstr(&np), NULL); + bu_vls_sprintf(&tmp, "%s", tbasename); + bu_free(tbasename, "free bu_path_basename string (caller's responsibility per bu/log.h)"); + bu_vls_sprintf(&np, "%s", bu_vls_cstr(&tmp)); + bu_vls_free(&tmp); + } else { + bu_vls_sprintf(&np, "%s", "/"); + } + + // If we've gotten this far, normalizing to nothing is considered invalid. + if (!bu_vls_strlen(&np)) { + bu_vls_free(&np); + return GED_PATHSPEC_INVALID; + } + + // If we reduced to the root fullpath, we're done + if (BU_STR_EQUAL(bu_vls_cstr(&np), "/")) { + bu_vls_free(&np); + return flags; + } + + /* We've handled the toplevel special cases. If we got here, we have a specific + * path - now the only question is whether that path is valid */ + flags |= GED_PATHSPEC_SPECIFIC; + struct directory *path_dp = db_lookup(gedp->dbip, bu_vls_cstr(&np), LOOKUP_QUIET); + if (path_dp == RT_DIR_NULL) { + flags = GED_PATHSPEC_INVALID; + } else { + if (normalized) + bu_vls_sprintf(normalized, "%s", bu_vls_cstr(&np)); + } + bu_vls_free(&np); + + return flags; +} + +#endif + + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libged/get_autoview/get_autoview.c b/src/libged/get_autoview/get_autoview.c index 44bc26050b0..17615bf0310 100644 --- a/src/libged/get_autoview/get_autoview.c +++ b/src/libged/get_autoview/get_autoview.c @@ -47,8 +47,8 @@ ged_get_core_autoview(struct ged *gedp, int argc, const char *argv[]) fastf_t size; int pflag = 0; int c; + double sval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -88,8 +88,8 @@ ged_get_core_autoview(struct ged *gedp, int argc, const char *argv[]) if (VNEAR_ZERO(radial, SQRT_SMALL_FASTF)) VSETALL(radial, 1.0); - VSCALE(center, center, gedp->dbip->dbi_base2local); - VSCALE(radial, radial, gedp->dbip->dbi_base2local * 2.0); + VSCALE(center, center, sval); + VSCALE(radial, radial, sval * 2.0); size = radial[X]; V_MAX(size, radial[Y]); V_MAX(size, radial[Z]); diff --git a/src/libged/get_eyemodel/get_eyemodel.c b/src/libged/get_eyemodel/get_eyemodel.c index 989694271f5..fa6e2470ce5 100644 --- a/src/libged/get_eyemodel/get_eyemodel.c +++ b/src/libged/get_eyemodel/get_eyemodel.c @@ -42,7 +42,6 @@ ged_get_eyemodel_core(struct ged *gedp, int argc, const char *argv[]) quat_t quat; vect_t eye_model; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/grid/grid.c b/src/libged/grid/grid.c index 28c91c4c39c..43b8e81fbcd 100644 --- a/src/libged/grid/grid.c +++ b/src/libged/grid/grid.c @@ -31,7 +31,7 @@ #include "vmath.h" #include "bv.h" -#include "bg/lseg.h" +#include "bv/snap.h" #include "../ged_private.h" @@ -54,10 +54,11 @@ grid_vsnap(struct ged *gedp) static void grid_vls_print(struct ged *gedp) { + double blval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; bu_vls_printf(gedp->ged_result_str, "anchor = %g %g %g\n", - gedp->ged_gvp->gv_s->gv_grid.anchor[0] * gedp->dbip->dbi_base2local, - gedp->ged_gvp->gv_s->gv_grid.anchor[1] * gedp->dbip->dbi_base2local, - gedp->ged_gvp->gv_s->gv_grid.anchor[2] * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_grid.anchor[0] * blval, + gedp->ged_gvp->gv_s->gv_grid.anchor[1] * blval, + gedp->ged_gvp->gv_s->gv_grid.anchor[2] * blval); bu_vls_printf(gedp->ged_result_str, "color = %d %d %d\n", gedp->ged_gvp->gv_s->gv_grid.color[0], gedp->ged_gvp->gv_s->gv_grid.color[1], @@ -65,8 +66,8 @@ grid_vls_print(struct ged *gedp) bu_vls_printf(gedp->ged_result_str, "draw = %d\n", gedp->ged_gvp->gv_s->gv_grid.draw); bu_vls_printf(gedp->ged_result_str, "mrh = %d\n", gedp->ged_gvp->gv_s->gv_grid.res_major_h); bu_vls_printf(gedp->ged_result_str, "mrv = %d\n", gedp->ged_gvp->gv_s->gv_grid.res_major_v); - bu_vls_printf(gedp->ged_result_str, "rh = %g\n", gedp->ged_gvp->gv_s->gv_grid.res_h * gedp->dbip->dbi_base2local); - bu_vls_printf(gedp->ged_result_str, "rv = %g\n", gedp->ged_gvp->gv_s->gv_grid.res_v * gedp->dbip->dbi_base2local); + bu_vls_printf(gedp->ged_result_str, "rh = %g\n", gedp->ged_gvp->gv_s->gv_grid.res_h * blval); + bu_vls_printf(gedp->ged_result_str, "rv = %g\n", gedp->ged_gvp->gv_s->gv_grid.res_v * blval); bu_vls_printf(gedp->ged_result_str, "snap = %d\n", gedp->ged_gvp->gv_s->gv_grid.snap); } @@ -100,8 +101,9 @@ ged_grid_core(struct ged *gedp, int argc, const char *argv[]) char **argp = (char **)argv; double user_pt[3]; /* Value(s) provided by user */ int i; + double blval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; + double lbval = (gedp->dbip) ? gedp->dbip->dbi_local2base : 1.0; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -188,10 +190,10 @@ ged_grid_core(struct ged *gedp, int argc, const char *argv[]) if (BU_STR_EQUAL(parameter, "rh")) { if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "%g", - gedp->ged_gvp->gv_s->gv_grid.res_h * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_grid.res_h * blval); return BRLCAD_OK; } else if (argc == 1) { - gedp->ged_gvp->gv_s->gv_grid.res_h = user_pt[X] * gedp->dbip->dbi_local2base; + gedp->ged_gvp->gv_s->gv_grid.res_h = user_pt[X] * lbval; return BRLCAD_OK; } @@ -203,10 +205,10 @@ ged_grid_core(struct ged *gedp, int argc, const char *argv[]) if (BU_STR_EQUAL(parameter, "rv")) { if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "%g", - gedp->ged_gvp->gv_s->gv_grid.res_v * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_grid.res_v * blval); return BRLCAD_OK; } else if (argc == 1) { - gedp->ged_gvp->gv_s->gv_grid.res_v = user_pt[X] * gedp->dbip->dbi_local2base; + gedp->ged_gvp->gv_s->gv_grid.res_v = user_pt[X] * lbval; return BRLCAD_OK; } @@ -246,14 +248,14 @@ ged_grid_core(struct ged *gedp, int argc, const char *argv[]) if (BU_STR_EQUAL(parameter, "anchor")) { if (argc == 0) { bu_vls_printf(gedp->ged_result_str, "%g %g %g", - gedp->ged_gvp->gv_s->gv_grid.anchor[X] * gedp->dbip->dbi_base2local, - gedp->ged_gvp->gv_s->gv_grid.anchor[Y] * gedp->dbip->dbi_base2local, - gedp->ged_gvp->gv_s->gv_grid.anchor[Z] * gedp->dbip->dbi_base2local); + gedp->ged_gvp->gv_s->gv_grid.anchor[X] * blval, + gedp->ged_gvp->gv_s->gv_grid.anchor[Y] * blval, + gedp->ged_gvp->gv_s->gv_grid.anchor[Z] * blval); return BRLCAD_OK; } else if (argc == 3) { - gedp->ged_gvp->gv_s->gv_grid.anchor[0] = user_pt[X] * gedp->dbip->dbi_local2base; - gedp->ged_gvp->gv_s->gv_grid.anchor[1] = user_pt[Y] * gedp->dbip->dbi_local2base; - gedp->ged_gvp->gv_s->gv_grid.anchor[2] = user_pt[Z] * gedp->dbip->dbi_local2base; + gedp->ged_gvp->gv_s->gv_grid.anchor[0] = user_pt[X] * lbval; + gedp->ged_gvp->gv_s->gv_grid.anchor[1] = user_pt[Y] * lbval; + gedp->ged_gvp->gv_s->gv_grid.anchor[2] = user_pt[Z] * lbval; return BRLCAD_OK; } diff --git a/src/libged/isize/isize.c b/src/libged/isize/isize.c index 6d9b90ac56e..8b4d8d554cb 100644 --- a/src/libged/isize/isize.c +++ b/src/libged/isize/isize.c @@ -35,7 +35,6 @@ int ged_isize_core(struct ged *gedp, int argc, const char *argv[]) { - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/label/label.c b/src/libged/label/label.c index 1d7791a9ef7..b19ad3fe273 100644 --- a/src/libged/label/label.c +++ b/src/libged/label/label.c @@ -37,7 +37,6 @@ ged_label(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "object(s)"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/lc/lc.c b/src/libged/lc/lc.c index 98229a63fa6..890463376aa 100644 --- a/src/libged/lc/lc.c +++ b/src/libged/lc/lc.c @@ -368,7 +368,9 @@ ged_lc_core(struct ged *gedp, int argc, const char *argv[]) int jm = im + 1; int mismatch = 0; while (!found_all_matches) { - if (jm == (int)BU_PTBL_LEN(&results2) || bu_strcmp(regions[im].region_id, regions[jm].region_id)) { + if (jm == (int)BU_PTBL_LEN(&results2) || + bu_strcmp(regions[im].region_id, regions[jm].region_id) || + !bu_strcmp(regions[im].region_id, "--")) { /* Found all matches - set ignore flags */ int km = 0; int ignored = (mismatch) ? 0 : 1; @@ -417,11 +419,24 @@ ged_lc_core(struct ged *gedp, int argc, const char *argv[]) regions[im].ignore = 0; regions[jm].ignore = 0; } + } else if (BU_STR_EQUAL(regions[im].region_id, "--") && + !BU_STR_EQUAL(regions[im].aircode, regions[jm].aircode)) { + /* edge case: + * aircodes usually do not have region_id + * if region_id are matching empty and aircodes do not match - this is not a match + * + * ie do nothing + */ } else { /* Found match - set ignore flags */ regions[im].ignore = 0; regions[jm].ignore = 0; } + } else if (BU_STR_EQUAL(regions[im].aircode, regions[jm].aircode) && + !BU_STR_EQUAL(regions[im].aircode, "--")) { + /* Found matching aircodes - set ignore flags */ + regions[im].ignore = 0; + regions[jm].ignore = 0; } jm++; } diff --git a/src/libged/lint/lint.cpp b/src/libged/lint/lint.cpp index e8a7267074c..f3a9fc5a303 100644 --- a/src/libged/lint/lint.cpp +++ b/src/libged/lint/lint.cpp @@ -32,8 +32,8 @@ extern "C" { #include "bu/opt.h" #include "bg/trimesh.h" #include "raytrace.h" -#include "../ged_private.h" } +#include "../ged_private.h" struct _ged_lint_opts { int verbosity; diff --git a/src/libged/list/list.c b/src/libged/list/list.c index 0605f6dffe7..da1f2566398 100644 --- a/src/libged/list/list.c +++ b/src/libged/list/list.c @@ -96,8 +96,15 @@ ged_list_core(struct ged *gedp, int argc, const char *argv[]) ged_exec(gedp, 3, (const char **)tmp_argv); } } else if (strchr(argv[arg], '/')) { - // Still need to check if the slash containing string is an object first... - if ((dp = db_lookup(gedp->dbip, argv[arg], LOOKUP_QUIET)) != RT_DIR_NULL) { + if ((dp = db_lookup(gedp->dbip, argv[arg], LOOKUP_QUIET)) == RT_DIR_NULL) { + continue; + } + + /* dp should have resolved to a shape. A slash still in d_namep likely means the + string is a name with a slash, not a path. + NOTE: this only works if the user is requesting a top-level name with a slash. + A slashed name anywhere else in the hierarchy will fail the db_lookup */ + if (strchr(dp->d_namep, '/')) { _ged_do_list(gedp, dp, verbose); /* very verbose */ continue; } @@ -115,8 +122,6 @@ ged_list_core(struct ged *gedp, int argc, const char *argv[]) if (db_follow_path_for_state(&ts, &path, argv[arg], 1)) continue; - dp = DB_FULL_PATH_CUR_DIR(&path); - if ((id = rt_db_get_internal(&intern, dp, gedp->dbip, ts.ts_mat, &rt_uniresource)) < 0) { bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal(%s) failure", dp->d_namep); continue; diff --git a/src/libged/lod/lod.c b/src/libged/lod/lod.c index 3e41fa74ed5..0b0dff85a22 100644 --- a/src/libged/lod/lod.c +++ b/src/libged/lod/lod.c @@ -46,7 +46,6 @@ ged_lod_core(struct ged *gedp, int argc, const char *argv[]) static const char *usage = "lod (on|off|enabled)\n" "lod scale (points|curves) \n"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_READ_ONLY(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/lookat/lookat.c b/src/libged/lookat/lookat.c index 21dc1b6d582..d3a1dbc8897 100644 --- a/src/libged/lookat/lookat.c +++ b/src/libged/lookat/lookat.c @@ -43,8 +43,8 @@ ged_lookat_core(struct ged *gedp, int argc, const char *argv[]) fastf_t new_az, new_el; double scan[3]; static const char *usage = "x y z"; + double lbval = (gedp->dbip) ? gedp->dbip->dbi_local2base : 1.0; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -87,7 +87,7 @@ ged_lookat_core(struct ged *gedp, int argc, const char *argv[]) VMOVE(look, scan); } - VSCALE(look, look, gedp->dbip->dbi_local2base); + VSCALE(look, look, lbval); VSET(tmp, 0.0, 0.0, 1.0); MAT4X3PNT(eye, gedp->ged_gvp->gv_view2model, tmp); diff --git a/src/libged/make/make.c b/src/libged/make/make.c index 91e2cc10ac0..e233e0a609f 100644 --- a/src/libged/make/make.c +++ b/src/libged/make/make.c @@ -646,10 +646,10 @@ ged_make_core(struct ged *gedp, int argc, const char *argv[]) VSET(&bot_ip->vertices[3], origin[X]-0.5*scale, origin[Y]+0.5*scale, origin[Z]-scale); VSET(&bot_ip->vertices[6], origin[X]-0.5*scale, origin[Y]-0.5*scale, origin[Z]-scale); VSET(&bot_ip->vertices[9], origin[X]+0.5*scale, origin[Y]+0.5*scale, origin[Z]-scale); - VSET(&bot_ip->faces[0], 0, 1, 3); + VSET(&bot_ip->faces[0], 0, 3, 1); VSET(&bot_ip->faces[3], 0, 1, 2); VSET(&bot_ip->faces[6], 0, 2, 3); - VSET(&bot_ip->faces[9], 1, 2, 3); + VSET(&bot_ip->faces[9], 1, 3, 2); } else if (BU_STR_EQUAL(argv[bu_optind+1], "extrude")) { char *av[8]; char center_str[512]; diff --git a/src/libged/model2grid_lu/model2grid_lu.c b/src/libged/model2grid_lu/model2grid_lu.c index acdc48b7965..fab2195aa01 100644 --- a/src/libged/model2grid_lu/model2grid_lu.c +++ b/src/libged/model2grid_lu/model2grid_lu.c @@ -42,6 +42,8 @@ ged_model2grid_lu_core(struct ged *gedp, int argc, const char *argv[]) point_t diff; double scan[3]; static const char *usage = "x y z"; + double l2bval = (gedp->dbip) ? gedp->dbip->dbi_local2base : 1.0; + double b2lval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); @@ -60,10 +62,10 @@ ged_model2grid_lu_core(struct ged *gedp, int argc, const char *argv[]) sscanf(argv[3], "%lf", &scan[Z]) != 1) goto bad; - VSCALE(model_pt, scan, gedp->dbip->dbi_local2base); + VSCALE(model_pt, scan, l2bval); MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt); VSUB2(diff, view_pt, mo_view_pt); - f = gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local; + f = gedp->ged_gvp->gv_scale * b2lval; VSCALE(diff, diff, f); bu_vls_printf(gedp->ged_result_str, "%.15e %.15e", diff[X], diff[Y]); diff --git a/src/libged/model2view/model2view.c b/src/libged/model2view/model2view.c index b6b32201865..915145c0ce4 100644 --- a/src/libged/model2view/model2view.c +++ b/src/libged/model2view/model2view.c @@ -40,7 +40,6 @@ ged_model2view_core(struct ged *gedp, int argc, const char *argv[]) double model_pt[3]; /* intentionally double for scan */ static const char *usage = "[x y z]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/model2view_lu/model2view_lu.c b/src/libged/model2view_lu/model2view_lu.c index e5f3663d3f7..ebadae79f68 100644 --- a/src/libged/model2view_lu/model2view_lu.c +++ b/src/libged/model2view_lu/model2view_lu.c @@ -39,6 +39,8 @@ ged_model2view_core_lu(struct ged *gedp, int argc, const char *argv[]) point_t view_pt; double model_pt[3]; /* intentionally double for scan */ static const char *usage = "x y z"; + double l2bval = (gedp->dbip) ? gedp->dbip->dbi_local2base : 1.0; + double b2lval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); @@ -55,9 +57,9 @@ ged_model2view_core_lu(struct ged *gedp, int argc, const char *argv[]) sscanf(argv[3], "%lf", &model_pt[Z]) != 1) goto bad; - VSCALE(model_pt, model_pt, gedp->dbip->dbi_local2base); + VSCALE(model_pt, model_pt, l2bval); MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt); - f = gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local; + f = gedp->ged_gvp->gv_scale * b2lval; VSCALE(view_pt, view_pt, f); bn_encode_vect(gedp->ged_result_str, view_pt, 1); diff --git a/src/libged/open/CMakeLists.txt b/src/libged/open/CMakeLists.txt index 4cd462df67b..9ff5534fad5 100644 --- a/src/libged/open/CMakeLists.txt +++ b/src/libged/open/CMakeLists.txt @@ -7,7 +7,7 @@ include_directories( ) add_definitions(-DGED_PLUGIN) -ged_plugin_library(ged-open SHARED open.c) +ged_plugin_library(ged-open SHARED open.cpp) target_link_libraries(ged-open libged libbu) set_property(TARGET ged-open APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) VALIDATE_STYLE(ged-open open.c) @@ -15,7 +15,7 @@ PLUGIN_SETUP(ged-open ged) CMAKEFILES( CMakeLists.txt - open.c + open.cpp ) # Local Variables: diff --git a/src/libged/open/open.c b/src/libged/open/open.c deleted file mode 100644 index 4c32d72f322..00000000000 --- a/src/libged/open/open.c +++ /dev/null @@ -1,148 +0,0 @@ -/* O P E N . C - * BRL-CAD - * - * Copyright (c) 2008-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libged/open.c - * - * The open command. - * - */ - -#include "common.h" - -#include - -#include "bu/cmd.h" -#include "bg/lod.h" - -#include "../ged_private.h" - - -int -ged_reopen_core(struct ged *gedp, int argc, const char *argv[]) -{ - struct db_i *new_dbip; - static const char *usage = "[filename]"; - - GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - /* get database filename */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "%s", gedp->dbip->dbi_filename); - return BRLCAD_OK; - } - - /* set database filename */ - if (argc == 2) { - char *av[2]; - struct db_i *old_dbip = gedp->dbip; - struct mater *old_materp = rt_material_head(); - struct mater *new_materp; - - // TODO - need to look more carefully at material_head and what - // its expected behavior is through a dbip change... - rt_new_material_head(MATER_NULL); - - if ((new_dbip = _ged_open_dbip(argv[1], 0)) == DBI_NULL) { - /* Restore RT's material head */ - rt_new_material_head(old_materp); - - bu_vls_printf(gedp->ged_result_str, "ged_reopen_core: failed to open %s\n", argv[1]); - return BRLCAD_ERROR; - } - - av[0] = "zap"; - av[1] = (char *)0; - ged_exec(gedp, 1, (const char **)av); - - new_materp = rt_material_head(); - - gedp->dbip = old_dbip; - rt_new_material_head(old_materp); - - /* close current database */ - if (gedp->dbip) - db_close(gedp->dbip); - gedp->dbip = NULL; - - /* Terminate any ged subprocesses */ - if (gedp != GED_NULL) { - for (size_t i = 0; i < BU_PTBL_LEN(&gedp->ged_subp); i++) { - struct ged_subprocess *rrp = (struct ged_subprocess *)BU_PTBL_GET(&gedp->ged_subp, i); - if (!rrp->aborted) { - bu_terminate(bu_process_pid(rrp->p)); - rrp->aborted = 1; - } - bu_ptbl_rm(&gedp->ged_subp, (long *)rrp); - BU_PUT(rrp, struct ged_subprocess); - } - bu_ptbl_reset(&gedp->ged_subp); - } - - gedp->dbip = new_dbip; - - rt_new_material_head(new_materp); - - /* New database open, need to initialize reference counts */ - db_update_nref(gedp->dbip, &rt_uniresource); - - - // Test LoD context creation - if (gedp->ged_lod) - bg_mesh_lod_context_destroy(gedp->ged_lod); - gedp->ged_lod = bg_mesh_lod_context_create(argv[1]); - - return BRLCAD_OK; - } - - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return BRLCAD_ERROR; -} - - -#ifdef GED_PLUGIN -#include "../include/plugin.h" -struct ged_cmd_impl reopen_cmd_impl = {"reopen", ged_reopen_core, GED_CMD_DEFAULT}; -const struct ged_cmd reopen_cmd = { &reopen_cmd_impl }; - -struct ged_cmd_impl open_cmd_impl = {"open", ged_reopen_core, GED_CMD_DEFAULT}; -const struct ged_cmd open_cmd = { &open_cmd_impl }; - - -const struct ged_cmd *open_cmds[] = { &reopen_cmd, &open_cmd, NULL }; - -static const struct ged_plugin pinfo = { GED_API, open_cmds, 2 }; - -COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info(void) -{ - return &pinfo; -} -#endif /* GED_PLUGIN */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libged/open/open.cpp b/src/libged/open/open.cpp new file mode 100644 index 00000000000..dbc70ae983d --- /dev/null +++ b/src/libged/open/open.cpp @@ -0,0 +1,189 @@ +/* O P E N . C P P + * BRL-CAD + * + * Copyright (c) 2008-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libged/open.cpp + * + * The open command. + * + */ + +#include "common.h" + +#include + +#include "bu/cmd.h" +#include "bu/opt.h" +#include "bv/lod.h" + +#include "../ged_private.h" + + +extern "C" int +ged_opendb_core(struct ged *gedp, int argc, const char *argv[]) +{ + int flip_endian = 0; + int force_create = 0; + int print_help = 0; + const char *cmdname = argv[0]; + static const char *usage = "[options] [filename]\n"; + + GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* get database filename */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "%s", gedp->dbip->dbi_filename); + return BRLCAD_OK; + } + + if (!BU_STR_EQUAL(cmdname, "reopen")) { + struct bu_opt_desc d[4]; + BU_OPT(d[0], "c", "create", "", NULL, &force_create, "Creates a new database if not already extant."); + BU_OPT(d[1], "f", "flip-endian", "", NULL, &flip_endian, "Opens file as a binary-incompatible v4 geometry database."); + BU_OPT(d[2], "h", "help", "", NULL, &print_help, "Print help."); + BU_OPT_NULL(d[3]); + + // We know we're the opendb command - start processing args + argc--; argv++; + + int ac = bu_opt_parse(NULL, argc, argv, d); + argc = ac; + + if (argc != 1) { + bu_vls_printf(gedp->ged_result_str, "%s ", cmdname); + _ged_cmd_help(gedp, usage, d); + return BRLCAD_ERROR; + } + } else { + // If we're doing reopen, the options aren't active + bu_vls_printf(gedp->ged_result_str, "%s filename", cmdname); + return BRLCAD_ERROR; + } + + /* Before proceeding with the full open logic, see if + * we can actually open what the caller provided */ + struct db_i *new_dbip = NULL; + struct mater *old_materp = rt_material_head(); + int existing_only = !force_create; + if ((new_dbip = _ged_open_dbip(argv[0], existing_only)) == DBI_NULL) { + + /* Restore RT's material head */ + rt_new_material_head(old_materp); + + bu_vls_printf(gedp->ged_result_str, "ged_opendb_core: failed to open %s\n", argv[0]); + + // If the caller has work to do after opendb call, trigger it - even + // though the open in its current form can't succeed, the caller may + // want to try again + if (gedp->ged_post_opendb_callback) + (*gedp->ged_post_opendb_callback)(gedp, gedp->ged_db_callback_udata); + + return BRLCAD_ERROR; + } + + /* Handle forced endian flipping, if needed and requested */ + if (flip_endian) { + if (db_version(new_dbip) != 4) { + bu_vls_printf(gedp->ged_result_str, "WARNING: [%s] is not a v4 database. The -f option will be ignored.\n", argv[0]); + } else { + if (new_dbip->dbi_version < 0) { + bu_vls_printf(gedp->ged_result_str, "Database [%s] was already (perhaps automatically) flipped, -f is redundant.\n", argv[0]); + } else { + bu_vls_printf(gedp->ged_result_str, "Treating [%s] as a binary-incompatible v4 geometry database.\n", argv[0]); + bu_vls_printf(gedp->ged_result_str, "Endianness flipped. Converting to READ ONLY.\n"); + /* flip the version number to indicate a flipped database. */ + new_dbip->dbi_version *= -1; + /* do NOT write to a flipped database */ + new_dbip->dbi_read_only = 1; + } + } + } + + /* Close current database, if we have one */ + if (gedp->dbip) { + const char *av[2]; + av[0] = "closedb"; + av[1] = (char *)0; + ged_exec(gedp, 1, (const char **)av); + } + + /* Set up the new database info in gedp */ + gedp->dbip = new_dbip; + rt_new_material_head(rt_material_head()); + + /* New database open, need to initialize reference counts */ + db_update_nref(gedp->dbip, &rt_uniresource); + + // LoD context creation (DbiState initialization can use info + // stored here, so do this first) + gedp->ged_lod = bv_mesh_lod_context_create(argv[0]); + + // If enabled, set up the DbiState container for fast structure access + const char *use_dbi_state = getenv("LIBGED_DBI_STATE"); + if (use_dbi_state) + gedp->dbi_state = new DbiState(gedp); + + // Set the view units, if we have a view + if (gedp->ged_gvp) { + gedp->ged_gvp->gv_base2local = gedp->dbip->dbi_base2local; + gedp->ged_gvp->gv_local2base = gedp->dbip->dbi_local2base; + } + + // If the caller has work to do after open, trigger it + if (gedp->ged_post_opendb_callback) + (*gedp->ged_post_opendb_callback)(gedp, gedp->ged_db_callback_udata); + + return BRLCAD_OK; +} + +extern "C" { +#ifdef GED_PLUGIN +#include "../include/plugin.h" +struct ged_cmd_impl reopen_cmd_impl = {"reopen", ged_opendb_core, GED_CMD_DEFAULT}; +const struct ged_cmd reopen_cmd = { &reopen_cmd_impl }; + +struct ged_cmd_impl opendb_cmd_impl = {"opendb", ged_opendb_core, GED_CMD_DEFAULT}; +const struct ged_cmd opendb_cmd = { &opendb_cmd_impl }; + +struct ged_cmd_impl open_cmd_impl = {"open", ged_opendb_core, GED_CMD_DEFAULT}; +const struct ged_cmd open_cmd = { &open_cmd_impl }; + +const struct ged_cmd *open_cmds[] = { &reopen_cmd, &opendb_cmd, &open_cmd, NULL }; + +static const struct ged_plugin pinfo = { GED_API, open_cmds, 3 }; + +COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info(void) +{ + return &pinfo; +} +#endif /* GED_PLUGIN */ +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/pathsum/pathsum.c b/src/libged/pathsum/pathsum.c index d3f0fa3e8de..52dda6f8a1c 100644 --- a/src/libged/pathsum/pathsum.c +++ b/src/libged/pathsum/pathsum.c @@ -97,6 +97,8 @@ ged_pathsum_core(struct ged *gedp, int argc, const char *argv[]) char *tok; tok = strtok((char *)argv[pos_in], "/"); while (tok) { + if (gtd.gtd_objpos >= _GED_MAX_LEVELS) + break; if ((gtd.gtd_obj[gtd.gtd_objpos++] = db_lookup(gedp->dbip, tok, LOOKUP_NOISY)) == RT_DIR_NULL) { return BRLCAD_ERROR; } @@ -124,7 +126,8 @@ ged_pathsum_core(struct ged *gedp, int argc, const char *argv[]) if (gtd.gtd_prflag == 0) { /* path not found */ bu_vls_printf(gedp->ged_result_str, "PATH: "); - for (i = 0; i < gtd.gtd_objpos; i++) { + /* NOTE: gtd.gtd_obj size is limited to _GED_MAX_LEVLES - make sure our loop bounds dont exceed */ + for (i = 0; i < FMIN(gtd.gtd_objpos, _GED_MAX_LEVELS); i++) { bu_vls_printf(gedp->ged_result_str, "/%s", gtd.gtd_obj[i]->d_namep); } bu_vls_printf(gedp->ged_result_str, " NOT FOUND\n"); diff --git a/src/libged/perspective/perspective.c b/src/libged/perspective/perspective.c index 1825487e2dc..0a1739f22ab 100644 --- a/src/libged/perspective/perspective.c +++ b/src/libged/perspective/perspective.c @@ -39,7 +39,6 @@ ged_perspective_core(struct ged *gedp, int argc, const char *argv[]) double perspective; static const char *usage = "[angle]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/pix2fb/pix2fb.c b/src/libged/pix2fb/pix2fb.c index 97b4953b987..0f9670da257 100644 --- a/src/libged/pix2fb/pix2fb.c +++ b/src/libged/pix2fb/pix2fb.c @@ -176,7 +176,6 @@ ged_pix2fb_core(struct ged *gedp, int argc, const char *argv[]) { int ret; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); if (!gedp->ged_gvp) { diff --git a/src/libged/plot/plot.c b/src/libged/plot/plot.c index ea641f0fca8..d04090b7019 100644 --- a/src/libged/plot/plot.c +++ b/src/libged/plot/plot.c @@ -58,7 +58,6 @@ ged_plot_core(struct ged *gedp, int argc, const char *argv[]) int is_pipe = 0; static const char *usage = "file [2|3] [f] [g] [z]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/pmodel2view/pmodel2view.c b/src/libged/pmodel2view/pmodel2view.c index e0036efa57b..503e0b9ad9c 100644 --- a/src/libged/pmodel2view/pmodel2view.c +++ b/src/libged/pmodel2view/pmodel2view.c @@ -35,7 +35,6 @@ int ged_pmodel2view_core(struct ged *gedp, int argc, const char *argv[]) { - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/png/png.c b/src/libged/png/png.c index 5688c2c242b..df7e7af57a3 100644 --- a/src/libged/png/png.c +++ b/src/libged/png/png.c @@ -125,7 +125,6 @@ ged_png_core(struct ged *gedp, int argc, const char *argv[]) int r, g, b; static const char *usage = "[-c r/g/b] [-s size] file"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/png2fb/png2fb.c b/src/libged/png2fb/png2fb.c index 7f52b4359bd..34f943ccd97 100644 --- a/src/libged/png2fb/png2fb.c +++ b/src/libged/png2fb/png2fb.c @@ -137,7 +137,6 @@ ged_png2fb_core(struct ged *gedp, int argc, const char *argv[]) { int ret; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/pnts/pnts.cpp b/src/libged/pnts/pnts.cpp index e9c965ce58c..1e2469e5c72 100644 --- a/src/libged/pnts/pnts.cpp +++ b/src/libged/pnts/pnts.cpp @@ -44,9 +44,9 @@ extern "C" { #include "rt/geom.h" #include "wdb.h" #include "analyze.h" +} #include "../ged_private.h" #include "../pnts_util.h" -} static void _pnt_to_tri(point_t *p, vect_t *n, struct rt_bot_internal *bot_ip, fastf_t scale, unsigned long pntcnt) @@ -603,11 +603,11 @@ _obj_to_pnts(struct ged *gedp, int argc, const char **argv) return BRLCAD_ERROR; } + bu_vls_printf(gedp->ged_result_str, "Generated pnts object %s with %ld points, avg. partition thickness %g", pnt_prim, pnts->count, avg_thickness); + GED_DB_DIRADD(gedp, dp, pnt_prim, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type, BRLCAD_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, BRLCAD_ERROR); - bu_vls_printf(gedp->ged_result_str, "Generated pnts object %s with %ld points, avg. partition thickness %g", pnt_prim, pnts->count, avg_thickness); - return BRLCAD_OK; } @@ -620,7 +620,20 @@ _pnt_read(struct rt_pnts_internal *pnts, int numcnt, const char **nums, const ch for (i = 0; i < numcnt; i++) { fastf_t val; fc = fmt[i]; - if (bu_opt_fastf_t(NULL, 1, (const char **)&nums[i], (void *)&val) == -1) { + + // trim trailing whitespace + char* num = (char*)nums[i]; + int j = strlen(nums[i]) - 1; + while (j > -1) { + if (num[j] == ' ') { + j--; + } else { + num[j+1] = '\0'; + break; + } + } + + if (bu_opt_fastf_t(NULL, 1, (const char **)&num, (void *)&val) == -1) { bu_log("Error - failed to read number %s\n", nums[i]); return BRLCAD_ERROR; } @@ -633,7 +646,7 @@ _pnt_read(struct rt_pnts_internal *pnts, int numcnt, const char **nums, const ch continue; } if ((fc == 'r') || (fc == 'g') || (fc == 'b')) { - _ged_pnt_c_set(point, pnts->type, fc, val); + _ged_pnt_c_set(point, pnts->type, fc, val / 255.0); continue; } if (fc == 's') { @@ -809,11 +822,11 @@ _read_pnts(struct ged *gedp, int argc, const char **argv) pnts->count = pnts_cnt; fclose(fp); + bu_vls_printf(gedp->ged_result_str, "Generated pnts object %s with %ld points", pnt_prim, pnts->count); + GED_DB_DIRADD(gedp, dp, pnt_prim, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type, BRLCAD_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, BRLCAD_ERROR); - bu_vls_printf(gedp->ged_result_str, "Generated pnts object %s with %ld points", pnt_prim, pnts->count); - bu_vls_free(&fmt); if (nums) bu_free(nums, "free old nums array"); return BRLCAD_OK; @@ -885,7 +898,8 @@ _write_pnts(struct ged *gedp, int argc, const char **argv) pnts = (struct rt_pnts_internal *)intern.idb_ptr; RT_PNTS_CK_MAGIC(pnts); - if (pnts->type != RT_PNT_TYPE_NRM) { + if (pnts->type == RT_PNT_UNKNOWN) { + bu_vls_sprintf(gedp->ged_result_str, "Error: unknown pnts type\n"); rt_db_free_internal(&intern); return BRLCAD_ERROR; } @@ -949,9 +963,10 @@ _write_pnts(struct ged *gedp, int argc, const char **argv) _pnts_fastf_t_to_vls(&pnt_str, pn->v[i], precis); fprintf(fp, "%s ", bu_vls_addr(&pnt_str)); } - if (bu_color_to_rgb_chars(&(pn->c), rgb)) { + if (!bu_color_to_rgb_chars(&(pn->c), rgb)) { bu_vls_sprintf(gedp->ged_result_str, "Error: cannot process point color\n"); rt_db_free_internal(&intern); + fclose(fp); return BRLCAD_ERROR; } fprintf(fp, "%d %d %d\n", rgb[RED], rgb[GRN], rgb[BLU]); @@ -1025,7 +1040,7 @@ _write_pnts(struct ged *gedp, int argc, const char **argv) _pnts_fastf_t_to_vls(&pnt_str, pn->s, precis); fprintf(fp, "%s ", bu_vls_addr(&pnt_str)); } - if (bu_color_to_rgb_chars(&(pn->c), rgb)) { + if (!bu_color_to_rgb_chars(&(pn->c), rgb)) { bu_vls_sprintf(gedp->ged_result_str, "Error: cannot process point color\n"); rt_db_free_internal(&intern); fclose(fp); @@ -1052,7 +1067,7 @@ _write_pnts(struct ged *gedp, int argc, const char **argv) _pnts_fastf_t_to_vls(&pnt_str, pn->n[i], precis); fprintf(fp, "%s ", bu_vls_addr(&pnt_str)); } - if (bu_color_to_rgb_chars(&(pn->c), rgb)) { + if (!bu_color_to_rgb_chars(&(pn->c), rgb)) { bu_vls_sprintf(gedp->ged_result_str, "Error: cannot process point color\n"); rt_db_free_internal(&intern); fclose(fp); @@ -1112,7 +1127,7 @@ _write_pnts(struct ged *gedp, int argc, const char **argv) _pnts_fastf_t_to_vls(&pnt_str, pn->s, precis); fprintf(fp, "%s ", bu_vls_addr(&pnt_str)); } - if (bu_color_to_rgb_chars(&(pn->c), rgb)) { + if (!bu_color_to_rgb_chars(&(pn->c), rgb)) { bu_vls_sprintf(gedp->ged_result_str, "Error: cannot process point color\n"); rt_db_free_internal(&intern); fclose(fp); diff --git a/src/libged/pnts_util.c b/src/libged/pnts_util.c index 1e3d2a6135d..103e0960ea7 100644 --- a/src/libged/pnts_util.c +++ b/src/libged/pnts_util.c @@ -236,7 +236,7 @@ _ged_pnts_fmt_type(const char *fc) if (has_pnt && has_nrm) return RT_PNT_TYPE_NRM; if (has_pnt && has_s && has_c) return RT_PNT_TYPE_COL_SCA; if (has_pnt && has_s) return RT_PNT_TYPE_SCA; - if (has_pnt && has_c) return RT_PNT_TYPE_SCA; + if (has_pnt && has_c) return RT_PNT_TYPE_COL; if (has_pnt) return RT_PNT_TYPE_PNT; return RT_PNT_UNKNOWN; diff --git a/src/libged/points_eval.c b/src/libged/points_eval.c index c01cee04018..c065826b54c 100644 --- a/src/libged/points_eval.c +++ b/src/libged/points_eval.c @@ -50,13 +50,13 @@ draw_points(struct bv_scene_obj *s) return BRLCAD_OK; /* nothing to do is fine */ struct db_full_path *fp = (struct db_full_path *)s->s_path; - if (!fp) + struct directory *dp = (fp) ? DB_FULL_PATH_CUR_DIR(fp) : (struct directory *)s->dp; + if (!dp) return BRLCAD_OK; /* nothing to do is fine */ /* there's a path to draw */ struct bn_tol btol = BN_TOL_INIT_TOL; struct db_i* dbip = d->dbip; - struct directory *dp = DB_FULL_PATH_CUR_DIR(fp); if (!dbip || !dp) return BRLCAD_ERROR; diff --git a/src/libged/polyclip.cpp b/src/libged/polyclip.cpp index 3ce51aadfd7..45333d2ab35 100644 --- a/src/libged/polyclip.cpp +++ b/src/libged/polyclip.cpp @@ -294,7 +294,10 @@ ged_polygons_overlap(struct ged *gedp, struct bg_polygon *polyA, struct bg_polyg GED_CHECK_VIEW(gedp, BRLCAD_ERROR); struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); - return bg_polygons_overlap(polyA, polyB, gedp->ged_gvp->gv_model2view, &wdbp->wdb_tol, gedp->ged_gvp->gv_scale); + plane_t pl; + bv_view_plane(&pl, gedp->ged_gvp); + + return bg_polygons_overlap(polyA, polyB, &pl, &wdbp->wdb_tol, gedp->ged_gvp->gv_scale); } static int diff --git a/src/libged/prcolor/prcolor.c b/src/libged/prcolor/prcolor.c index 1d343acd66e..8a14a08082c 100644 --- a/src/libged/prcolor/prcolor.c +++ b/src/libged/prcolor/prcolor.c @@ -84,7 +84,7 @@ pr_mater(struct ged *gedp, { char buf[128]; - (void)sprintf(buf, "%5d..%d", mp->mt_low, mp->mt_high); + (void)sprintf(buf, "%5ld..%ld", mp->mt_low, mp->mt_high); pr_vls_col_item(gedp->ged_result_str, buf, ccp, clp); (void)sprintf(buf, "%3d, %3d, %3d", mp->mt_r, mp->mt_g, mp->mt_b); pr_vls_col_item(gedp->ged_result_str, buf, ccp, clp); diff --git a/src/libged/qvrot/qvrot.c b/src/libged/qvrot/qvrot.c index 744e269f911..77e9daf489b 100644 --- a/src/libged/qvrot/qvrot.c +++ b/src/libged/qvrot/qvrot.c @@ -62,7 +62,6 @@ ged_qvrot_core(struct ged *gedp, int argc, const char *argv[]) double theta; static const char *usage = "x y z angle"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/rect/rect.c b/src/libged/rect/rect.c index 8cf0a3743f9..baaf828fd0b 100644 --- a/src/libged/rect/rect.c +++ b/src/libged/rect/rect.c @@ -131,8 +131,6 @@ rect_rt(struct ged *gedp, int port) int xmin, xmax; int ymin, ymax; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); - /* initialize result in case we need to report something here */ bu_vls_trunc(gedp->ged_result_str, 0); @@ -221,7 +219,6 @@ rect_zoom(struct ged *gedp) point_t old_view_center; point_t new_view_center; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); /* initialize result */ @@ -289,7 +286,6 @@ ged_rect_core(struct ged *gedp, point_t user_pt; /* Value(s) provided by user */ int i; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/rot_point/rot_point.c b/src/libged/rot_point/rot_point.c index 3cd62095a2e..22ecb58826b 100644 --- a/src/libged/rot_point/rot_point.c +++ b/src/libged/rot_point/rot_point.c @@ -40,7 +40,6 @@ ged_rot_point_core(struct ged *gedp, int argc, const char *argv[]) point_t rpoint; static const char *usage = "x y z"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/rtcheck/rtcheck2.cpp b/src/libged/rtcheck/rtcheck2.cpp index 3d5d17c871c..a4ad46c5859 100644 --- a/src/libged/rtcheck/rtcheck2.cpp +++ b/src/libged/rtcheck/rtcheck2.cpp @@ -115,10 +115,12 @@ rtcheck_vector_handler(void *clientData, int type) struct bview *v = gedp->ged_gvp; struct bu_ptbl *vobjs = bv_view_objs(v, BV_VIEW_OBJS); std::set robjs; - for (i = 0; i < BU_PTBL_LEN(vobjs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(vobjs, i); - if (!bu_strncmp(sname, bu_vls_cstr(&s->s_name), strlen(sname))) { - robjs.insert(s); + if (vobjs) { + for (i = 0; i < BU_PTBL_LEN(vobjs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(vobjs, i); + if (!bu_strncmp(sname, bu_vls_cstr(&s->s_name), strlen(sname))) { + robjs.insert(s); + } } } std::set::iterator r_it; diff --git a/src/libged/select.cpp b/src/libged/select.cpp deleted file mode 100644 index 6fb2c8c72d1..00000000000 --- a/src/libged/select.cpp +++ /dev/null @@ -1,1175 +0,0 @@ -/* S E L E C T . C P P - * BRL-CAD - * - * Copyright (c) 2008-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file select.cpp - * - * "Sets" in BRL-CAD have some interesting complications, particularly when it - * comes to geometric scenes. Graphically visible scene objects representing - * .g geometry always correspond to one instance of one solid. Frequently those - * "raw geometry" scene objects will be grouped as children of a parent scene - * object that corresponds to the requested "drawn" object. Those top level - * groups are what is reported out by the who command, since it will be more - * compact and informative to users than a detailed itemization of (potentially) - * thousands of individual instance shape objects. Those top level groups also - * offer convenient subsets which alleviate the need for the drawing logic to - * check all scene object paths for matches of a user specified path - if the - * parent scene object isn't a partial match, none of the children need to be - * checked. - * - * However, when defining selection sets, it gets more complex. Building selection - * sets graphically by interrogating the scene will build up sets of individual - * shape objects. If the correct sub-sets of those objects are selected, we can - * conceptually regard a parent comb as being fully selected, if we so choose. - * However, that parent comb may not have a directly corresponding scene object, - * if it was not what was originally requested by the user (or generated as - * consequence of the processing actions of the draw/erase routines.) Nor would we - * always want the "fully selected" parent comb to replace all of its children in - * the set, since different types of actions may want/need the individual instance - * solids rather than the parent combs. - * - * We will need "expand" and "collapse" operations for sets, the former of which - * will take each entry in the set and replace it with all of its child instances. - * In the event of multiple expansions producing duplicates, the duplicates will - * be collapsed to a unique set. - * - * Likewise, the "collapse" operation will look at the children contained in the set, - * and for cases where all children are present, those children will be replaced - * with one reference to the parent. This will be done working "up" the various - * trees until either all potential collapses are missing one or more children, or - * all entries collapse to top level objects. - * - * Nor do we want to always expand or collapse - in some cases we want exactly - * what was selected. For example, if we have the tree - * - * a - * b - * c - * d - * e - * - * and we want to select and operate on /a/b/c, we can't simply collapse (which - * will result in /a) or expand (which will result in /a/b/c/d/e). If /a/b/c/d/e - * is part of a larger selection set and we want to replace it with /a/b/c, we will - * need a "insert" operation that identifies and removes all subset paths of - * /a/b/c prior to insertion of /a/b/c into the set, but does not alter any - * other paths or process /a/b/c itself. - * - * As an exercise, we consider a potential use of sets - selecting an instance of - * an object in a scene for editing operations. There are a number of things we - * will need to know: - * - * The solids associated with the selected instance itself. If a solid was - * selected we already know where to get the editing wireframe, but if comb was - * selected from the tree, there's more work to do. We have the advantage of - * explicitly knowing the level at which the editing operations will take place - * (a tree selection would correspond to the previously discussed "insert" - * operation to the set), but we will need to generate a list of that comb's - * child solids so we can create appropriate editing wireframe visual objects - * to represent the comb in the scene. In the event of multiple selections we - * would need to construct the instance set from multiple sources. - * - * If we are performing graphical selection operations, we may be either refining - * a set by selecting objects to be removed from it, or selecting objects not - * already part of the set to add to it. In either case we will be operating - * at the individual instance level, and must provide ways to allow the user - * to refine (perhaps via the tree view) their selection intent for editing - * purposes. - * - * If we want to (say) set all non-active objects to be highly transparent when - * an editing operation commences, we will also need to be able to construct the - * set of all scene objects which are NOT active in the currently processed set. - * - * If we want to edit primitive parameters, rather than comb instances, we will - * need to boil down a set of selected comb instances to one or a set of solid - * names. (Usually a set count > 1 won't work for primitive editing... in that - * case we may want to just reject an attempt to solid edit...) Given the solid, - * we will then need to extract the set of all drawn instances of that solid from - * the scene, so we can generate and update per-instance wireframes for all of - * them to visually reflect the impact of the edit (MGED's inability to do this - * is why solid editing is rejected if more than one instance of the object is - * drawn in the scene - we don't want that limitation.) - * - */ - -#include "common.h" - -#include -#include -#include -#include - -extern "C" { -#define XXH_STATIC_LINKING_ONLY -#include "xxhash.h" -} - -#include "bu/path.h" -#include "bu/str.h" -#include "ged/view/select.h" -#include "./ged_private.h" - -static void -fp_path_split(std::vector *objs, const char *str) -{ - std::string s(str); - size_t pos = 0; - if (s.c_str()[0] == '/') - s.erase(0, 1); //Remove leading slash - while ((pos = s.find_first_of("/", 0)) != std::string::npos) { - std::string ss = s.substr(0, pos); - (*objs).push_back(ss); - s.erase(0, pos + 1); - } - (*objs).push_back(s); -} - -static bool -fp_path_top_match(std::vector *top, std::vector *candidate) -{ - for (size_t i = 0; i < top->size(); i++) { - if (i == candidate->size()) - return false; - if ((*top)[i] != (*candidate)[i]) - return false; - } - return true; -} - - -struct ged_selection_set_impl { - std::map *>> m; -}; - -struct ged_selection_sets_impl { - std::map *s; -}; - - -struct ged_selection_sets * -ged_selection_sets_create(struct ged *gedp) -{ - if (!gedp) - return NULL; - struct ged_selection_sets *s; - BU_GET(s, struct ged_selection_sets); - s->gedp = gedp; - s->i = new ged_selection_sets_impl; - s->i->s = new std::map; - struct ged_selection_set *ds; - BU_GET(ds, struct ged_selection_set); - bu_vls_init(&ds->name); - bu_vls_sprintf(&ds->name, "default"); - ds->gedp = gedp; - ds->i = new ged_selection_set_impl; - (*s->i->s)[std::string("default")] = ds; - return s; -} - -void -ged_selection_sets_destroy(struct ged_selection_sets *s) -{ - if (!s) - return; - // TODO - clean up set contents - delete s->i->s; - delete s->i; - BU_PUT(s, struct ged_selection_sets); -} - - -int -ged_selection_set_cpy(struct ged_selection_set *to, struct ged_selection_set *from) -{ - if (!from || !to || from == to) - return 0; - - ged_selection_set_clear(to); - std::map *>>::iterator it; - int i = 0; - for (it = from->i->m.begin(); it != from->i->m.end(); it++) { - struct ged_selection *o; - BU_GET(o, struct ged_selection); - bu_vls_init(&o->path); - bu_vls_sprintf(&o->path, "%s", bu_vls_cstr(&it->second.first->path)); - o->r_os = it->second.first->r_os; - bu_ptbl_init(&o->sobjs, 8, "selection objs"); - for (size_t j = 0; j < BU_PTBL_LEN(&it->second.first->sobjs); j++) { - bu_ptbl_ins(&o->sobjs, BU_PTBL_GET(&it->second.first->sobjs, j)); - } - - std::vector *nsp = new std::vector; - for (size_t j = 0; j < it->second.second->size(); j++) { - std::string dpstr = (*it->second.second)[j]; - (*nsp).push_back(dpstr); - } - - to->i->m[it->first] = std::make_pair(o, nsp); - i++; - } - - return i; -} - -struct ged_selection_set * -ged_selection_set_create(const char *s_name, struct ged *gedp) -{ - struct ged_selection_set *ds; - BU_GET(ds, struct ged_selection_set); - ds->gedp = gedp; - bu_vls_init(&ds->name); - if (s_name) - bu_vls_sprintf(&ds->name, "%s", s_name); - ds->i = new ged_selection_set_impl; - return ds; -} - -void -ged_selection_set_destroy(struct ged_selection_set *s) -{ - if (!s) - return; - - ged_selection_set_clear(s); - - // If we have a null or empty s_name, we're targeting the "default" set. We don't - // delete it, since there is always a default set - if (BU_STR_EQUAL(bu_vls_cstr(&s->name), "default")) { - return; - } - - bu_vls_free(&s->name); - delete s->i; - BU_PUT(s, struct ged_selection_set); -} - -struct ged_selection_set * -ged_selection_sets_get(struct ged_selection_sets *s, const char *s_name) -{ - if (!s || !s_name || !strlen(s_name)) - return NULL; - std::map::iterator s_it; - std::string sname = (s_name || !strlen(s_name)) ? std::string("default") : std::string(s_name); - s_it = s->i->s->find(sname); - if (s_it == s->i->s->end()) { - struct ged_selection_set *ds = ged_selection_set_create(s_name, s->gedp); - (*s->i->s)[sname] = ds; - s_it = s->i->s->find(sname); - } - return s_it->second; -} - -void -ged_selection_sets_put(struct ged_selection_sets *s, const char *s_name) -{ - if (!s) - return; - std::map::iterator s_it; - std::string sname = (!s_name || !strlen(s_name)) ? std::string("default") : std::string(s_name); - s_it = s->i->s->find(sname); - if (s_it == s->i->s->end()) - return; - - ged_selection_set_destroy(s_it->second); - - // If we have a null or empty s_name, we're targeting the "default" set. We don't - // delete it, since there is always a default set - if (sname == std::string("default")) { - return; - } - - s->i->s->erase(s_it); -} - -size_t -ged_selection_sets_lookup(struct bu_ptbl *sets, struct ged_selection_sets *s, const char *pattern) -{ - if (!sets|| !s || !pattern || !strlen(pattern)) - return 0; - - bu_ptbl_reset(sets); - - std::vector s_sets; - std::map::iterator s_it; - for (s_it = s->i->s->begin(); s_it != s->i->s->end(); s_it++) { - if (!bu_path_match(pattern, s_it->first.c_str(), 0)) { - s_sets.push_back(s_it->second); - } - } - - for (size_t i = 0; i < s_sets.size(); i++) { - bu_ptbl_ins(sets, (long *)s_sets[i]); - } - - return s_sets.size(); -} - -int -ged_selection_find(struct ged_selection_set *s, const char *s_name) -{ - if (!s || !s_name || !strlen(s_name)) - return 0; - - std::string key(s_name); - if (s->i->m.find(key) != s->i->m.end()) - return 1; - - return 0; -} - -size_t -ged_selection_lookup(struct bu_ptbl *matches, struct ged_selection_set *s, const char *s_name) -{ - if (!matches || !s || !s_name || !strlen(s_name)) - return 0; - - bu_ptbl_reset(matches); - - std::vector s_top; - fp_path_split(&s_top, s_name); - - // We want to do a "db_fullpath" style check to see if any active entries are matches or - // subsets of this path. To allow for the possibility of selections that have no corresponding - // database object (in particular, invalid comb entries we may want to select to edit) we - // do like the erase command and operate on the strings themselves. - std::vector s_matches; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - if (fp_path_top_match(&s_top, s_it->second.second)) { - s_matches.push_back(s_it->second.first); - } - } - - for (size_t i = 0; i < s_matches.size(); i++) { - bu_ptbl_ins(matches, (long *)s_matches[i]); - } - - return s_matches.size(); -} - -size_t -ged_selection_lookup_fp(struct bu_ptbl *matches, struct ged_selection_set *s, struct db_full_path *fp) -{ - if (!matches || !s || !fp) - return 0; - char *fp_s = db_path_to_string(fp); - size_t ret = ged_selection_lookup(matches, s, fp_s); - bu_free(fp_s, "fp_s"); - return ret; -} - - -int -ged_selection_set_list(char ***keys, struct ged_selection_set *s) -{ - if (!keys || !s || !s->i->m.size()) - return 0; - - (*keys) = (char **)bu_calloc(s->i->m.size()+1, sizeof(char *), "name array"); - std::map *>>::iterator s_it; - int i = 0; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - (*keys)[i] = bu_strdup(s_it->first.c_str()); - i++; - } - return (int)s->i->m.size(); -} - -void -ged_selection_set_clear(struct ged_selection_set *s) -{ - if (!s) - return; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - bu_vls_free(&s_it->second.first->path); - BU_PUT(s_it->second.first, struct ged_selection); - delete s_it->second.second; - } - s->i->m.clear(); -} - -struct ged_selection * -_selection_get(struct ged_selection_set *s, const char *s_name, std::vector *pvec) -{ - if (!s || !s_name || !strlen(s_name)) - return NULL; - struct ged_selection *s_o; - BU_GET(s_o, struct ged_selection); - s_o->gedp = s->gedp; - s_o->r_os = NULL; - bu_ptbl_init(&s_o->sobjs, 8, "selection objs"); - bu_vls_init(&s_o->path); - bu_vls_sprintf(&s_o->path, "%s", s_name); - if (pvec) - s->i->m[std::string(s_name)] = std::pair *>(s_o, pvec); - return s_o; -} - -void -_selection_put(struct ged_selection_set *s, const char *s_name) -{ - if (!s || !s_name || !strlen(s_name)) - return; - std::map *>>::iterator s_it; - s_it = s->i->m.find(std::string(s_name)); - if (s_it == s->i->m.end()) - return; - struct ged_selection *gs = s_it->second.first; - if (gs) { - bu_vls_free(&gs->path); - BU_PUT(gs, struct ged_selection); - } - if (s_it->second.second) - delete s_it->second.second; - - s->i->m.erase(s_it); -} - -struct ged_selection * -ged_selection_insert(struct ged_selection_set *s, const char *s_path) -{ - if (!s || !s_path || !strlen(s_path)) - return NULL; - - // If s_path isn't a valid path, don't add it - struct db_full_path ifp; - db_full_path_init(&ifp); - int spathret = db_string_to_path(&ifp, s->gedp->dbip, s_path); - if (spathret < 0) { - db_free_full_path(&ifp); - return NULL; - } - db_free_full_path(&ifp); - - // Unlike the lookup, with the insert operation we need to check if this - // path is equal to or below any already added paths in the set. If so, - // it's already active (either explicitly or implicitly) in the set and we - // don't duplicate it. So the incoming path is the child candidate and the - // existing paths are the top candidates, switching the - // ged_selection_lookup behavior. - struct bu_vls tpath = BU_VLS_INIT_ZERO; - std::vector *s_c = new std::vector; - fp_path_split(s_c, s_path); - - struct ged_selection *match = NULL; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - if (fp_path_top_match(s_it->second.second, s_c)) { - match = s_it->second.first; - break; - } - } - - if (match) { - bu_vls_free(&tpath); - delete s_c; - return match; - } - - // If no match found, we're adding the path. We also need to remove any - // paths that are below this path. - std::set to_remove; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - if (fp_path_top_match(s_c, s_it->second.second)) - to_remove.insert(s_it->first); - } - std::set::iterator r_it; - for (r_it = to_remove.begin(); r_it != to_remove.end(); r_it++) { - bu_vls_sprintf(&tpath, "%s", r_it->c_str()); - _selection_put(s, bu_vls_cstr(&tpath)); - } - - // Children cleared - add the new path - match = _selection_get(s, s_path, s_c); - - bu_vls_free(&tpath); - - return match; -} - -struct ged_selection * -ged_selection_insert_fp(struct ged_selection_set *s, struct db_full_path *fp) -{ - if (!s || !fp) - return NULL; - char *fp_s = db_path_to_string(fp); - struct ged_selection *ss = ged_selection_insert(s, fp_s); - bu_free(fp_s, "fp_s"); - return ss; -} - -struct ged_selection * -ged_selection_insert_obj(struct ged_selection_set *s, struct bv_scene_obj *o) -{ - if (!s || !o) - return NULL; - struct ged_selection *ss = ged_selection_insert(s, bu_vls_cstr(&o->s_name)); - if (ss) - bu_ptbl_ins(&ss->sobjs, (long *)o); - return ss; -} - - -// The remove operation may require splitting of an existing path into its components, -// unless it happens to match exactly a selected path. This basically looks like an -// expanding of the path which is a tops path of the erase candidate, the removal -// of every expanded path for which the erase path is a match or parent, and then the -// collapse of the remaining paths. This new set is then the replacement for the -// original parent path. -void -ged_selection_remove(struct ged_selection_set *s, const char *s_path) -{ - if (!s || !s_path || !strlen(s_path)) - return; - - // See if the proposed erase path is a child (or equal to) any existing path - std::vector *s_c = new std::vector; - fp_path_split(s_c, s_path); - - struct ged_selection *match = NULL; - std::vector *msplit = NULL; - std::string match_str; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - if (fp_path_top_match(s_it->second.second, s_c)) { - match = s_it->second.first; - msplit = s_it->second.second; - match_str = s_it->first; - break; - } - } - if (!match) { - s->i->m.erase(std::string(s_path)); - delete s_c; - return; - } - - // If we have an exact match we're done - if (BU_STR_EQUAL(s_path, bu_vls_cstr(&match->path))) { - _selection_put(s, s_path); - delete s_c; - return; - } - - // If not, s_path is a child of match. The hard case - need to split and - // reconstitute the remaining sub-paths of match as new selections - - // Create a temporary selection set - struct ged_selection_set *tmp_s; - BU_GET(tmp_s, struct ged_selection_set); - tmp_s->gedp = s->gedp; - tmp_s->i = new ged_selection_set_impl; - - // Move the match from the original set to the temporary set - s->i->m.erase(match_str); - tmp_s->i->m[(std::string(s_path))] = std::pair *>(match, msplit); - - ged_selection_set_expand(tmp_s, tmp_s); - - // Remove everything in the expanded temp set where s_c is a - // top path of the current path - std::set rm_tmp; - for (s_it = tmp_s->i->m.begin(); s_it != tmp_s->i->m.end(); s_it++) { - if (fp_path_top_match(s_c, s_it->second.second)) { - rm_tmp.insert(s_it->first.c_str()); - } - } - std::set::iterator tmp_it; - for (tmp_it = rm_tmp.begin(); tmp_it != rm_tmp.end(); tmp_it++) { - _selection_put(tmp_s, (*tmp_it).c_str()); - } - - // Collapse everything that's left into the new selection paths - ged_selection_set_collapse(tmp_s, tmp_s); - - // Move the tmp_s selections into the original set - for (s_it = tmp_s->i->m.begin(); s_it != tmp_s->i->m.end(); s_it++) { - s->i->m[s_it->first] = s_it->second; - } - tmp_s->i->m.clear(); - - // Delete temporary selection set - delete tmp_s->i; - BU_PUT(tmp_s, struct ged_selection_set); - delete s_c; -} - -void -ged_selection_remove_fp(struct ged_selection_set *s, struct db_full_path *fp) -{ - if (!s || !fp) - return; - char *fp_s = db_path_to_string(fp); - ged_selection_remove(s, fp_s); - bu_free(fp_s, "fp_s"); -} - -void -ged_selection_remove_obj(struct ged_selection_set *s, struct bv_scene_obj *o) -{ - if (!s || !o) - return; - ged_selection_remove(s, bu_vls_cstr(&o->s_name)); -} - - - -/* Search client data container */ -struct expand_client_data_t { - struct db_i *dbip; - struct bu_ptbl *full_paths; -}; - -/** - * A generic traversal function maintaining awareness of the full path - * to a given object. - */ -static void -expand_subtree(struct db_full_path *path, int curr_bool, union tree *tp, - void (*traverse_func) (struct db_full_path *path, void *), - void *cmap, void *client_data) -{ - struct directory *dp; - struct expand_client_data_t *ecd= (struct expand_client_data_t *)client_data; - std::unordered_map *c_inst_map = (std::unordered_map *)cmap; - - if (!tp) - return; - - RT_CK_FULL_PATH(path); - RT_CHECK_DBI(ecd->dbip); - RT_CK_TREE(tp); - - switch (tp->tr_op) { - case OP_NOT: - case OP_GUARD: - case OP_XNOP: - expand_subtree(path, OP_UNION, tp->tr_b.tb_left, traverse_func, cmap, client_data); - break; - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - expand_subtree(path, OP_UNION, tp->tr_b.tb_left, traverse_func, cmap, client_data); - expand_subtree(path, tp->tr_op, tp->tr_b.tb_right, traverse_func, cmap, client_data); - break; - case OP_DB_LEAF: - if (UNLIKELY(ecd->dbip->dbi_use_comb_instance_ids && c_inst_map)) - (*c_inst_map)[std::string(tp->tr_l.tl_name)]++; - if ((dp=db_lookup(ecd->dbip, tp->tr_l.tl_name, LOOKUP_QUIET)) == RT_DIR_NULL) { - return; - } else { - /* Create the new path */ - if (!(dp->d_flags & RT_DIR_HIDDEN)) { - db_add_node_to_full_path(path, dp); - DB_FULL_PATH_SET_CUR_BOOL(path, curr_bool); - if (UNLIKELY(ecd->dbip->dbi_use_comb_instance_ids && c_inst_map)) - DB_FULL_PATH_SET_CUR_COMB_INST(path, (*c_inst_map)[std::string(tp->tr_l.tl_name)]-1); - if (!db_full_path_cyclic(path, NULL, 0)) { - /* Keep going */ - traverse_func(path, client_data); - } else { - char *path_string = db_path_to_string(path); - bu_log("WARNING: not traversing cyclic path %s\n", path_string); - bu_free(path_string, "free path str"); - } - } - DB_FULL_PATH_POP(path); - break; - } - break; - default: - bu_log("db_functree_subtree: unrecognized operator %d\n", tp->tr_op); - bu_bomb("db_functree_subtree: unrecognized operator\n"); - } -} - -static void -expand_list(struct db_full_path *path, void *client_data) -{ - struct directory *dp; - struct expand_client_data_t *ecd= (struct expand_client_data_t *)client_data; - RT_CK_FULL_PATH(path); - RT_CK_DBI(ecd->dbip); - - dp = DB_FULL_PATH_CUR_DIR(path); - if (!dp) - return; - if (dp->d_flags & RT_DIR_COMB) { - struct rt_db_internal in; - struct rt_comb_internal *comb; - - if (rt_db_get_internal(&in, dp, ecd->dbip, NULL, &rt_uniresource) < 0) - return; - - std::unordered_map c_inst_map; - comb = (struct rt_comb_internal *)in.idb_ptr; - // For these purposes, treat an empty comb as a leaf - if (!comb->tree) { - struct db_full_path *newpath; - BU_ALLOC(newpath, struct db_full_path); - db_full_path_init(newpath); - db_dup_full_path(newpath, path); - bu_ptbl_ins(ecd->full_paths, (long *)newpath); - return; - } - expand_subtree(path, OP_UNION, comb->tree, expand_list, &c_inst_map, client_data); - rt_db_free_internal(&in); - } else { - struct db_full_path *newpath; - BU_ALLOC(newpath, struct db_full_path); - db_full_path_init(newpath); - db_dup_full_path(newpath, path); - bu_ptbl_ins(ecd->full_paths, (long *)newpath); - } -} - - -int -ged_selection_set_expand(struct ged_selection_set *s_out, struct ged_selection_set *s) -{ - if (!s_out || !s) - return BRLCAD_ERROR; - - std::queue *>> initial; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - initial.push(s_it->second); - } - if (s_out != s) { - ged_selection_set_clear(s_out); - } - - while (!initial.empty()) { - struct ged_selection *ss = initial.front().first; - initial.pop(); - - struct db_full_path dfp; - db_full_path_init(&dfp); - if (db_string_to_path(&dfp, s->gedp->dbip, bu_vls_cstr(&ss->path))) { - // If we can't get a valid dbip, there's nothing from the database - // to expand this to - just keep it and move on - ged_selection_insert(s_out, bu_vls_cstr(&ss->path)); - db_free_full_path(&dfp); - continue; - } - - struct expand_client_data_t ecd; - struct bu_ptbl *solid_paths; - BU_ALLOC(solid_paths, struct bu_ptbl); - BU_PTBL_INIT(solid_paths); - ecd.dbip = s->gedp->dbip; - ecd.full_paths = solid_paths; - - // Get the full paths of all solid stances below dfp - expand_list(&dfp, (void *)&ecd); - - db_free_full_path(&dfp); - - if (BU_PTBL_LEN(solid_paths)) { - bool keep_orig = false; - for (size_t i = 0; i < BU_PTBL_LEN(solid_paths); i++) { - struct db_full_path *sfp = (struct db_full_path *)BU_PTBL_GET(solid_paths, i); - char *s_path = db_path_to_string(sfp); - std::vector *s_vpath = new std::vector; - fp_path_split(s_vpath, s_path); - _selection_get(s_out, s_path, s_vpath); - if (BU_STR_EQUAL(s_path, bu_vls_cstr(&ss->path))) - keep_orig = true; - } - // Expanded - remove original - if (!keep_orig && s_out == s) - _selection_put(s_out, bu_vls_cstr(&ss->path)); - } else { - // No expansion - keep initial - if (s_out != s) { - ged_selection_insert(s_out, bu_vls_cstr(&ss->path)); - } - } - bu_ptbl_free(solid_paths); - BU_FREE(solid_paths, struct bu_ptbl); - } - - return BRLCAD_OK; -} - -void -child_name_set_tree(union tree *tp, struct db_i *dbip, void *cmap, void *client_data) -{ - std::unordered_map *cinst_map = (std::unordered_map *)cmap; - std::set *g_c = (std::set *)client_data; - struct bu_vls iname = BU_VLS_INIT_ZERO; - - if (!tp) - return; - - RT_CK_TREE(tp); - - switch (tp->tr_op) { - case OP_NOT: - case OP_GUARD: - case OP_XNOP: - child_name_set_tree(tp->tr_b.tb_left, dbip, cmap, client_data); - break; - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - child_name_set_tree(tp->tr_b.tb_left, dbip, cmap, client_data); - child_name_set_tree(tp->tr_b.tb_right, dbip, cmap, client_data); - break; - case OP_DB_LEAF: - if (UNLIKELY(dbip->dbi_use_comb_instance_ids && cinst_map)) { - (*cinst_map)[std::string(tp->tr_l.tl_name)]++; - if ((*cinst_map)[std::string(tp->tr_l.tl_name)] > 1) { - bu_vls_printf(&iname, "%s@%d", tp->tr_l.tl_name, (*cinst_map)[std::string(tp->tr_l.tl_name)] - 1); - } else { - bu_vls_printf(&iname, "%s", tp->tr_l.tl_name); - } - } else { - bu_vls_printf(&iname, "%s", tp->tr_l.tl_name); - } - g_c->insert(std::string(bu_vls_cstr(&iname))); - bu_vls_free(&iname); - return; - default: - bu_log("child_name_set_tree: unrecognized operator %d\n", tp->tr_op); - bu_bomb("child_name_set_tree: unrecognized operator\n"); - } -} - -void -child_name_set(std::set *g_c, struct ged *gedp, const std::string &dp_name) -{ - if (!g_c || !gedp || !dp_name.size()) - return; - - struct directory *dp = db_lookup(gedp->dbip, dp_name.c_str(), LOOKUP_QUIET); - if (!dp) - return; - - struct rt_db_internal in; - if (rt_db_get_internal(&in, dp, gedp->dbip, NULL, &rt_uniresource) < 0) - return; - struct rt_comb_internal *comb = (struct rt_comb_internal *)in.idb_ptr; - if (UNLIKELY(gedp->dbip->dbi_use_comb_instance_ids)) { - std::unordered_map cinst_map; - child_name_set_tree(comb->tree, gedp->dbip, (void *)&cinst_map, (void *)g_c); - } else { - child_name_set_tree(comb->tree, gedp->dbip, NULL, (void *)g_c); - } -} - - -struct vstr_cmp { - bool operator() (std::vector fp, std::vector o) const { - // First, check length - if (fp.size() != o.size()) - return (fp.size() > o.size()); - - // If length is the same, check the dp contents - for (size_t i = 0; i < fp.size(); i++) { - if (fp[i] != o[i]) - return (bu_strcmp(fp[i].c_str(), o[i].c_str()) > 0); - } - return (bu_strcmp(fp[fp.size()-1].c_str(), o[fp.size()-1].c_str()) > 0); - } -}; - - -int -ged_selection_set_collapse(struct ged_selection_set *s_out, struct ged_selection_set *s) -{ - if (!s_out || !s) - return BRLCAD_ERROR; - - // Seed the set with the current paths - std::vector *> split_paths; - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - bu_log("path size: %zd\n", s_it->second.second->size()); - split_paths.push_back(s_it->second.second); - } - - std::map *>> grouped_paths; - for (size_t i = 0; i < split_paths.size(); i++) { - bu_log("path size: %zd\n", split_paths[i]->size()); - grouped_paths[split_paths[i]->size()].insert(split_paths[i]); - bu_log("gp: %zd\n", grouped_paths.size()); - } - - std::set *> final_paths; - - while (grouped_paths.size() > 0) { - size_t plen = grouped_paths.rbegin()->first; - std::set *> &lset = grouped_paths.rbegin()->second; - if (plen < 2) - break; - bu_log("%zd: %zd\n", plen, lset.size()); - - // Group paths of the same depth by common parents - std::map *>> c_ind; - std::set *>::iterator ss_it; - for (ss_it = lset.begin(); ss_it != lset.end(); ss_it++) { - std::vector *sp = *ss_it; - c_ind[(*sp)[plen - 2]].insert(sp); - } - bu_log("parent groups: %zd\n", c_ind.size()); - - std::map *>>::iterator c_it; - for (c_it = c_ind.begin(); c_it != c_ind.end(); c_it++) { - std::set g_c; - child_name_set(&g_c, s->gedp, c_it->first); - std::set *>::iterator cf_it; - for (cf_it = c_it->second.begin(); cf_it != c_it->second.end(); cf_it++) { - g_c.erase((*(*cf_it))[plen - 1]); - } - if (!g_c.size()) { - cf_it = c_it->second.begin(); - std::vector *ssp = *cf_it; - ssp->pop_back(); - grouped_paths[plen - 1].insert(ssp); - bu_log("%s: fully active\n", c_it->first.c_str()); - } else { - bu_log("%s: partially active\n", c_it->first.c_str()); - std::set::iterator a_it; - for (a_it = g_c.begin(); a_it != g_c.end(); a_it++) { - bu_log("\t%s\n", (*a_it).c_str()); - } - for (cf_it = c_it->second.begin(); cf_it != c_it->second.end(); cf_it++) { - final_paths.insert(*cf_it); - } - } - } - - bu_log("\n\n\n\n\n\n"); - - grouped_paths.erase(plen); - } - - if (grouped_paths.find(1) != grouped_paths.end()) { - std::set *> &lset = grouped_paths[1]; - std::set *>::iterator l_it; - for (l_it = lset.begin(); l_it != lset.end(); l_it++) { - final_paths.insert(*l_it); - } - } - - // Have final path set, add it to s_out - std::vector fpaths; - std::set *>::iterator fp_it; - for (fp_it = final_paths.begin(); fp_it != final_paths.end(); fp_it++) { - const std::vector *v = *fp_it; - std::string fpath; - for (size_t i = 0; i < v->size(); i++) { - fpath.append("/"); - fpath.append((*v)[i]); - } - fpaths.push_back(fpath); - } - - ged_selection_set_clear(s_out); - - for (size_t i = 0; i < fpaths.size(); i++) { - ged_selection_insert(s_out, fpaths[i].c_str()); - } - - return BRLCAD_OK; -} - - -void -ged_selection_assign_objs(struct ged_selection_set *s) -{ - if (!s || !s->i->m.size()) - return; - - // If we don't have view objects, there's nothing to associate - struct bu_ptbl *sg = bv_view_objs(s->gedp->ged_gvp, BV_DB_OBJS); - if (!sg) { - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - struct ged_selection *ss = s_it->second.first; - bu_ptbl_reset(&ss->sobjs); - } - return; - } - - // populate the paths map with scene objects - std::map> so_paths; - std::map path_to_obj; - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(sg, i); - struct db_full_path *dfp = (struct db_full_path *)so->s_path; - so_paths[DB_FULL_PATH_GET(dfp, 0)].insert(dfp); - path_to_obj[dfp] = so; - } - - // For the selections, add any scene objects with paths below the selection - // path to that selections sobjs ptbl - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - struct ged_selection *ss = s_it->second.first; - struct db_full_path *sel_fp; - BU_GET(sel_fp, struct db_full_path); - db_full_path_init(sel_fp); - // If the path isn't valid, there's nothing to add - if (db_string_to_path(sel_fp, s->gedp->dbip, bu_vls_cstr(&ss->path))) { - db_free_full_path(sel_fp); - BU_PUT(sel_fp, struct db_full_path); - continue; - } - // If no paths match the first pointer, there's no point checking further - if (so_paths.find(DB_FULL_PATH_GET(sel_fp, 0)) == so_paths.end()) { - db_free_full_path(sel_fp); - BU_PUT(sel_fp, struct db_full_path); - continue; - } - // Pull the set of paths that are a first pointer match, and check them - // to see which ones are top matches for this selection path. If they - // are a match, add to sobjs. This can probably be made more efficient - // - we filter on first pointer matching to try and help cut down the - // unnecessary checks, but there are probably better ways. - std::set &dpaths = so_paths[DB_FULL_PATH_GET(sel_fp, 0)]; - std::set::iterator d_it; - for (d_it = dpaths.begin(); d_it != dpaths.end(); d_it++) { - struct db_full_path *so_fp = *d_it; - if (db_full_path_match_top(sel_fp, so_fp)) { - struct bv_scene_obj *sso = path_to_obj[sel_fp]; - if (!sso) - continue; - bu_ptbl_ins(&ss->sobjs, (long *)sso); - } - } - db_free_full_path(sel_fp); - BU_PUT(sel_fp, struct db_full_path); - } -} - -static void -_ill_toggle(struct bv_scene_obj *s, char ill_state) -{ - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - _ill_toggle(s_c, ill_state); - } - s->s_iflag = ill_state; -} - - -void -ged_selection_toggle_illum(struct ged_selection_set *s, char ill_state) -{ - - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - struct ged_selection *ss = s_it->second.first; - for (size_t i = 0; i < BU_PTBL_LEN(&ss->sobjs); i++) { - struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(&ss->sobjs, i); - _ill_toggle(so, ill_state); - } - } -} - -unsigned long long -ged_selection_hash_set(struct ged_selection_set *s) -{ - if (!s) - return 0; - - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - std::map *>>::iterator s_it; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - XXH64_update(&h_state, bu_vls_cstr(&s_it->second.first->path), bu_vls_strlen(&s_it->second.first->path)*sizeof(char)); - } - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - return hash; -} - -unsigned long long -ged_selection_hash_sets(struct ged_selection_sets *ss) -{ - if (!ss) - return 0; - - - XXH64_state_t h_state; - XXH64_reset(&h_state, 0); - struct bu_vls sname = BU_VLS_INIT_ZERO; - - std::map::iterator ss_it; - std::map *>>::iterator s_it; - for (ss_it = ss->i->s->begin(); ss_it != ss->i->s->end(); ss_it++) { - bu_vls_sprintf(&sname, "%s", ss_it->first.c_str()); - XXH64_update(&h_state, bu_vls_cstr(&sname), bu_vls_strlen(&sname)*sizeof(char)); - struct ged_selection_set *s = ss_it->second; - for (s_it = s->i->m.begin(); s_it != s->i->m.end(); s_it++) { - XXH64_update(&h_state, bu_vls_cstr(&s_it->second.first->path), bu_vls_strlen(&s_it->second.first->path)*sizeof(char)); - } - } - bu_vls_free(&sname); - - XXH64_hash_t hash_val; - hash_val = XXH64_digest(&h_state); - unsigned long long hash = (unsigned long long)hash_val; - return hash; -} - - -struct rt_object_selections * -ged_get_object_selections(struct ged *gedp, const char *object_name) -{ - struct ged_selection_set *ss = (*gedp->ged_selection_sets->i->s)[std::string("default")]; - struct ged_selection *s = _selection_get(ss, object_name, NULL); - if (!s->r_os) { - struct rt_object_selections *ro_s; - BU_GET(ro_s, struct rt_object_selections); - s->r_os = ro_s; - } - return s->r_os; -} - - -struct rt_selection_set * -ged_get_selection_set(struct ged *gedp, const char *object_name, const char *selection_name) -{ - struct rt_object_selections *o_s = ged_get_object_selections(gedp, object_name); - struct rt_selection_set *set = (struct rt_selection_set *)bu_hash_get(o_s->sets, (uint8_t *)selection_name, strlen(selection_name)); - if (!set) { - BU_ALLOC(set, struct rt_selection_set); - BU_PTBL_INIT(&set->selections); - bu_hash_set(o_s->sets, (uint8_t *)selection_name, strlen(selection_name), (void *)set); - } - - return set; -} - - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/src/libged/select/select2.cpp b/src/libged/select/select2.cpp index cd75736128b..29c0fd4624a 100644 --- a/src/libged/select/select2.cpp +++ b/src/libged/select/select2.cpp @@ -21,6 +21,86 @@ * * The select command. * + * "Sets" in BRL-CAD have some interesting complications, particularly when it + * comes to geometric scenes. Graphically visible scene objects representing + * .g geometry always correspond to one instance of one solid, or a set of data + * representing an evaluation of a composite object. + * + * Because there may be thousands of such objects in a scene, commands such as + * "who" report "collapsed" top level groups that represent the highest level + * paths that contain beneath them all the drawn solids. Generally this + * report will be more compact and informative to users than a detailed + * itemization of individual instance shape objects. + * + * However, when defining selection sets, it gets more complex. Building selection + * sets graphically by interrogating the scene will build up sets of individual + * shape objects. If the correct sub-sets of those objects are selected, we can + * conceptually regard a parent comb as being fully selected, if we so choose. + * However, we do not always want the "fully selected" parent comb to replace + * all of its children in the set, since different types of actions may + * want/need to operate on the individual comb instances rather than the parent + * comb as an aggregate whole. + * + * We thus need "expand" and "collapse" operations for sets, the former of + * which will take each entry in the set and replace it with all of its child + * leaf instances. + * + * Likewise, the "collapse" operation will look at the children contained in the set, + * and for cases where all children are present, those children will be replaced + * with one reference to the parent. This will be done working "up" the various + * trees until either all potential collapses are missing one or more children, or + * all entries collapse to top level objects. + * + * Nor do we want to always either expand OR collapse - in some cases we want + * exactly what was selected. For example, if we have the tree + * + * a + * b + * c + * d + * e + * + * and we want to select and operate on /a/b/c, we can't simply collapse (which + * will result in /a) or expand (which will result in /a/b/c/d/e). If /a/b/c/d/e + * is part of a larger selection set and we want to replace it with /a/b/c, to + * avoid a confusing multiple-path-instance state the selection command will need + * to ensure all selections below /a/b/c are removed in favor of /a/b/c. + * + * As an exercise, we consider a potential use of sets - selecting an instance of + * an object in a scene for editing operations. There are a number of things we + * will need to know: + * + * The solids associated with the selected instance itself. If a solid was + * selected we already know where to get the editing wireframe, but if comb was + * selected from the tree, there's more work to do. We have the advantage of + * explicitly knowing the level at which the editing operations will take place + * (a tree selection would correspond to the previously discussed "insert" + * operation to the set), but we will need a list of that comb's child solids + * so we can create appropriate editing wireframe visual objects to represent + * the comb in the scene. In the event of multiple selections we would need to + * construct the instance set from multiple sources. + * + * If we are performing graphical selection operations, we may be either + * refining a set by selecting objects to be removed from it, or selecting + * objects not already part of the set to add to it. In either case we will be + * operating at the individual instance level, and must provide ways to allow + * the user to refine their selection intent for editing purposes. + * + * If we want to (say) set all non-active objects to be highly transparent when + * an editing operation commences, we will also need to be able to construct the + * set of all scene objects which are NOT active in the currently processed set. + * + * If we want to edit primitive parameters, rather than comb instances, we will + * need to boil down a set of selected comb instances to one or a set of solid + * names. (Usually a set count > 1 won't work for primitive editing if we have + * multiple different independent solid leaf objects... in that case we may + * want to just reject an attempt to solid edit...) Given the solid, we will + * then need to extract the set of all drawn instances of that solid from the + * scene, so we can generate and update per-instance wireframes for all of them + * to visually reflect the impact of the edit (MGED's inability to do this is + * why solid editing is rejected if more than one instance of the object is + * drawn in the scene - we don't want that limitation.) + */ #include "common.h" @@ -33,7 +113,6 @@ struct _ged_select_info { struct ged *gedp; struct bu_vls curr_set; - const char *key; }; int @@ -64,67 +143,31 @@ _select_cmd_list(void *bs, int argc, const char **argv) argc--; argv++; struct ged *gedp = gd->gedp; - if (!gedp->ged_selection_sets) + if (!gedp->dbi_state || argc > 1) return BRLCAD_ERROR; - if (!argc && !bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, "*"); - if (scnt) { - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *s = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - bu_vls_printf(gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->name)); - } + if (!argc) { + std::vector ssets = gedp->dbi_state->list_selection_sets(); + for (size_t i = 0; i < ssets.size(); i++) { + bu_vls_printf(gedp->ged_result_str, "%s\n", ssets[i].c_str()); } - bu_ptbl_free(&ssets); return BRLCAD_OK; } - if (bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", bu_vls_cstr(&gd->curr_set)); - return BRLCAD_ERROR; - } - - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - char **selection_names = NULL; - int ac = ged_selection_set_list(&selection_names, gs); - if (ac) { - for (int j = 0; j < ac; j++) { - bu_vls_printf(gedp->ged_result_str, "%s\n", selection_names[j]); - } - bu_argv_free(ac, selection_names); - } - } - bu_ptbl_free(&ssets); - - if (!argc || BU_STR_EQUAL(bu_vls_cstr(&gd->curr_set), argv[0])) - return BRLCAD_OK; - } - - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, argv[0]); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", argv[0]); + const char *sname = argv[0]; + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (!ss.size()) { + bu_vls_printf(gedp->ged_result_str, ": %s does not match any selection sets\n", sname); return BRLCAD_ERROR; } - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - char **selection_names = NULL; - int ac = ged_selection_set_list(&selection_names, gs); - if (ac) { - for (int j = 0; j < ac; j++) { - bu_vls_printf(gedp->ged_result_str, "%s\n", selection_names[j]); - } - bu_argv_free(ac, selection_names); + for (size_t i = 0; i < ss.size(); i++) { + std::vector paths = ss[i]->list_selected_paths(); + + for (size_t j = 0; j < paths.size(); j++) { + bu_vls_printf(gedp->ged_result_str, "%s\n", paths[j].c_str()); } } - bu_ptbl_free(&ssets); - return BRLCAD_OK; } @@ -141,52 +184,27 @@ _select_cmd_clear(void *bs, int argc, const char **argv) argc--; argv++; struct ged *gedp = gd->gedp; - if (!gedp->ged_selection_sets) - return BRLCAD_ERROR; - - if (!argc && !bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, "default"); - if (scnt) { - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *s = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_clear(s); - } - } - bu_ptbl_free(&ssets); - return BRLCAD_OK; - } - if (bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", bu_vls_cstr(&gd->curr_set)); - return BRLCAD_ERROR; - } - - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_clear(gs); - } - bu_ptbl_free(&ssets); + if (!gedp->dbi_state) + return BRLCAD_ERROR; - if (!argc || BU_STR_EQUAL(bu_vls_cstr(&gd->curr_set), argv[0])) - return BRLCAD_OK; + const char *sname = NULL; + if (argc) { + sname = argv[0]; + } else if (bu_vls_strlen(&gd->curr_set)) { + sname = bu_vls_cstr(&gd->curr_set); } - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, argv[0]); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", argv[0]); + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (!ss.size()) { + if (sname) + bu_vls_printf(gedp->ged_result_str, ": %s does not match any selection sets\n", sname); return BRLCAD_ERROR; } - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_clear(gs); + for (size_t i = 0; i < ss.size(); i++) { + ss[i]->clear(); } - bu_ptbl_free(&ssets); return BRLCAD_OK; } @@ -211,36 +229,36 @@ _select_cmd_add(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - if (!gedp->ged_selection_sets) + if (!gedp->dbi_state) return BRLCAD_ERROR; - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = 0; - if (bu_vls_strlen(&gd->curr_set)) { - scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - } else { - scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, "default"); - } - if (scnt != 1) { - bu_vls_printf(gedp->ged_result_str, "invalid name for current set: %s", (bu_vls_strlen(&gd->curr_set)) ? bu_vls_cstr(&gd->curr_set): "default"); + const char *sname = NULL; + if (bu_vls_strlen(&gd->curr_set)) + sname = bu_vls_cstr(&gd->curr_set); + + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (ss.size() != 1) { + if (sname) + bu_vls_printf(gedp->ged_result_str, ": %s does not match one selection set\n", sname); return BRLCAD_ERROR; } - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, 0); - bu_ptbl_free(&ssets); - struct bu_vls dpath = BU_VLS_INIT_ZERO; for (int i = 0; i < argc; i++) { bu_vls_sprintf(&dpath, "%s", argv[i]); if (bu_vls_cstr(&dpath)[0] != '/') bu_vls_prepend(&dpath, "/"); - if (!ged_selection_insert(gs, bu_vls_cstr(&dpath))) { - bu_vls_printf(gedp->ged_result_str, "unable to add path to selection: %s", argv[i]); + if (!ss[0]->select_path(bu_vls_cstr(&dpath), false)) { + bu_vls_printf(gedp->ged_result_str, "Selection set %s: unable to add path: %s", (sname) ? sname : "default", argv[i]); bu_vls_free(&dpath); return BRLCAD_ERROR; } } + + ss[0]->characterize(); + bu_vls_free(&dpath); + return BRLCAD_OK; } @@ -263,27 +281,34 @@ _select_cmd_rm(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - if (!gedp->ged_selection_sets) + if (!gedp->dbi_state) return BRLCAD_ERROR; - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = 0; - if (bu_vls_strlen(&gd->curr_set)) { - scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - } else { - scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, "default"); - } - if (scnt != 1) { - bu_vls_printf(gedp->ged_result_str, "invalid name for current set: %s", (bu_vls_strlen(&gd->curr_set)) ? bu_vls_cstr(&gd->curr_set): "default"); + const char *sname = NULL; + if (bu_vls_strlen(&gd->curr_set)) + sname = bu_vls_cstr(&gd->curr_set); + + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (ss.size() != 1) { + if (sname) + bu_vls_printf(gedp->ged_result_str, ": %s does not match one selection set\n", sname); return BRLCAD_ERROR; } - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, 0); - bu_ptbl_free(&ssets); - + struct bu_vls dpath = BU_VLS_INIT_ZERO; for (int i = 0; i < argc; i++) { - ged_selection_remove(gs, argv[i]); + bu_vls_sprintf(&dpath, "%s", argv[i]); + if (bu_vls_cstr(&dpath)[0] != '/') + bu_vls_prepend(&dpath, "/"); + if (!ss[0]->deselect_path(bu_vls_cstr(&dpath), false)) { + bu_vls_printf(gedp->ged_result_str, "Selection set %s: unable to remove path: %s", (sname) ? sname : "default", argv[i]); + bu_vls_free(&dpath); + return BRLCAD_ERROR; + } } + bu_vls_free(&dpath); + + ss[0]->characterize(); return BRLCAD_OK; } @@ -301,44 +326,35 @@ _select_cmd_collapse(void *bs, int argc, const char **argv) argc--; argv++; struct ged *gedp = gd->gedp; - if (!gedp->ged_selection_sets) + if (!gedp->dbi_state) return BRLCAD_ERROR; - if (!argc && !bu_vls_strlen(&gd->curr_set)) { - bu_vls_printf(gedp->ged_result_str, ": no set specified\n"); - return BRLCAD_OK; + const char *sname = NULL; + if (argc) { + sname = argv[0]; + } else if (bu_vls_strlen(&gd->curr_set)) { + sname = bu_vls_cstr(&gd->curr_set); } - if (bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", bu_vls_cstr(&gd->curr_set)); - return BRLCAD_ERROR; - } - - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_collapse(gs, gs); - } - bu_ptbl_free(&ssets); - - if (!argc || BU_STR_EQUAL(bu_vls_cstr(&gd->curr_set), argv[0])) - return BRLCAD_OK; + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (!ss.size()) { + if (sname) + bu_vls_printf(gedp->ged_result_str, ": %s does not match any selection sets\n", sname); + return BRLCAD_ERROR; } - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, argv[0]); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", argv[0]); - return BRLCAD_ERROR; + for (size_t i = 0; i < ss.size(); i++) { + ss[i]->collapse(); } - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_collapse(gs, gs); + // TODO - for now, printing results - maybe tie this to a verbose option at some point... + for (size_t i = 0; i < ss.size(); i++) { + std::vector paths = ss[i]->list_selected_paths(); + + for (size_t j = 0; j < paths.size(); j++) { + bu_vls_printf(gedp->ged_result_str, "%s\n", paths[j].c_str()); + } } - bu_ptbl_free(&ssets); return BRLCAD_OK; } @@ -356,44 +372,36 @@ _select_cmd_expand(void *bs, int argc, const char **argv) argc--; argv++; struct ged *gedp = gd->gedp; - if (!gedp->ged_selection_sets) + + if (!gedp->dbi_state) return BRLCAD_ERROR; - if (!argc && !bu_vls_strlen(&gd->curr_set)) { - bu_vls_printf(gedp->ged_result_str, ": no set specified\n"); - return BRLCAD_OK; + const char *sname = NULL; + if (argc) { + sname = argv[0]; + } else if (bu_vls_strlen(&gd->curr_set)) { + sname = bu_vls_cstr(&gd->curr_set); } - if (bu_vls_strlen(&gd->curr_set)) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, bu_vls_cstr(&gd->curr_set)); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", bu_vls_cstr(&gd->curr_set)); - return BRLCAD_ERROR; - } - - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_expand(gs, gs); - } - bu_ptbl_free(&ssets); - - if (!argc || BU_STR_EQUAL(bu_vls_cstr(&gd->curr_set), argv[0])) - return BRLCAD_OK; + std::vector ss = gedp->dbi_state->get_selected_states(sname); + if (!ss.size()) { + if (sname) + bu_vls_printf(gedp->ged_result_str, ": %s does not match any selection sets\n", sname); + return BRLCAD_ERROR; } - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, argv[0]); - if (!scnt) { - bu_vls_printf(gedp->ged_result_str, ": %s does not match any sets\n", argv[0]); - return BRLCAD_ERROR; + for (size_t i = 0; i < ss.size(); i++) { + ss[i]->expand(); } - for (size_t i = 0; i < scnt; i++) { - struct ged_selection_set *gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, i); - ged_selection_set_expand(gs, gs); + // TODO - for now, printing results - maybe tie this to a verbose option at some point... + for (size_t i = 0; i < ss.size(); i++) { + std::vector paths = ss[i]->list_selected_paths(); + + for (size_t j = 0; j < paths.size(); j++) { + bu_vls_printf(gedp->ged_result_str, "%s\n", paths[j].c_str()); + } } - bu_ptbl_free(&ssets); return BRLCAD_OK; } @@ -423,7 +431,6 @@ ged_select2_core(struct ged *gedp, int argc, const char *argv[]) // Initialize select info gd.gedp = gedp; bu_vls_init(&gd.curr_set); - gd.key = NULL; /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); diff --git a/src/libged/set_transparency/set_transparency.c b/src/libged/set_transparency/set_transparency.c index ef9e9567169..434a2947e30 100644 --- a/src/libged/set_transparency/set_transparency.c +++ b/src/libged/set_transparency/set_transparency.c @@ -46,7 +46,6 @@ ged_set_transparency_core(struct ged *gedp, int argc, const char *argv[]) static const char *usage = "node tval"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/set_uplotOutputMode/set_uplotOutputMode.c b/src/libged/set_uplotOutputMode/set_uplotOutputMode.c index 7b388152176..e43f7b7f681 100644 --- a/src/libged/set_uplotOutputMode/set_uplotOutputMode.c +++ b/src/libged/set_uplotOutputMode/set_uplotOutputMode.c @@ -40,7 +40,6 @@ ged_set_uplotOutputMode_core(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[binary|text]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/shaded_mode/shaded_mode.c b/src/libged/shaded_mode/shaded_mode.c index e2ff89c6fff..a47824cd68b 100644 --- a/src/libged/shaded_mode/shaded_mode.c +++ b/src/libged/shaded_mode/shaded_mode.c @@ -43,7 +43,6 @@ ged_shaded_mode_core(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[0|1|2]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/showmats/showmats.c b/src/libged/showmats/showmats.c index 0c3e43eb409..383c45b99e3 100644 --- a/src/libged/showmats/showmats.c +++ b/src/libged/showmats/showmats.c @@ -154,7 +154,7 @@ int ged_showmats_core(struct ged *gedp, int argc, const char *argv[]) { int aflag = 0; - static const char *usage = "path"; + static const char *usage = "[-a] path"; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -163,7 +163,7 @@ ged_showmats_core(struct ged *gedp, int argc, const char *argv[]) bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ - if (argc == 1) { + if (argc == 1 || (argc == 2 && argv[1][0] == '-')) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } diff --git a/src/libged/solid_report/solid_report.c b/src/libged/solid_report/solid_report.c index a4987d8d9fd..9bc0cbef39d 100644 --- a/src/libged/solid_report/solid_report.c +++ b/src/libged/solid_report/solid_report.c @@ -49,18 +49,14 @@ ged_solid_report_core(struct ged *gedp, int argc, const char *argv[]) /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); - /* must be wanting help */ - if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - return GED_HELP; - } - - if (argc != 2) { + if (argc > 2 || (argc == 2 && argv[1][0] == '-')) { + /* assume user needs help */ bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return BRLCAD_ERROR; } - lvl = atoi(argv[1]); + if (argc > 1) /* don't use default level */ + lvl = atoi(argv[1]); if (lvl <= 3) dl_print_schain(gedp->ged_gdp->gd_headDisplay, gedp->dbip, lvl, 0, gedp->ged_result_str); diff --git a/src/libged/tests/CMakeLists.txt b/src/libged/tests/CMakeLists.txt index 6db015741f1..05dfe09a00a 100644 --- a/src/libged/tests/CMakeLists.txt +++ b/src/libged/tests/CMakeLists.txt @@ -21,6 +21,8 @@ DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/ged_test_material.g) BRLCAD_ADDEXEC(ged_test_select test_select.c libged TEST) add_dependencies(ged_test_select ged_plugins) +add_subdirectory(draw) + # Note: it is particularly important that the lint tests in particular are kept # in a separate file, since its bad input examples stand an excellent chance of # breaking commands. diff --git a/src/libged/tests/draw/CMakeLists.txt b/src/libged/tests/draw/CMakeLists.txt new file mode 100644 index 00000000000..0fa008d402d --- /dev/null +++ b/src/libged/tests/draw/CMakeLists.txt @@ -0,0 +1,205 @@ +set(test_deps + dm-swrast + ged-autoview + ged-close + ged-draw + ged-dm + ged-facetize + ged-open + ged-png2fb + ged-select + ged-tol + ged-view + ged-zap + ) + + +set(basic_view_test_ctrls + v001_ctrl.png + v002_ctrl.png + v003_ctrl.png + v004_ctrl.png + v005_ctrl.png + v006_ctrl.png + v007_ctrl.png + v008_ctrl.png + v009_ctrl.png + v010_ctrl.png + v011_ctrl.png + v012_ctrl.png + v013_ctrl.png + v014_ctrl.png + v015_ctrl.png + v016_ctrl.png + v017_ctrl.png + v018_ctrl.png + v019_ctrl.png + v020_ctrl.png + v021_ctrl.png + v022_ctrl.png + v023_ctrl.png + v024_ctrl.png + v025_ctrl.png + v026_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_draw "draw.cpp;util.cpp" "libged;libdm" TEST) +add_dependencies(ged_test_draw ${test_deps}) +BRLCAD_ADD_TEST(NAME ged_test_drawing_basic COMMAND ged_test_draw "${CMAKE_CURRENT_SOURCE_DIR}") + + +set(faceplate_test_ctrls + fp001_ctrl.png + fp002_ctrl.png + fp003_ctrl.png + fp004_ctrl.png + fp005_ctrl.png + fp006_ctrl.png + fp007_ctrl.png + fp008_ctrl.png + fp009_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_faceplate "faceplate.cpp;util.cpp" "libged;libdm" TEST) +add_dependencies(ged_test_faceplate ${test_deps}) +BRLCAD_ADD_TEST(NAME ged_test_drawing_faceplate COMMAND ged_test_faceplate "${CMAKE_CURRENT_SOURCE_DIR}") + + +set(lod_test_ctrls + lod001_ctrl.png + lod002_ctrl.png + lod003_ctrl.png + lod004_ctrl.png + lod005_ctrl.png + lod006_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_lod "lod.cpp;util.cpp" "libged;libdm" TEST) +add_dependencies(ged_test_lod ${test_deps}) +BRLCAD_ADD_TEST(NAME ged_test_drawing_lod COMMAND ged_test_lod "${CMAKE_CURRENT_SOURCE_DIR}") +DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/moss_lod_tmp.g) + +set(select_test_ctrls + select001_ctrl.png + select002_ctrl.png + select003_ctrl.png + select004_ctrl.png + select005_ctrl.png + select006_ctrl.png + select007_ctrl.png + select008_ctrl.png + select009_ctrl.png + select010_ctrl.png + select011_ctrl.png + select012_ctrl.png + select013_ctrl.png + select014_ctrl.png + select015_ctrl.png + select016_ctrl.png + select017_ctrl.png + select018_ctrl.png + select019_ctrl.png + select020_ctrl.png + select021_ctrl.png + select022_ctrl.png + select023_ctrl.png + select024_ctrl.png + select001_ctrl.png + select002_ctrl.png + select003_ctrl.png + select004_ctrl.png + select005_ctrl.png + select006_ctrl.png + select007_ctrl.png + select008_ctrl.png + select009_ctrl.png + select010_ctrl.png + select011_ctrl.png + select012_ctrl.png + select013_ctrl.png + select019_ctrl.png + select020_ctrl.png + select021_ctrl.png + select022_ctrl.png + select023_ctrl.png + select024_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_select_draw "select.cpp;util.cpp" "libged;libdm" TEST) +add_dependencies(ged_test_select_draw ${test_deps}) +BRLCAD_ADD_TEST(NAME ged_test_drawing_select COMMAND ged_test_select_draw "${CMAKE_CURRENT_SOURCE_DIR}") +DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/moss_select_tmp.g) + +set(quad_test_ctrls + quad_00_001_ctrl.png + quad_00_002_ctrl.png + quad_00_003_ctrl.png + quad_00_004_ctrl.png + quad_00_005_ctrl.png + quad_00_006_ctrl.png + quad_00_007_ctrl.png + quad_00_008_ctrl.png + quad_01_001_ctrl.png + quad_01_002_ctrl.png + quad_01_003_ctrl.png + quad_01_004_ctrl.png + quad_01_005_ctrl.png + quad_01_006_ctrl.png + quad_01_007_ctrl.png + quad_01_008_ctrl.png + quad_02_001_ctrl.png + quad_02_002_ctrl.png + quad_02_003_ctrl.png + quad_02_004_ctrl.png + quad_02_005_ctrl.png + quad_02_006_ctrl.png + quad_02_007_ctrl.png + quad_02_008_ctrl.png + quad_03_001_ctrl.png + quad_03_002_ctrl.png + quad_03_003_ctrl.png + quad_03_004_ctrl.png + quad_03_005_ctrl.png + quad_03_006_ctrl.png + quad_03_007_ctrl.png + quad_03_008_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_quad quad.cpp "libged;libdm" TEST) +add_dependencies(ged_test_quad ${test_deps}) +BRLCAD_ADD_TEST(NAME ged_test_drawing_quad COMMAND ged_test_quad "${CMAKE_CURRENT_SOURCE_DIR}") +DISTCLEAN(${CMAKE_CURRENT_BINARY_DIR}/moss_quad_tmp.g) + +# The idea here is to test view stability across resize events +set(aet_test_ctrls + aet_00_001_ctrl.png + aet_00_002_ctrl.png + aet_01_001_ctrl.png + aet_01_002_ctrl.png + aet_02_001_ctrl.png + aet_02_002_ctrl.png + aet_03_001_ctrl.png + aet_03_002_ctrl.png + ) +BRLCAD_ADDEXEC(ged_test_aet "aet.cpp;util.cpp" "libged;libdm" TEST) +add_dependencies(ged_test_aet ${test_deps}) + +CMAKEFILES( + README + empty.png + moss.g + moss.png + rook.g + util.cpp + ${basic_view_test_ctrls} + ${faceplate_test_ctrls} + ${lod_test_ctrls} + ${select_test_ctrls} + ${quad_test_ctrls} + ${aet_test_ctrls} + ) + +CMAKEFILES(CMakeLists.txt) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/libged/tests/draw/README b/src/libged/tests/draw/README new file mode 100644 index 00000000000..d41295fce22 --- /dev/null +++ b/src/libged/tests/draw/README @@ -0,0 +1,25 @@ +The tests in this directory are intended to detect breakage in the libdm +drawing system and its integration into libged's drawing routines. The images +here are not "finalized" in the sense of the images used for raytracing +regression testing - rather, they should reflect the current expected drawing +output for the BRL-CAD scene drawing system. If (for example) the faceplate +axes or the grid drawing routines are updated, the control images related to +those features should be updated to reflect the new expected answers, rather +than trying to match the scene visuals to what is in these images. + +Historically, the primary OpenGL drawing logic of BRL-CAD's scene rendering +could only be checked by manual, visual inspection of the drawing results in a +graphical context. Such an approach doesn't scale to a Continuous Integration +context and makes comprehensive coverage impractical. With the addition of the +swrast libdm rendering backend, we can now test the actual results of the +OpenGL drawing calls themselves in an automated fashion, even on CI runners +without any graphics system. Initially the focus is to get basic checks in +place to spot when refactoring has completely broken a feature - in time, we +may be able to work towards more "full coverage" CI testing of the drawing +system's code paths. + + +Tests to set up: + +multiple shared and independent attached dms, with view independent drawing +(eventually) embedded framebuffer raytracing diff --git a/src/libged/tests/draw/aet.cpp b/src/libged/tests/draw/aet.cpp new file mode 100644 index 00000000000..8e6d8f7cd54 --- /dev/null +++ b/src/libged/tests/draw/aet.cpp @@ -0,0 +1,359 @@ +/* A E T . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file aet.cpp + * + * Attempts to test the stability of views across various operations + * such as resizing. + * + */ + +#include "common.h" + +#include +#include +#include +#include +#define DM_WITH_RT +#include +#include + +void +dm_refresh(struct ged *gedp, int vnum) +{ + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + struct bview *v = (struct bview *)BU_PTBL_GET(views, vnum); + if (!v) + return; + BViewState *bvs = gedp->dbi_state->get_view_state(v); + gedp->dbi_state->update(); + std::unordered_set uset; + uset.insert(v); + bvs->redraw(NULL, uset, 1); + + struct dm *dmp = (struct dm *)v->dmp; + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + dm_set_dirty(dmp, 0); + dm_draw_objs(v, NULL, NULL); + dm_draw_end(dmp); +} + +void +img_cmp(int vnum, int id, struct ged *gedp, const char *cdir, int soft_fail) +{ + icv_image_t *ctrl, *timg; + struct bu_vls tname = BU_VLS_INIT_ZERO; + struct bu_vls cname = BU_VLS_INIT_ZERO; + if (id <= 0) { + bu_vls_sprintf(&tname, "aet_clear.png"); + bu_vls_sprintf(&cname, "%s/empty.png", cdir); + } else { + bu_vls_sprintf(&tname, "aet_%02d_%03d.png", vnum, id); + bu_vls_sprintf(&cname, "%s/aet_%02d_%03d_ctrl.png", cdir, vnum, id); + } + + dm_refresh(gedp, vnum); + + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + struct bview *v = (struct bview *)BU_PTBL_GET(views, vnum); + if (!v) + bu_exit(EXIT_FAILURE, "Invalid view specifier: %d\n", vnum); + struct dm *dmp = (struct dm *)v->dmp; + + const char *s_av[4] = {NULL}; + s_av[0] = "screengrab"; + s_av[1] = "-D"; + s_av[2] = bu_vls_cstr(dm_get_pathname(dmp)); + s_av[3] = bu_vls_cstr(&tname); + if (ged_exec(gedp, 4, s_av) & BRLCAD_ERROR) { + bu_log("Failed to grab screen for DM %s\n", bu_vls_cstr(dm_get_pathname(dmp))); + bu_vls_free(&tname); + return; + } + + timg = icv_read(bu_vls_cstr(&tname), BU_MIME_IMAGE_PNG, 0, 0); + if (!timg) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&tname)); + bu_vls_free(&tname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&tname)); + } + ctrl = icv_read(bu_vls_cstr(&cname), BU_MIME_IMAGE_PNG, 0, 0); + if (!ctrl) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&cname)); + bu_vls_free(&tname); + bu_vls_free(&cname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&cname)); + } + bu_vls_free(&cname); + int matching_cnt = 0; + int off_by_1_cnt = 0; + int off_by_many_cnt = 0; + int iret = icv_diff(&matching_cnt, &off_by_1_cnt, &off_by_many_cnt, ctrl,timg); + if (iret) { + if (soft_fail) { + bu_log("%d wireframe diff failed. %d matching, %d off by 1, %d off by many\n", id, matching_cnt, off_by_1_cnt, off_by_many_cnt); + icv_destroy(ctrl); + icv_destroy(timg); + return; + } + bu_exit(EXIT_FAILURE, "%d wireframe diff failed. %d matching, %d off by 1, %d off by many\n", id, matching_cnt, off_by_1_cnt, off_by_many_cnt); + } + + icv_destroy(ctrl); + icv_destroy(timg); + + // Image comparison done and successful + bu_file_delete(bu_vls_cstr(&tname)); + bu_vls_free(&tname); +} + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int run_unstable_tests = 0; + int soft_fail = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[4]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "U", "enable-unstable", "", NULL, &run_unstable_tests, "Test drawing routines known to differ between build configs/platforms."); + BU_OPT(d[2], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT_NULL(d[3]); + + /* Done with program name */ + (void)bu_opt_parse(NULL, ac, (const char **)av, d); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* make a temporary copy of moss */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + std::ifstream orig(bu_vls_cstr(&fname), std::ios::binary); + std::ofstream tmpg("moss_aet_tmp.g", std::ios::binary); + tmpg << orig.rdbuf(); + orig.close(); + tmpg.close(); + + /* Open the temp file */ + const char *s_av[15] = {NULL}; + dbp = ged_open("db", "moss_aet_tmp.g", 1); + // We don't want the default GED views for this test + bv_set_rm_view(&dbp->ged_views, NULL); + + // Set up the views. Unlike the other drawing tests, we are explicitly + // out to test the behavior of multiple views and dms, so we need to + // set up multiples. We'll start out with four non-independent views, + // to mimic the most common multi-dm/view display - a Quad view widget. + // Each view will get its own attached swrast DM. + struct bview *views[4]; + for (size_t i = 0; i < 4; i++) { + BU_GET(views[i], struct bview); + if (!i) + dbp->ged_gvp = views[i]; + struct bview *v = views[i]; + bv_init(v, &dbp->ged_views); + bu_vls_sprintf(&v->gv_name, "V%zd", i); + bv_set_add_view(&dbp->ged_views, v); + bu_ptbl_ins(&dbp->ged_free_views, (long *)v); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + struct bu_vls dm_name = BU_VLS_INIT_ZERO; + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "-V"; + s_av[3] = bu_vls_cstr(&v->gv_name); + s_av[4] = "swrast"; + bu_vls_sprintf(&dm_name, "SW%zd", i); + s_av[5] = bu_vls_cstr(&dm_name); + s_av[6] = NULL; + ged_exec(dbp, 6, s_av); + bu_vls_free(&dm_name); + + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + dm_set_vp(dmp, &v->gv_scale); + v->dmp = dmp; + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + } + + /* Set distinct view az/el for each of the four quad views. For + * this test we are deliberately testing view settings that have + * the potential to be challenging in "gimbal lock" positions in + * multiples of 90 degrees and using non-zero twist components. */ + VSET(views[0]->gv_aet, 0, 0, 90); + bv_mat_aet(views[0]); + bv_update(views[0]); + + VSET(views[1]->gv_aet, 90, 90, 180); + bv_mat_aet(views[1]); + bv_update(views[1]); + + VSET(views[2]->gv_aet, -90, 270, -90); + bv_mat_aet(views[2]); + bv_update(views[2]); + + VSET(views[3]->gv_aet, 270, -180, 90); + bv_mat_aet(views[3]); + bv_update(views[3]); + + + /************************************************************************/ + /* Draw a wireframe. Because we're doing tests of view and dm + * manipulation, this is the only draw command needed for this particular + * setup - we just need some non-empty geometry displayed. */ + bu_log("Basic drawing test...\n"); + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + + // Sanity + img_cmp(0, 1, dbp, av[1], soft_fail); + img_cmp(1, 1, dbp, av[1], soft_fail); + img_cmp(2, 1, dbp, av[1], soft_fail); + img_cmp(3, 1, dbp, av[1], soft_fail); + + // Resize dm to larger dimensions + bu_log("Resize to 600x600...\n"); + int len = 600; + for (size_t i = 0; i < 4; i++) { + struct dm *dmp = (struct dm *)views[i]->dmp; + dm_set_width(dmp, len); + dm_set_height(dmp, len); + views[i]->gv_width = len; + views[i]->gv_height = len; + dm_configure_win(dmp, 0); + // NOTE: deliberately not resetting aet here - we want to see if it is + // stable without adjustment. + bv_update(views[i]); + } + img_cmp(0, 2, dbp, av[1], soft_fail); + img_cmp(1, 2, dbp, av[1], soft_fail); + img_cmp(2, 2, dbp, av[1], soft_fail); + img_cmp(3, 2, dbp, av[1], soft_fail); + + // Shrink back to default dimensions + bu_log("Shrink to 512x512...\n"); + len = 512; + for (size_t i = 0; i < 4; i++) { + struct dm *dmp = (struct dm *)views[i]->dmp; + dm_set_width(dmp, len); + dm_set_height(dmp, len); + views[i]->gv_width = len; + views[i]->gv_height = len; + dm_configure_win(dmp, 0); + // NOTE: deliberately not resetting aet here - we want to see if it is + // stable without adjustment. + bv_update(views[i]); + } + img_cmp(0, 1, dbp, av[1], soft_fail); + img_cmp(1, 1, dbp, av[1], soft_fail); + img_cmp(2, 1, dbp, av[1], soft_fail); + img_cmp(3, 1, dbp, av[1], soft_fail); + + // Cycle through a bunch of resizes + bu_log("Cycle through multiple resizes...\n"); + for (int i = 513; i < 600; i++) { + for (size_t j = 0; j < 4; j++) { + struct dm *dmp = (struct dm *)views[j]->dmp; + dm_set_width(dmp, i); + dm_set_height(dmp, i); + views[j]->gv_width = i; + views[j]->gv_height = i; + dm_configure_win(dmp, 0); + // NOTE: deliberately not resetting aet here - we want to see if it is + // stable without adjustment. + bv_update(views[j]); + } + } + len = 512; + for (size_t i = 0; i < 4; i++) { + struct dm *dmp = (struct dm *)views[i]->dmp; + dm_set_width(dmp, len); + dm_set_height(dmp, len); + views[i]->gv_width = len; + views[i]->gv_height = len; + dm_configure_win(dmp, 0); + // NOTE: deliberately not resetting aet here - we want to see if it is + // stable without adjustment. + bv_update(views[i]); + } + img_cmp(0, 1, dbp, av[1], soft_fail); + img_cmp(1, 1, dbp, av[1], soft_fail); + img_cmp(2, 1, dbp, av[1], soft_fail); + img_cmp(3, 1, dbp, av[1], soft_fail); + + + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/aet_00_001_ctrl.png b/src/libged/tests/draw/aet_00_001_ctrl.png new file mode 100644 index 00000000000..fcfd518081f Binary files /dev/null and b/src/libged/tests/draw/aet_00_001_ctrl.png differ diff --git a/src/libged/tests/draw/aet_00_002_ctrl.png b/src/libged/tests/draw/aet_00_002_ctrl.png new file mode 100644 index 00000000000..ef639709b86 Binary files /dev/null and b/src/libged/tests/draw/aet_00_002_ctrl.png differ diff --git a/src/libged/tests/draw/aet_01_001_ctrl.png b/src/libged/tests/draw/aet_01_001_ctrl.png new file mode 100644 index 00000000000..1f7e4252243 Binary files /dev/null and b/src/libged/tests/draw/aet_01_001_ctrl.png differ diff --git a/src/libged/tests/draw/aet_01_002_ctrl.png b/src/libged/tests/draw/aet_01_002_ctrl.png new file mode 100644 index 00000000000..0a80c3d066a Binary files /dev/null and b/src/libged/tests/draw/aet_01_002_ctrl.png differ diff --git a/src/libged/tests/draw/aet_02_001_ctrl.png b/src/libged/tests/draw/aet_02_001_ctrl.png new file mode 100644 index 00000000000..2c9cb5e9209 Binary files /dev/null and b/src/libged/tests/draw/aet_02_001_ctrl.png differ diff --git a/src/libged/tests/draw/aet_02_002_ctrl.png b/src/libged/tests/draw/aet_02_002_ctrl.png new file mode 100644 index 00000000000..059e71d7907 Binary files /dev/null and b/src/libged/tests/draw/aet_02_002_ctrl.png differ diff --git a/src/libged/tests/draw/aet_03_001_ctrl.png b/src/libged/tests/draw/aet_03_001_ctrl.png new file mode 100644 index 00000000000..4f7dc614efb Binary files /dev/null and b/src/libged/tests/draw/aet_03_001_ctrl.png differ diff --git a/src/libged/tests/draw/aet_03_002_ctrl.png b/src/libged/tests/draw/aet_03_002_ctrl.png new file mode 100644 index 00000000000..3ca33c91456 Binary files /dev/null and b/src/libged/tests/draw/aet_03_002_ctrl.png differ diff --git a/src/libged/tests/draw/draw.cpp b/src/libged/tests/draw/draw.cpp new file mode 100644 index 00000000000..e9ce52080ce --- /dev/null +++ b/src/libged/tests/draw/draw.cpp @@ -0,0 +1,767 @@ +/* D R A W . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file draw.cpp + * + * Testing routines for new drawing logic + * + */ + +#include "common.h" +#include + +#include +#define DM_WITH_RT +#include +#include + +extern "C" void ged_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data); +extern "C" void dm_refresh(struct ged *gedp); +extern "C" void scene_clear(struct ged *gedp); +extern "C" void img_cmp(int id, struct ged *gedp, const char *cdir, bool clear_scene, bool clear_image, int soft_fail, int approximate_check, const char *clear_root, const char *img_root); + +/* We will often want to do multiple different operations with + * similar shapes - to make this easier, we encapsulate the + * creation calls for some reusable cases */ + +/* Creates a view circle "c1" */ +void +poly_circ(struct ged *gedp) +{ + const char *s_av[15] = {NULL}; + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "c1"; + s_av[3] = "polygon"; + s_av[4] = "create"; + s_av[5] = "256"; + s_av[6] = "256"; + s_av[7] = "circle"; + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "c1"; + s_av[3] = "update"; + s_av[4] = "300"; + s_av[5] = "300"; + s_av[6] = NULL; + ged_exec(gedp, 6, s_av); +} + +/* Creates a view ellipse "e1" */ +void +poly_ell(struct ged *gedp) +{ + const char *s_av[15] = {NULL}; + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "e1"; + s_av[3] = "polygon"; + s_av[4] = "create"; + s_av[5] = "300"; + s_av[6] = "256"; + s_av[7] = "ellipse"; + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "e1"; + s_av[3] = "update"; + s_av[4] = "400"; + s_av[5] = "300"; + s_av[6] = NULL; + ged_exec(gedp, 6, s_av); +} + +/* Creates a view square "s1" */ +void +poly_sq(struct ged *gedp) +{ + const char *s_av[15] = {NULL}; + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "s1"; + s_av[3] = "polygon"; + s_av[4] = "create"; + s_av[5] = "200"; + s_av[6] = "200"; + s_av[7] = "square"; + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "s1"; + s_av[3] = "update"; + s_av[4] = "310"; + s_av[5] = "310"; + s_av[6] = NULL; + ged_exec(gedp, 6, s_av); +} + +/* Creates a view rectangle "r1" */ +void +poly_rect(struct ged *gedp) +{ + const char *s_av[15] = {NULL}; + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "r1"; + s_av[3] = "polygon"; + s_av[4] = "create"; + s_av[5] = "190"; + s_av[6] = "190"; + s_av[7] = "rectangle"; + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "r1"; + s_av[3] = "update"; + s_av[4] = "380"; + s_av[5] = "290"; + s_av[6] = NULL; + ged_exec(gedp, 6, s_av); +} + + +/* Creates a general polygon "g1" */ +void +poly_general(struct ged *gedp) +{ + const char *s_av[15] = {NULL}; + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "g1"; + s_av[3] = "polygon"; + s_av[4] = "create"; + s_av[5] = "190"; + s_av[6] = "350"; + s_av[7] = NULL; + ged_exec(gedp, 7, s_av); + + s_av[4] = "append"; + s_av[5] = "400"; + s_av[6] = "300"; + ged_exec(gedp, 7, s_av); + + s_av[4] = "append"; + s_av[5] = "380"; + s_av[6] = "300"; + ged_exec(gedp, 7, s_av); + + s_av[4] = "append"; + s_av[5] = "230"; + s_av[6] = "245"; + ged_exec(gedp, 7, s_av); + + s_av[4] = "append"; + s_av[5] = "180"; + s_av[6] = "150"; + ged_exec(gedp, 7, s_av); + + s_av[4] = "append"; + s_av[5] = "210"; + s_av[6] = "300"; + ged_exec(gedp, 7, s_av); + + s_av[4] = "close"; + s_av[5] = NULL; + ged_exec(gedp, 5, s_av); +} + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int soft_fail = 0; + int keep_images = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[4]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT(d[2], "k", "keep", "", NULL, &keep_images, "Keep images generated by the run."); + BU_OPT_NULL(d[3]); + + /* Done with program name */ + int uac = bu_opt_parse(NULL, ac, (const char **)av, d); + if (uac == -1 || need_help) + + if (ac != 2) + bu_exit(EXIT_FAILURE, "%s [-h] [-U] ", av[0]); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + bool clear_images = !keep_images; + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* We are going to generate geometry from the basic moss data, + * so we make a temporary copy */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + std::ifstream orig(bu_vls_cstr(&fname), std::ios::binary); + std::ofstream tmpg("moss_tmp.g", std::ios::binary); + tmpg << orig.rdbuf(); + orig.close(); + tmpg.close(); + + /* Open the temp file */ + const char *s_av[15] = {NULL}; + dbp = ged_open("db", "moss_tmp.g", 1); + + // Set callback so database changes will update dbi_state + db_add_changed_clbk(dbp->dbip, &ged_changed_callback, (void *)dbp); + + // Set up a basic view and set view name + BU_ALLOC(dbp->ged_gvp, struct bview); + bv_init(dbp->ged_gvp, &dbp->ged_views); + bv_set_add_view(&dbp->ged_views, dbp->ged_gvp); + bu_ptbl_ins(&dbp->ged_free_views, (long *)dbp->ged_gvp); + bu_vls_sprintf(&dbp->ged_gvp->gv_name, "default"); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "swrast"; + s_av[3] = "SW"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + struct bview *v = dbp->ged_gvp; + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... TODO - if we need this consistently, + // it should be part of the dm setup. + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + // TODO - these syncing operations need to happen whenever the dm size + // changes - can they be done in dm_set_width/dm_set_height? + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + dm_set_vp(dmp, &v->gv_scale); + + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + + /***** Basic wireframe draw *****/ + bu_log("Testing basic db wireframe draw...\n"); + s_av[0] = "draw"; + s_av[1] = "all.g"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "ae"; + s_av[1] = "35"; + s_av[2] = "25"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + img_cmp(1, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + + // Check that everything is in fact cleared + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Polygon circle *****/ + bu_log("Testing view polygon circle draw...\n"); + poly_circ(dbp); + img_cmp(2, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + + // Check that everything is in fact cleared + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Polygon ellipse *****/ + bu_log("Testing view polygon ellipse draw...\n"); + poly_ell(dbp); + img_cmp(3, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Polygon square *****/ + bu_log("Testing view polygon square draw...\n"); + poly_sq(dbp); + img_cmp(4, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Polygon rectangle *****/ + bu_log("Testing view polygon rectangle draw...\n"); + poly_rect(dbp); + img_cmp(5, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Polygon general *****/ + bu_log("Testing view general polygon draw...\n"); + poly_general(dbp); + img_cmp(6, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test draw UP and DOWN *****/ + bu_log("Testing UP and DOWN visibility control of drawn objects...\n"); + poly_general(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "g1"; + s_av[3] = "draw"; + s_av[4] = "DOWN"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + // Should be an empty scene - make sure we don't clear after this + // comparison, as we want to re-enable the drawing of this object. + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "clear", "v"); + + s_av[4] = "UP"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + // Enabling the draw should produce the same visual as the general polygon + // draw test above, so we can check using the same image + img_cmp(6, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test view polygon booleans: union ****/ + bu_log("Testing view polygon boolean operation: union...\n"); + poly_circ(dbp); + poly_ell(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "c1"; + s_av[3] = "polygon"; + s_av[4] = "csg"; + s_av[5] = "u"; + s_av[6] = "e1"; + s_av[7] = NULL; + ged_exec(dbp, 7, s_av); + + // Result is stored in c1 - turn off e1 + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "e1"; + s_av[3] = "draw"; + s_av[4] = "DOWN"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + // See if we got what we expected + img_cmp(7, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test view polygon booleans: subtraction ****/ + bu_log("Testing view polygon boolean operation: subtraction...\n"); + poly_circ(dbp); + poly_ell(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "c1"; + s_av[3] = "polygon"; + s_av[4] = "csg"; + s_av[5] = "-"; + s_av[6] = "e1"; + s_av[7] = NULL; + ged_exec(dbp, 7, s_av); + + // Result is stored in c1 - turn off e1 + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "e1"; + s_av[3] = "draw"; + s_av[4] = "DOWN"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + // See if we got what we expected + img_cmp(8, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test view polygon booleans: intersection ****/ + bu_log("Testing view polygon boolean operation: intersection...\n"); + poly_circ(dbp); + poly_ell(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "c1"; + s_av[3] = "polygon"; + s_av[4] = "csg"; + s_av[5] = "+"; + s_av[6] = "e1"; + s_av[7] = NULL; + ged_exec(dbp, 7, s_av); + + // Result is stored in c1 - turn off e1 + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "e1"; + s_av[3] = "draw"; + s_av[4] = "DOWN"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + // See if we got what we expected + img_cmp(9, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + + /***** Test color ****/ + bu_log("Testing setting view object color...\n"); + poly_general(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "g1"; + s_av[3] = "color"; + s_av[4] = "0/255/0"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + // See if we got what we expected + img_cmp(10, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test fill ****/ + bu_log("Testing enabling polygon fill...\n"); + poly_general(dbp); + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "g1"; + s_av[3] = "polygon"; + s_av[4] = "fill"; + s_av[5] = "1"; + s_av[6] = "10"; + s_av[7] = "3"; + s_av[8] = NULL; + ged_exec(dbp, 8, s_av); + + // See if we got what we expected + img_cmp(11, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test label ****/ + bu_log("Testing label with leader line...\n"); + s_av[0] = "draw"; + s_av[1] = "all.g"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "lbl1"; + s_av[3] = "label"; + s_av[4] = "create"; + s_av[5] = "LIGHT"; + s_av[6] = "110.41"; + s_av[7] = "-32.2352"; + s_av[8] = "90.4497"; + s_av[9] = "20.1576"; + s_av[10] = "-13.526"; + s_av[11] = "8"; + s_av[12] = NULL; + ged_exec(dbp, 12, s_av); + + img_cmp(12, dbp, av[1], false, clear_images, soft_fail, 30, "clear", "v"); + + s_av[0] = "ae"; + s_av[1] = "10"; + s_av[2] = "4"; + s_av[3] = "11"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(13, dbp, av[1], false, clear_images, soft_fail, 30, "clear", "v"); + + s_av[0] = "ae"; + s_av[1] = "270"; + s_av[2] = "0"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(14, dbp, av[1], false, clear_images, soft_fail, 30, "clear", "v"); + + s_av[0] = "ae"; + s_av[1] = "48"; + s_av[2] = "16"; + s_av[3] = "143"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(15, dbp, av[1], false, clear_images, soft_fail, 50, "clear", "v"); + + s_av[0] = "ae"; + s_av[1] = "40"; + s_av[2] = "-15"; + s_av[3] = "180"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(16, dbp, av[1], false, clear_images, soft_fail, 60, "clear", "v"); + + s_av[0] = "ae"; + s_av[1] = "250"; + s_av[2] = "5"; + s_av[3] = "-140"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(17, dbp, av[1], true, clear_images, soft_fail, 35, "clear", "v"); + + // Restore view to ae 35/25 + s_av[0] = "ae"; + s_av[1] = "35"; + s_av[2] = "25"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + bu_log("Done.\n"); + + /***** Test axes ****/ + bu_log("Testing simple data axes drawing...\n"); + s_av[0] = "draw"; + s_av[1] = "all.g"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "a1"; + s_av[3] = "axes"; + s_av[4] = "create"; + s_av[5] = "1"; + s_av[6] = "1"; + s_av[7] = "1"; + s_av[8] = NULL; + ged_exec(dbp, 8, s_av); + + img_cmp(18, dbp, av[1], false, clear_images, soft_fail, 0, "clear", "v"); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "a1"; + s_av[3] = "axes"; + s_av[4] = "axes_color"; + s_av[5] = "0/0/255"; + s_av[6] = NULL; + ged_exec(dbp, 6, s_av); + + img_cmp(19, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + /***** Test shaded modes ****/ + bu_log("Testing shaded mode 1 (triangle only) drawing, Level-of-Detail disabled...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "facetize"; + s_av[1] = "-r"; + s_av[2] = "all.g"; + s_av[3] = "all.bot"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + dbp->dbi_state->update(); + + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(20, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + bu_log("Testing shaded mode 2 drawing (unevaluated primitive shading). (Note: does not use Level-of-Detail)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m2"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(21, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + bu_log("Testing mode 3 drawing (evaluated wireframe)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m3"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(22, dbp, av[1], true, clear_images, soft_fail, 30, "clear", "v"); + bu_log("Done.\n"); + + bu_log("Testing mode 4 drawing (hidden lines)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m4"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(23, dbp, av[1], true, clear_images, soft_fail, 30, "clear", "v"); + bu_log("Done.\n"); + + bu_log("Testing mode 5 drawing (point based triangles)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m5"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(24, dbp, av[1], true, clear_images, soft_fail, 30, "clear", "v"); + bu_log("Done.\n"); + + bu_log("Test clearing of previous drawing mode (shaded and wireframe)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m2"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(1, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + + bu_log("Testing mixed drawing (shaded and wireframe)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m2"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-A"; + s_av[2] = "-m0"; + s_av[3] = "all.g"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(25, dbp, av[1], true, clear_images, soft_fail, 0, "clear", "v"); + bu_log("Done.\n"); + + + // Done with moss.g + s_av[0] = "closedb"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + bu_file_delete("moss_tmp.g"); + + /* The rook model is a more appropriate test case for mode 3, since its + * wireframe is dramatically different when evaluated.*/ + bu_vls_sprintf(&fname, "%s/rook.g", av[1]); + s_av[0] = "opendb"; + s_av[1] = bu_vls_cstr(&fname); + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + bu_log("Testing mode 3 drawing (evaluated wireframe)...\n"); + s_av[0] = "draw"; + s_av[1] = "-m3"; + s_av[2] = "scene.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(26, dbp, av[1], true, clear_images, soft_fail, 30, "clear", "v"); + bu_log("Done.\n"); + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/empty.png b/src/libged/tests/draw/empty.png new file mode 100644 index 00000000000..5220d0f9dbf Binary files /dev/null and b/src/libged/tests/draw/empty.png differ diff --git a/src/libged/tests/draw/faceplate.cpp b/src/libged/tests/draw/faceplate.cpp new file mode 100644 index 00000000000..b91b6bc9724 --- /dev/null +++ b/src/libged/tests/draw/faceplate.cpp @@ -0,0 +1,337 @@ +/* F A C E P L A T E . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file faceplate.cpp + * + * Testing routines for drawing "built-in" faceplate view elements + * + */ + +#include "common.h" + +#include +#include + +#include +#define DM_WITH_RT +#include +#include + +extern "C" void dm_refresh(struct ged *gedp); +extern "C" void scene_clear(struct ged *gedp); +extern "C" void img_cmp(int id, struct ged *gedp, const char *cdir, bool clear_scene, bool clear_image, int soft_fail, int approximate_check, const char *clear_root, const char *img_root); + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int run_unstable_tests = 0; + int soft_fail = 0; + int keep_images = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[5]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "U", "enable-unstable", "", NULL, &run_unstable_tests, "Test drawing routines known to differ between build configs/platforms."); + BU_OPT(d[2], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT(d[3], "k", "keep", "", NULL, &keep_images, "Keep images generated by the run."); + BU_OPT_NULL(d[4]); + + /* Done with program name */ + int uac = bu_opt_parse(NULL, ac, (const char **)av, d); + if (uac == -1 || need_help) + + if (ac != 2) + bu_exit(EXIT_FAILURE, "%s [-h] [-U] ", av[0]); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + bool clear_images = !keep_images; + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* Open the temp file, then dbconcat argv[1] into it */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + dbp = ged_open("db", bu_vls_cstr(&fname), 1); + + // Set up a basic view and set view name + BU_ALLOC(dbp->ged_gvp, struct bview); + bv_init(dbp->ged_gvp, &dbp->ged_views); + bv_set_add_view(&dbp->ged_views, dbp->ged_gvp); + bu_ptbl_ins(&dbp->ged_free_views, (long *)dbp->ged_gvp); + bu_vls_sprintf(&dbp->ged_gvp->gv_name, "default"); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + const char *s_av[15] = {NULL}; + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "swrast"; + s_av[3] = "SW"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + struct bview *v = dbp->ged_gvp; + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + dm_set_vp(dmp, &v->gv_scale); + v->dmp = dmp; + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + + /***** Sanity - basic wireframe draw *****/ + bu_log("Testing basic db wireframe draw...\n"); + s_av[0] = "draw"; + s_av[1] = "all.g"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "ae"; + s_av[1] = "35"; + s_av[2] = "25"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + img_cmp(1, dbp, av[1], true, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that everything is in fact cleared + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + /***** Center Dot *****/ + bu_log("Testing center dot...\n"); + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "center_dot"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(2, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + /***** Grid *****/ + bu_log("Testing grid...\n"); + + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "grid"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(3, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + /***** Params *****/ + bu_log("Testing parameters reporting...\n"); + + // First make the font smaller so we can see all params + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "params"; + s_av[3] = "font_size"; + s_av[4] = "10"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "params"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(4, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + bu_log("Testing turning on frames per second reporting...\n"); + + // So we don't get random values here, override the timing variable values + ((struct dm *)v->dmp)->start_time = 0; + v->gv_s->gv_frametime = 1000000000; + + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "params"; + s_av[3] = "fps"; + s_av[4] = "0"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + img_cmp(5, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + // Restore default font size + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "params"; + s_av[3] = "font_size"; + s_av[4] = "20"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + + + /***** Scale *****/ + bu_log("Testing scale reporting...\n"); + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "scale"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(6, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + + /***** View axes *****/ + bu_log("Testing view axes drawing...\n"); + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "view_axes"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(7, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + /***** Model axes *****/ + bu_log("Testing model axes drawing...\n"); + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "model_axes"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(8, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + bu_log("Done.\n"); + + /***** Framebuffer *****/ + bu_log("Testing framebuffer...\n"); + struct bu_vls fb_img = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&fb_img, "%s/moss.png", av[1]); + s_av[0] = "png2fb"; + s_av[1] = bu_vls_cstr(&fb_img); + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "fb"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + img_cmp(9, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Check that turning off works + s_av[3] = "0"; + ged_exec(dbp, 4, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + // Re-enable and make sure clear works + s_av[3] = "1"; + ged_exec(dbp, 4, s_av); + img_cmp(9, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + s_av[0] = "fbclear"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + img_cmp(0, dbp, av[1], false, clear_images, soft_fail, 0, "faceplate_clear", "fp"); + + s_av[0] = "view"; + s_av[1] = "faceplate"; + s_av[2] = "fb"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + bu_log("Done.\n"); + + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/fp001_ctrl.png b/src/libged/tests/draw/fp001_ctrl.png new file mode 100644 index 00000000000..65f7c41603c Binary files /dev/null and b/src/libged/tests/draw/fp001_ctrl.png differ diff --git a/src/libged/tests/draw/fp002_ctrl.png b/src/libged/tests/draw/fp002_ctrl.png new file mode 100644 index 00000000000..1f2d518bcd1 Binary files /dev/null and b/src/libged/tests/draw/fp002_ctrl.png differ diff --git a/src/libged/tests/draw/fp003_ctrl.png b/src/libged/tests/draw/fp003_ctrl.png new file mode 100644 index 00000000000..b78d13a4f70 Binary files /dev/null and b/src/libged/tests/draw/fp003_ctrl.png differ diff --git a/src/libged/tests/draw/fp004_ctrl.png b/src/libged/tests/draw/fp004_ctrl.png new file mode 100644 index 00000000000..f9c3ec71bc9 Binary files /dev/null and b/src/libged/tests/draw/fp004_ctrl.png differ diff --git a/src/libged/tests/draw/fp005_ctrl.png b/src/libged/tests/draw/fp005_ctrl.png new file mode 100644 index 00000000000..8f151e8ea89 Binary files /dev/null and b/src/libged/tests/draw/fp005_ctrl.png differ diff --git a/src/libged/tests/draw/fp006_ctrl.png b/src/libged/tests/draw/fp006_ctrl.png new file mode 100644 index 00000000000..64316dc0aab Binary files /dev/null and b/src/libged/tests/draw/fp006_ctrl.png differ diff --git a/src/libged/tests/draw/fp007_ctrl.png b/src/libged/tests/draw/fp007_ctrl.png new file mode 100644 index 00000000000..7c72a3f28d1 Binary files /dev/null and b/src/libged/tests/draw/fp007_ctrl.png differ diff --git a/src/libged/tests/draw/fp008_ctrl.png b/src/libged/tests/draw/fp008_ctrl.png new file mode 100644 index 00000000000..aca70a73ba1 Binary files /dev/null and b/src/libged/tests/draw/fp008_ctrl.png differ diff --git a/src/libged/tests/draw/fp009_ctrl.png b/src/libged/tests/draw/fp009_ctrl.png new file mode 100644 index 00000000000..8a5ac991c13 Binary files /dev/null and b/src/libged/tests/draw/fp009_ctrl.png differ diff --git a/src/libged/tests/draw/lod.cpp b/src/libged/tests/draw/lod.cpp new file mode 100644 index 00000000000..44e5ec531aa --- /dev/null +++ b/src/libged/tests/draw/lod.cpp @@ -0,0 +1,431 @@ +/* L O D . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file lod.cpp + * + * Testing routines for Level of Detail (LoD) logic + * + */ + +#include "common.h" + +#include +#include + +#include +#define DM_WITH_RT +#include +#include + +extern "C" void ged_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data); +extern "C" void dm_refresh(struct ged *gedp); +extern "C" void scene_clear(struct ged *gedp); +extern "C" void img_cmp(int id, struct ged *gedp, const char *cdir, bool clear_scene, bool clear_image, int soft_fail, int approximate_check, const char *clear_root, const char *img_root); + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int run_unstable_tests = 0; + int soft_fail = 0; + int keep_images = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[5]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "U", "enable-unstable", "", NULL, &run_unstable_tests, "Test drawing routines known to differ between build configs/platforms."); + BU_OPT(d[2], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT(d[3], "k", "keep", "", NULL, &keep_images, "Keep images generated by the run."); + BU_OPT_NULL(d[4]); + + + /* Done with program name */ + int uac = bu_opt_parse(NULL, ac, (const char **)av, d); + if (uac == -1 || need_help) + + if (ac != 2) + bu_exit(EXIT_FAILURE, "%s [-h] [-U] ", av[0]); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + bool clear_images = !keep_images; + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* We are going to generate geometry from the basic moss data, + * so we make a temporary copy */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + std::ifstream orig(bu_vls_cstr(&fname), std::ios::binary); + std::ofstream tmpg("moss_lod_tmp.g", std::ios::binary); + tmpg << orig.rdbuf(); + orig.close(); + tmpg.close(); + + /* Open the temp file */ + const char *s_av[15] = {NULL}; + dbp = ged_open("db", "moss_lod_tmp.g", 1); + + // Set callback so database changes will update dbi_state + db_add_changed_clbk(dbp->dbip, &ged_changed_callback, (void *)dbp); + + // Set up a basic view and set view name + BU_ALLOC(dbp->ged_gvp, struct bview); + bv_init(dbp->ged_gvp, &dbp->ged_views); + bv_set_add_view(&dbp->ged_views, dbp->ged_gvp); + bu_ptbl_ins(&dbp->ged_free_views, (long *)dbp->ged_gvp); + bu_vls_sprintf(&dbp->ged_gvp->gv_name, "default"); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "swrast"; + s_av[3] = "SW"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + struct bview *v = dbp->ged_gvp; + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + dm_set_vp(dmp, &v->gv_scale); + v->dmp = dmp; + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + + /* Fully clear any prior cached LoD data */ + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "cache"; + s_av[3] = "clear"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + /* Generate geometry appropriate for mesh LoD */ + s_av[0] = "tol"; + s_av[1] = "rel"; + s_av[2] = "0.0002"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "facetize"; + s_av[1] = "-r"; + s_av[2] = "all.g"; + s_av[3] = "all.bot"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + dbp->dbi_state->update(); + + s_av[0] = "ae"; + s_av[1] = "35"; + s_av[2] = "25"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + + /***** Mesh LoD ****/ + bu_log("Sanity - testing shaded mode 1 (triangle only) drawing, Level-of-Detail disabled...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(1, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + bu_log("Done.\n"); + + bu_log("Enable LoD, using coarse scale to enhance visual change...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "scale"; + s_av[3] = "0.8"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(2, dbp, av[1], false, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Disable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(1, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + + bu_log("Re-enable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(2, dbp, av[1], true, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Done.\n"); + + /***** Brep LoD ****/ + + s_av[0] = "tol"; + s_av[1] = "rel"; + s_av[2] = "0.01"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "brep"; + s_av[1] = "all.g"; + s_av[2] = "brep"; + s_av[3] = "all.brep"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + dbp->dbi_state->update(); + + bu_log("Sanity - testing shaded mode 1 (triangle only) drawing, Level-of-Detail disabled...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.brep"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(3, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + bu_log("Done.\n"); + + bu_log("Enable LoD, keeping above coarse scale to enhance visual change...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(4, dbp, av[1], false, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Disable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(3, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + + bu_log("Re-enable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(4, dbp, av[1], true, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Done.\n"); + + + /***** CSG LoD ****/ + bu_log("Sanity - testing wireframe, Level-of-Detail disabled...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(5, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + bu_log("Done.\n"); + + bu_log("Enable LoD...\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(6, dbp, av[1], false, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Disable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(5, dbp, av[1], false, clear_images, soft_fail, 0, "lod_clear", "lod"); + + bu_log("Re-enable LoD\n"); + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(6, dbp, av[1], true, clear_images, soft_fail, 10, "lod_clear", "lod"); + + bu_log("Done.\n"); + + /* Check cache behavior */ + + /* Fully clear any cached LoD data */ + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "cache"; + s_av[3] = "clear"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + /* Generate cached LoD data */ + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "cache"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + /* Enable LoD and check drawing of meshes and breps */ + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "scale"; + s_av[3] = "0.8"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(2, dbp, av[1], true, clear_images, soft_fail, 10, "lod_clear", "lod"); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.brep"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(4, dbp, av[1], true, clear_images, soft_fail, 10, "lod_clear", "lod"); + + /* Fully clear any cached LoD data */ + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "cache"; + s_av[3] = "clear"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/lod001_ctrl.png b/src/libged/tests/draw/lod001_ctrl.png new file mode 100644 index 00000000000..1959deffd79 Binary files /dev/null and b/src/libged/tests/draw/lod001_ctrl.png differ diff --git a/src/libged/tests/draw/lod002_ctrl.png b/src/libged/tests/draw/lod002_ctrl.png new file mode 100644 index 00000000000..c90c886bae5 Binary files /dev/null and b/src/libged/tests/draw/lod002_ctrl.png differ diff --git a/src/libged/tests/draw/lod003_ctrl.png b/src/libged/tests/draw/lod003_ctrl.png new file mode 100644 index 00000000000..04cc1f6e876 Binary files /dev/null and b/src/libged/tests/draw/lod003_ctrl.png differ diff --git a/src/libged/tests/draw/lod004_ctrl.png b/src/libged/tests/draw/lod004_ctrl.png new file mode 100644 index 00000000000..5fb177f39de Binary files /dev/null and b/src/libged/tests/draw/lod004_ctrl.png differ diff --git a/src/libged/tests/draw/lod005_ctrl.png b/src/libged/tests/draw/lod005_ctrl.png new file mode 100644 index 00000000000..65f7c41603c Binary files /dev/null and b/src/libged/tests/draw/lod005_ctrl.png differ diff --git a/src/libged/tests/draw/lod006_ctrl.png b/src/libged/tests/draw/lod006_ctrl.png new file mode 100644 index 00000000000..095ede1db5b Binary files /dev/null and b/src/libged/tests/draw/lod006_ctrl.png differ diff --git a/src/libged/tests/draw/moss.g b/src/libged/tests/draw/moss.g new file mode 100644 index 00000000000..dd7a8d03aaa Binary files /dev/null and b/src/libged/tests/draw/moss.g differ diff --git a/src/libged/tests/draw/moss.png b/src/libged/tests/draw/moss.png new file mode 100644 index 00000000000..179450a334e Binary files /dev/null and b/src/libged/tests/draw/moss.png differ diff --git a/src/libged/tests/draw/quad.cpp b/src/libged/tests/draw/quad.cpp new file mode 100644 index 00000000000..1c03c7133c6 --- /dev/null +++ b/src/libged/tests/draw/quad.cpp @@ -0,0 +1,1086 @@ +/* Q U A D . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file quad.cpp + * + * Testing drawing routines and view management with multiple shared + * and independent views. + * + */ + +#include "common.h" + +#include +#include + +#define XXH_STATIC_LINKING_ONLY +#define XXH_IMPLEMENTATION +#include "xxhash.h" + +#include +#include +#include +#define DM_WITH_RT +#include +#include + +// In order to handle changes to .g geometry contents, we need to defined +// callbacks for the librt hooks that will update the working data structures. +// In Qt we have libqtcad handle this, but as we are not using a QgModel we +// need to do it ourselves. +extern "C" void +ged_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data) +{ + XXH64_state_t h_state; + unsigned long long hash; + struct ged *gedp = (struct ged *)u_data; + DbiState *ctx = gedp->dbi_state; + + // Clear cached GED drawing data and update + ctx->clear_cache(dp); + + // Need to invalidate any LoD caches associated with this dp + if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && ctx->gedp) { + unsigned long long key = bv_mesh_lod_key_get(ctx->gedp->ged_lod, dp->d_namep); + if (key) { + bv_mesh_lod_clear_cache(ctx->gedp->ged_lod, key); + bv_mesh_lod_key_put(ctx->gedp->ged_lod, dp->d_namep, 0); + } + } + + switch(mode) { + case 0: + ctx->changed.insert(dp); + break; + case 1: + ctx->added.insert(dp); + break; + case 2: + // When this callback is made, dp is still valid, but in subsequent + // processing it will not be. We need to capture everything we + // will need from this dp now, for later use when updating state + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + hash = (unsigned long long)XXH64_digest(&h_state); + ctx->removed.insert(hash); + ctx->old_names[hash] = std::string(dp->d_namep); + break; + default: + bu_log("changed callback mode error: %d\n", mode); + } +} + +void +dm_refresh(struct ged *gedp, int vnum) +{ + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + struct bview *v = (struct bview *)BU_PTBL_GET(views, vnum); + if (!v) + return; + BViewState *bvs = gedp->dbi_state->get_view_state(v); + gedp->dbi_state->update(); + std::unordered_set uset; + uset.insert(v); + bvs->redraw(NULL, uset, 1); + + struct dm *dmp = (struct dm *)v->dmp; + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + dm_set_dirty(dmp, 0); + dm_draw_objs(v, NULL, NULL); + dm_draw_end(dmp); +} + +void +scene_clear(struct ged *gedp, int vnum, int cnum) +{ + const char *s_av[4] = {NULL}; + if (cnum < 0) { + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(gedp, 1, s_av); + } else { + struct bu_vls vname = BU_VLS_INIT_ZERO; + s_av[0] = "Z"; + s_av[1] = "-V"; + bu_vls_sprintf(&vname, "V%d", vnum); + s_av[2] = bu_vls_cstr(&vname); + ged_exec(gedp, 3, s_av); + bu_vls_free(&vname); + } + dm_refresh(gedp, vnum); +} + +void +img_cmp(int vnum, int id, struct ged *gedp, const char *cdir, bool clear, int soft_fail) +{ + icv_image_t *ctrl, *timg; + struct bu_vls tname = BU_VLS_INIT_ZERO; + struct bu_vls cname = BU_VLS_INIT_ZERO; + if (id <= 0) { + bu_vls_sprintf(&tname, "quad_clear.png"); + bu_vls_sprintf(&cname, "%s/empty.png", cdir); + } else { + bu_vls_sprintf(&tname, "quad_%02d_%03d.png", vnum, id); + bu_vls_sprintf(&cname, "%s/quad_%02d_%03d_ctrl.png", cdir, vnum, id); + } + + dm_refresh(gedp, vnum); + + struct bu_ptbl *views = bv_set_views(&gedp->ged_views); + struct bview *v = (struct bview *)BU_PTBL_GET(views, vnum); + if (!v) + bu_exit(EXIT_FAILURE, "Invalid view specifier: %d\n", vnum); + struct dm *dmp = (struct dm *)v->dmp; + int cnum = (v->independent) ? vnum : -1; + + const char *s_av[4] = {NULL}; + s_av[0] = "screengrab"; + s_av[1] = "-D"; + s_av[2] = bu_vls_cstr(dm_get_pathname(dmp)); + s_av[3] = bu_vls_cstr(&tname); + if (ged_exec(gedp, 4, s_av) & BRLCAD_ERROR) { + bu_log("Failed to grab screen for DM %s\n", bu_vls_cstr(dm_get_pathname(dmp))); + if (clear) + scene_clear(gedp, vnum, cnum); + bu_vls_free(&tname); + return; + } + + timg = icv_read(bu_vls_cstr(&tname), BU_MIME_IMAGE_PNG, 0, 0); + if (!timg) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&tname)); + if (clear) + scene_clear(gedp, vnum, cnum); + bu_vls_free(&tname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&tname)); + } + ctrl = icv_read(bu_vls_cstr(&cname), BU_MIME_IMAGE_PNG, 0, 0); + if (!ctrl) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&cname)); + if (clear) + scene_clear(gedp, vnum, cnum); + bu_vls_free(&tname); + bu_vls_free(&cname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&cname)); + } + bu_vls_free(&cname); + int matching_cnt = 0; + int off_by_1_cnt = 0; + int off_by_many_cnt = 0; + int iret = icv_diff(&matching_cnt, &off_by_1_cnt, &off_by_many_cnt, ctrl,timg); + if (iret) { + if (soft_fail) { + bu_log("%d wireframe diff failed. %d matching, %d off by 1, %d off by many\n", id, matching_cnt, off_by_1_cnt, off_by_many_cnt); + icv_destroy(ctrl); + icv_destroy(timg); + if (clear) + scene_clear(gedp, vnum, cnum); + return; + } + bu_exit(EXIT_FAILURE, "%d wireframe diff failed. %d matching, %d off by 1, %d off by many\n", id, matching_cnt, off_by_1_cnt, off_by_many_cnt); + } + + icv_destroy(ctrl); + icv_destroy(timg); + + // Image comparison done and successful - clear image + bu_file_delete(bu_vls_cstr(&tname)); + bu_vls_free(&tname); + + if (clear) + scene_clear(gedp, vnum, cnum); +} + +/* Creates a view circle "c1" */ +void +poly_circ(struct ged *gedp, int v_id, int local) +{ + const char *s_av[15] = {NULL}; + struct bu_vls vname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vname, "V%d", v_id); + + if (local) { + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = bu_vls_cstr(&vname); + s_av[3] = "obj"; + s_av[4] = "-L"; + s_av[5] = "c1"; + s_av[6] = "polygon"; + s_av[7] = "create"; + s_av[8] = "256"; + s_av[9] = "256"; + s_av[10] = "circle"; + s_av[11] = NULL; + ged_exec(gedp, 11, s_av); + } else { + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = bu_vls_cstr(&vname); + s_av[3] = "obj"; + s_av[4] = "c1"; + s_av[5] = "polygon"; + s_av[6] = "create"; + s_av[7] = "256"; + s_av[8] = "256"; + s_av[9] = "circle"; + s_av[10] = NULL; + ged_exec(gedp, 10, s_av); + } + + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = bu_vls_cstr(&vname); + s_av[3] = "obj"; + s_av[4] = "c1"; + s_av[5] = "update"; + s_av[6] = "300"; + s_av[7] = "300"; + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + bu_vls_free(&vname); +} + +/* Creates a shared line */ +void +vline(struct ged *gedp, int l_id, int x0, int y0, int z0, int x1, int y1, int z1) +{ + const char *s_av[15] = {NULL}; + struct bu_vls lname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&lname, "l%d", l_id); + + struct bu_vls vx0 = BU_VLS_INIT_ZERO; + struct bu_vls vy0 = BU_VLS_INIT_ZERO; + struct bu_vls vz0 = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vx0, "%d", x0); + bu_vls_sprintf(&vy0, "%d", y0); + bu_vls_sprintf(&vz0, "%d", z0); + + struct bu_vls vx1 = BU_VLS_INIT_ZERO; + struct bu_vls vy1 = BU_VLS_INIT_ZERO; + struct bu_vls vz1 = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vx1, "%d", x1); + bu_vls_sprintf(&vy1, "%d", y1); + bu_vls_sprintf(&vz1, "%d", z1); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = bu_vls_cstr(&lname); + s_av[3] = "line"; + s_av[4] = "create"; + s_av[5] = bu_vls_cstr(&vx0); + s_av[6] = bu_vls_cstr(&vy0); + s_av[7] = bu_vls_cstr(&vz0); + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = bu_vls_cstr(&lname); + s_av[3] = "line"; + s_av[4] = "append"; + s_av[5] = bu_vls_cstr(&vx1); + s_av[6] = bu_vls_cstr(&vy1); + s_av[7] = bu_vls_cstr(&vz1); + s_av[8] = NULL; + ged_exec(gedp, 8, s_av); + + bu_vls_free(&lname); + bu_vls_free(&vx0); + bu_vls_free(&vy0); + bu_vls_free(&vz0); + bu_vls_free(&vx1); + bu_vls_free(&vy1); + bu_vls_free(&vz1); +} + +/* View local line */ +void +l_line(struct ged *gedp, int v_id, int l_id, int x0, int y0, int z0, int x1, int y1, int z1) +{ + const char *s_av[15] = {NULL}; + struct bu_vls vname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vname, "V%d", v_id); + + struct bu_vls lname = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&lname, "l%d", l_id); + + struct bu_vls vx0 = BU_VLS_INIT_ZERO; + struct bu_vls vy0 = BU_VLS_INIT_ZERO; + struct bu_vls vz0 = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vx0, "%d", x0); + bu_vls_sprintf(&vy0, "%d", y0); + bu_vls_sprintf(&vz0, "%d", z0); + + struct bu_vls vx1 = BU_VLS_INIT_ZERO; + struct bu_vls vy1 = BU_VLS_INIT_ZERO; + struct bu_vls vz1 = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&vx1, "%d", x1); + bu_vls_sprintf(&vy1, "%d", y1); + bu_vls_sprintf(&vz1, "%d", z1); + + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = bu_vls_cstr(&vname); + s_av[3] = "obj"; + s_av[4] = "-L"; + s_av[5] = bu_vls_cstr(&lname); + s_av[6] = "line"; + s_av[7] = "create"; + s_av[8] = bu_vls_cstr(&vx0); + s_av[9] = bu_vls_cstr(&vy0); + s_av[10] = bu_vls_cstr(&vz0); + s_av[11] = NULL; + ged_exec(gedp, 11, s_av); + + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = bu_vls_cstr(&vname); + s_av[3] = "obj"; + s_av[4] = "-L"; + s_av[5] = bu_vls_cstr(&lname); + s_av[6] = "line"; + s_av[7] = "append"; + s_av[8] = bu_vls_cstr(&vx1); + s_av[9] = bu_vls_cstr(&vy1); + s_av[10] = bu_vls_cstr(&vz1); + s_av[11] = NULL; + ged_exec(gedp, 11, s_av); + + bu_vls_free(&vname); + bu_vls_free(&lname); + bu_vls_free(&vx0); + bu_vls_free(&vy0); + bu_vls_free(&vz0); + bu_vls_free(&vx1); + bu_vls_free(&vy1); + bu_vls_free(&vz1); +} + + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int run_unstable_tests = 0; + int soft_fail = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[4]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "U", "enable-unstable", "", NULL, &run_unstable_tests, "Test drawing routines known to differ between build configs/platforms."); + BU_OPT(d[2], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT_NULL(d[3]); + + /* Done with program name */ + (void)bu_opt_parse(NULL, ac, (const char **)av, d); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* We are going to generate geometry from the basic moss data, + * so we make a temporary copy */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + std::ifstream orig(bu_vls_cstr(&fname), std::ios::binary); + std::ofstream tmpg("moss_quad_tmp.g", std::ios::binary); + tmpg << orig.rdbuf(); + orig.close(); + tmpg.close(); + + /* Open the temp file */ + const char *s_av[15] = {NULL}; + dbp = ged_open("db", "moss_quad_tmp.g", 1); + // We don't want the default GED views for this test + bv_set_rm_view(&dbp->ged_views, NULL); + + // Set callback so database changes will update dbi_state + db_add_changed_clbk(dbp->dbip, &ged_changed_callback, (void *)dbp); + + // Set up the views. Unlike the other drawing tests, we are explicitly + // out to test the behavior of multiple views and dms, so we need to + // set up multiples. We'll start out with four non-independent views, + // to mimic the most common multi-dm/view display - a Quad view widget. + // Each view will get its own attached swrast DM. + for (size_t i = 0; i < 4; i++) { + struct bview *v; + BU_GET(v, struct bview); + if (!i) + dbp->ged_gvp = v; + bv_init(v, &dbp->ged_views); + bu_vls_sprintf(&v->gv_name, "V%zd", i); + bv_set_add_view(&dbp->ged_views, v); + bu_ptbl_ins(&dbp->ged_free_views, (long *)v); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + struct bu_vls dm_name = BU_VLS_INIT_ZERO; + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "-V"; + s_av[3] = bu_vls_cstr(&v->gv_name); + s_av[4] = "swrast"; + bu_vls_sprintf(&dm_name, "SW%zd", i); + s_av[5] = bu_vls_cstr(&dm_name); + s_av[6] = NULL; + ged_exec(dbp, 6, s_av); + bu_vls_free(&dm_name); + + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + dm_set_vp(dmp, &v->gv_scale); + v->dmp = dmp; + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + } + + /* Set distinct view az/el for each of the four quad views */ + s_av[0] = "view"; + s_av[1] = "-V"; + s_av[2] = "V0"; + s_av[3] = "aet"; + s_av[4] = "35"; + s_av[5] = "25"; + s_av[6] = "0"; + s_av[7] = NULL; + ged_exec(dbp, 7, s_av); + + s_av[2] = "V1"; + s_av[4] = "90"; + s_av[5] = "0"; + s_av[6] = "0"; + ged_exec(dbp, 7, s_av); + + s_av[2] = "V2"; + s_av[4] = "0"; + s_av[5] = "90"; + s_av[6] = "0"; + ged_exec(dbp, 7, s_av); + + s_av[2] = "V3"; + s_av[4] = "0"; + s_av[5] = "0"; + s_av[6] = "90"; + ged_exec(dbp, 7, s_av); + + + /************************************/ + /* Set up a basic wireframe */ + bu_log("Basic shared view drawing test...\n"); + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, 1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], true, soft_fail); + + /* Make sure "Z" clears everything */ + s_av[0] = "Z"; + ged_exec(dbp, 1, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + /************************************/ + /* Check behavior of a view element */ + bu_log("View object, shared views drawing test...\n"); + poly_circ(dbp, 1, 0); + img_cmp(0, 2, dbp, av[1], false, soft_fail); + img_cmp(1, 2, dbp, av[1], false, soft_fail); + img_cmp(2, 2, dbp, av[1], false, soft_fail); + img_cmp(3, 2, dbp, av[1], true, soft_fail); + + /* Make sure "Z" clears everything */ + s_av[0] = "Z"; + ged_exec(dbp, 1, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + /***************************************************/ + /* Check view independent behavior - basic drawing */ + bu_log("Basic independent views drawing test - V1 active\n"); + + struct bu_ptbl *views = bv_set_views(&dbp->ged_views); + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *v = (struct bview *)BU_PTBL_GET(views, i); + v->independent = 1; + } + + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V1"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + bu_log("Basic independent views drawing test - V0, V1 active\n"); + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V0"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + bu_log("Basic independent views drawing test - V0, V1, V3 active\n"); + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V3"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + bu_log("Basic independent views drawing test - all active\n"); + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V2"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, 1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + /* Make sure "Z" clears in the expected way */ + bu_log("Independent views - clear.\n"); + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V0"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, 1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V2"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V3"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + /**************************************************/ + /* Check view independent behavior - view element */ + bu_log("Independent views - view object drawing test. V2\n"); + poly_circ(dbp, 2, 1); + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, 3, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + bu_log("Independent views - view object drawing test. V3\n"); + poly_circ(dbp, 3, 1); + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, 3, dbp, av[1], false, soft_fail); + img_cmp(3, 3, dbp, av[1], false, soft_fail); + + bu_log("Independent views - view object drawing test. V0\n"); + poly_circ(dbp, 0, 1); + img_cmp(0, 3, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, 3, dbp, av[1], false, soft_fail); + img_cmp(3, 3, dbp, av[1], false, soft_fail); + + bu_log("Independent views - view object drawing test. V1\n"); + poly_circ(dbp, 1, 1); + img_cmp(0, 3, dbp, av[1], false, soft_fail); + img_cmp(1, 3, dbp, av[1], false, soft_fail); + img_cmp(2, 3, dbp, av[1], false, soft_fail); + img_cmp(3, 3, dbp, av[1], false, soft_fail); + + + /* Make sure "Z" clears in the expected way */ + bu_log("Independent views - view obj clearing - default\n"); + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V0"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 3, dbp, av[1], false, soft_fail); + img_cmp(2, 3, dbp, av[1], false, soft_fail); + img_cmp(3, 3, dbp, av[1], false, soft_fail); + + bu_log("Independent views - view obj clearing - V2\n"); + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V2"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 3, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, 3, dbp, av[1], false, soft_fail); + + + bu_log("Independent views - view obj clearing - V3\n"); + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V3"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 3, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + bu_log("Independent views - view obj clearing - V1\n"); + s_av[0] = "Z"; + s_av[1] = "-V"; + s_av[2] = "V1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + // Scrub all data out of the views, switch back to non-independent + scene_clear(dbp, 0, 0); + scene_clear(dbp, 1, 1); + scene_clear(dbp, 2, 2); + scene_clear(dbp, 3, 3); + + for (size_t i = 0; i < BU_PTBL_LEN(views); i++) { + struct bview *v = (struct bview *)BU_PTBL_GET(views, i); + v->independent = 0; + } + scene_clear(dbp, 0, -1); + + /***************************************************/ + /* Check shared view behavior - non-local line drawing */ + bu_log("Shared views drawing test - non-local view line\n"); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + + vline(dbp, 1, -200, -200, -200, 200, 200, 200); + img_cmp(0, 4, dbp, av[1], false, soft_fail); + img_cmp(1, 4, dbp, av[1], false, soft_fail); + img_cmp(2, 4, dbp, av[1], false, soft_fail); + img_cmp(3, 4, dbp, av[1], false, soft_fail); + + /* Make sure we've cleared everything */ + s_av[0] = "Z"; + ged_exec(dbp, 1, s_av); + + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + /***************************************************/ + /* Check shared view behavior - local line drawing. + * This combines shared and non-shared elements, + * the most complex of the structural scenarios. */ + bu_log("Shared views drawing test - local view line\n"); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + + l_line(dbp, 0, 0, -200, -100, -100, 200, 100, 100); + img_cmp(0, 5, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, 1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + + l_line(dbp, 2, 2, -50, -50, -30, 100, -70, 80); + img_cmp(0, 5, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, 5, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + + l_line(dbp, 1, 1, 50, -20, 10, 130, 70, -80); + img_cmp(0, 5, dbp, av[1], false, soft_fail); + img_cmp(1, 5, dbp, av[1], false, soft_fail); + img_cmp(2, 5, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + + l_line(dbp, 3, 3, 0, 0, 0, 100, 100, 100); + img_cmp(0, 5, dbp, av[1], false, soft_fail); + img_cmp(1, 5, dbp, av[1], false, soft_fail); + img_cmp(2, 5, dbp, av[1], false, soft_fail); + img_cmp(3, 5, dbp, av[1], false, soft_fail); + + + // Add a shared line to all four views + vline(dbp, 4, 0, 0, 0, 10, 10, -100); + // Turn the shared line green + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "l4"; + s_av[3] = "color"; + s_av[4] = "0/255/0"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + img_cmp(0, 6, dbp, av[1], false, soft_fail); + img_cmp(1, 6, dbp, av[1], false, soft_fail); + img_cmp(2, 6, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + // Scrub view specific data + bu_log("Clearing view-specific data only...\n"); + scene_clear(dbp, 0, 0); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, 7, dbp, av[1], false, soft_fail); + img_cmp(1, 6, dbp, av[1], false, soft_fail); + img_cmp(2, 6, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + scene_clear(dbp, 1, 1); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, 7, dbp, av[1], false, soft_fail); + img_cmp(1, 7, dbp, av[1], false, soft_fail); + img_cmp(2, 6, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + + scene_clear(dbp, 2, 2); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, 7, dbp, av[1], false, soft_fail); + img_cmp(1, 7, dbp, av[1], false, soft_fail); + img_cmp(2, 7, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + + scene_clear(dbp, 3, 3); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, 7, dbp, av[1], false, soft_fail); + img_cmp(1, 7, dbp, av[1], false, soft_fail); + img_cmp(2, 7, dbp, av[1], false, soft_fail); + img_cmp(3, 7, dbp, av[1], false, soft_fail); + + + scene_clear(dbp, 0, -1); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + // Reset the stage - clearing only shared + bu_log("Restore drawn data for shared-only clearing test...\n"); + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + l_line(dbp, 0, 0, -200, -100, -100, 200, 100, 100); + l_line(dbp, 2, 2, -50, -50, -30, 100, -70, 80); + l_line(dbp, 1, 1, 50, -20, 10, 130, 70, -80); + l_line(dbp, 3, 3, 0, 0, 0, 100, 100, 100); + vline(dbp, 4, 0, 0, 0, 10, 10, -100); + // Turn the shared line green + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "l4"; + s_av[3] = "color"; + s_av[4] = "0/255/0"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 6, dbp, av[1], false, soft_fail); + img_cmp(1, 6, dbp, av[1], false, soft_fail); + img_cmp(2, 6, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + s_av[0] = "Z"; + s_av[1] = "-S"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(0, 8, dbp, av[1], false, soft_fail); + img_cmp(1, 8, dbp, av[1], false, soft_fail); + img_cmp(2, 8, dbp, av[1], false, soft_fail); + img_cmp(3, 8, dbp, av[1], false, soft_fail); + + scene_clear(dbp, 0, 0); + scene_clear(dbp, 1, 1); + scene_clear(dbp, 2, 2); + scene_clear(dbp, 3, 3); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + + // Reset the stage - clearing everything test + bu_log("Restore drawn data for clear all test...\n"); + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 4, s_av); + l_line(dbp, 0, 0, -200, -100, -100, 200, 100, 100); + l_line(dbp, 2, 2, -50, -50, -30, 100, -70, 80); + l_line(dbp, 1, 1, 50, -20, 10, 130, 70, -80); + l_line(dbp, 3, 3, 0, 0, 0, 100, 100, 100); + vline(dbp, 4, 0, 0, 0, 10, 10, -100); + // Turn the shared line green + s_av[0] = "view"; + s_av[1] = "obj"; + s_av[2] = "l4"; + s_av[3] = "color"; + s_av[4] = "0/255/0"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 6, dbp, av[1], false, soft_fail); + img_cmp(1, 6, dbp, av[1], false, soft_fail); + img_cmp(2, 6, dbp, av[1], false, soft_fail); + img_cmp(3, 6, dbp, av[1], false, soft_fail); + + bu_log("Clearing everything...\n"); + scene_clear(dbp, 0, 0); + scene_clear(dbp, 1, 1); + scene_clear(dbp, 2, 2); + scene_clear(dbp, 3, 3); + scene_clear(dbp, 0, -1); + for (int i = 0; i < 4; i++) + dm_refresh(dbp, i); + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + // Next, test a mix of shared and independent views + bu_log("Testing mixed shared and independent views\n"); + ((struct bview *)BU_PTBL_GET(views, 0))->independent = 1; + ((struct bview *)BU_PTBL_GET(views, 1))->independent = 0; + ((struct bview *)BU_PTBL_GET(views, 2))->independent = 1; + ((struct bview *)BU_PTBL_GET(views, 3))->independent = 0; + + // First, draw without specifying any particular view. + // This should result in the non-independent views being + // populated. + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(0, -1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + // Populate an independent view + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V0"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, 1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, 1, dbp, av[1], false, soft_fail); + + // Clear shared views + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + // Draw specifying a view, but this time specifying a shared view. + // Should be a no-op - we can mix shared and independent view + // objects, but db objects are either independent or shared. + // TODO - should we support mixing them? Would complicate the + // who, B and Z command usage somewhat - right now, for geometry + // objects, those are consistent across shared views. + s_av[0] = "draw"; + s_av[1] = "-V"; + s_av[2] = "V1"; + s_av[3] = "-m0"; + s_av[4] = "all.g"; + s_av[5] = NULL; + ged_exec(dbp, 5, s_av); + + img_cmp(0, 1, dbp, av[1], false, soft_fail); + img_cmp(1, -1, dbp, av[1], false, soft_fail); + img_cmp(2, -1, dbp, av[1], false, soft_fail); + img_cmp(3, -1, dbp, av[1], false, soft_fail); + + //bu_setenv("BV_LOG", "1", 1); + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/quad_00_001_ctrl.png b/src/libged/tests/draw/quad_00_001_ctrl.png new file mode 100644 index 00000000000..65f7c41603c Binary files /dev/null and b/src/libged/tests/draw/quad_00_001_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_002_ctrl.png b/src/libged/tests/draw/quad_00_002_ctrl.png new file mode 100644 index 00000000000..d01bd3f43e2 Binary files /dev/null and b/src/libged/tests/draw/quad_00_002_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_003_ctrl.png b/src/libged/tests/draw/quad_00_003_ctrl.png new file mode 100644 index 00000000000..6a2f8ad5ccb Binary files /dev/null and b/src/libged/tests/draw/quad_00_003_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_004_ctrl.png b/src/libged/tests/draw/quad_00_004_ctrl.png new file mode 100644 index 00000000000..eae0023730f Binary files /dev/null and b/src/libged/tests/draw/quad_00_004_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_005_ctrl.png b/src/libged/tests/draw/quad_00_005_ctrl.png new file mode 100644 index 00000000000..3cca67fa63f Binary files /dev/null and b/src/libged/tests/draw/quad_00_005_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_006_ctrl.png b/src/libged/tests/draw/quad_00_006_ctrl.png new file mode 100644 index 00000000000..3f58405f861 Binary files /dev/null and b/src/libged/tests/draw/quad_00_006_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_007_ctrl.png b/src/libged/tests/draw/quad_00_007_ctrl.png new file mode 100644 index 00000000000..cf24b7941ae Binary files /dev/null and b/src/libged/tests/draw/quad_00_007_ctrl.png differ diff --git a/src/libged/tests/draw/quad_00_008_ctrl.png b/src/libged/tests/draw/quad_00_008_ctrl.png new file mode 100644 index 00000000000..09fb25f8874 Binary files /dev/null and b/src/libged/tests/draw/quad_00_008_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_001_ctrl.png b/src/libged/tests/draw/quad_01_001_ctrl.png new file mode 100644 index 00000000000..2dec71a1201 Binary files /dev/null and b/src/libged/tests/draw/quad_01_001_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_002_ctrl.png b/src/libged/tests/draw/quad_01_002_ctrl.png new file mode 100644 index 00000000000..31e168ad587 Binary files /dev/null and b/src/libged/tests/draw/quad_01_002_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_003_ctrl.png b/src/libged/tests/draw/quad_01_003_ctrl.png new file mode 100644 index 00000000000..31e168ad587 Binary files /dev/null and b/src/libged/tests/draw/quad_01_003_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_004_ctrl.png b/src/libged/tests/draw/quad_01_004_ctrl.png new file mode 100644 index 00000000000..26498bc96fe Binary files /dev/null and b/src/libged/tests/draw/quad_01_004_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_005_ctrl.png b/src/libged/tests/draw/quad_01_005_ctrl.png new file mode 100644 index 00000000000..3babb8db109 Binary files /dev/null and b/src/libged/tests/draw/quad_01_005_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_006_ctrl.png b/src/libged/tests/draw/quad_01_006_ctrl.png new file mode 100644 index 00000000000..1ebcf6e7308 Binary files /dev/null and b/src/libged/tests/draw/quad_01_006_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_007_ctrl.png b/src/libged/tests/draw/quad_01_007_ctrl.png new file mode 100644 index 00000000000..253374c5680 Binary files /dev/null and b/src/libged/tests/draw/quad_01_007_ctrl.png differ diff --git a/src/libged/tests/draw/quad_01_008_ctrl.png b/src/libged/tests/draw/quad_01_008_ctrl.png new file mode 100644 index 00000000000..f76b8bc96a0 Binary files /dev/null and b/src/libged/tests/draw/quad_01_008_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_001_ctrl.png b/src/libged/tests/draw/quad_02_001_ctrl.png new file mode 100644 index 00000000000..0c3254a1ea6 Binary files /dev/null and b/src/libged/tests/draw/quad_02_001_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_002_ctrl.png b/src/libged/tests/draw/quad_02_002_ctrl.png new file mode 100644 index 00000000000..e1d0a2f001e Binary files /dev/null and b/src/libged/tests/draw/quad_02_002_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_003_ctrl.png b/src/libged/tests/draw/quad_02_003_ctrl.png new file mode 100644 index 00000000000..3c6d5168d95 Binary files /dev/null and b/src/libged/tests/draw/quad_02_003_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_004_ctrl.png b/src/libged/tests/draw/quad_02_004_ctrl.png new file mode 100644 index 00000000000..8c228bfe24c Binary files /dev/null and b/src/libged/tests/draw/quad_02_004_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_005_ctrl.png b/src/libged/tests/draw/quad_02_005_ctrl.png new file mode 100644 index 00000000000..d57bec74e0c Binary files /dev/null and b/src/libged/tests/draw/quad_02_005_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_006_ctrl.png b/src/libged/tests/draw/quad_02_006_ctrl.png new file mode 100644 index 00000000000..94c3296f0db Binary files /dev/null and b/src/libged/tests/draw/quad_02_006_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_007_ctrl.png b/src/libged/tests/draw/quad_02_007_ctrl.png new file mode 100644 index 00000000000..a0e12f6a7f6 Binary files /dev/null and b/src/libged/tests/draw/quad_02_007_ctrl.png differ diff --git a/src/libged/tests/draw/quad_02_008_ctrl.png b/src/libged/tests/draw/quad_02_008_ctrl.png new file mode 100644 index 00000000000..127ed5133eb Binary files /dev/null and b/src/libged/tests/draw/quad_02_008_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_001_ctrl.png b/src/libged/tests/draw/quad_03_001_ctrl.png new file mode 100644 index 00000000000..fcfd518081f Binary files /dev/null and b/src/libged/tests/draw/quad_03_001_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_002_ctrl.png b/src/libged/tests/draw/quad_03_002_ctrl.png new file mode 100644 index 00000000000..8511eb1b534 Binary files /dev/null and b/src/libged/tests/draw/quad_03_002_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_003_ctrl.png b/src/libged/tests/draw/quad_03_003_ctrl.png new file mode 100644 index 00000000000..f27b374abba Binary files /dev/null and b/src/libged/tests/draw/quad_03_003_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_004_ctrl.png b/src/libged/tests/draw/quad_03_004_ctrl.png new file mode 100644 index 00000000000..fe3c38f13ec Binary files /dev/null and b/src/libged/tests/draw/quad_03_004_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_005_ctrl.png b/src/libged/tests/draw/quad_03_005_ctrl.png new file mode 100644 index 00000000000..d41dd78e53f Binary files /dev/null and b/src/libged/tests/draw/quad_03_005_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_006_ctrl.png b/src/libged/tests/draw/quad_03_006_ctrl.png new file mode 100644 index 00000000000..190361dbd46 Binary files /dev/null and b/src/libged/tests/draw/quad_03_006_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_007_ctrl.png b/src/libged/tests/draw/quad_03_007_ctrl.png new file mode 100644 index 00000000000..2a062ba31ea Binary files /dev/null and b/src/libged/tests/draw/quad_03_007_ctrl.png differ diff --git a/src/libged/tests/draw/quad_03_008_ctrl.png b/src/libged/tests/draw/quad_03_008_ctrl.png new file mode 100644 index 00000000000..bfb21327826 Binary files /dev/null and b/src/libged/tests/draw/quad_03_008_ctrl.png differ diff --git a/src/libged/tests/draw/rook.g b/src/libged/tests/draw/rook.g new file mode 100644 index 00000000000..a83e039109a Binary files /dev/null and b/src/libged/tests/draw/rook.g differ diff --git a/src/libged/tests/draw/select.cpp b/src/libged/tests/draw/select.cpp new file mode 100644 index 00000000000..7fd87a7b7ee --- /dev/null +++ b/src/libged/tests/draw/select.cpp @@ -0,0 +1,760 @@ +/* S E L E C T . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file select.cpp + * + * Testing routines for selection logic, with a focus on verifying + * drawing response + * + */ + +#include "common.h" + +#include +#include + +#include +#define DM_WITH_RT +#include +#include + +extern "C" void ged_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data); +extern "C" void dm_refresh(struct ged *gedp); +extern "C" void scene_clear(struct ged *gedp); +extern "C" void img_cmp(int id, struct ged *gedp, const char *cdir, bool clear_scene, bool clear_image, int soft_fail, int approximate_check, const char *clear_root, const char *img_root); + +int +main(int ac, char *av[]) { + struct ged *dbp; + struct bu_vls fname = BU_VLS_INIT_ZERO; + int need_help = 0; + int run_unstable_tests = 0; + int soft_fail = 0; + int keep_images = 0; + + bu_setprogname(av[0]); + + struct bu_opt_desc d[5]; + BU_OPT(d[0], "h", "help", "", NULL, &need_help, "Print help and exit"); + BU_OPT(d[1], "U", "enable-unstable", "", NULL, &run_unstable_tests, "Test drawing routines known to differ between build configs/platforms."); + BU_OPT(d[2], "c", "continue", "", NULL, &soft_fail, "Continue testing if a failure is encountered."); + BU_OPT(d[3], "k", "keep", "", NULL, &keep_images, "Keep images generated by the run."); + BU_OPT_NULL(d[4]); + + /* Done with program name */ + int uac = bu_opt_parse(NULL, ac, (const char **)av, d); + if (uac == -1 || need_help) + + if (ac != 2) + bu_exit(EXIT_FAILURE, "%s [-h] [-U] ", av[0]); + + if (!bu_file_directory(av[1])) { + printf("ERROR: [%s] is not a directory. Expecting control image directory\n", av[1]); + return 2; + } + + bool clear_images = !keep_images; + + /* Enable all the experimental logic */ + bu_setenv("LIBRT_USE_COMB_INSTANCE_SPECIFIERS", "1", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + bu_setenv("LIBGED_DBI_STATE", "1", 1); + + if (!bu_file_exists(av[1], NULL)) { + printf("ERROR: [%s] does not exist, expecting .g file\n", av[1]); + return 2; + } + + /* FIXME: To draw, we need to init this LIBRT global */ + BU_LIST_INIT(&RTG.rtg_vlfree); + + /* We are going to generate geometry from the basic moss data, + * so we make a temporary copy */ + bu_vls_sprintf(&fname, "%s/moss.g", av[1]); + std::ifstream orig(bu_vls_cstr(&fname), std::ios::binary); + std::ofstream tmpg("moss_select_tmp.g", std::ios::binary); + tmpg << orig.rdbuf(); + orig.close(); + tmpg.close(); + + /* Open the temp file */ + const char *s_av[15] = {NULL}; + dbp = ged_open("db", "moss_select_tmp.g", 1); + + // Set callback so database changes will update dbi_state + db_add_changed_clbk(dbp->dbip, &ged_changed_callback, (void *)dbp); + + // Set up a basic view and set view name + BU_ALLOC(dbp->ged_gvp, struct bview); + bv_init(dbp->ged_gvp, &dbp->ged_views); + bv_set_add_view(&dbp->ged_views, dbp->ged_gvp); + bu_ptbl_ins(&dbp->ged_free_views, (long *)dbp->ged_gvp); + bu_vls_sprintf(&dbp->ged_gvp->gv_name, "default"); + + /* To generate images that will allow us to check if the drawing + * is proceeding as expected, we use the swrast off-screen dm. */ + s_av[0] = "dm"; + s_av[1] = "attach"; + s_av[2] = "swrast"; + s_av[3] = "SW"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + struct bview *v = dbp->ged_gvp; + struct dm *dmp = (struct dm *)v->dmp; + dm_set_width(dmp, 512); + dm_set_height(dmp, 512); + + dm_configure_win(dmp, 0); + dm_set_zbuffer(dmp, 1); + + // See QtSW.cpp... + fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; + dm_set_win_bounds(dmp, windowbounds); + + dm_set_vp(dmp, &v->gv_scale); + v->dmp = dmp; + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + v->gv_base2local = dbp->dbip->dbi_base2local; + v->gv_local2base = dbp->dbip->dbi_local2base; + + s_av[0] = "ae"; + s_av[1] = "35"; + s_av[2] = "25"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + /***** Basic CSG wireframe ****/ + bu_log("Sanity - basic wireframe, no selection...\n"); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(1, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + bu_log("Done.\n"); + + bu_log("Selecting a single object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(2, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("De-selected object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(1, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select higher level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(2, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select object below selected object (should be no-op)...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(2, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select second object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/box.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(3, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Select top level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(4, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Expand selection list to solid objects...\n"); + s_av[0] = "select"; + s_av[1] = "expand"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(4, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("De-select one object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(5, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Collapse selected paths...\n"); + s_av[0] = "select"; + s_av[1] = "collapse"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(5, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Check correct highlighting after Z, selection change and redraw...\n"); + + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/box.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(6, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Check correct highlighting after clear...\n"); + + s_av[0] = "select"; + s_av[1] = "clear"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(1, dbp, av[1], true, clear_images, soft_fail, 0, "select_clear", "select"); + + /***** Basic Mesh wireframe, no LoD ****/ + + /* Generate mesh geometry */ + s_av[0] = "tol"; + s_av[1] = "rel"; + s_av[2] = "0.0001"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "facetize"; + s_av[1] = "-r"; + s_av[2] = "all.g"; + s_av[3] = "all.bot"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + dbp->dbi_state->update(); + + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "0"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(7, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + bu_log("Done.\n"); + + bu_log("Selecting a single object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(8, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("De-selected object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(7, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select higher level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(8, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select object below selected object (should be no-op)...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(8, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select second object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/box.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(9, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Select top level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(10, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Expand selection list to solid objects...\n"); + s_av[0] = "select"; + s_av[1] = "expand"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(10, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("De-select one object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(11, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Collapse selected paths...\n"); + s_av[0] = "select"; + s_av[1] = "collapse"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(11, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Check correct highlighting after Z, selection change and redraw...\n"); + + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/box.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(12, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Check correct highlighting after clear...\n"); + + s_av[0] = "select"; + s_av[1] = "clear"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(7, dbp, av[1], true, clear_images, soft_fail, 0, "select_clear", "select"); + + + /***** LoD CSG wireframe ****/ + s_av[0] = "tol"; + s_av[1] = "rel"; + s_av[2] = "0.01"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + bu_log("Sanity - basic LoD wireframe, no selection...\n"); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "csg"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(13, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + bu_log("Done.\n"); + + bu_log("Selecting a single object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(14, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("De-selected object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(13, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select higher level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(14, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select object below selected object (should be no-op)...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(14, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Select second object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g/box.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(15, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Select top level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(16, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Expand selection list to solid objects...\n"); + s_av[0] = "select"; + s_av[1] = "expand"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(16, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("De-select one object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/tor.r/tor"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(17, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Collapse selected paths...\n"); + s_av[0] = "select"; + s_av[1] = "collapse"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(17, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + + bu_log("Check correct highlighting after Z, selection change and redraw...\n"); + + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.g/box.r"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m0"; + s_av[2] = "all.g"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(18, dbp, av[1], false, clear_images, soft_fail, 0, "select_clear", "select"); + + bu_log("Check correct highlighting after clear...\n"); + + s_av[0] = "select"; + s_av[1] = "clear"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(13, dbp, av[1], true, clear_images, soft_fail, 0, "select_clear", "select"); + + /***** LoD Mesh wireframe ****/ + + // Temporary - remove when above CSG tests can be enabled + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "mesh"; + s_av[3] = "1"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "view"; + s_av[1] = "lod"; + s_av[2] = "scale"; + s_av[3] = "0.8"; + s_av[4] = NULL; + ged_exec(dbp, 4, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(19, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + bu_log("Done.\n"); + + bu_log("Selecting a single object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(20, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("De-selected object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(19, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Select higher level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(20, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Select object below selected object (should be no-op)...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(20, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Select second object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot/all.g-1/box.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(21, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + bu_log("Select top level object...\n"); + s_av[0] = "select"; + s_av[1] = "add"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(22, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Expand selection list to solid objects...\n"); + s_av[0] = "select"; + s_av[1] = "expand"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(22, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + bu_log("De-select one object...\n"); + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/tor.r-1/tor.r.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + img_cmp(23, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Collapse selected paths...\n"); + s_av[0] = "select"; + s_av[1] = "collapse"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(23, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + + bu_log("Check correct highlighting after Z, selection change and redraw...\n"); + + s_av[0] = "Z"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + s_av[0] = "select"; + s_av[1] = "rm"; + s_av[2] = "all.bot/all.g-1/box.r-1"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "draw"; + s_av[1] = "-m1"; + s_av[2] = "all.bot"; + s_av[3] = NULL; + ged_exec(dbp, 3, s_av); + + s_av[0] = "autoview"; + s_av[1] = NULL; + ged_exec(dbp, 1, s_av); + + img_cmp(24, dbp, av[1], false, clear_images, soft_fail, 10, "select_clear", "select"); + + bu_log("Check correct highlighting after clear...\n"); + + s_av[0] = "select"; + s_av[1] = "clear"; + s_av[2] = NULL; + ged_exec(dbp, 2, s_av); + + img_cmp(19, dbp, av[1], true, clear_images, soft_fail, 10, "select_clear", "select"); + + + ged_close(dbp); + + return 0; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/select001_ctrl.png b/src/libged/tests/draw/select001_ctrl.png new file mode 100644 index 00000000000..65f7c41603c Binary files /dev/null and b/src/libged/tests/draw/select001_ctrl.png differ diff --git a/src/libged/tests/draw/select002_ctrl.png b/src/libged/tests/draw/select002_ctrl.png new file mode 100644 index 00000000000..4c90455060d Binary files /dev/null and b/src/libged/tests/draw/select002_ctrl.png differ diff --git a/src/libged/tests/draw/select003_ctrl.png b/src/libged/tests/draw/select003_ctrl.png new file mode 100644 index 00000000000..59dc112e387 Binary files /dev/null and b/src/libged/tests/draw/select003_ctrl.png differ diff --git a/src/libged/tests/draw/select004_ctrl.png b/src/libged/tests/draw/select004_ctrl.png new file mode 100644 index 00000000000..103fa9c414d Binary files /dev/null and b/src/libged/tests/draw/select004_ctrl.png differ diff --git a/src/libged/tests/draw/select005_ctrl.png b/src/libged/tests/draw/select005_ctrl.png new file mode 100644 index 00000000000..93648cb033c Binary files /dev/null and b/src/libged/tests/draw/select005_ctrl.png differ diff --git a/src/libged/tests/draw/select006_ctrl.png b/src/libged/tests/draw/select006_ctrl.png new file mode 100644 index 00000000000..ee53d100006 Binary files /dev/null and b/src/libged/tests/draw/select006_ctrl.png differ diff --git a/src/libged/tests/draw/select007_ctrl.png b/src/libged/tests/draw/select007_ctrl.png new file mode 100644 index 00000000000..44a9ec05fe5 Binary files /dev/null and b/src/libged/tests/draw/select007_ctrl.png differ diff --git a/src/libged/tests/draw/select008_ctrl.png b/src/libged/tests/draw/select008_ctrl.png new file mode 100644 index 00000000000..8445a0c31df Binary files /dev/null and b/src/libged/tests/draw/select008_ctrl.png differ diff --git a/src/libged/tests/draw/select009_ctrl.png b/src/libged/tests/draw/select009_ctrl.png new file mode 100644 index 00000000000..800a712ad7c Binary files /dev/null and b/src/libged/tests/draw/select009_ctrl.png differ diff --git a/src/libged/tests/draw/select010_ctrl.png b/src/libged/tests/draw/select010_ctrl.png new file mode 100644 index 00000000000..4efd82e5c86 Binary files /dev/null and b/src/libged/tests/draw/select010_ctrl.png differ diff --git a/src/libged/tests/draw/select011_ctrl.png b/src/libged/tests/draw/select011_ctrl.png new file mode 100644 index 00000000000..a0dcf933458 Binary files /dev/null and b/src/libged/tests/draw/select011_ctrl.png differ diff --git a/src/libged/tests/draw/select012_ctrl.png b/src/libged/tests/draw/select012_ctrl.png new file mode 100644 index 00000000000..f89e8b7b9fb Binary files /dev/null and b/src/libged/tests/draw/select012_ctrl.png differ diff --git a/src/libged/tests/draw/select013_ctrl.png b/src/libged/tests/draw/select013_ctrl.png new file mode 100644 index 00000000000..095ede1db5b Binary files /dev/null and b/src/libged/tests/draw/select013_ctrl.png differ diff --git a/src/libged/tests/draw/select014_ctrl.png b/src/libged/tests/draw/select014_ctrl.png new file mode 100644 index 00000000000..21185d7f507 Binary files /dev/null and b/src/libged/tests/draw/select014_ctrl.png differ diff --git a/src/libged/tests/draw/select015_ctrl.png b/src/libged/tests/draw/select015_ctrl.png new file mode 100644 index 00000000000..17662331b13 Binary files /dev/null and b/src/libged/tests/draw/select015_ctrl.png differ diff --git a/src/libged/tests/draw/select016_ctrl.png b/src/libged/tests/draw/select016_ctrl.png new file mode 100644 index 00000000000..ab127b11265 Binary files /dev/null and b/src/libged/tests/draw/select016_ctrl.png differ diff --git a/src/libged/tests/draw/select017_ctrl.png b/src/libged/tests/draw/select017_ctrl.png new file mode 100644 index 00000000000..9074f75a41c Binary files /dev/null and b/src/libged/tests/draw/select017_ctrl.png differ diff --git a/src/libged/tests/draw/select018_ctrl.png b/src/libged/tests/draw/select018_ctrl.png new file mode 100644 index 00000000000..821debd24be Binary files /dev/null and b/src/libged/tests/draw/select018_ctrl.png differ diff --git a/src/libged/tests/draw/select019_ctrl.png b/src/libged/tests/draw/select019_ctrl.png new file mode 100644 index 00000000000..73303700541 Binary files /dev/null and b/src/libged/tests/draw/select019_ctrl.png differ diff --git a/src/libged/tests/draw/select020_ctrl.png b/src/libged/tests/draw/select020_ctrl.png new file mode 100644 index 00000000000..0f612b7906a Binary files /dev/null and b/src/libged/tests/draw/select020_ctrl.png differ diff --git a/src/libged/tests/draw/select021_ctrl.png b/src/libged/tests/draw/select021_ctrl.png new file mode 100644 index 00000000000..fe04dd40ffb Binary files /dev/null and b/src/libged/tests/draw/select021_ctrl.png differ diff --git a/src/libged/tests/draw/select022_ctrl.png b/src/libged/tests/draw/select022_ctrl.png new file mode 100644 index 00000000000..da98033d4d3 Binary files /dev/null and b/src/libged/tests/draw/select022_ctrl.png differ diff --git a/src/libged/tests/draw/select023_ctrl.png b/src/libged/tests/draw/select023_ctrl.png new file mode 100644 index 00000000000..f32a29d0d91 Binary files /dev/null and b/src/libged/tests/draw/select023_ctrl.png differ diff --git a/src/libged/tests/draw/select024_ctrl.png b/src/libged/tests/draw/select024_ctrl.png new file mode 100644 index 00000000000..a63809dd7ec Binary files /dev/null and b/src/libged/tests/draw/select024_ctrl.png differ diff --git a/src/libged/tests/draw/util.cpp b/src/libged/tests/draw/util.cpp new file mode 100644 index 00000000000..39ecbf77120 --- /dev/null +++ b/src/libged/tests/draw/util.cpp @@ -0,0 +1,248 @@ +/* U T I L . C P P + * BRL-CAD + * + * Copyright (c) 2018-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file util.cpp + * + * Utility testing for drawing routines + * + */ + +#include "common.h" + +#include +#include +#include + +#define XXH_STATIC_LINKING_ONLY +#define XXH_IMPLEMENTATION +#include "xxhash.h" + +#include +#include +#include +#define DM_WITH_RT +#include +#include + +// In order to handle changes to .g geometry contents, we need to defined +// callbacks for the librt hooks that will update the working data structures. +// In Qt we have libqtcad handle this, but as we are not using a QgModel we +// need to do it ourselves. +extern "C" void +ged_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data) +{ + XXH64_state_t h_state; + unsigned long long hash; + struct ged *gedp = (struct ged *)u_data; + DbiState *ctx = gedp->dbi_state; + + // Clear cached GED drawing data and update + ctx->clear_cache(dp); + + // Need to invalidate any LoD caches associated with this dp + if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && ctx->gedp) { + unsigned long long key = bv_mesh_lod_key_get(ctx->gedp->ged_lod, dp->d_namep); + if (key) { + bv_mesh_lod_clear_cache(ctx->gedp->ged_lod, key); + bv_mesh_lod_key_put(ctx->gedp->ged_lod, dp->d_namep, 0); + } + } + + switch(mode) { + case 0: + ctx->changed.insert(dp); + break; + case 1: + ctx->added.insert(dp); + break; + case 2: + // When this callback is made, dp is still valid, but in subsequent + // processing it will not be. We need to capture everything we + // will need from this dp now, for later use when updating state + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + hash = (unsigned long long)XXH64_digest(&h_state); + ctx->removed.insert(hash); + ctx->old_names[hash] = std::string(dp->d_namep); + break; + default: + bu_log("changed callback mode error: %d\n", mode); + } +} + +extern "C" void +dm_refresh(struct ged *gedp) +{ + struct bview *v= gedp->ged_gvp; + BViewState *bvs = gedp->dbi_state->get_view_state(v); + gedp->dbi_state->update(); + std::unordered_set uset; + uset.insert(v); + bvs->redraw(NULL, uset, 1); + + struct dm *dmp = (struct dm *)v->dmp; + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + dm_set_dirty(dmp, 0); + dm_draw_objs(v, NULL, NULL); + dm_draw_end(dmp); +} + +extern "C" void +scene_clear(struct ged *gedp) +{ + const char *s_av[2] = {NULL}; + s_av[0] = "Z"; + ged_exec(gedp, 1, s_av); + dm_refresh(gedp); +} + +extern "C" void +img_cmp(int id, struct ged *gedp, const char *cdir, bool clear_scene, bool clear_image, int soft_fail, int approximate_check, const char *clear_root, const char *img_root) +{ + icv_image_t *ctrl, *timg; + struct bu_vls tname = BU_VLS_INIT_ZERO; + struct bu_vls cname = BU_VLS_INIT_ZERO; + if (id <= 0) { + bu_vls_sprintf(&tname, "%s.png", clear_root); + bu_vls_sprintf(&cname, "%s/empty.png", cdir); + } else { + bu_vls_sprintf(&tname, "%s%03d.png", img_root, id); + bu_vls_sprintf(&cname, "%s/%s%03d_ctrl.png", cdir, img_root, id); + } + + dm_refresh(gedp); + const char *s_av[2] = {NULL}; + s_av[0] = "screengrab"; + s_av[1] = bu_vls_cstr(&tname); + ged_exec(gedp, 2, s_av); + + timg = icv_read(bu_vls_cstr(&tname), BU_MIME_IMAGE_PNG, 0, 0); + if (!timg) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&tname)); + if (clear_scene) + scene_clear(gedp); + bu_vls_free(&tname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&tname)); + } + ctrl = icv_read(bu_vls_cstr(&cname), BU_MIME_IMAGE_PNG, 0, 0); + if (!ctrl) { + if (soft_fail) { + bu_log("Failed to read %s\n", bu_vls_cstr(&cname)); + if (clear_scene) + scene_clear(gedp); + bu_vls_free(&tname); + bu_vls_free(&cname); + return; + } + bu_exit(EXIT_FAILURE, "failed to read %s\n", bu_vls_cstr(&cname)); + } + bu_vls_free(&cname); + int matching_cnt = 0; + int off_by_1_cnt = 0; + int off_by_many_cnt = 0; + int iret = icv_diff(&matching_cnt, &off_by_1_cnt, &off_by_many_cnt, ctrl, timg); + if (iret) { + if (approximate_check) { + // First, if we're allowing approximate and all we have are off by one errors, + // allow it. + if (!off_by_many_cnt) { + bu_log("%d approximate matching enabled, no off by many - passing. %d matching, %d off by 1\n", id, matching_cnt, off_by_1_cnt); + iret = 0; + // We don't need it as a pass/fail, but for information report the + // Hamming distance on the approximate match + uint32_t pret = icv_pdiff(ctrl, timg); + bu_log("icv_pdiff Hamming distance(%d): %" PRIu32 "\n", id, pret); + } else { + // We have off by many - do perceptual hashing difference calculation + uint32_t pret = icv_pdiff(ctrl, timg); + // The return is a Hamming distance . The scale of possible + // returns ranges from 0 (same) to ~500 (completely different) + bu_log("icv_pdiff Hamming distance(%d): %" PRIu32 "\n", id, pret); + if (pret < (uint32_t)approximate_check) { + iret = 0; + } + } + } + + if (iret) { + if (soft_fail) { + bu_log("%d %s diff failed. %d matching, %d off by 1, %d off by many\n", id, img_root, matching_cnt, off_by_1_cnt, off_by_many_cnt); + + if (clear_image) { + // We're in soft fail mode, so we're not keeping the image unless the user requested it + // In hard fail, we leave the last image for inspection. + bu_file_delete(bu_vls_cstr(&tname)); + } else { + // Keeping the image - also generate a diff image for debugging work + struct bu_vls diff_name = BU_VLS_INIT_ZERO; + icv_image_t *diff_img = icv_diffimg(ctrl, timg); + if (diff_img) { + bu_vls_sprintf(&diff_name, "%s_%d_diff.png", img_root, id); + icv_write(diff_img, bu_vls_cstr(&diff_name), BU_MIME_IMAGE_PNG); + } + + } + + icv_destroy(ctrl); + icv_destroy(timg); + + if (clear_scene) + scene_clear(gedp); + return; + } else { + // Hard fail - generate a diff image for debugging work + struct bu_vls diff_name = BU_VLS_INIT_ZERO; + icv_image_t *diff_img = icv_diffimg(ctrl, timg); + if (diff_img) { + bu_vls_sprintf(&diff_name, "%s_%d_diff.png", img_root, id); + icv_write(diff_img, bu_vls_cstr(&diff_name), BU_MIME_IMAGE_PNG); + } + icv_destroy(ctrl); + icv_destroy(timg); + } + bu_exit(EXIT_FAILURE, "%d %s diff failed. %d matching, %d off by 1, %d off by many\n", id, img_root, matching_cnt, off_by_1_cnt, off_by_many_cnt); + } + } + + if (clear_image) + bu_file_delete(bu_vls_cstr(&tname)); + + bu_vls_free(&tname); + icv_destroy(ctrl); + icv_destroy(timg); + + if (clear_scene) + scene_clear(gedp); +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libged/tests/draw/v001_ctrl.png b/src/libged/tests/draw/v001_ctrl.png new file mode 100644 index 00000000000..65f7c41603c Binary files /dev/null and b/src/libged/tests/draw/v001_ctrl.png differ diff --git a/src/libged/tests/draw/v002_ctrl.png b/src/libged/tests/draw/v002_ctrl.png new file mode 100644 index 00000000000..6a2f8ad5ccb Binary files /dev/null and b/src/libged/tests/draw/v002_ctrl.png differ diff --git a/src/libged/tests/draw/v003_ctrl.png b/src/libged/tests/draw/v003_ctrl.png new file mode 100644 index 00000000000..23fac732015 Binary files /dev/null and b/src/libged/tests/draw/v003_ctrl.png differ diff --git a/src/libged/tests/draw/v004_ctrl.png b/src/libged/tests/draw/v004_ctrl.png new file mode 100644 index 00000000000..e9a85f19dde Binary files /dev/null and b/src/libged/tests/draw/v004_ctrl.png differ diff --git a/src/libged/tests/draw/v005_ctrl.png b/src/libged/tests/draw/v005_ctrl.png new file mode 100644 index 00000000000..be5aa3b6763 Binary files /dev/null and b/src/libged/tests/draw/v005_ctrl.png differ diff --git a/src/libged/tests/draw/v006_ctrl.png b/src/libged/tests/draw/v006_ctrl.png new file mode 100644 index 00000000000..01db062bf3a Binary files /dev/null and b/src/libged/tests/draw/v006_ctrl.png differ diff --git a/src/libged/tests/draw/v007_ctrl.png b/src/libged/tests/draw/v007_ctrl.png new file mode 100644 index 00000000000..a9d119870ae Binary files /dev/null and b/src/libged/tests/draw/v007_ctrl.png differ diff --git a/src/libged/tests/draw/v008_ctrl.png b/src/libged/tests/draw/v008_ctrl.png new file mode 100644 index 00000000000..c08c256a021 Binary files /dev/null and b/src/libged/tests/draw/v008_ctrl.png differ diff --git a/src/libged/tests/draw/v009_ctrl.png b/src/libged/tests/draw/v009_ctrl.png new file mode 100644 index 00000000000..61912014e3d Binary files /dev/null and b/src/libged/tests/draw/v009_ctrl.png differ diff --git a/src/libged/tests/draw/v010_ctrl.png b/src/libged/tests/draw/v010_ctrl.png new file mode 100644 index 00000000000..c8856308207 Binary files /dev/null and b/src/libged/tests/draw/v010_ctrl.png differ diff --git a/src/libged/tests/draw/v011_ctrl.png b/src/libged/tests/draw/v011_ctrl.png new file mode 100644 index 00000000000..458c4c08fc9 Binary files /dev/null and b/src/libged/tests/draw/v011_ctrl.png differ diff --git a/src/libged/tests/draw/v012_ctrl.png b/src/libged/tests/draw/v012_ctrl.png new file mode 100644 index 00000000000..fe22bf04b0a Binary files /dev/null and b/src/libged/tests/draw/v012_ctrl.png differ diff --git a/src/libged/tests/draw/v013_ctrl.png b/src/libged/tests/draw/v013_ctrl.png new file mode 100644 index 00000000000..f1594fc94b5 Binary files /dev/null and b/src/libged/tests/draw/v013_ctrl.png differ diff --git a/src/libged/tests/draw/v014_ctrl.png b/src/libged/tests/draw/v014_ctrl.png new file mode 100644 index 00000000000..0824dd07d73 Binary files /dev/null and b/src/libged/tests/draw/v014_ctrl.png differ diff --git a/src/libged/tests/draw/v015_ctrl.png b/src/libged/tests/draw/v015_ctrl.png new file mode 100644 index 00000000000..49c0d528544 Binary files /dev/null and b/src/libged/tests/draw/v015_ctrl.png differ diff --git a/src/libged/tests/draw/v016_ctrl.png b/src/libged/tests/draw/v016_ctrl.png new file mode 100644 index 00000000000..7dadddecdcf Binary files /dev/null and b/src/libged/tests/draw/v016_ctrl.png differ diff --git a/src/libged/tests/draw/v017_ctrl.png b/src/libged/tests/draw/v017_ctrl.png new file mode 100644 index 00000000000..ce400b81441 Binary files /dev/null and b/src/libged/tests/draw/v017_ctrl.png differ diff --git a/src/libged/tests/draw/v018_ctrl.png b/src/libged/tests/draw/v018_ctrl.png new file mode 100644 index 00000000000..4fb834b5c53 Binary files /dev/null and b/src/libged/tests/draw/v018_ctrl.png differ diff --git a/src/libged/tests/draw/v019_ctrl.png b/src/libged/tests/draw/v019_ctrl.png new file mode 100644 index 00000000000..0e63ae9ace7 Binary files /dev/null and b/src/libged/tests/draw/v019_ctrl.png differ diff --git a/src/libged/tests/draw/v020_ctrl.png b/src/libged/tests/draw/v020_ctrl.png new file mode 100644 index 00000000000..cdb93faa03c Binary files /dev/null and b/src/libged/tests/draw/v020_ctrl.png differ diff --git a/src/libged/tests/draw/v021_ctrl.png b/src/libged/tests/draw/v021_ctrl.png new file mode 100644 index 00000000000..aa69e454e87 Binary files /dev/null and b/src/libged/tests/draw/v021_ctrl.png differ diff --git a/src/libged/tests/draw/v022_ctrl.png b/src/libged/tests/draw/v022_ctrl.png new file mode 100644 index 00000000000..32786bf2f03 Binary files /dev/null and b/src/libged/tests/draw/v022_ctrl.png differ diff --git a/src/libged/tests/draw/v023_ctrl.png b/src/libged/tests/draw/v023_ctrl.png new file mode 100644 index 00000000000..4573f82a59d Binary files /dev/null and b/src/libged/tests/draw/v023_ctrl.png differ diff --git a/src/libged/tests/draw/v024_ctrl.png b/src/libged/tests/draw/v024_ctrl.png new file mode 100644 index 00000000000..bc6af8e2c5d Binary files /dev/null and b/src/libged/tests/draw/v024_ctrl.png differ diff --git a/src/libged/tests/draw/v025_ctrl.png b/src/libged/tests/draw/v025_ctrl.png new file mode 100644 index 00000000000..7d19a137925 Binary files /dev/null and b/src/libged/tests/draw/v025_ctrl.png differ diff --git a/src/libged/tests/draw/v026_ctrl.png b/src/libged/tests/draw/v026_ctrl.png new file mode 100644 index 00000000000..2768a2a2ec3 Binary files /dev/null and b/src/libged/tests/draw/v026_ctrl.png differ diff --git a/src/libged/tests/test_select.c b/src/libged/tests/test_select.c index 59f965122c0..cd5dee64e00 100644 --- a/src/libged/tests/test_select.c +++ b/src/libged/tests/test_select.c @@ -53,7 +53,7 @@ main(int ac, char *av[]) { s_av[0] = "select"; s_av[1] = "list"; ged_exec(dbp, 2, s_av); - printf("sets: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("sets:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[0] = "select"; s_av[1] = "add"; @@ -74,17 +74,18 @@ main(int ac, char *av[]) { s_av[1] = "list"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("init: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("init:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[1] = "expand"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); + printf("expand:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[1] = "list"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("expand: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("list post expand:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[1] = "clear"; s_av[2] = "default"; @@ -93,7 +94,7 @@ main(int ac, char *av[]) { s_av[1] = "list"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("clear: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("clear:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[1] = "add"; @@ -113,17 +114,58 @@ main(int ac, char *av[]) { s_av[1] = "list"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("re-init: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("re-init:\n%s\n", bu_vls_addr(dbp->ged_result_str)); s_av[1] = "collapse"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("%s\n", bu_vls_addr(dbp->ged_result_str)); + printf("collapse:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "expand"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + printf("expand:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "collapse"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + printf("collapse after expand:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "clear"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + + s_av[1] = "add"; + s_av[2] = "all.g/platform.r"; + ged_exec(dbp, 3, s_av); + s_av[2] = "all.g/box.r/box.s"; + ged_exec(dbp, 3, s_av); + s_av[2] = "all.g/ellipse.r"; + ged_exec(dbp, 3, s_av); + s_av[2] = "all.g/tor.r"; + ged_exec(dbp, 3, s_av); + s_av[2] = "all.g/light.r"; + ged_exec(dbp, 3, s_av); s_av[1] = "list"; s_av[2] = "default"; ged_exec(dbp, 3, s_av); - printf("collapse: %s\n", bu_vls_addr(dbp->ged_result_str)); + printf("partial-init:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "collapse"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + printf("collapse after partial init:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "expand"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + printf("expand after partial init collapse:\n%s\n", bu_vls_addr(dbp->ged_result_str)); + + s_av[1] = "collapse"; + s_av[2] = "default"; + ged_exec(dbp, 3, s_av); + printf("collapse after expand:\n%s\n", bu_vls_addr(dbp->ged_result_str)); ged_close(dbp); diff --git a/src/libged/v2m_point/v2m_point.c b/src/libged/v2m_point/v2m_point.c index 5863034410e..886daedb5fe 100644 --- a/src/libged/v2m_point/v2m_point.c +++ b/src/libged/v2m_point/v2m_point.c @@ -39,7 +39,6 @@ ged_v2m_point_core(struct ged *gedp, int argc, const char *argv[]) point_t model; static const char *usage = "x y z"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view/aet.c b/src/libged/view/aet.c index 7ec6caef924..76c56594277 100644 --- a/src/libged/view/aet.c +++ b/src/libged/view/aet.c @@ -39,7 +39,6 @@ ged_aet_core(struct ged *gedp, int argc, const char *argv[]) int iflag = 0; static const char *usage = "[[-i] az el [tw]]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view/axes.c b/src/libged/view/axes.c index 6e210109e4b..ca67a13c494 100644 --- a/src/libged/view/axes.c +++ b/src/libged/view/axes.c @@ -73,9 +73,13 @@ _axes_cmd_create(void *bs, int argc, const char **argv) } } - s = bv_obj_get(gd->cv, BV_VIEW_OBJS); + int flags = BV_VIEW_OBJS; + if (gd->local_obj) + flags |= BV_LOCAL_OBJS; + s = bv_obj_get(gd->cv, flags); + BU_LIST_INIT(&(s->s_vlist)); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); VSET(s->s_color, 255, 255, 0); struct bv_axes *l; @@ -89,8 +93,8 @@ _axes_cmd_create(void *bs, int argc, const char **argv) s->s_type_flags |= BV_VIEWONLY; s->s_type_flags |= BV_AXES; - bu_vls_init(&s->s_uuid); - bu_vls_printf(&s->s_uuid, "%s", gd->vobj); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", gd->vobj); return BRLCAD_OK; } diff --git a/src/libged/view/center.cpp b/src/libged/view/center.cpp index c610cf2df70..b23d2dee547 100644 --- a/src/libged/view/center.cpp +++ b/src/libged/view/center.cpp @@ -43,7 +43,6 @@ ged_center_core(struct ged *gedp, int argc, const char *argv[]) point_t center; static const char *usage = "[-v] | [x y z]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -53,7 +52,8 @@ ged_center_core(struct ged *gedp, int argc, const char *argv[]) /* get view center */ if (argc == 1) { MAT_DELTAS_GET_NEG(center, gedp->ged_gvp->gv_center); - VSCALE(center, center, gedp->dbip->dbi_base2local); + if (gedp->dbip) + VSCALE(center, center, gedp->dbip->dbi_base2local); bn_encode_vect(gedp->ged_result_str, center, 1); return BRLCAD_OK; @@ -62,7 +62,8 @@ ged_center_core(struct ged *gedp, int argc, const char *argv[]) if (argc == 2 && BU_STR_EQUAL(argv[1], "-v")) { std::ostringstream ss; MAT_DELTAS_GET_NEG(center, gedp->ged_gvp->gv_center); - VSCALE(center, center, gedp->dbip->dbi_base2local); + if (gedp->dbip) + VSCALE(center, center, gedp->dbip->dbi_base2local); ss << std::fixed << std::setprecision(std::numeric_limits::max_digits10) << center[X]; ss << " "; ss << std::fixed << std::setprecision(std::numeric_limits::max_digits10) << center[Y]; @@ -143,7 +144,8 @@ ged_center_core(struct ged *gedp, int argc, const char *argv[]) VMOVE(center, scan); } - VSCALE(center, center, gedp->dbip->dbi_local2base); + if (gedp->dbip) + VSCALE(center, center, gedp->dbip->dbi_local2base); MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, center); bv_update(gedp->ged_gvp); diff --git a/src/libged/view/eye.c b/src/libged/view/eye.c index bd443f39d47..da0c672cc19 100644 --- a/src/libged/view/eye.c +++ b/src/libged/view/eye.c @@ -42,7 +42,6 @@ ged_eye_core(struct ged *gedp, int argc, const char *argv[]) vect_t new_cent; static const char *usage = "x y z"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -56,7 +55,8 @@ ged_eye_core(struct ged *gedp, int argc, const char *argv[]) /* calculate eye point */ VSET(xlate, 0.0, 0.0, 1.0); MAT4X3PNT(eye, gedp->ged_gvp->gv_view2model, xlate); - VSCALE(eye, eye, gedp->dbip->dbi_base2local); + if (gedp->dbip) + VSCALE(eye, eye, gedp->dbip->dbi_base2local); bn_encode_vect(gedp->ged_result_str, eye, 1); return BRLCAD_OK; @@ -92,7 +92,8 @@ ged_eye_core(struct ged *gedp, int argc, const char *argv[]) VMOVE(eye_model, scan); } - VSCALE(eye_model, eye_model, gedp->dbip->dbi_local2base); + if (gedp->dbip) + VSCALE(eye_model, eye_model, gedp->dbip->dbi_local2base); /* First step: put eye at view center (view 0, 0, 0) */ MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, eye_model); diff --git a/src/libged/view/faceplate/faceplate.c b/src/libged/view/faceplate/faceplate.c index 6836f79b528..c4e0ecfa7bc 100644 --- a/src/libged/view/faceplate/faceplate.c +++ b/src/libged/view/faceplate/faceplate.c @@ -130,50 +130,6 @@ _fp_cmd_center_dot(void *ds, int argc, const char **argv) return BRLCAD_OK; } -int -_fp_cmd_fps(void *ds, int argc, const char **argv) -{ - const char *usage_string = "faceplate [options] fps [0|1]"; - const char *purpose_string = "Enable/disable frames-per-second"; - if (_fp_cmd_msgs(ds, argc, argv, usage_string, purpose_string)) { - return BRLCAD_OK; - } - - argc--; argv++; - - struct _ged_fp_info *gd = (struct _ged_fp_info *)ds; - struct ged *gedp = gd->gedp; - struct bview *v = gedp->ged_gvp; - - if (!argc) { - if (gd->verbosity) { - bu_vls_printf(gedp->ged_result_str, "%d (%d/%d/%d)", v->gv_s->gv_center_dot.gos_draw, - v->gv_s->gv_center_dot.gos_line_color[0], v->gv_s->gv_center_dot.gos_line_color[1], - v->gv_s->gv_center_dot.gos_line_color[2]); - } else { - bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_center_dot.gos_draw); - } - return BRLCAD_OK; - } - - if (argc == 1) { - if (BU_STR_EQUAL("1", argv[0])) { - v->gv_s->gv_fps = 1; - return BRLCAD_OK; - } - if (BU_STR_EQUAL("0", argv[0])) { - v->gv_s->gv_fps = 0; - return BRLCAD_OK; - } - bu_vls_printf(gedp->ged_result_str, "value %s is invalid - valid values are 0 or 1\n", argv[0]); - return BRLCAD_ERROR; - } - - bu_vls_printf(gedp->ged_result_str, "invalid command\n"); - - return BRLCAD_OK; -} - int _fp_cmd_fb(void *ds, int argc, const char **argv) { @@ -279,8 +235,8 @@ _fp_cmd_scale(void *ds, int argc, const char **argv) int _fp_cmd_params(void *ds, int argc, const char **argv) { - const char *usage_string = "faceplate [options] params [0|1] [color r/g/b]"; - const char *purpose_string = "Enable/disable params and set its color."; + const char *usage_string = "faceplate [options] params [0|1] [size 0/1] [center 0/1] [az 0/1] [el 0/1] [tw 0/1] [fps 0/1] [color r/g/b] [font_size [#]"; + const char *purpose_string = "Enable/disable params and set color/font size."; if (_fp_cmd_msgs(ds, argc, argv, usage_string, purpose_string)) { return BRLCAD_OK; } @@ -293,42 +249,136 @@ _fp_cmd_params(void *ds, int argc, const char **argv) if (!argc) { if (gd->verbosity) { - bu_vls_printf(gedp->ged_result_str, "%d (%d/%d/%d)", v->gv_s->gv_view_params.gos_draw, - v->gv_s->gv_view_params.gos_text_color[0], v->gv_s->gv_view_params.gos_text_color[1], - v->gv_s->gv_view_params.gos_text_color[2]); + bu_vls_printf(gedp->ged_result_str, "%d[%d] (%d/%d/%d) [%d %d %d %d %d %d]", + v->gv_s->gv_view_params.draw, + v->gv_s->gv_view_params.font_size, + V3ARGS(v->gv_s->gv_view_params.color), + v->gv_s->gv_view_params.draw_size, + v->gv_s->gv_view_params.draw_center, + v->gv_s->gv_view_params.draw_az, + v->gv_s->gv_view_params.draw_el, + v->gv_s->gv_view_params.draw_tw, + v->gv_s->gv_view_params.draw_fps + ); } else { - bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.gos_draw); + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw); } return BRLCAD_OK; } if (argc == 1) { if (BU_STR_EQUAL("1", argv[0])) { - v->gv_s->gv_view_params.gos_draw = 1; + v->gv_s->gv_view_params.draw = 1; return BRLCAD_OK; } if (BU_STR_EQUAL("0", argv[0])) { - v->gv_s->gv_view_params.gos_draw = 0; + v->gv_s->gv_view_params.draw = 0; return BRLCAD_OK; } - bu_vls_printf(gedp->ged_result_str, "value %s is invalid - valid values are 0 or 1\n", argv[0]); + if (BU_STR_EQUAL("size", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_size); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("center", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_center); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("az", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_az); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("el", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_el); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("tw", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_tw); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("fps", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.draw_fps); + return BRLCAD_OK; + } + if (BU_STR_EQUAL("font_size", argv[0])) { + bu_vls_printf(gedp->ged_result_str, "%d", v->gv_s->gv_view_params.font_size); + return BRLCAD_OK; + } + bu_vls_printf(gedp->ged_result_str, "input %s is invalid\n", argv[0]); return BRLCAD_ERROR; } if (argc > 1) { - if (!BU_STR_EQUAL("color", argv[0])) { - bu_vls_printf(gedp->ged_result_str, "unknown subcommand %s\n", argv[0]); - return BRLCAD_ERROR; + if (BU_STR_EQUAL("color", argv[0])) { + argc--; argv++; + struct bu_color c; + struct bu_vls msg = BU_VLS_INIT_ZERO; + if (bu_opt_color(&msg, argc, argv, &c) == -1) { + bu_vls_printf(gedp->ged_result_str, "invalid color specification\n"); + } + int *cls = (int *)(v->gv_s->gv_view_params.color); + bu_color_to_rgb_ints(&c, &cls[0], &cls[1], &cls[2]); + return BRLCAD_OK; } - argc--; argv++; - struct bu_color c; - struct bu_vls msg = BU_VLS_INIT_ZERO; - if (bu_opt_color(&msg, argc, argv, &c) == -1) { - bu_vls_printf(gedp->ged_result_str, "invalid color specification\n"); + if (BU_STR_EQUAL("size", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_size = 0; + } else { + v->gv_s->gv_view_params.draw_size = 1; + } + return BRLCAD_OK; } - int *cls = (int *)(v->gv_s->gv_view_params.gos_text_color); - bu_color_to_rgb_ints(&c, &cls[0], &cls[1], &cls[2]); - return BRLCAD_OK; + if (BU_STR_EQUAL("center", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_center = 0; + } else { + v->gv_s->gv_view_params.draw_center = 1; + } + return BRLCAD_OK; + } + if (BU_STR_EQUAL("az", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_az = 0; + } else { + v->gv_s->gv_view_params.draw_az = 1; + } + return BRLCAD_OK; + } + if (BU_STR_EQUAL("el", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_el = 0; + } else { + v->gv_s->gv_view_params.draw_el = 1; + } + return BRLCAD_OK; + } + if (BU_STR_EQUAL("tw", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_tw = 0; + } else { + v->gv_s->gv_view_params.draw_tw = 1; + } + return BRLCAD_OK; + } + if (BU_STR_EQUAL("fps", argv[0])) { + if (BU_STR_EQUAL("0", argv[0])) { + v->gv_s->gv_view_params.draw_fps = 0; + } else { + v->gv_s->gv_view_params.draw_fps = 1; + } + return BRLCAD_OK; + } + if (BU_STR_EQUAL("font_size", argv[0])) { + argc--; argv++; + int fsize; + struct bu_vls msg = BU_VLS_INIT_ZERO; + if (bu_opt_int(&msg, argc, argv, &fsize) == -1) { + bu_vls_printf(gedp->ged_result_str, "invalid font size specification\n"); + } + v->gv_s->gv_view_params.font_size = fsize; + return BRLCAD_OK; + } + bu_vls_printf(gedp->ged_result_str, "unknown subcommand %s\n", argv[0]); + return BRLCAD_ERROR; } bu_vls_printf(gedp->ged_result_str, "invalid command\n"); @@ -338,10 +388,9 @@ _fp_cmd_params(void *ds, int argc, const char **argv) const struct bu_cmdtab _fp_cmds[] = { { "center_dot", _fp_cmd_center_dot}, + { "fb", _fp_cmd_fb}, { "grid", _fp_cmd_grid}, { "irect", _fp_cmd_irect}, - { "fb", _fp_cmd_fb}, - { "fps", _fp_cmd_fps}, { "model_axes", _fp_cmd_model_axes}, { "params", _fp_cmd_params}, { "scale", _fp_cmd_scale}, diff --git a/src/libged/view/ged_view.h b/src/libged/view/ged_view.h index 82227562d0f..128a48d2612 100644 --- a/src/libged/view/ged_view.h +++ b/src/libged/view/ged_view.h @@ -40,6 +40,7 @@ struct _ged_view_info { const char *vobj; struct bview *cv; struct bv_scene_obj *s; + int local_obj; }; extern int _view_cmd_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps); extern int _view_cmd_lines(void *bs, int argc, const char **argv); diff --git a/src/libged/view/gobjs.cpp b/src/libged/view/gobjs.cpp index 00cd54eb4d1..30d3db78e55 100644 --- a/src/libged/view/gobjs.cpp +++ b/src/libged/view/gobjs.cpp @@ -80,15 +80,7 @@ _gobjs_cmd_create(void *bs, int argc, const char **argv) } gd->vobj = argv[0]; - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - if (BU_STR_EQUAL(argv[1], bu_vls_cstr(&s->s_uuid))) { - gd->s = s; - break; - } - } - - struct bv_scene_obj *s = gd->s; + struct bv_scene_obj *s = bv_find_obj(gedp->ged_gvp, argv[1]); if (s) { bu_vls_printf(gedp->ged_result_str, "View object %s already exists\n", argv[1]); return BRLCAD_ERROR; @@ -136,7 +128,6 @@ _gobjs_cmd_create(void *bs, int argc, const char **argv) db_full_path_init((struct db_full_path *)g->s_path); db_dup_full_path((struct db_full_path *)g->s_path, fp); db_path_to_vls(&g->s_name, fp); - bu_vls_sprintf(&g->s_uuid, "%s", argv[1]); g->s_i_data = (void *)ip; g->s_free_callback = &gobjs_scene_free; @@ -166,9 +157,6 @@ _gobjs_cmd_create(void *bs, int argc, const char **argv) // Create a wireframe from the current state of the specified object draw_gather_paths(fp, &mat, (void *)&dd); - // Add to the scene - bu_ptbl_ins(v->gv_objs.view_objs, (long *)g); - // TODO - set the object callbacks // TODO - in principle, we should be sharing a lot of logic with the edit command - @@ -251,26 +239,24 @@ _view_cmd_gobjs(void *bs, int argc, const char **argv) struct bview *v = gd->cv; if (!ac && cmd_pos < 0 && !help) { struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); - // TODO - strip gobjs:: prefix - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_uuid)); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); + } } - - if (view_objs != v->gv_objs.view_objs) { - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - // TODO - strip gobjs:: prefix - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_uuid)); + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (local_view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); } } return BRLCAD_OK; } gd->s = NULL; - // TODO - if independent use gv_objs.view_objs, else use gv_objs.view_shared_objs - // TODO - append gobjs:: prefix - + if (!gd->s) { // View object doesn't already exist. subcommands will either need to create it // or handle the error case diff --git a/src/libged/view/labels.c b/src/libged/view/labels.c index b3c24390812..6fdb2da150d 100644 --- a/src/libged/view/labels.c +++ b/src/libged/view/labels.c @@ -121,10 +121,13 @@ _label_cmd_create(void *bs, int argc, const char **argv) } } - s = bv_obj_get(gd->cv, BV_VIEW_OBJS); + int flags = BV_VIEW_OBJS; + if (gd->local_obj) + flags |= BV_LOCAL_OBJS; + s = bv_obj_get(gd->cv, flags); s->s_v = gd->cv; BU_LIST_INIT(&(s->s_vlist)); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); VSET(s->s_color, 255, 255, 0); struct bv_label *l; @@ -141,8 +144,8 @@ _label_cmd_create(void *bs, int argc, const char **argv) s->s_type_flags |= BV_VIEWONLY; s->s_type_flags |= BV_LABELS; - bu_vls_init(&s->s_uuid); - bu_vls_printf(&s->s_uuid, "%s", gd->vobj); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", gd->vobj); return BRLCAD_OK; } diff --git a/src/libged/view/lines.c b/src/libged/view/lines.c index 92057ec215e..1847358d1a2 100644 --- a/src/libged/view/lines.c +++ b/src/libged/view/lines.c @@ -77,13 +77,17 @@ _line_cmd_create(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - s = bv_obj_get(gd->cv, BV_VIEW_OBJS); + int flags = BV_VIEW_OBJS; + if (gd->local_obj) + flags |= BV_LOCAL_OBJS; + + s = bv_obj_get(gd->cv, flags); BU_LIST_INIT(&(s->s_vlist)); - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p, BV_VLIST_LINE_MOVE); - bu_vls_init(&s->s_uuid); - bu_vls_printf(&s->s_uuid, "%s", gd->vobj); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", gd->vobj); return BRLCAD_OK; } @@ -128,7 +132,7 @@ _line_cmd_append(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - BV_ADD_VLIST(&s->s_v->gv_objs.gv_vlfree, &s->s_vlist, p, BV_VLIST_LINE_DRAW); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p, BV_VLIST_LINE_DRAW); return BRLCAD_OK; } diff --git a/src/libged/view/lod.cpp b/src/libged/view/lod.cpp index 9cff23882ef..b21ebc8c09f 100644 --- a/src/libged/view/lod.cpp +++ b/src/libged/view/lod.cpp @@ -31,7 +31,7 @@ #include "bu/cmd.h" #include "bu/vls.h" -#include "bg/lod.h" +#include "bv/lod.h" #include "../ged_private.h" #include "./ged_view.h" @@ -181,7 +181,7 @@ _view_cmd_lod(void *bs, int argc, const char **argv) struct rt_wdb *wdbp = wdb_dbopen(gedp->dbip, RT_WDB_TYPE_DB_DEFAULT); // Clear any old cache in memory - bg_mesh_lod_clear_cache(gedp->ged_lod, 0); + bv_mesh_lod_clear_cache(gedp->ged_lod, 0); int done = 0; int total = 0; @@ -224,9 +224,9 @@ _view_cmd_lod(void *bs, int argc, const char **argv) bu_vls_free(&pname); struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; RT_BOT_CK_MAGIC(bot); - key = bg_mesh_lod_cache(gedp->ged_lod, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); + key = bv_mesh_lod_cache(gedp->ged_lod, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); if (key) - bg_mesh_lod_key_put(gedp->ged_lod, dp->d_namep, key); + bv_mesh_lod_key_put(gedp->ged_lod, dp->d_namep, key); rt_db_free_internal(&dbintern); } @@ -234,7 +234,7 @@ _view_cmd_lod(void *bs, int argc, const char **argv) struct bu_external ext = BU_EXTERNAL_INIT_ZERO; if (db_get_external(&ext, dp, gedp->dbip)) continue; - key = bg_mesh_lod_custom_key((void *)ext.ext_buf, ext.ext_nbytes); + key = bv_mesh_lod_custom_key((void *)ext.ext_buf, ext.ext_nbytes); bu_free_external(&ext); if (!key) continue; @@ -278,10 +278,10 @@ _view_cmd_lod(void *bs, int argc, const char **argv) // Because we won't have the internal data to use for a full detail scenario, we set the ratio // to 1 rather than .66 for breps... - key = bg_mesh_lod_cache(gedp->ged_lod, (const point_t *)pnts, pnt_cnt, normals, faces, face_cnt, key, 1); + key = bv_mesh_lod_cache(gedp->ged_lod, (const point_t *)pnts, pnt_cnt, normals, faces, face_cnt, key, 1); if (key) - bg_mesh_lod_key_put(gedp->ged_lod, dp->d_namep, key); + bv_mesh_lod_key_put(gedp->ged_lod, dp->d_namep, key); rt_db_free_internal(&dbintern); bu_free(faces, "faces"); @@ -296,13 +296,13 @@ _view_cmd_lod(void *bs, int argc, const char **argv) } if (argc == 2) { if (BU_STR_EQUAL(argv[1], "clear")) { - bg_mesh_lod_clear_cache(gedp->ged_lod, 0); + bv_mesh_lod_clear_cache(gedp->ged_lod, 0); return BRLCAD_OK; } } if (argc == 3) { if (BU_STR_EQUAL(argv[1], "clear") && BU_STR_EQUAL(argv[2], "all_files")) { - bg_mesh_lod_clear_cache(NULL, 0); + bv_mesh_lod_clear_cache(NULL, 0); return BRLCAD_OK; } } diff --git a/src/libged/view/objs.cpp b/src/libged/view/objs.cpp index 90df655f71b..1978626783e 100644 --- a/src/libged/view/objs.cpp +++ b/src/libged/view/objs.cpp @@ -36,8 +36,8 @@ extern "C" { #include "bu/opt.h" #include "bu/vls.h" #include "bv.h" -#include "./ged_view.h" } +#include "./ged_view.h" #include "../ged_private.h" int @@ -149,7 +149,7 @@ _objs_cmd_color(void *bs, int argc, const char **argv) while (!sobjs.empty()) { struct bv_scene_obj *sc = sobjs.front(); sobjs.pop(); - bu_vls_printf(gedp->ged_result_str, "%s: %d/%d/%d\n", bu_vls_cstr(&sc->s_uuid), sc->s_color[0], sc->s_color[1], sc->s_color[2]); + bu_vls_printf(gedp->ged_result_str, "%s: %d/%d/%d\n", bu_vls_cstr(&sc->s_name), sc->s_color[0], sc->s_color[1], sc->s_color[2]); for (size_t i = 0; i < BU_PTBL_LEN(&sc->children); i++) { struct bv_scene_obj *scn = (struct bv_scene_obj *)BU_PTBL_GET(&sc->children, i); sobjs.push(scn); @@ -324,6 +324,7 @@ _objs_cmd_update(void *bs, int argc, const char **argv) } v->gv_mouse_x = x; v->gv_mouse_y = y; + bv_screen_pt(&v->gv_point, x, y, v); } update_recurse(s, v, 0); @@ -352,6 +353,7 @@ _view_cmd_objs(void *bs, int argc, const char **argv) int help = 0; int list_view = 0; int list_db = 0; + int not_shared = 0; struct _ged_view_info *gd = (struct _ged_view_info *)bs; struct ged *gedp = gd->gedp; @@ -366,11 +368,12 @@ _view_cmd_objs(void *bs, int argc, const char **argv) } // See if we have any high level options set - struct bu_opt_desc d[4]; - BU_OPT(d[0], "h", "help", "", NULL, &help, "Print help"); - BU_OPT(d[1], "G", "geom_only", "", NULL, &list_db, "List view scene objects representing .g database objs"); - BU_OPT(d[2], "", "view_only", "", NULL, &list_view, "List view-only scene objects (default)"); - BU_OPT_NULL(d[3]); + struct bu_opt_desc d[5]; + BU_OPT(d[0], "h", "help", "", NULL, &help, "Print help"); + BU_OPT(d[1], "L", "local", "", NULL, ¬_shared, "Object is scoped only to current/specified view"); + BU_OPT(d[2], "G", "geom_only", "", NULL, &list_db, "List view scene objects representing .g database objs"); + BU_OPT(d[3], "", "view_only", "", NULL, &list_view, "List view-only scene objects (default)"); + BU_OPT_NULL(d[4]); gd->gopts = d; @@ -392,34 +395,55 @@ _view_cmd_objs(void *bs, int argc, const char **argv) if (!list_db && !list_view) list_view = 1; + gd->local_obj = not_shared; + // If we're not wanting help and we have no subcommand, list defined view objects struct bview *v = gd->cv; if (!ac && cmd_pos < 0 && !help) { if (list_db) { struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); - if (bu_list_len(&cg->s_vlist)) { - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&cg->s_name)); - } else { - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); + if (db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&cg->s_name)); + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); + } + } + } + } + struct bu_ptbl *local_db_objs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + if (local_db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(local_db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&cg->s_name)); + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); + } } } } } if (list_view) { struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_uuid)); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); + } } - if (view_objs != v->gv_objs.view_objs) { - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_uuid)); + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (local_view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + bu_vls_printf(gd->gedp->ged_result_str, "%s\n", bu_vls_cstr(&s->s_name)); } } } @@ -434,36 +458,73 @@ _view_cmd_objs(void *bs, int argc, const char **argv) } gd->vobj = argv[0]; gd->s = NULL; - argc--; argv++; + // Clear out vobj name and any high level opts prior to subcommand + for (int i = 0; i < acnt; i++) { + argc--; argv++; + } - // View-only objects come first, unless we're explicitly excluding them by only specifying -G + // View-only objects take priority, unless we're explicitly excluding them by only specifying -G if (list_view) { - struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); - if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_uuid))) { - gd->s = s; - break; + if (!gd->local_obj) { + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_name))) { + gd->s = s; + break; + } + } + } + if (!gd->s) { + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_name))) { + gd->s = s; + break; + } } } } if (!gd->s) { - struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); - if (bu_list_len(&cg->s_vlist)) { - if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&cg->s_name))) { - gd->s = cg; - break; + if (!gd->local_obj) { + struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&cg->s_name))) { + gd->s = cg; + break; + } + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_name))) { + gd->s = s; + break; + } + } } - } else { - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_name))) { - gd->s = s; + } + } + if (!gd->s) { + struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&cg->s_name))) { + gd->s = cg; break; } + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + if (BU_STR_EQUAL(gd->vobj, bu_vls_cstr(&s->s_name))) { + gd->s = s; + break; + } + } } } } diff --git a/src/libged/view/polygons.c b/src/libged/view/polygons.c index 8e48a3bcc8b..b519ce4aa86 100644 --- a/src/libged/view/polygons.c +++ b/src/libged/view/polygons.c @@ -76,6 +76,9 @@ _poly_cmd_create(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } + point_t sp; + bv_screen_pt(&sp, (fastf_t)x, (fastf_t)y, gedp->ged_gvp); + int type = BV_POLYGON_GENERAL; if (argc == 3) { if (BU_STR_EQUAL(argv[2], "circ") || BU_STR_EQUAL(argv[2], "circle")) @@ -92,14 +95,16 @@ _poly_cmd_create(void *bs, int argc, const char **argv) } } - s = bv_create_polygon(gd->cv, type, x, y); + int flags = BV_VIEW_OBJS; + if (gd->local_obj) + flags |= BV_LOCAL_OBJS; + s = bv_create_polygon(gd->cv, flags, type, sp); if (!s) { bu_vls_printf(gedp->ged_result_str, "Failed to create %s\n", gd->vobj); return BRLCAD_ERROR; } - bu_vls_init(&s->s_uuid); - bu_vls_printf(&s->s_uuid, "%s", gd->vobj); - bu_ptbl_ins(gd->cv->gv_objs.view_objs, (long *)s); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", gd->vobj); return BRLCAD_OK; } @@ -165,6 +170,8 @@ _poly_cmd_select(void *bs, int argc, const char **argv) p->curr_contour_i = contour_ind; s->s_v->gv_mouse_x = x; s->s_v->gv_mouse_y = y; + bv_screen_pt(&s->s_v->gv_point, (fastf_t)x, (fastf_t)y, gedp->ged_gvp); + bv_update_polygon(s, s->s_v, BV_POLYGON_UPDATE_PT_SELECT); return BRLCAD_OK; @@ -230,6 +237,7 @@ _poly_cmd_append(void *bs, int argc, const char **argv) s->s_v->gv_mouse_x = x; s->s_v->gv_mouse_y = y; + bv_screen_pt(&s->s_v->gv_point, (fastf_t)x, (fastf_t)y, gedp->ged_gvp); bv_update_polygon(s, s->s_v, BV_POLYGON_UPDATE_PT_APPEND); return BRLCAD_OK; @@ -282,6 +290,7 @@ _poly_cmd_move(void *bs, int argc, const char **argv) s->s_v->gv_mouse_x = x; s->s_v->gv_mouse_y = y; + bv_screen_pt(&s->s_v->gv_point, (fastf_t)x, (fastf_t)y, gedp->ged_gvp); bv_update_polygon(s, s->s_v, BV_POLYGON_UPDATE_PT_MOVE); return BRLCAD_OK; @@ -433,73 +442,6 @@ _poly_cmd_open(void *bs, int argc, const char **argv) return BRLCAD_OK; } -int -_poly_cmd_viewsnap(void *bs, int argc, const char **argv) -{ - struct _ged_view_info *gd = (struct _ged_view_info *)bs; - struct ged *gedp = gd->gedp; - const char *usage_string = "view obj polygon"; - const char *purpose_string = "set view to match that used for polygon creation"; - if (_view_cmd_msgs(bs, argc, argv, usage_string, purpose_string)) - return BRLCAD_OK; - - argc--; argv++; - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - struct bv_scene_obj *s = gd->s; - if (!s) { - bu_vls_printf(gedp->ged_result_str, "View object %s does not exist\n", gd->vobj); - return BRLCAD_ERROR; - } - if (!(s->s_type_flags & BV_VIEWONLY) || !(s->s_type_flags & BV_POLYGONS)) { - bu_vls_printf(gedp->ged_result_str, "Specified object is not a view polygon.\n"); - return BRLCAD_ERROR; - } - - // Set view info - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - bv_sync(gd->cv, &p->v); - bv_update(gd->cv); - - return BRLCAD_OK; -} - -int -_poly_cmd_to_curr_view(void *bs, int argc, const char **argv) -{ - struct _ged_view_info *gd = (struct _ged_view_info *)bs; - struct ged *gedp = gd->gedp; - const char *usage_string = "view obj polygon"; - const char *purpose_string = "set view to match that used for polygon creation"; - if (_view_cmd_msgs(bs, argc, argv, usage_string, purpose_string)) - return BRLCAD_OK; - - argc--; argv++; - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - - struct bv_scene_obj *s = gd->s; - if (!s) { - bu_vls_printf(gedp->ged_result_str, "View object %s does not exist\n", gd->vobj); - return BRLCAD_ERROR; - } - if (!(s->s_type_flags & BV_VIEWONLY) || !(s->s_type_flags & BV_POLYGONS)) { - bu_vls_printf(gedp->ged_result_str, "Specified object is not a view polygon.\n"); - return BRLCAD_ERROR; - } - - // Set view info - struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - bv_sync(&p->v, gd->cv); - bv_update_polygon(s, s->s_v, BV_POLYGON_UPDATE_DEFAULT); - bv_update(gd->cv); - - return BRLCAD_OK; -} - int _poly_cmd_area(void *bs, int argc, const char **argv) { @@ -527,10 +469,13 @@ _poly_cmd_area(void *bs, int argc, const char **argv) struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; - double area = bg_find_polygon_area(&p->polygon, CLIPPER_MAX, - p->v.gv_model2view, p->v.gv_scale); + double area = bg_find_polygon_area(&p->polygon, CLIPPER_MAX, &p->vp, s->s_v->gv_scale); - bu_vls_printf(gedp->ged_result_str, "%g", area * gedp->dbip->dbi_base2local); + if (gedp->dbip) { + bu_vls_printf(gedp->ged_result_str, "%g", area * gedp->dbip->dbi_base2local); + } else { + bu_vls_printf(gedp->ged_result_str, "%g", area); + } return BRLCAD_OK; } @@ -568,12 +513,27 @@ _poly_cmd_overlap(void *bs, int argc, const char **argv) // Look up the polygon to check for overlaps struct bview *v = gd->cv; struct bv_scene_obj *s2 = NULL; - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - if (BU_STR_EQUAL(argv[0], bu_vls_cstr(&stest->s_uuid))) { - s2 = stest; - break; - } + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + if (BU_STR_EQUAL(argv[0], bu_vls_cstr(&stest->s_name))) { + s2 = stest; + break; + } + } + } + if (!s2) { + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (local_view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + if (BU_STR_EQUAL(argv[1], bu_vls_cstr(&stest->s_name))) { + s2 = stest; + break; + } + } + } } if (!s2) { bu_vls_printf(gedp->ged_result_str, "View object %s does not exist\n", argv[0]); @@ -584,12 +544,12 @@ _poly_cmd_overlap(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - // Have two polygons. Check for overlaps, using the origin view of the + // Have two polygons. Check for overlaps, using the origin plane of the // obj1 polygon. struct bv_polygon *polyA = (struct bv_polygon *)s->s_i_data; struct bv_polygon *polyB = (struct bv_polygon *)s2->s_i_data; - int ovlp = bg_polygons_overlap(&polyA->polygon, &polyB->polygon, polyA->v.gv_model2view, &wdbp->wdb_tol, polyA->v.gv_scale); + int ovlp = bg_polygons_overlap(&polyA->polygon, &polyB->polygon, &polyA->vp, &wdbp->wdb_tol, v->gv_scale); bu_vls_printf(gedp->ged_result_str, "%d", ovlp); @@ -634,6 +594,10 @@ _poly_cmd_import(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } + if (!gedp->dbip) { + bu_vls_printf(gedp->ged_result_str, "no database open\n"); + return BRLCAD_ERROR; + } // Begin import struct directory *dp = db_lookup(gedp->dbip, argv[0], LOOKUP_QUIET); @@ -641,15 +605,15 @@ _poly_cmd_import(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - s = db_sketch_to_scene_obj(gd->vobj, gedp->dbip, dp, gd->cv); + int flags = BV_VIEW_OBJS; + if (gd->local_obj) + flags |= BV_LOCAL_OBJS; + s = db_sketch_to_scene_obj(gd->vobj, gedp->dbip, dp, gd->cv, flags); if (!s) { bu_vls_printf(gedp->ged_result_str, "Failed to create %s\n", gd->vobj); return BRLCAD_ERROR; } - /* Done - add to scene objects */ - bu_ptbl_ins(gd->cv->gv_objs.view_objs, (long *)s); - return BRLCAD_OK; } @@ -683,8 +647,12 @@ _poly_cmd_export(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - GED_CHECK_EXISTS(gedp, argv[0], LOOKUP_QUIET, BRLCAD_ERROR); + if (!gedp->dbip) { + bu_vls_printf(gedp->ged_result_str, "no database open\n"); + return BRLCAD_ERROR; + } + GED_CHECK_EXISTS(gedp, argv[0], LOOKUP_QUIET, BRLCAD_ERROR); if (db_scene_obj_to_sketch(gedp->dbip, argv[0], s) != BRLCAD_OK) { bu_vls_printf(gedp->ged_result_str, "Failed to create sketch.\n"); @@ -795,15 +763,7 @@ _poly_cmd_fill_color(void *bs, int argc, const char **argv) return BRLCAD_ERROR; } - struct bv_scene_obj *fobj = NULL; - for (size_t i = 0; i < BU_PTBL_LEN(&s->children); i++) { - struct bv_scene_obj *s_c = (struct bv_scene_obj *)BU_PTBL_GET(&s->children, i); - if (BU_STR_EQUAL(bu_vls_cstr(&s_c->s_uuid), "fill")) { - fobj = s_c; - break; - } - } - + struct bv_scene_obj *fobj = bv_find_child(s, "*fill*"); if (fobj) { bu_color_to_rgb_chars(&p->fill_color, fobj->s_color); } @@ -861,12 +821,27 @@ _poly_cmd_csg(void *bs, int argc, const char **argv) // Look up the polygon to check for overlaps struct bview *v = gd->cv; struct bv_scene_obj *s2 = NULL; - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - if (BU_STR_EQUAL(argv[1], bu_vls_cstr(&stest->s_uuid))) { - s2 = stest; - break; - } + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + if (BU_STR_EQUAL(argv[1], bu_vls_cstr(&stest->s_name))) { + s2 = stest; + break; + } + } + } + if (!s2) { + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + if (local_view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *stest = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + if (BU_STR_EQUAL(argv[1], bu_vls_cstr(&stest->s_name))) { + s2 = stest; + break; + } + } + } } if (!s2) { bu_vls_printf(gedp->ged_result_str, "View object %s does not exist\n", argv[0]); @@ -882,7 +857,7 @@ _poly_cmd_csg(void *bs, int argc, const char **argv) struct bv_polygon *polyA = (struct bv_polygon *)s->s_i_data; struct bv_polygon *polyB = (struct bv_polygon *)s2->s_i_data; - struct bg_polygon *cp = bg_clip_polygon(op, &polyA->polygon, &polyB->polygon, CLIPPER_MAX, polyA->v.gv_model2view, polyA->v.gv_view2model); + struct bg_polygon *cp = bg_clip_polygon(op, &polyA->polygon, &polyB->polygon, CLIPPER_MAX, &polyA->vp); if (!cp) return BRLCAD_ERROR; @@ -917,8 +892,6 @@ const struct bu_cmdtab _poly_cmds[] = { { "open", _poly_cmd_open}, { "overlap", _poly_cmd_overlap}, { "select", _poly_cmd_select}, - { "to_curr_view", _poly_cmd_to_curr_view}, - { "viewsnap", _poly_cmd_viewsnap}, { (char *)NULL, NULL} }; diff --git a/src/libged/view/quat.c b/src/libged/view/quat.c index a1f79c8acd2..8879ce9f26b 100644 --- a/src/libged/view/quat.c +++ b/src/libged/view/quat.c @@ -40,7 +40,6 @@ ged_quat_core(struct ged *gedp, int argc, const char *argv[]) double scan[4]; static const char *usage = "a b c d"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view/size.c b/src/libged/view/size.c index e4103fb96f1..6bc91d17dac 100644 --- a/src/libged/view/size.c +++ b/src/libged/view/size.c @@ -40,7 +40,6 @@ ged_size_core(struct ged *gedp, int argc, const char *argv[]) double size; static const char *usage = "[s]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); @@ -49,8 +48,11 @@ ged_size_core(struct ged *gedp, int argc, const char *argv[]) /* get view size */ if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "%g", - gedp->ged_gvp->gv_size * gedp->dbip->dbi_base2local); + if (gedp->dbip) { + bu_vls_printf(gedp->ged_result_str, "%g", gedp->ged_gvp->gv_size * gedp->dbip->dbi_base2local); + } else { + bu_vls_printf(gedp->ged_result_str, "%g", gedp->ged_gvp->gv_size); + } return BRLCAD_OK; } @@ -64,7 +66,7 @@ ged_size_core(struct ged *gedp, int argc, const char *argv[]) return BRLCAD_ERROR; } - gedp->ged_gvp->gv_size = gedp->dbip->dbi_local2base * size; + gedp->ged_gvp->gv_size = (gedp->dbip) ? gedp->dbip->dbi_local2base * size : size; if (gedp->ged_gvp->gv_size < BV_MINVIEWSIZE) gedp->ged_gvp->gv_size = BV_MINVIEWSIZE; gedp->ged_gvp->gv_isize = 1.0 / gedp->ged_gvp->gv_size; diff --git a/src/libged/view/snap.c b/src/libged/view/snap.c index 0f51856b3df..5c14d30bbfc 100644 --- a/src/libged/view/snap.c +++ b/src/libged/view/snap.c @@ -32,7 +32,7 @@ #include "bu/opt.h" #include "bu/vls.h" -#include "bg/lseg.h" +#include "bv/snap.h" #include "dm.h" #include "../ged_private.h" #include "./ged_view.h" @@ -168,11 +168,9 @@ ged_view_snap(struct ged *gedp, int argc, const char *argv[]) VMOVE(view_pt, p); } - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); - /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); diff --git a/src/libged/view/view.c b/src/libged/view/view.c index 0c3bc28756a..4a697660467 100644 --- a/src/libged/view/view.c +++ b/src/libged/view/view.c @@ -60,7 +60,11 @@ _view_cmd_aet(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_aet_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_aet_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -73,7 +77,11 @@ _view_cmd_center(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_center_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_center_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -86,7 +94,11 @@ _view_cmd_eye(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_eye_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_eye_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -99,7 +111,11 @@ _view_cmd_faceplate(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_faceplate_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_faceplate_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } /* When a view is "independent", it displays only those objects when have been @@ -176,7 +192,7 @@ _view_cmd_independent(void *bs, int argc, const char **argv) if (BU_STR_EQUAL(argv[1], "0")) { v->independent = 0; // Clear local containers - struct bu_ptbl *sg = v->gv_objs.db_objs; + struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); if (sg) { for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); @@ -225,7 +241,11 @@ _view_cmd_quat(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_quat_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_quat_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -261,7 +281,11 @@ _view_cmd_size(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_size_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_size_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -274,7 +298,11 @@ _view_cmd_snap(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_view_snap(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_view_snap(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } int @@ -287,7 +315,11 @@ _view_cmd_ypr(void *bs, int argc, const char **argv) return BRLCAD_OK; } - return ged_ypr_core(gd->gedp, argc, argv); + struct bview *cv = gd->gedp->ged_gvp; + gd->gedp->ged_gvp = gd->cv; + int ret = ged_ypr_core(gd->gedp, argc, argv); + gd->gedp->ged_gvp = cv; + return ret; } @@ -336,7 +368,7 @@ _view_cmd_vZ(void *bs, int argc, const char **argv) argc = ac; if (print_help || (calc_near.set && calc_far.set)) { - bu_vls_printf(gedp->ged_result_str, "Usage:\n%s", usage_string); + bu_vls_printf(gedp->ged_result_str, "[WARNING] this command is deprecated - vZ values should be set on data objects\n\nUsage:\n%s", usage_string); return GED_HELP; } @@ -357,34 +389,7 @@ _view_cmd_vZ(void *bs, int argc, const char **argv) struct bview *v = gd->cv; if (bu_vls_strlen(&calc_target)) { // User has specified a view object to use - try to find it -struct bv_scene_obj *wobj = NULL; - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - if (!bu_vls_strcmp(&s->s_uuid, &calc_target)) { - wobj = s; - break; - } - } - if (!wobj) { - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - if (bu_list_len(&cg->s_vlist)) { - if (!bu_vls_strcmp(&cg->s_name, &calc_target)) { - wobj = cg; - break; - } - } else { - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - if (!bu_vls_strcmp(&s->s_name, &calc_target)) { - wobj = s; - break; - } - } - } - } - } + struct bv_scene_obj *wobj = bv_find_obj(v, bu_vls_cstr(&calc_target)); if (wobj) { fastf_t vZ = bv_vZ_calc(wobj, gd->cv, calc_mode); bu_vls_sprintf(gedp->ged_result_str, "%0.15f", vZ); @@ -397,28 +402,33 @@ struct bv_scene_obj *wobj = NULL; } else { // No specific view object to use - check all drawn // view objects. + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); + struct bu_ptbl *local_view_objs = bv_view_objs(v, BV_VIEW_OBJS | BV_LOCAL_OBJS); + struct bu_ptbl *db_objs = bv_view_objs(v, BV_DB_OBJS); + struct bu_ptbl *local_db_objs = bv_view_objs(v, BV_DB_OBJS | BV_LOCAL_OBJS); double vZ = (calc_mode) ? -DBL_MAX : DBL_MAX; int have_vz = 0; - for (size_t i = 0; i < BU_PTBL_LEN(v->gv_objs.view_objs); i++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(v->gv_objs.view_objs, i); - fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); - if (calc_mode) { - if (calc_val > vZ) { - vZ = calc_mode; - have_vz = 1; - } - } else { - if (calc_val < vZ) { - vZ = calc_mode; - have_vz = 1; + if (view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(view_objs, i); + fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); + if (calc_mode) { + if (calc_val > vZ) { + vZ = calc_mode; + have_vz = 1; + } + } else { + if (calc_val < vZ) { + vZ = calc_mode; + have_vz = 1; + } } } } - struct bu_ptbl *sg = bv_view_objs(v, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - if (bu_list_len(&cg->s_vlist)) { - fastf_t calc_val = bv_vZ_calc(cg, gd->cv, calc_mode); + if (local_view_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_view_objs); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(local_view_objs, i); + fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); if (calc_mode) { if (calc_val > vZ) { vZ = calc_mode; @@ -430,10 +440,49 @@ struct bv_scene_obj *wobj = NULL; have_vz = 1; } } - } else { - for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { - struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); - fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); + } + } + + if (db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + fastf_t calc_val = bv_vZ_calc(cg, gd->cv, calc_mode); + if (calc_mode) { + if (calc_val > vZ) { + vZ = calc_mode; + have_vz = 1; + } + } else { + if (calc_val < vZ) { + vZ = calc_mode; + have_vz = 1; + } + } + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); + if (calc_mode) { + if (calc_val > vZ) { + vZ = calc_mode; + have_vz = 1; + } + } else { + if (calc_val < vZ) { + vZ = calc_mode; + have_vz = 1; + } + } + } + } + } + } + if (local_db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_db_objs); i++) { + struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(local_db_objs, i); + if (bu_list_len(&cg->s_vlist)) { + fastf_t calc_val = bv_vZ_calc(cg, gd->cv, calc_mode); if (calc_mode) { if (calc_val > vZ) { vZ = calc_mode; @@ -445,6 +494,22 @@ struct bv_scene_obj *wobj = NULL; have_vz = 1; } } + } else { + for (size_t j = 0; j < BU_PTBL_LEN(&cg->children); j++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&cg->children, j); + fastf_t calc_val = bv_vZ_calc(s, gd->cv, calc_mode); + if (calc_mode) { + if (calc_val > vZ) { + vZ = calc_mode; + have_vz = 1; + } + } else { + if (calc_val < vZ) { + vZ = calc_mode; + have_vz = 1; + } + } + } } } } @@ -457,7 +522,7 @@ struct bv_scene_obj *wobj = NULL; if (!argc) { - bu_vls_printf(gedp->ged_result_str, "%g\n", gd->cv->gv_data_vZ); + bu_vls_printf(gedp->ged_result_str, "%g\n", gd->cv->gv_tcl.gv_data_vZ); return BRLCAD_OK; } @@ -465,7 +530,7 @@ struct bv_scene_obj *wobj = NULL; if (argc == 1) { fastf_t val; if (bu_opt_fastf_t(NULL, 1, (const char **)&argv[0], (void *)&val) == 1) { - gd->cv->gv_data_vZ = val; + gd->cv->gv_tcl.gv_data_vZ = val; return BRLCAD_OK; } } @@ -480,7 +545,7 @@ struct bv_scene_obj *wobj = NULL; } vect_t vpt; MAT4X3PNT(vpt, gd->cv->gv_model2view, mpt); - gd->cv->gv_data_vZ = vpt[Z]; + gd->cv->gv_tcl.gv_data_vZ = vpt[Z]; return BRLCAD_OK; } @@ -534,6 +599,7 @@ const struct bu_cmdtab _view_cmds[] = { { "list", _view_cmd_list}, { "lod", _view_cmd_lod}, { "obj", _view_cmd_objs}, + { "objs", _view_cmd_objs}, { "quat", _view_cmd_quat}, { "selections", _view_cmd_selections}, { "size", _view_cmd_size}, @@ -662,7 +728,6 @@ ged_view_func_core(struct ged *gedp, int argc, const char *argv[]) static const char *usage = "quat|ypr|aet|center|eye|size [args]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view/ypr.c b/src/libged/view/ypr.c index b9057d70f09..6d16489e25f 100644 --- a/src/libged/view/ypr.c +++ b/src/libged/view/ypr.c @@ -40,7 +40,6 @@ ged_ypr_core(struct ged *gedp, int argc, const char *argv[]) double scan[3]; static const char *usage = "yaw pitch roll"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view2grid_lu/view2grid_lu.c b/src/libged/view2grid_lu/view2grid_lu.c index 34868f9fd6a..b0a7cd06c92 100644 --- a/src/libged/view2grid_lu/view2grid_lu.c +++ b/src/libged/view2grid_lu/view2grid_lu.c @@ -43,6 +43,7 @@ ged_view2grid_lu_core(struct ged *gedp, int argc, const char *argv[]) point_t mo_view_pt; /* model origin in view space */ point_t diff; static const char *usage = "x y z"; + double b2lval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); @@ -60,7 +61,7 @@ ged_view2grid_lu_core(struct ged *gedp, int argc, const char *argv[]) goto bad; MAT4X3PNT(mo_view_pt, gedp->ged_gvp->gv_model2view, model_pt); - f = gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local; + f = gedp->ged_gvp->gv_scale * b2lval; VSCALE(mo_view_pt, mo_view_pt, f); VSUB2(diff, view_pt, mo_view_pt); diff --git a/src/libged/view2model/view2model.c b/src/libged/view2model/view2model.c index 9069fafbb22..f30b60380f4 100644 --- a/src/libged/view2model/view2model.c +++ b/src/libged/view2model/view2model.c @@ -35,7 +35,6 @@ int ged_view2model_core(struct ged *gedp, int argc, const char *argv[]) { - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/view2model_lu/view2model_lu.c b/src/libged/view2model_lu/view2model_lu.c index 205a9f5c6a6..762cd15ff7d 100644 --- a/src/libged/view2model_lu/view2model_lu.c +++ b/src/libged/view2model_lu/view2model_lu.c @@ -40,6 +40,7 @@ ged_view2model_core_lu(struct ged *gedp, int argc, const char *argv[]) point_t model_pt; double scan[3]; static const char *usage = "x y z"; + double b2lval = (gedp->dbip) ? gedp->dbip->dbi_base2local : 1.0; GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); @@ -58,7 +59,7 @@ ged_view2model_core_lu(struct ged *gedp, int argc, const char *argv[]) /* convert from double to fastf_t */ VMOVE(view_pt, scan); - sf = 1.0 / (gedp->ged_gvp->gv_scale * gedp->dbip->dbi_base2local); + sf = 1.0 / (gedp->ged_gvp->gv_scale * b2lval); VSCALE(view_pt, view_pt, sf); MAT4X3PNT(model_pt, gedp->ged_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, gedp->dbip->dbi_base2local); diff --git a/src/libged/view2model_vec/view2model_vec.c b/src/libged/view2model_vec/view2model_vec.c index 246f5cec6af..2e6ebd09606 100644 --- a/src/libged/view2model_vec/view2model_vec.c +++ b/src/libged/view2model_vec/view2model_vec.c @@ -41,7 +41,6 @@ ged_view2model_core_vec(struct ged *gedp, int argc, const char *argv[]) double scan[3]; static const char *usage = "x y z"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/viewdir/viewdir.c b/src/libged/viewdir/viewdir.c index 2a8963dc53a..33e53a4d3e6 100644 --- a/src/libged/viewdir/viewdir.c +++ b/src/libged/viewdir/viewdir.c @@ -41,7 +41,6 @@ ged_viewdir_core(struct ged *gedp, int argc, const char *argv[]) int iflag; static const char *usage = "[-i]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_VIEW(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/who/who.c b/src/libged/who/who.c index a1c5cdbb86c..99a262596be 100644 --- a/src/libged/who/who.c +++ b/src/libged/who/who.c @@ -45,7 +45,6 @@ ged_who_core(struct ged *gedp, int argc, const char *argv[]) int skip_real, skip_phony; static const char *usage = "[r(eal)|p(hony)|b(oth)]"; - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); diff --git a/src/libged/who/who2.cpp b/src/libged/who/who2.cpp index d7d65d8afe2..f5314a93f0c 100644 --- a/src/libged/who/who2.cpp +++ b/src/libged/who/who2.cpp @@ -43,24 +43,47 @@ extern "C" int ged_who2_core(struct ged *gedp, int argc, const char *argv[]) { - GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); - if (argc > 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s", argv[0]); + int expand = 0; + struct bu_vls cvls = BU_VLS_INIT_ZERO; + struct bu_opt_desc vd[4]; + int mode = -1; + BU_OPT(vd[0], "V", "view", "name", &bu_opt_vls, &cvls, "specify view to work with"); + BU_OPT(vd[1], "m", "mode", "#", &bu_opt_int, &mode, "only report paths drawn in the specified drawing mode"); + BU_OPT(vd[2], "E", "expand", "", NULL, &expand, "report individual drawn objects"); + BU_OPT_NULL(vd[3]); + int opt_ret = bu_opt_parse(NULL, argc, argv, vd); + if (opt_ret < 0) { + bu_vls_printf(gedp->ged_result_str, "who cmd: option parsing error\n"); + bu_vls_free(&cvls); return BRLCAD_ERROR; } + struct bview *v = gedp->ged_gvp; + if (bu_vls_strlen(&cvls)) { + v = bv_set_find_view(&gedp->ged_views, bu_vls_cstr(&cvls)); + if (!v) { + bu_vls_printf(gedp->ged_result_str, "Specified view %s not found\n", bu_vls_cstr(&cvls)); + bu_vls_free(&cvls); + return BRLCAD_ERROR; + } + } + bu_vls_free(&cvls); - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - if (!sg) + /* Check that we have a view */ + if (!v) { + bu_vls_printf(gedp->ged_result_str, "No view specified and no current view defined in GED, nothing to generate a list of paths from"); return BRLCAD_ERROR; - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - bu_vls_printf(gedp->ged_result_str, "%s\n", bu_vls_cstr(&cg->s_name)); + } + + BViewState *bvs = gedp->dbi_state->get_view_state(v); + std::vector paths = bvs->list_drawn_paths(mode, (bool)!expand); + for (size_t i = 0; i < paths.size(); i++) { + bu_vls_printf(gedp->ged_result_str, "%s\n", paths[i].c_str()); } return BRLCAD_OK; diff --git a/src/libged/wireframe_eval.c b/src/libged/wireframe_eval.c index 76748f36212..4ed3daeac51 100644 --- a/src/libged/wireframe_eval.c +++ b/src/libged/wireframe_eval.c @@ -1820,11 +1820,16 @@ draw_m3(struct bv_scene_obj *s) dgcdp.ap->a_rt_i = dgcdp.rtip; dgcdp.nvectors = 0; + const char *path = NULL; struct bu_vls ppath = BU_VLS_INIT_ZERO; - db_path_to_vls(&ppath, dgcdp.fp); - const char *path = bu_vls_cstr(&ppath); + if (dgcdp.fp) { + db_path_to_vls(&ppath, dgcdp.fp); + path = bu_vls_cstr(&ppath); + } else { + path = bu_vls_cstr(&s->s_name); + } - if (rt_gettrees(dgcdp.rtip, 1, (const char **)&path, 1)) { + if (!path || rt_gettrees(dgcdp.rtip, 1, (const char **)&path, 1)) { bu_ptbl_free(&dgcdp.leaf_list); /* do not do an rt_free_rti() (closes the database!!!!) */ diff --git a/src/libged/zap/zap2.cpp b/src/libged/zap/zap2.cpp index 1f1c35ae9b7..38fa10a5ff7 100644 --- a/src/libged/zap/zap2.cpp +++ b/src/libged/zap/zap2.cpp @@ -45,24 +45,26 @@ ged_zap2_core(struct ged *gedp, int argc, const char *argv[]) int clear_view_objs = 0; int clear_solid_objs = 0; int clear_all_views = 0; + int shared_only = 0; GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, BRLCAD_ERROR); const char *usage = "zap [options]\n"; - struct bview *v = gedp->ged_gvp; + struct bview *v = NULL; argc-=(argc>0); argv+=(argc>0); /* done with command name argv[0] */ /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); - struct bu_opt_desc d[7]; - BU_OPT(d[0], "h", "help", "", NULL, &print_help, "Print help and exit"); - BU_OPT(d[1], "?", "", "", NULL, &print_help, ""); - BU_OPT(d[2], "V", "view", "name", &bu_opt_vls, &cvls, "specify view to draw on"); - BU_OPT(d[3], "v", "view-objs", "", NULL, &clear_view_objs, "clear non-solid based view objects"); - BU_OPT(d[4], "g", "solid-objs", "", NULL, &clear_solid_objs, "clear solid based view objects"); - BU_OPT(d[5], "", "all", "", NULL, &clear_all_views, "clear shared and independent views"); - BU_OPT_NULL(d[6]); + struct bu_opt_desc d[8]; + BU_OPT(d[0], "h", "help", "", NULL, &print_help, "Print help and exit"); + BU_OPT(d[1], "?", "", "", NULL, &print_help, ""); + BU_OPT(d[2], "V", "view", "name", &bu_opt_vls, &cvls, "clear data specific to this view"); + BU_OPT(d[3], "S", "shared", "", NULL, &shared_only, "clear only data shared across views"); + BU_OPT(d[4], "v", "view-objs", "", NULL, &clear_view_objs, "clear non-solid based view objects"); + BU_OPT(d[5], "g", "solid-objs", "", NULL, &clear_solid_objs, "clear solid based view objects"); + BU_OPT(d[6], "", "all", "", NULL, &clear_all_views, "clear shared and independent views"); + BU_OPT_NULL(d[7]); int opt_ret = bu_opt_parse(NULL, argc, argv, d); argc = opt_ret; @@ -77,36 +79,42 @@ ged_zap2_core(struct ged *gedp, int argc, const char *argv[]) return BRLCAD_ERROR; } + if (!clear_solid_objs && !clear_view_objs) { + clear_solid_objs = 1; + clear_view_objs = 1; + } + if (!clear_all_views && bu_vls_strlen(&cvls)) { - v = bv_set_find_view(&gedp->ged_views, bu_vls_cstr(&cvls)); - if (!v) { - bu_vls_printf(gedp->ged_result_str, "Specified view %s not found\n", bu_vls_cstr(&cvls)); + + if (shared_only) { + bu_vls_printf(gedp->ged_result_str, "Zap scope defined as view %s - not clearing shared data\n", bu_vls_cstr(&cvls)); bu_vls_free(&cvls); return BRLCAD_ERROR; } - if (!v->independent) { - bu_vls_printf(gedp->ged_result_str, "Specified view %s is not an independent view, and as such does not support clearing db objects in only this view. To change the view's status, the command 'view independent %s 1' may be applied.\n", bu_vls_cstr(&cvls), bu_vls_cstr(&cvls)); + v = bv_set_find_view(&gedp->ged_views, bu_vls_cstr(&cvls)); + if (!v) { + bu_vls_printf(gedp->ged_result_str, "Specified view %s not found\n", bu_vls_cstr(&cvls)); bu_vls_free(&cvls); return BRLCAD_ERROR; } - } - bu_vls_free(&cvls); - if (!clear_solid_objs && !clear_view_objs) { - clear_solid_objs = 1; - clear_view_objs = 1; - } - - // If we're clearing just one view, handle it - if (v && v->independent && !clear_all_views) { - int flags = 0; - if (clear_solid_objs) + int flags = BV_LOCAL_OBJS; + if (clear_solid_objs) { flags |= BV_DB_OBJS; + if (gedp->dbi_state) { + BViewState *bvs = gedp->dbi_state->get_view_state(v); + bvs->clear(); + } + } + if (clear_view_objs) flags |= BV_VIEW_OBJS; + if (!bv_clear(v, flags)) v->gv_s->gv_cleared = 1; + + bu_vls_free(&cvls); return BRLCAD_OK; } @@ -118,20 +126,28 @@ ged_zap2_core(struct ged *gedp, int argc, const char *argv[]) if (v->independent && !clear_all_views) continue; int flags = 0; - if (clear_solid_objs) + if (clear_solid_objs) { flags |= BV_DB_OBJS; + if (gedp->dbi_state) { + BViewState *bvs = gedp->dbi_state->get_view_state(v); + bvs->clear(); + } + } if (clear_view_objs) flags |= BV_VIEW_OBJS; int nret = bv_clear(v, flags); - if (nret) { + int lret = 1; + if (!shared_only) { flags |= BV_LOCAL_OBJS; - nret = bv_clear(v, flags); + lret = bv_clear(v, flags); } - if (!nret) + if (!nret || !lret) v->gv_s->gv_cleared = 1; + ret = BRLCAD_OK; } + bu_vls_free(&cvls); return ret; } diff --git a/src/libicv/CMakeLists.txt b/src/libicv/CMakeLists.txt index 98d82a6db15..6bf910b8a5f 100644 --- a/src/libicv/CMakeLists.txt +++ b/src/libicv/CMakeLists.txt @@ -8,6 +8,7 @@ set(ICV_INCLUDE_DIRS BRLCAD_LIB_INCLUDE_DIRS(icv ICV_INCLUDE_DIRS "") set(LIBICV_SOURCES + PImgHash.cpp fileformat.c rot.c color_space.c @@ -15,6 +16,7 @@ set(LIBICV_SOURCES filter.c encoding.c operations.c + pdiff.cpp stat.c size.c pix.c @@ -24,7 +26,7 @@ set(LIBICV_SOURCES dpix.c ) -BRLCAD_ADDLIB(libicv "${LIBICV_SOURCES}" "libbu;libbn;${PNG_LIBRARIES};${NETPBM_LIBRARY}") +BRLCAD_ADDLIB(libicv "${LIBICV_SOURCES}" "${libicv_deps};${PNG_LIBRARIES};${NETPBM_LIBRARY}") set_target_properties(libicv PROPERTIES VERSION 20.0.1 SOVERSION 20) set(stgts png netpbm) @@ -50,6 +52,7 @@ add_subdirectory(tests) CMAKEFILES( CMakeLists.txt TODO + PImgHash.h icv_private.h ) diff --git a/src/libicv/PImgHash.cpp b/src/libicv/PImgHash.cpp new file mode 100644 index 00000000000..19a0eb44039 --- /dev/null +++ b/src/libicv/PImgHash.cpp @@ -0,0 +1,421 @@ +// MIT License +// +// Copyright (c) 2021 Samuel Bear Powell +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// https://github.com/s-bear/image-hash + +#include "PImgHash.h" + +#include +#include +#include +#include + +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif + +namespace imghash +{ + +template<> uint8_t convert_pix(uint8_t p) +{ + return p; +} +template<> uint16_t convert_pix(uint8_t p) +{ + return static_cast(p << 8); +} +template<> float convert_pix(uint8_t p) +{ + return static_cast(p) / 255.0f; +} +template<> uint16_t convert_pix(uint16_t p) +{ + return p; +} +template<> uint8_t convert_pix(uint16_t p) +{ + return static_cast(p >> 8); +} +template<> float convert_pix(uint16_t p) +{ + return static_cast(p) / 65535.0f; +} + +template<> float convert_pix(float p) +{ + return p; +} +template<> uint8_t convert_pix(float p) +{ + return static_cast(p * 255.9999f); //we could use nextafter(256, 0) but it might not be optimized away +} +template<> uint16_t convert_pix(float p) +{ + return static_cast(p * 65535.9999f); //we could use nextafter(65536, 0) but it might not be optimized away +} + +void save(const std::string& fname, const Image& img, float vmax) +{ + + std::ofstream out(fname, std::ios::out | std::ios::binary); + if (img.channels == 1) { + out << "P5\n"; + } else if (img.channels == 3) { + out << "P6\n"; + } + out << img.width << " " << img.height << " " << 255 << "\n"; + float scale = nextafter(256.0f, 0.0f)/vmax; + for (size_t y = 0, i = 0; y < img.height; ++y, i += img.row_size) { + for (size_t x = 0, j = i; x < img.width*img.channels; ++x, ++j) { + uint8_t p = static_cast(img[j] * scale); + out.put(p); + } + } +} + +Hasher::Hasher() : bytes(), bi(8) {} + +void Hasher::clear() +{ + bytes.clear(); + bi = 8; +} + +void Hasher::append_bit(bool b) +{ + if (bi > 7) { + bytes.push_back(0); + bi = 0; + } + if (b) { + bytes.back() |= (uint8_t(1) << bi); + } + ++bi; +} + +bool Hasher::equal(const hash_type& h1, const hash_type& h2) +{ + return h1.size() == h2.size() && Hasher::match(h1, h2); +} + +bool Hasher::match(const hash_type& h1, const hash_type& h2) +{ + size_t n = std::min(h1.size(), h2.size()); + return std::equal(h1.begin(), h1.begin() + n, h2.begin(), h2.begin() + n); +} + +uint32_t Hasher::hamming_distance(const hash_type& h1, const hash_type& h2) +{ + //TODO: use span to avoid copies + + //NB we only look at bytes in common + size_t n = std::min(h1.size(), h2.size()); + size_t d = 0; + for (size_t i = 0; i < n; ++i) { + d += std::bitset<8*sizeof(hash_type::value_type)>(h1[i] ^ h2[i]).count(); + } + return static_cast(d); +} +uint32_t Hasher::distance(const hash_type& h1, const hash_type& h2) +{ + return hamming_distance(h1, h2); +} + +std::vector BlockHasher::apply(const Image& image) +{ + const size_t N = 8; + const size_t M = N + 2; + Image tmp(2*M, 2*M); + resize(image, tmp); + + //fold the 4 quadrants into the top left + for (size_t y = 0, i = 0, im = tmp.index(2*M-1,0,0); + y < M; + ++y, i += tmp.row_size, im -= tmp.row_size) { + for (size_t x = 0, xm = tmp.index(0,2*M-1,0); + x < M; + ++x, --xm) { + tmp[i + x] += tmp[i + xm] + tmp[im + x] + tmp[im + xm]; + } + } + + clear(); + bytes.reserve(8); + size_t i0 = 0; + size_t i1 = tmp.row_size; + size_t i2 = 2*tmp.row_size; + for (size_t y = 0; y < N; ++y) { + for (size_t x = 0; x < N; ++x) { + //we want the rank of the pixel in the center of the 3x3 neighborhood + float p = tmp[i1 + x + 1]; + + //get the surrounding 8 pixels + auto p00 = tmp[i0 + x]; + auto p01 = tmp[i0 + x + 1]; + auto p02 = tmp[i0 + x + 2]; + auto p10 = tmp[i1 + x]; + auto p12 = tmp[i1 + x + 2]; + auto p20 = tmp[i2 + x]; + auto p21 = tmp[i2 + x + 1]; + auto p22 = tmp[i2 + x + 2]; + //calculate the rank by comparing + int rank = (p > p00) + (p > p01) + (p > p02) + (p > p10); + rank += (p > p12) + (p > p20) + (p > p21) + (p > p22); + //the bit is set if p is greater than half the others + append_bit(rank >= 4); + } + i0 = i1; + i1 = i2; + i2 += tmp.row_size; + } + return bytes; +} + +DCTHasher::DCTHasher(unsigned M, bool even) + : N_(128), M_(M), even_(even), m_(mat(N_, M_, even_)) +{ + //nothing to do +} + +DCTHasher::DCTHasher() : DCTHasher(8, false) {} + +std::vector DCTHasher::mat(unsigned N, unsigned M) +{ + if (M > N) M = N; + std::vector m; + if (M <= 1) return m; + //column-major order! + m.reserve(static_cast(N) * M); + for (unsigned j = 0; j < N; ++j) { + for (unsigned i = 0; i < M; ++i) { + m.push_back(coef(N, i+1, j)); + } + } + return m; +} + +std::vector DCTHasher::mat_even(unsigned N, unsigned M) +{ + if (M > N/2) M = N/2; + std::vector m; + if (M <= 1) return m; + //column-major order! + m.reserve(static_cast(N) * M); + for (unsigned j = 0; j < N; ++j) { + for (unsigned i = 0; i < M; ++i) { + m.push_back(coef(N, 2*(i+1), j)); + } + } + return m; +} + +std::vector DCTHasher::mat(unsigned N, unsigned M, bool even) +{ + if (even) return mat_even(N, M); + else return mat(N, M); +} + +std::vector DCTHasher::apply(const Image& image) +{ + if (image.width != image.height || image.channels != 1) { + throw std::runtime_error("DCT: image must be square and single-channel"); + } + if (N_ != image.width) { + N_ = static_cast(image.width); + m_ = mat(N_, M_, even_); + } + + /* Phase 1: Apply DCT across rows */ + Image dct_1(image.height, M_); + + //iterate over image rows + for (size_t y = 0, ti = 0, di = 0; + y < image.height; + ++y, ti += image.row_size, di += dct_1.row_size) { + //init dct + for (size_t u = 0, dj = di; u < dct_1.width; ++u, ++dj) { + dct_1[dj] = 0.0f; + } + + //iterate over image columns (reduction) + for (size_t x = 0, tj = ti, k = 0; + x < image.width; + ++x, ++tj) { + //iterate over horizontal spatial frequencies + float p = image[tj]; + for (size_t u = 0, dj = di; u < dct_1.width; ++u, ++k, ++dj) { + dct_1[dj] += m_[k] * p; + } + } + } + + /* Phase 2: Apply DCT along columns */ + Image dct(M_, M_); + //iterate over vertical spatial frequencies + for (size_t v = 0, i = 0; v < M_; ++v, i += dct.row_size) { + //iterate over horizontal spatial frequencies + for (size_t u = 0, j = i; u < M_; ++u, ++j) { + //reduce over image rows + float dct_uv = 0.0f; + for (size_t y = 0, k = v, di = u; y < N_; ++y, k += M_, di += M_) { + dct_uv += m_[k] * dct_1[di]; + } + dct[j] = dct_uv; + } + } + + /* Phase 3: Compute hash */ + clear(); + bytes.reserve((size_t(M_) * M_ + 7) / 8); + //iterate over the DCT so that we always output the bits in the same order, no matter the size + // we will start in the corner, and then build up in square shells: + // 0 1 4 + // 2 3 5 + // 6 7 8 + + //iterate across the first row + for (size_t u = 0; u < M_; ++u) { + //iterate down the column at u, to the (u-1) row + size_t i = 0; + for (size_t v = 0; v < u; ++v, i += dct.row_size) { + append_bit(dct[i + u] > 0); + } + //iterate across row v, to column u + for (size_t uu = 0, j = i; uu < u + 1; ++uu, ++j) { + append_bit(dct[j] > 0); + } + } + + return bytes; +} + +std::vector tile_size(size_t a, size_t b) +{ + // a > b + //Use modified Bresenham's algorithm to distribute b groups over a items + + intptr_t D = intptr_t(b) - intptr_t(a); //the usual algorithm uses b - 2*a, but that reduces the size of the first and last bins by half + std::vector sizes(b, 0); + for (size_t i = 0, j = 0; i < a; ++i) { + sizes[j]++; + if (D > 0) { + ++j; + D += intptr_t(b) - intptr_t(a); + } else { + D += intptr_t(b); + } + } + return sizes; +} + +Preprocess::Preprocess(size_t w, size_t h) + : img(h,w,3), hist(), y(0), i(0), ty(0), in_w(0), in_h(0), in_c(0) +{ + //nothing else to do +} + +Preprocess::Preprocess() : Preprocess(0, 0) +{ + //nothing else to do +} + +void Preprocess::start(size_t input_height, size_t input_width, size_t input_channels) +{ + in_w = input_width; + in_h = input_height; + in_c = input_channels; + + if (img.height > in_h) tile_h = tile_size(img.height, in_h); + else if (in_h> img.height) tile_h = tile_size(in_h, img.height); + + if (img.width > in_w) tile_w = tile_size(img.width, in_w); + else if (in_w> img.width) tile_w = tile_size(in_w, img.width); + + if (hist.size() != in_c * 256) { + hist.resize(in_c * 256); + } + std::fill(hist.begin(), hist.end(), 0); + + if (img.channels != in_c) { + img = Image(img.height, img.width, in_c); + } + y = 0; + i = 0; + ty = 0; +} + +Image Preprocess::stop() +{ + //equalization lookup table + // cumulative sum of the normalized histogram + std::vector lut; + lut.reserve(hist.size()); + size_t in_count = in_c * in_w * in_h; + for (size_t c = 0, j = 0; c < in_c; ++c) { + size_t sum = 0; + for (size_t ip = 0; ip < hist_bins; ++ip, ++j) { + sum += hist[j]; + lut.push_back(float(sum) / in_count); + } + } + + Image out(img.height, img.width, 1); + //apply the equalization, storing the result in out + for (size_t out_y = 0, out_i = 0, img_i = 0; + out_y < out.height; + ++out_y, out_i += out.row_size, img_i += img.row_size) { + for (size_t out_x = 0, out_j = out_i, img_j = img_i; out_x < out.width; ++out_x, ++out_j) { + float sum = 0.0f; + for (size_t c = 0; c < img.channels; ++c, ++img_j) { + auto p = img[img_j]; + sum += lut[c * hist_bins + convert_pix(p)]; + } + out[out_j] = sum; + } + } + return out; +} + +Image Preprocess::apply(const Image& input) +{ + start(input.height, input.width, input.channels); + for (const uint8_t* row = (const uint8_t*)input.data->data(); add_row(row); row += input.row_size); + return stop(); +} + +} + + + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libicv/PImgHash.h b/src/libicv/PImgHash.h new file mode 100644 index 00000000000..e84165560fd --- /dev/null +++ b/src/libicv/PImgHash.h @@ -0,0 +1,435 @@ +// MIT License +// +// Copyright (c) 2021 Samuel Bear Powell +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// https://github.com/s-bear/image-hash + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace imghash +{ + +template struct Image; + +class Preprocess; + +template T convert_pix(uint8_t p); +template T convert_pix(uint16_t p); +template T convert_pix(float p); + +std::vector tile_size(size_t a, size_t b); + +template +void resize_row(size_t in_c, size_t in_w, const InT* in, size_t out_w, OutT* out, const std::vector& tiles, bool accumulate, std::vector& hist) +{ + //3 cases + if (in_w == out_w) { + for (size_t in_x = 0; in_x < in_w; ++in_x) { + for (size_t c = 0; c < in_c; ++c, ++in, ++out) { + auto p = *in; + hist[c * 256 + convert_pix(p)] += 1; + if (accumulate) *out += convert_pix(p); + else *out = convert_pix(p); + } + } + } else if (in_w < out_w) { + std::vector pix(in_c, 0); + for (size_t in_x = 0; in_x < in_w; ++in_x) { + for (size_t c = 0; c < in_c; ++c, ++in) { + auto p = *in; + hist[c * 256 + convert_pix(p)] += 1; + pix[c] = convert_pix(p); + } + size_t tw = tiles[in_x]; + for (size_t tx = 0; tx < tw; ++tx) { + for (size_t c = 0; c < in_c; ++c, ++out) { + if (accumulate) *out += pix[c]; + else *out = pix[c]; + } + } + } + } else { + //out_w < in_w + std::vector pix(in_c, TmpT(0)); + for (size_t out_x = 0; out_x < out_w; ++out_x) { + for (size_t c = 0; c < in_c; ++c) { + pix[c] = 0; + } + size_t tw = tiles[out_x]; + for (size_t tx = 0; tx < tw; ++tx) { + for (size_t c = 0; c < in_c; ++c, ++in) { + auto p = *in; + hist[c * 256 + convert_pix(p)] += 1; + pix[c] += convert_pix(p); + } + } + for (size_t c = 0; c < in_c; ++c, ++out) { + if (accumulate) *out += convert_pix(pix[c] / tw); + else *out = convert_pix(pix[c] / tw); + } + } + } +} + +template +void resize(const Image& in, Image& out, std::vector& hist) +{ + if (out.channels != in.channels) { + throw std::runtime_error("resize: in & out must have same channels"); + } + + if (hist.size() != in.channels * 256) { + hist.resize(in.channels * 256); + } + std::fill(hist.begin(), hist.end(), 0); + + //generate evenly distributed tile sizes + std::vector tile_h; + if (out.height > in.height) tile_h = tile_size(out.height, in.height); + else if (in.height > out.height) tile_h = tile_size(in.height, out.height); + + std::vector tile_w; + if (out.width > in.width) tile_w = tile_size(out.width, in.width); + else if (in.width > out.width) tile_w = tile_size(in.width, out.width); + + const InT* in_row = in.begin(); + OutT* out_row = out.begin(); + + //there are 3 cases + if (out.height == in.height) { + for (size_t y = 0; y < out.height; ++y, in_row += in.row_size, out_row += out.row_size) { + resize_row(in.channels, in.width, in_row, out.width, out_row, tile_w, false, hist); + } + } else if (in.height < out.height) { + std::vector tmp(out.channels*out.width, 0); + for (size_t in_y = 0; in_y < in.height; ++in_y, in_row += in.row_size) { + resize_row(in.channels, in.width, in_row, out.width, tmp.data(), tile_w, false, hist); + size_t th = tile_h[in_y]; + //copy the input row to each row of the output in the tile + for (size_t ty = 0; ty < th; ++ty, out_row += out.row_size) { + for (size_t out_x = 0, i = 0; out_x < out.width; ++out_x) { + for (size_t c = 0; c < out.channels; ++c, ++i) { + out_row[i] = tmp[i]; + } + } + } + } + } else { + //out.height < in.height + std::vector tmp(out.channels * out.width, 0); + for (size_t out_y = 0; out_y < out.height; ++out_y, out_row += out.row_size) { + std::fill(tmp.begin(), tmp.end(), TmpT(0)); + size_t th = tile_h[out_y]; + for (size_t ty = 0; ty < th; ++ty, in_row += in.row_size) { + resize_row(in.channels, in.width, in_row, out.width, tmp.data(), tile_w, true, hist); + } + for (size_t out_x = 0, i = 0; out_x < out.width; ++out_x) { + for (size_t c = 0; c < out.channels; ++c, ++i) { + out_row[i] = convert_pix(tmp[i] / th); + } + } + } + } +} + +template +void resize(const Image& in, Image& out) +{ + std::vector hist; + resize(in, out, hist); +} + +template +struct Image { + std::vector *data = NULL; + size_t height, width, channels; + size_t size, row_size; + + Image(size_t i_height, size_t i_width, size_t i_channels, size_t i_size, size_t i_row_size) + : data(nullptr), height(i_height), width(i_width), channels(i_channels), size(i_size), row_size(i_row_size) + { + allocate(); + } + Image(size_t i_height, size_t i_width, size_t i_channels = 1) + : Image(i_height, i_width, i_channels, i_height* i_width* i_channels, i_width* i_channels) + {} + Image(const Image& other) = default; + Image(Image&& other) = default; + Image& operator=(const Image& other) = default; + Image& operator=(Image&& other) = default; + + void allocate() + { + if (data) + delete data; + data = new std::vector; + data->resize(size, 0); + } + + size_t index(size_t y, size_t x, size_t c) const + { + return y * row_size + x * channels + c; + } + + T* begin() + { + return (T*)data->data(); + } + const T* begin() const + { + return (const T*)data->data(); + } + + T* end() + { + return begin() + size; + } + const T* end() const + { + return begin() + size; + } + + T at(size_t i) const + { + return data[i]; + } + T& at(size_t i) + { + return data[i]; + } + + T operator[](size_t i) const + { + return (*data)[i]; + } + T& operator[](size_t i) + { + return (*data)[i]; + } + + T operator()(size_t y, size_t x, size_t c) const + { + return at(index(y, x, c)); + } + T& operator()(size_t y, size_t x, size_t c) + { + return at(index(y, x, c)); + } +}; + +//! Preprocess image for hashing by resizing and histogram-equalizing +class Preprocess +{ + static constexpr size_t hist_bins = 256; + + Image img; + std::vector hist; //histogram + std::vector tile_w, tile_h; //tile sizes for resizing + size_t y, i; // the current image row, and pixel index + size_t ty; //the current row within the tile (downsampling) or tile within the image (upsampling) + size_t in_w, in_h, in_c; //input width, height, channels +public: + + Preprocess(); + Preprocess(size_t w, size_t h); + + //by row: + void start(size_t input_height, size_t input_width, size_t input_channels); + + template + bool add_row(const RowT* input_row) + { + auto img_row = img.begin() + i; + if (img.height == in_h) { + resize_row(in_c, in_w, input_row, img.width, img_row, tile_w, false, hist); + ++y; + i += img.row_size; + } else if (img.height < in_h) { + if (ty == 0) { + //zero the first row + for (size_t x = 0, j = i; x < img.width; ++x) { + for (size_t c = 0; c < img.channels; ++c, ++j) { + img[j] = 0.0f; + } + } + } + resize_row(in_c, in_w, input_row, img.width, img_row, tile_w, true, hist); + ++ty; + size_t th = tile_h[y]; + if (ty >= th) { + ty = 0; + ++y; + i += img.row_size; + for (size_t x = 0, j = 0; x < img.width; ++x) { + for (size_t c = 0; c < img.channels; ++c, ++j) { + img_row[j] /= th; + } + } + } + } else { + std::vector tmp(img.width * img.channels, 0); + resize_row(in_c, in_w, input_row, img.width, tmp.data(), tile_w, false, hist); + size_t th = tile_h[ty++]; + for (size_t k = 0; k < th; ++k, ++y, i += img.row_size) { + for (size_t x = 0, j = 0; x < img.width; ++x) { + for (size_t c = 0; c < img.channels; ++c, ++j) { + img[i + j] = tmp[j]; + } + } + } + } + //do we need more rows? + return y < img.height; + } + + Image stop(); + + //full-frame: + Image apply(const Image& input); +}; + +//! Class for implementing image hash functions +class Hasher +{ +public: + typedef std::vector hash_type; +protected: + hash_type bytes; + size_t bi; + + void clear(); + void append_bit(bool b); +public: + Hasher(); + virtual ~Hasher() {} + virtual hash_type apply(const Image& image) = 0; + + //return true if the hashes are equal up to the length of the shorter hash + static bool match(const hash_type& h1, const hash_type& h2); + //return true if the hashes match and are the same length + static bool equal(const hash_type& h1, const hash_type& h2); + + //bitwise distance, up to the length of the shorter hash + static uint32_t hamming_distance(const hash_type& h1, const hash_type& h2); + + static uint32_t distance(const hash_type& h1, const hash_type& h2); +}; + +//! Block-average hash +class BlockHasher : public Hasher +{ +public: + hash_type apply(const Image& image); +}; + +//! Discrete Cosine Transform hash +class DCTHasher : public Hasher +{ +protected: + //! 1D Discrete Cosine Transform coefficient + /*! + \param N The number of samples. + \param i Cosine order (DCT matrix row) + \param j Sample index + \return The DCT coefficient, sqrt(2/N)*cos(pi*i*(2*j + 1)/(2*N)) + */ + static inline float coef(unsigned N, unsigned i, unsigned j) + { + const float d = 1.5707963267948966f / N; // pi/(2 N) + return cos(d * i * (2 * j + 1)); + } + + //! 1D Discrete Cosine Transform matrix + /*! + \param N The number of samples (pixels) + \param M The number of DCT rows, must be less than N + \return N*M DCT matrix coefficients, in column-major order. The DC coefficients are excluded + */ + static std::vector mat(unsigned N, unsigned M); + + //! 1D Discrete Cosine Transform matrix, even rows only + /*! + \param N The number of samples (pixels) + \param M The number of DCT rows (even only), must be less than or equal to (N-1)/2 + \return N*M DCT matrix coefficients, in column-major order. The DC coefficients are excluded + */ + static std::vector mat_even(unsigned N, unsigned M); + + //! 1D Discrete Cosine Transform matrix + /*! + \param N The number of samples (pixels) + \param M The number of DCT rows, must be less than (N-1)/2 if even == true, less than N otherwise. + \param even If true, generate only even frequency coefficients + \return N*M DCT matrix coefficients, in column-major order. The DC coefficients are excluded + */ + static std::vector mat(unsigned N, unsigned M, bool even); + + unsigned N_, M_; + bool even_; + //! 1D DCT matrix coefficients + std::vector m_; + +public: + DCTHasher(); + + //! Construct a DCTHash object with M frequencies + /*! + This Hash transforms a square image using the Discrete Cosine Transform, producing MxM bits + of output. The DCT is computed over the full resolution of the image, and the resulting + coefficients are ordered independently of M. That is, hashes produced from the same image + with different values of M will have a common prefix. The ordering is by square shells, + reading down the next column before reading across the next row: + + 0 1 4 9 + 2 3 5 A + 6 7 8 B + C D E F + + Each bit of the hash corresponds to the sign of the DCT coefficients. + + \param M The number of DCT components in the output + \param even If true, use only even frequencies, for a symmetrical hash (mirror/flip tolerant). + */ + DCTHasher(unsigned M, bool even); + + //! Apply the hash function + hash_type apply(const Image& image); +}; + +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libicv/operations.c b/src/libicv/operations.c index 882f66378d0..3b1154f8c68 100644 --- a/src/libicv/operations.c +++ b/src/libicv/operations.c @@ -32,6 +32,8 @@ #include "bio.h" #include "bu/log.h" #include "bu/magic.h" +#include "bu/malloc.h" +#include "bn/tol.h" #include "vmath.h" @@ -301,6 +303,201 @@ int icv_saturate(icv_image_t* img, double sat) return 0; } +int +icv_diff( + int *matching, int *off_by_1, int *off_by_many, + icv_image_t *img1, icv_image_t *img2 + ) +{ + if (!img1 || !img2) + return -1; + + int ret = 0; + + // Have images + unsigned char *d1 = icv_data2uchar(img1); + unsigned char *d2 = icv_data2uchar(img2); + size_t s1 = img1->width * img1->height; + size_t s2 = img2->width * img2->height; + size_t smin = (s1 < s2) ? s1 : s2; + size_t smax = (s1 > s2) ? s1 : s2; + for (size_t i = 0; i < smin; i++) { + int r1 = d1[i*3+0]; + int g1 = d1[i*3+1]; + int b1 = d1[i*3+2]; + int r2 = d2[i*3+0]; + int g2 = d2[i*3+1]; + int b2 = d2[i*3+2]; + int dcnt = 0; + dcnt += (r1 != r2) ? 1 : 0; + dcnt += (g1 != g2) ? 1 : 0; + dcnt += (b1 != b2) ? 1 : 0; + switch (dcnt) { + case 0: + if (matching) + (*matching)++; + break; + case 1: + ret = 1; + if (off_by_1) + (*off_by_1)++; + break; + default: + ret = 1; + if (off_by_many) + (*off_by_many)++; + } + } + if (smin != smax) { + ret = 1; + if (off_by_many) { + (*off_by_many) += (int)(smax - smin); + } + } + bu_free(d1, "image 1 rgb"); + bu_free(d2, "image 2 rgb"); + + return ret; +} + +icv_image_t * +icv_diffimg(icv_image_t *img1, icv_image_t *img2) +{ + long p; + + if (!img1 || !img2 || !img1->width || !img2->width) + return NULL; + + if ((img1->width != img2->width) || (img1->height != img2->height) || (img1->channels != img2->channels)) { + bu_log("icv_diffimg : Image Parameters not Equal"); + return NULL; + } + + // Have images + unsigned char *d1 = icv_data2uchar(img1); + unsigned char *d2 = icv_data2uchar(img2); + unsigned char *od = icv_data2uchar(img1); + size_t s = img1->width * img1->height; + for (size_t i = 0; i < s; i++) { + int r1 = d1[i*3+0]; + int g1 = d1[i*3+1]; + int b1 = d1[i*3+2]; + int r2 = d2[i*3+0]; + int g2 = d2[i*3+1]; + int b2 = d2[i*3+2]; + int dcnt = 0; + dcnt += (r1 != r2) ? 1 : 0; + dcnt += (g1 != g2) ? 1 : 0; + dcnt += (b1 != b2) ? 1 : 0; + switch (dcnt) { + case 0: + p = ((22937 * r1 + 36044 * g1 + 6553 * b1)>>17); + if (p < 0) + p = 0; + p /= 2; + + od[3*i+0] = (int)p; + od[3*i+1] = (int)p; + od[3*i+2] = (int)p; + break; + case 1: + od[3*i+0] = 0xC0; + od[3*i+1] = 0xC0; + od[3*i+2] = 0xC0; + break; + default: + od[3*i+0] = 0xFF; + od[3*i+1] = 0xFF; + od[3*i+2] = 0xFF; + } + } + + icv_image_t *out_img; + BU_ALLOC(out_img, struct icv_image); + ICV_IMAGE_INIT(out_img); + out_img->width = img1->width; + out_img->height = img1->height; + out_img->channels = 3; + out_img->data = icv_uchar2double(od, img1->width * img1->height * 3); + + bu_free(d1, "image 1 rgb"); + bu_free(d2, "image 2 rgb"); + + return out_img; +} + + +int +icv_fit(icv_image_t *img, struct bu_vls *msg, size_t o_width_req, size_t o_height_req, fastf_t sf) +{ + if (!img) + return BRLCAD_ERROR; + + size_t i_w, i_n; + size_t o_w_used, o_n_used; + size_t x_offset, y_offset; + fastf_t ar_w; + + i_w = img->width; + i_n = img->height; + ar_w = o_width_req / (fastf_t)i_w; + + o_w_used = (size_t)(i_w * ar_w * sf); + o_n_used = (size_t)(i_n * ar_w * sf); + + if (icv_resize(img, ICV_RESIZE_BINTERP, o_w_used, o_n_used, 1) < 0) { + if (msg) + bu_vls_printf(msg, "icv_resize failed"); + return BRLCAD_ERROR; + } + + if (NEAR_EQUAL(sf, 1.0, BN_TOL_DIST)) { + fastf_t ar_n = o_height_req / (fastf_t)i_n; + + if (ar_w > ar_n && !NEAR_EQUAL(ar_w, ar_n, BN_TOL_DIST)) { + /* need to crop final image height so that we keep the center of the image */ + size_t x_orig = 0; + size_t y_orig = (o_n_used - o_height_req) * 0.5; + + if (icv_rect(img, x_orig, y_orig, o_width_req, o_height_req) < 0) { + if (msg) + bu_vls_printf(msg, "icv_rect failed"); + return BRLCAD_ERROR; + } + + x_offset = 0; + y_offset = 0; + } else { + /* user needs to offset final image in the window */ + x_offset = 0; + y_offset = (size_t)((o_height_req - o_n_used) * 0.5); + } + } else { + if (sf > 1.0) { + size_t x_orig = (o_w_used - o_width_req) * 0.5; + size_t y_orig = (o_n_used - o_height_req) * 0.5; + + if (icv_rect(img, x_orig, y_orig, o_width_req, o_height_req) < 0) { + if (msg) + bu_vls_printf(msg, "icv_rect failed"); + return BRLCAD_ERROR; + } + + x_offset = 0; + y_offset = 0; + } else { + /* user needs to offset final image in the window */ + x_offset = (size_t)((o_width_req - o_w_used) * 0.5); + y_offset = (size_t)((o_height_req - o_n_used) * 0.5); + } + } + + if (msg) + bu_vls_printf(msg, "%zu %zu %zu %zu", img->width, img->height, x_offset, y_offset); + + return BRLCAD_OK; +} + /* * Local Variables: * tab-width: 8 diff --git a/src/libicv/pdiff.cpp b/src/libicv/pdiff.cpp new file mode 100644 index 00000000000..f2ec7209069 --- /dev/null +++ b/src/libicv/pdiff.cpp @@ -0,0 +1,117 @@ +/* P D I F F . C P P + * BRL-CAD + * + * Copyright (c) 2013-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file libicv/pdiff.cpp + * + * This file implements perceptual image hashing based difference + * checking - as opposed to icv_diff, icv_pdiff does an approximate + * comparison of two images to determine how similar they are. + */ + +#include "common.h" + +#include +#include +#include +#include +#include + +#include "PImgHash.h" + +#include "icv.h" + +#include "bio.h" +#include "bu/log.h" +#include "bu/magic.h" +#include "bu/malloc.h" +#include "vmath.h" + +#if 0 +std::string format_hash(const std::vector& hash) +{ + std::ostringstream oss; + oss << std::hex << std::setfill('0'); + for (auto b : hash) oss << std::setw(2) << int(b); + return oss.str(); +} +#endif + +void +load_icv(icv_image_t *img, imghash::Preprocess *prep) +{ + size_t rows, cols; + prep->start(img->height, img->width, 3); + rows = img->height; + cols = img->width; + for (size_t i = 0; i < rows; i++) { + std::vector row; + for (size_t j = 0; j < cols ; j++) { + long l; + int offset = ((rows - 1) * cols * 3) - (i * cols * 3); + l = lrint(img->data[offset + j*3+0]*255.0); + row.push_back((uint8_t)l); + l = lrint(img->data[offset + j*3+1]*255.0); + row.push_back((uint8_t)l); + l = lrint(img->data[offset + j*3+2]*255.0); + row.push_back((uint8_t)l); + //std::cout << "rgb: " << (int)row[row.size()-3] << " " << (int)row[row.size()-2] << " " << (int)row[row.size()-1] << "\n"; + } + prep->add_row(row.data()); + } +} + + +extern "C" uint32_t +icv_pdiff(icv_image_t *img1, icv_image_t *img2) +{ + if (!img1 || !img2) + return -1; + + std::unique_ptr hasher; + int dct_size = 4; // 1024 bits + hasher = std::make_unique(8 * dct_size, true); + + int d1 = (img1->width < img1->height) ? img1->width : img1->height; + imghash::Preprocess prep1(d1, d1); + load_icv(img1, &prep1); + imghash::Image pimg1 = prep1.stop(); + + int d2 = (img2->width < img2->height) ? img2->width : img2->height; + imghash::Preprocess prep2(d2, d2); + load_icv(img2, &prep2); + imghash::Image pimg2 = prep2.stop(); + + auto hash1 = hasher->apply(pimg1); + auto hash2 = hasher->apply(pimg2); + + //std::cout << "hash1:" << format_hash(hash1) << "\n"; + //std::cout << "hash2:" << format_hash(hash2) << "\n"; + + return hasher->hamming_distance(hash1, hash2); +} + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libicv/tests/operations.c b/src/libicv/tests/operations.c index 8d1a6fd4897..defcbd31c0c 100644 --- a/src/libicv/tests/operations.c +++ b/src/libicv/tests/operations.c @@ -25,6 +25,7 @@ #include "common.h" +#include #include #include "bio.h" @@ -122,7 +123,11 @@ int main(int argc, char* argv[]) out_bif = icv_multiply(bif1, bif2); else if (BU_STR_EQUAL(operation, "*")) out_bif = icv_divide(bif1, bif2); - else { + else if (BU_STR_EQUAL(operation, "pdiff")) { + uint32_t hd = icv_pdiff(bif1, bif2); + bu_log("%"PRIu32"\n", hd); + return 0; + } else { bu_log("Using Default operation (+)"); out_bif = icv_add(bif1, bif2); } diff --git a/src/libnmg/CMakeLists.txt b/src/libnmg/CMakeLists.txt index bca09a1b7f3..106c025415d 100644 --- a/src/libnmg/CMakeLists.txt +++ b/src/libnmg/CMakeLists.txt @@ -65,7 +65,7 @@ CMAKEFILES( nmg_private.h ) -BRLCAD_ADDLIB(libnmg "${LIBNMG_SOURCES}" "libbg;libbv;libbn;libbu;${STDCXX_LIBRARIES}") +BRLCAD_ADDLIB(libnmg "${LIBNMG_SOURCES}" "${libnmg_deps};${STDCXX_LIBRARIES}") add_subdirectory(tests) diff --git a/src/libnmg/fuse.c b/src/libnmg/fuse.c index de3085b4d95..e1567259b0b 100644 --- a/src/libnmg/fuse.c +++ b/src/libnmg/fuse.c @@ -2275,9 +2275,14 @@ nmg_radial_build_list(struct bu_list *hd, struct bu_ptbl *shell_tbl, int existin for (;;) { struct nmg_radial *next; next = rmax; + if (!next) + break; do { next = BU_LIST_PNEXT_CIRC(nmg_radial, next); - } while (next->fu == (struct faceuse *)NULL); + } while (next && next->fu == (struct faceuse *)NULL); + + if (!next) + break; if ((next->ang > amax) || (ZERO(next->ang - amax))) { rmax = next; /* a repeated max */ @@ -2286,6 +2291,10 @@ nmg_radial_build_list(struct bu_list *hd, struct bu_ptbl *shell_tbl, int existin } else break; } + + if (!rmax) + return; + /* wires before min establish new rmin */ first = rmin; for (;;) { diff --git a/src/libnmg/misc.c b/src/libnmg/misc.c index c049ab5dbb3..fc7cd81d512 100644 --- a/src/libnmg/misc.c +++ b/src/libnmg/misc.c @@ -1276,6 +1276,9 @@ nmg_loop_plane_newell(const struct loopuse *lu, plane_t pl) eu_next = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l); vg_next = eu_next->vu_p->v_p->vg_p; + if (!vg || !vg_next) + return; + pl_tmp[X] += (vg->coord[Y] - vg_next->coord[Y]) * (vg->coord[Z] + vg_next->coord[Z]); pl_tmp[Y] += (vg->coord[Z] - vg_next->coord[Z]) * (vg->coord[X] + vg_next->coord[X]); pl_tmp[Z] += (vg->coord[X] - vg_next->coord[X]) * (vg->coord[Y] + vg_next->coord[Y]); @@ -1292,6 +1295,9 @@ nmg_loop_plane_newell(const struct loopuse *lu, plane_t pl) fastf_t htest; vg = eu->vu_p->v_p->vg_p; + if (!vg) + return; + htest = VDOT(vg->coord, pl); if (htest > hmax) hmax = htest; diff --git a/src/liboptical/CMakeLists.txt b/src/liboptical/CMakeLists.txt index e97fd5b7ea3..632c76e9eb2 100644 --- a/src/liboptical/CMakeLists.txt +++ b/src/liboptical/CMakeLists.txt @@ -5,7 +5,6 @@ set(OPTICAL_INCLUDE_DIRS ${BU_INCLUDE_DIRS} ${BN_INCLUDE_DIRS} ${RT_INCLUDE_DIRS} - ${TCL_INCLUDE_PATH} ) if (BRLCAD_ENABLE_TCL) set(OPTICAL_INCLUDE_DIRS ${OPTICAL_INCLUDE_DIRS} ${TCL_INCLUDE_PATH}) @@ -112,22 +111,18 @@ if(BRLCAD_ENABLE_OSL) # Add the osl shader to the list of shaders set(LIBOPTICAL_SOURCES ${LIBOPTICAL_SOURCES} sh_osl.cpp) - # Link liboptical with osl-renderer library - if (BRLCAD_ENABLE_TCL) - BRLCAD_ADDLIB(liboptical "${LIBOPTICAL_SOURCES}" "librt;libbn;libbu;liboslrend;${TCL_LIBRARY}") - else (BRLCAD_ENABLE_TCL) - BRLCAD_ADDLIB(liboptical "${LIBOPTICAL_SOURCES}" "librt;libbn;libbu;liboslrend") - endif (BRLCAD_ENABLE_TCL) +endif(BRLCAD_ENABLE_OSL) -else(BRLCAD_ENABLE_OSL) +set(olibs "${liboptical_deps}") +if (TARGET liboslrend) + set(olibs "${olibs};liboslrend") +endif (TARGET liboslrend) +if (BRLCAD_ENABLE_TCL) + set(olibs "${olibs};${TCL_LIBRARY}") +endif (BRLCAD_ENABLE_TCL) - if (BRLCAD_ENABLE_TCL) - BRLCAD_ADDLIB(liboptical "${LIBOPTICAL_SOURCES}" "librt;libbn;libbu;${TCL_LIBRARY}") - else (BRLCAD_ENABLE_TCL) - BRLCAD_ADDLIB(liboptical "${LIBOPTICAL_SOURCES}" "librt;libbn;libbu") - endif (BRLCAD_ENABLE_TCL) +BRLCAD_ADDLIB(liboptical "${LIBOPTICAL_SOURCES}" "${olibs}") -endif(BRLCAD_ENABLE_OSL) CMAKEFILES( CMakeLists.txt diff --git a/src/liboptical/sh_treetherm.c b/src/liboptical/sh_treetherm.c index 2749f567d0a..0860c0b6259 100644 --- a/src/liboptical/sh_treetherm.c +++ b/src/liboptical/sh_treetherm.c @@ -196,7 +196,7 @@ tree_parse(struct bu_list *UNUSED(br), union tree *tr) case OP_NOT: break; case OP_GUARD: break; case OP_XNOP: break; - case OP_NMG_TESS: break; + case OP_TESS: break; /* LIBWDB import/export interface to combinations */ case OP_DB_LEAF: break; } diff --git a/src/libpkg/CMakeLists.txt b/src/libpkg/CMakeLists.txt index e906c99557e..c45fc46135d 100644 --- a/src/libpkg/CMakeLists.txt +++ b/src/libpkg/CMakeLists.txt @@ -11,12 +11,12 @@ set(LIBPKG_SOURCES vers.c ) +BRLCAD_ADDLIB(libpkg "${LIBPKG_SOURCES}" "${libpkg_deps}") +set_target_properties(libpkg PROPERTIES VERSION 20.0.1 SOVERSION 20) + BRLCAD_ADDDATA(tpkg.c sample_applications) BRLCAD_ADDEXEC(tpkg tpkg.c "libbu;libpkg" NO_INSTALL) -BRLCAD_ADDLIB(libpkg "${LIBPKG_SOURCES}" libbu) -SET_TARGET_PROPERTIES(libpkg PROPERTIES VERSION 20.0.1 SOVERSION 20) - add_subdirectory(example) add_subdirectory(example_qt) CMAKEFILES(CMakeLists.txt) diff --git a/src/libpkg/example_qt/client.cpp b/src/libpkg/example_qt/client.cpp index d3250e9b4ed..53d964fa40e 100644 --- a/src/libpkg/example_qt/client.cpp +++ b/src/libpkg/example_qt/client.cpp @@ -142,9 +142,16 @@ main() { /* server's done, send our own message back to it */ bytes = pkg_send(MSG_DATA, "Message from client", 20, connection); + if (bytes < 0) { + bu_log("Unable to cleanly send to %s, port %d.\n", server, port); + } /* let the server know we're done. */ bytes = pkg_send(MSG_CIAO, "DONE", 5, connection); + if (bytes < 0) { + bu_log("Unable to cleanly send DONE to %s, port %d.\n", server, port); + } + bytes = pkg_send(MSG_CIAO, "BYE", 4, connection); if (bytes < 0) { bu_log("Unable to cleanly disconnect from %s, port %d.\n", server, port); diff --git a/src/libqtcad/CMakeLists.txt b/src/libqtcad/CMakeLists.txt index 6a8d3178cb6..62f8a7be36d 100644 --- a/src/libqtcad/CMakeLists.txt +++ b/src/libqtcad/CMakeLists.txt @@ -41,27 +41,31 @@ add_subdirectory(images) set(qtcad_srcs bindings.cpp - gInstance.cpp - QAccordion.cpp - QColorRGB.cpp - QFlowLayout.cpp - QKeyVal.cpp - QToolPalette.cpp - QViewCtrl.cpp + QgAccordion.cpp + QgAppExecDialog.cpp + QgAttributesModel.cpp + QgColorRGB.cpp + QgConsole.cpp + QgConsoleListener.cpp QgDockWidget.cpp + QgFlowLayout.cpp + QgGeomImport.cpp + QgKeyVal.cpp + QgMeasureFilter.cpp QgModel.cpp + QgPolyFilter.cpp + QgQuadView.cpp + QgSW.cpp + QgSelectFilter.cpp + QgToolPalette.cpp QgTreeSelectionModel.cpp QgTreeView.cpp QgUtil.cpp - QtAppExecDialog.cpp - QtSW.cpp - QtCADQuad.cpp - QtCADView.cpp - QtConsole.cpp - QtConsoleListener.cpp + QgView.cpp + QgViewCtrl.cpp ) if (OPENGL_LIBS) - set(qtcad_srcs ${qtcad_srcs} QtGL.cpp) + set(qtcad_srcs ${qtcad_srcs} QgGL.cpp) endif (OPENGL_LIBS) # We need to run Qt's Meta-Object Compiler on some of the @@ -72,24 +76,29 @@ endif (OPENGL_LIBS) # and file-cleanup lists. set(QTCAD_HDR_DIR ${BRLCAD_SOURCE_DIR}/include/qtcad) set(qth_names - QAccordion - QColorRGB - QKeyVal - QToolPalette - QViewCtrl + QgAccordion + QgAppExecDialog + QgAttributesModel + QgColorRGB + QgConsole + QgConsoleListener QgDockWidget + QgGeomImport + QgKeyVal + QgMeasureFilter QgModel + QgPolyFilter + QgQuadView + QgSW + QgSelectFilter + QgToolPalette QgTreeSelectionModel QgTreeView - QtAppExecDialog - QtCADView - QtCADQuad - QtConsole - QtConsoleListener - QtSW + QgView + QgViewCtrl ) if (OPENGL_LIBS) - set(qth_names ${qth_names} QtGL) + set(qth_names ${qth_names} QgGL) endif (OPENGL_LIBS) foreach(qh ${qth_names}) @@ -108,9 +117,9 @@ if(BRLCAD_ENABLE_QT) QT5_ADD_RESOURCES(qtcad_qrc qtcad_resources.qrc) endif (Qt6Widgets_FOUND) if (Qt6Widgets_FOUND) - BRLCAD_ADDLIB(libqtcad "${qtcad_srcs};${qtcad_moc_srcs};${qtcad_qrc}" "libged;libdm;librt;libbv;libbu;Qt6::Core;Qt6::Widgets;${OPENGL_LIBS}" SHARED) + BRLCAD_ADDLIB(libqtcad "${qtcad_srcs};${qtcad_moc_srcs};${qtcad_qrc}" "${libqtcad_deps};Qt6::Core;Qt6::Widgets;${OPENGL_LIBS}" SHARED) else() - BRLCAD_ADDLIB(libqtcad "${qtcad_srcs};${qtcad_moc_srcs};${qtcad_qrc}" "libged;libdm;librt;libbv;libbu;Qt5::Core;Qt5::Widgets;${OPENGL_LIBS}" SHARED) + BRLCAD_ADDLIB(libqtcad "${qtcad_srcs};${qtcad_moc_srcs};${qtcad_qrc}" "${libqtcad_deps};Qt5::Core;Qt5::Widgets;${OPENGL_LIBS}" SHARED) endif (Qt6Widgets_FOUND) set_target_properties(libqtcad PROPERTIES VERSION 20.0.1 SOVERSION 20) if (OPENGL_LIBS) @@ -133,7 +142,7 @@ set(qtcad_ignore_srcs ${qtcad_moc_hdrs} bindings.h qtcad_resources.qrc - QtGL.cpp + QgGL.cpp ) CMAKEFILES(${qtcad_ignore_srcs}) diff --git a/src/libqtcad/QAccordion.cpp b/src/libqtcad/QAccordion.cpp deleted file mode 100644 index bd3533625f8..00000000000 --- a/src/libqtcad/QAccordion.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* Q A C C O R D I O N . C P P - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QAccordion.cpp - * - * Simple accordion widget - * - */ - -#include "common.h" - -#include "qtcad/QAccordion.h" - -QAccordionObject::QAccordionObject(QWidget *pparent, QWidget *object, QString header_title) - : QWidget(pparent) -{ - title = header_title; - toggle = new QPushButton(title, this); - toggle->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - objscrollarea= new QScrollArea(); - objscrollarea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); - objlayout = new QVBoxLayout(this); - objlayout->setSpacing(0); - objlayout->setContentsMargins(0,0,0,0); - objlayout->setAlignment(Qt::AlignTop); - objlayout->addWidget(toggle); - objscrollarea->setWidget(object); - objscrollarea->setWidgetResizable(true); - objlayout->addWidget(objscrollarea); - this->setLayout(objlayout); - - QObject::connect(toggle, &QPushButton::clicked, this, &QAccordionObject::toggleVisibility); -} - -QAccordionObject::~QAccordionObject() -{ -} - -void -QAccordionObject::toggleVisibility() -{ - emit select(this); -} - - -QAccordion::QAccordion(QWidget *pparent) : QWidget(pparent) -{ - mlayout = new QVBoxLayout(); - mlayout->setSpacing(0); - mlayout->setContentsMargins(1,1,1,1); - this->setLayout(mlayout); -} - -QAccordion::~QAccordion() -{ -} - -void -QAccordion::addObject(QAccordionObject *o) -{ - if (!selected) { - selected = o; - } - objs.insert(o); - foreach(QAccordionObject *obj, objs) { - if (obj == selected) { - obj->objscrollarea->show(); - } else { - obj->objscrollarea->hide(); - } - } - mlayout->addWidget(o); - QObject::connect(o, &QAccordionObject::select, this, &QAccordion::open); -} - -void -QAccordion::open(QAccordionObject *o) -{ - if (selected == o) - return; - - selected = o; - - foreach(QAccordionObject *obj, objs) { - if (obj == selected) { - obj->objscrollarea->show(); - } else { - obj->objscrollarea->hide(); - } - } -} - - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - - diff --git a/src/libqtcad/QColorRGB.cpp b/src/libqtcad/QColorRGB.cpp deleted file mode 100644 index cb0b9617787..00000000000 --- a/src/libqtcad/QColorRGB.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* Q C O L O R R G B . C P P - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QColorRGB.cpp - * - * Color selection widget - * - */ - -#include "common.h" - -#include -#include "bu/malloc.h" -#include "bu/str.h" -#include "qtcad/QColorRGB.h" - -QColorRGB::QColorRGB(QWidget *p, QString lstr, QColor dcolor) : QWidget(p) -{ - mlayout = new QHBoxLayout(); - mlayout->setSpacing(0); - mlayout->setContentsMargins(1,1,1,1); - - QString lstrm = QString("%1").arg(lstr); - QLabel *clbl = new QLabel(lstrm); - - - rgbcolor = new QPushButton(""); - rgbcolor->setMinimumWidth(30); - rgbcolor->setMaximumWidth(30); - rgbcolor->setMinimumHeight(30); - rgbcolor->setMaximumHeight(30); - - - qc = dcolor; - - QFont f(""); - f.setStyleHint(QFont::Monospace); - QString rgbstr = QString("%1/%2/%3").arg(qc.red()).arg(qc.green()).arg(qc.blue()); - rgbtext = new QLineEdit(rgbstr); - rgbtext->setFont(f); - set_color_from_text(); - - mlayout->addWidget(clbl); - mlayout->addWidget(rgbtext); - mlayout->addWidget(rgbcolor); - - this->setLayout(mlayout); - - QObject::connect(rgbcolor, &QPushButton::clicked, this, &QColorRGB::set_color_from_button); - QObject::connect(rgbtext, &QLineEdit::returnPressed, this, &QColorRGB::set_color_from_text); -} - -QColorRGB::~QColorRGB() -{ -} - -void -QColorRGB::set_color_from_button() -{ - QColor nc = QColorDialog::getColor(qc); - if (nc.isValid() && nc != qc) { - qc = nc; - QString rgbstr = QString("%1/%2/%3").arg(qc.red()).arg(qc.green()).arg(qc.blue()); - rgbtext->setText(rgbstr); - QString qss = QString("background-color: rgb(%1, %2, %3);").arg(qc.red()).arg(qc.green()).arg(qc.blue()); - rgbcolor->setStyleSheet(qss); - - // Sync bu_color - QString colstr = rgbtext->text(); - char *ccstr = bu_strdup(colstr.toLocal8Bit().data()); - bu_opt_color(NULL, 1, (const char **)&ccstr, (void *)&bc); - bu_free(ccstr, "ccstr"); - - emit color_changed(); - } -} - -void -QColorRGB::set_color_from_text() -{ - QString colstr = rgbtext->text(); - if (!colstr.length()) - return; - - // We need a C string to send into the libbu routines - directly referencing - // QString data isn't stable. Also, split into argv array, in case of spaces - char *ccstr = bu_strdup(colstr.toLocal8Bit().data()); - char **av = (char **)bu_calloc(strlen(ccstr) + 1, sizeof(char *), "argv array"); - int nargs = bu_argv_from_string(av, strlen(ccstr), ccstr); - int acnt = bu_opt_color(NULL, nargs, (const char **)av, (void *)&bc); - bu_free(av, "av"); - bu_free(ccstr, "ccstr"); - - if (acnt != 1) - return; - - int rgb[3]; - if (!bu_color_to_rgb_ints(&bc, &rgb[0], &rgb[1], &rgb[2])) - return; - - QColor nc(rgb[0], rgb[1], rgb[2]); - - if (nc.isValid()) { - qc = nc; - QString qss = QString("background-color: rgb(%1, %2, %3);").arg(qc.red()).arg(qc.green()).arg(qc.blue()); - rgbcolor->setStyleSheet(qss); - - emit color_changed(); - } -} - - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - - diff --git a/src/libqtcad/QFlowLayout.cpp b/src/libqtcad/QFlowLayout.cpp deleted file mode 100644 index 288a6a3de45..00000000000 --- a/src/libqtcad/QFlowLayout.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "common.h" - -#include -#include -#include -#include -#include "qtcad/QFlowLayout.h" - -QFlowLayout::QFlowLayout(QWidget *pparent, int mmargin, int hSpacing, int vSpacing) - : QLayout(pparent), m_hSpace(hSpacing), m_vSpace(vSpacing) -{ - setContentsMargins(mmargin, mmargin, mmargin, mmargin); -} - -QFlowLayout::QFlowLayout(int mmargin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing) -{ - setContentsMargins(mmargin, mmargin, mmargin, mmargin); -} - -QFlowLayout::~QFlowLayout() -{ - QLayoutItem *item; - while ((item = takeAt(0))) - delete item; -} - -void QFlowLayout::addItem(QLayoutItem *item) -{ - itemList.append(item); -} - -int QFlowLayout::horizontalSpacing() const -{ - if (m_hSpace >= 0) { - return m_hSpace; - } else { - return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); - } -} - -int QFlowLayout::verticalSpacing() const -{ - if (m_vSpace >= 0) { - return m_vSpace; - } else { - return smartSpacing(QStyle::PM_LayoutVerticalSpacing); - } -} - -void QFlowLayout::setHorizontalSpacing(int hspacing) -{ - m_hSpace = hspacing; -} - -void QFlowLayout::setVerticalSpacing(int vspacing) -{ - m_vSpace = vspacing; -} - -int QFlowLayout::count() const -{ - return itemList.size(); -} - -QLayoutItem *QFlowLayout::itemAt(int index) const -{ - return itemList.value(index); -} - -QLayoutItem *QFlowLayout::takeAt(int index) -{ - if (index >= 0 && index < itemList.size()) - return itemList.takeAt(index); - else - return 0; -} - -Qt::Orientations QFlowLayout::expandingDirections() const -{ - return Qt::Orientations{}; -} - -bool QFlowLayout::hasHeightForWidth() const -{ - return true; -} - -int QFlowLayout::heightForWidth(int width) const -{ - int height = doLayout(QRect(0, 0, width, 0), true); - return height; -} - -void QFlowLayout::setGeometry(const QRect &rect) -{ - QLayout::setGeometry(rect); - doLayout(rect, false); -} - -QSize QFlowLayout::sizeHint() const -{ - return minimumSize(); -} - -QSize QFlowLayout::minimumSize() const -{ - QSize size; - QLayoutItem *item; - foreach (item, itemList) - size = size.expandedTo(item->minimumSize()); - -#ifndef USE_QT6 - // TODO - figure out the right Qt6 logic here... - size += QSize(2*margin(), 2*margin()); -#endif - return size; -} - -int QFlowLayout::doLayout(const QRect &rect, bool testOnly) const -{ - int left, top, right, bottom; - getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); - int lineHeight = 0; - - QLayoutItem *item; - foreach (item, itemList) { - QWidget *wid = item->widget(); - int spaceX = horizontalSpacing(); - if (spaceX == -1) - spaceX = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = verticalSpacing(); - if (spaceY == -1) - spaceY = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { - x = effectiveRect.x(); - y = y + lineHeight + spaceY; - nextX = x + item->sizeHint().width() + spaceX; - lineHeight = 0; - } - - if (!testOnly) - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); - - x = nextX; - lineHeight = qMax(lineHeight, item->sizeHint().height()); - } - return y + lineHeight - rect.y() + bottom; -} -int QFlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ - QObject *pparent = this->parent(); - if (!pparent) { - return -1; - } else if (pparent->isWidgetType()) { - QWidget *pw = static_cast(pparent); - return pw->style()->pixelMetric(pm, 0, pw); - } else { - return static_cast(pparent)->spacing(); - } -} diff --git a/src/libqtcad/QKeyVal.cpp b/src/libqtcad/QKeyVal.cpp deleted file mode 100644 index e685cce8c05..00000000000 --- a/src/libqtcad/QKeyVal.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* Q K E Y V A L . C P P - * BRL-CAD - * - * Copyright (c) 2020-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QKeyVal.cpp - * - */ - -#include - -#include "qtcad/QKeyVal.h" - -// *********** Node ************** - -QKeyValNode::QKeyValNode(QKeyValNode *aParent) -: parent(aParent) -{ - if(parent) { - parent->children.append(this); - } -} - -QKeyValNode::~QKeyValNode() -{ - qDeleteAll(children); -} - -// *********** Model ************** - -QKeyValModel::QKeyValModel(QObject *aParent) -: QAbstractItemModel(aParent) -{ -} - -QKeyValModel::~QKeyValModel() -{ -} - -QVariant -QKeyValModel::headerData(int section, Qt::Orientation, int role) const -{ - if (role != Qt::DisplayRole) return QVariant(); - if (section == 0) return QString("Property"); - if (section == 1) return QString("Value"); - return QVariant(); -} - -QVariant -QKeyValModel::data(const QModelIndex & idx, int role) const -{ - if (!idx.isValid()) return QVariant(); - QKeyValNode *curr_node = IndexNode(idx); - if (role == Qt::DisplayRole && idx.column() == 0) return QVariant(curr_node->name); - if (role == Qt::DisplayRole && idx.column() == 1) return QVariant(curr_node->value); - return QVariant(); -} - -bool -QKeyValModel::setData(const QModelIndex & idx, const QVariant & value, int role) -{ - if (!idx.isValid()) return false; - QVector roles; - bool ret = false; - QKeyValNode *curr_node = IndexNode(idx); - if (role == Qt::DisplayRole) { - curr_node->name = value.toString(); - roles.append(Qt::DisplayRole); - ret = true; - } - if (ret) emit dataChanged(idx, idx, roles); - return ret; -} - -void QKeyValModel::setRootNode(QKeyValNode *root) -{ - m_root = root; - beginResetModel(); - endResetModel(); -} - -QModelIndex QKeyValModel::index(int row, int column, const QModelIndex &parent_idx) const -{ - if (hasIndex(row, column, parent_idx)) { - QKeyValNode *cnode = IndexNode(parent_idx)->children.at(row); - return createIndex(row, column, cnode); - } - return QModelIndex(); -} - -QModelIndex QKeyValModel::parent(const QModelIndex &child) const -{ - QKeyValNode *pnode = IndexNode(child)->parent; - if (pnode == m_root) return QModelIndex(); - return createIndex(NodeRow(pnode), 0, pnode); -} - -int QKeyValModel::rowCount(const QModelIndex &parent_idx) const -{ - return IndexNode(parent_idx)->children.count(); -} - -int QKeyValModel::columnCount(const QModelIndex &parent_idx) const -{ - Q_UNUSED(parent_idx); - return 2; -} - -QModelIndex QKeyValModel::NodeIndex(QKeyValNode *node) const -{ - if (node == m_root) return QModelIndex(); - return createIndex(NodeRow(node), 0, node); -} - -QKeyValNode * QKeyValModel::IndexNode(const QModelIndex &idx) const -{ - if (idx.isValid()) { - return static_cast(idx.internalPointer()); - } - return m_root; -} - -int QKeyValModel::NodeRow(QKeyValNode *node) const -{ - return node->parent->children.indexOf(node); -} - -QKeyValNode * -QKeyValModel::add_pair(const char *name, const char *value, QKeyValNode *curr_node, int type) -{ - QKeyValNode *new_node = new QKeyValNode(curr_node); - new_node->name = name; - new_node->value = value; - new_node->attr_type = type; - return new_node; -} - - -// *********** View ************** -void QKeyValDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QString text = index.data().toString(); - painter->drawText(option.rect, text, QTextOption(Qt::AlignLeft)); -} - -QSize QKeyValDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QSize name_size = option.fontMetrics.size(Qt::TextSingleLine, index.data().toString()); - return name_size; -} - - -QKeyValView::QKeyValView(QWidget *pparent, int tree_decorate) : QTreeView(pparent) -{ - //this->setContextMenuPolicy(Qt::CustomContextMenu); - if (!tree_decorate) { - setRootIsDecorated(false); - } -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - - diff --git a/src/libqtcad/QToolPalette.cpp b/src/libqtcad/QToolPalette.cpp deleted file mode 100644 index 6b7e525a6d6..00000000000 --- a/src/libqtcad/QToolPalette.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* Q T O O L P A L E T T E . C X X - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QToolPalette.cxx - * - * Qt Tool Palette implementation - * - */ - -#include "common.h" - -#include -#include -#include "qtcad/QToolPalette.h" - -QToolPaletteButton::QToolPaletteButton(QWidget *bparent, QIcon *iicon, QToolPaletteElement *eparent) : QPushButton(bparent) -{ - setIcon(*iicon); - element = eparent; - QObject::connect(this, &QToolPaletteButton::clicked, this, &QToolPaletteButton::select_element); -} - - -void -QToolPaletteButton::select_element() -{ - emit element_selected(element); -} - -void -QToolPaletteButton::setButtonElement(QIcon *iicon, QToolPaletteElement *n_element) -{ - setIcon(*iicon); - element = n_element; -} - - -QToolPaletteElement::QToolPaletteElement(QIcon *iicon, QWidget *control) -{ - button = new QToolPaletteButton(this, iicon, this); - button->setCheckable(true); - controls = control; - controls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); -} - -QToolPaletteElement::~QToolPaletteElement() -{ - delete button; -} - -#if 0 -bool -QToolPaletteElement::eventFilter(QObject *o, QEvent *e) -{ - if (!o || !e) - return false; - - printf("palette element filter\n"); - - return controls->eventFilter(o, e); -} -#endif - -void -QToolPaletteElement::setButton(QToolPaletteButton *n_button) -{ - button = n_button; -} - -void -QToolPaletteElement::setControls(QWidget *n_control) -{ - controls = n_control; -} - -void -QToolPaletteElement::element_view_changed(unsigned long long flags) -{ - emit view_changed(flags); -} - -void -QToolPaletteElement::do_view_update(unsigned long long flags) -{ - // TODO - do any element level updating (button highlighting?) - emit element_view_update(flags); -} - -void -QToolPaletteElement::do_element_unhide(void *) -{ - emit element_unhide(); -} - -QToolPalette::QToolPalette(QWidget *pparent) : QWidget(pparent) -{ - always_selected = 1; - icon_width = 30; - icon_height = 30; - mlayout = new QVBoxLayout(); - mlayout->setSpacing(0); - mlayout->setContentsMargins(1,1,1,1); - - - button_container = new QWidget(); - button_layout = new QFlowLayout(); - button_layout->setHorizontalSpacing(0); - button_layout->setVerticalSpacing(0); - button_layout->setContentsMargins(0,0,0,0); - button_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - button_container->setMinimumHeight(icon_height); - button_container->setMinimumWidth(icon_width*5+1); - button_container->setLayout(button_layout); - - control_container = new QScrollArea(); - control_container->setWidgetResizable(true); - mlayout->addWidget(button_container); - mlayout->addWidget(control_container); - - selected = NULL; - - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - this->setLayout(mlayout); -} - -QToolPalette::~QToolPalette() -{ -} - -void -QToolPalette::button_layout_resize() -{ - div_t layout_dim = div(button_container->size().width()-1, icon_width); - div_t layout_grid = div((int)elements.count(), (int)layout_dim.quot); - if (layout_grid.rem > 0) { - button_container->setMinimumHeight((layout_grid.quot + 1) * icon_height); - button_container->setMaximumHeight((layout_grid.quot + 1) * icon_height); - } else { - button_container->setMinimumHeight((layout_grid.quot) * icon_height); - button_container->setMaximumHeight((layout_grid.quot) * icon_height); - } -} - -void -QToolPalette::resizeEvent(QResizeEvent *pevent) -{ - QWidget::resizeEvent(pevent); - button_layout_resize(); -} - -void -QToolPalette::setIconWidth(int iwidth) -{ - icon_width = iwidth; - foreach(QToolPaletteElement *el, elements) { - el->button->setMinimumWidth(icon_height); - el->button->setMaximumWidth(icon_height); - } - updateGeometry(); -} - -void -QToolPalette::setIconHeight(int iheight) -{ - icon_height = iheight; - foreach(QToolPaletteElement *el, elements) { - el->button->setMinimumHeight(icon_height); - el->button->setMaximumHeight(icon_height); - } - updateGeometry(); -} - - -void -QToolPalette::setAlwaysSelected(int toggle) -{ - always_selected = toggle; - if (always_selected && selected == NULL) { - palette_displayElement(*(elements.begin())); - } -} - -void -QToolPalette::do_view_update(unsigned long long flags) -{ - emit palette_view_update(flags); -} - - -void -QToolPalette::palette_do_view_changed(unsigned long long flags) -{ - emit view_changed(flags); -} - -void -QToolPalette::addElement(QToolPaletteElement *element) -{ - element->button->setMinimumWidth(icon_width); - element->button->setMaximumWidth(icon_width); - element->button->setMinimumHeight(icon_height); - element->button->setMaximumHeight(icon_height); - button_layout->addWidget(element->button); - elements.insert(element); - - QObject::connect(element->button, &QToolPaletteButton::element_selected, this, &QToolPalette::palette_displayElement); - - QObject::connect(this, &QToolPalette::palette_view_update, element, &QToolPaletteElement::do_view_update); - QObject::connect(element, &QToolPaletteElement::view_changed, this, &QToolPalette::palette_do_view_changed); - - - updateGeometry(); - if (!selected && always_selected) { - palette_displayElement(element); - selected->button->setStyleSheet(""); - } -} - -void -QToolPalette::deleteElement(QToolPaletteElement *element) -{ - elements.remove(element); - if (selected == element) { - palette_displayElement(*elements.begin()); - } - button_layout->removeWidget(element->button); - updateGeometry(); - delete element; -} - -void -QToolPalette::palette_displayElement(QToolPaletteElement *element) -{ - if (element) { - if (element == selected) { - if (!always_selected) { - if (element->button->isChecked()) element->button->setChecked(false); - element->controls->hide(); - selected = NULL; - } else { - element->button->setStyleSheet(selected_style); - } - } else { - if (!element->button->isChecked()) element->button->setChecked(true); - if (selected && element != selected) { - selected->scroll_pos = control_container->verticalScrollBar()->sliderPosition(); - selected->controls->hide(); - if (selected->button->isChecked()) selected->button->setChecked(false); - } - control_container->takeWidget(); - control_container->setWidget(element->controls); - element->controls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - element->controls->show(); - element->do_element_unhide(NULL); - control_container->verticalScrollBar()->setSliderPosition(element->scroll_pos); - selected = element; - foreach(QToolPaletteElement *el, elements) { - if (el != selected) { - el->button->setDown(false); - el->button->setStyleSheet(""); - } else { - el->button->setStyleSheet(selected_style); - } - } - } - emit palette_element_selected(element); - } -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - - diff --git a/src/libqtcad/QViewCtrl.cpp b/src/libqtcad/QViewCtrl.cpp deleted file mode 100644 index 7efeb7344df..00000000000 --- a/src/libqtcad/QViewCtrl.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* Q V I E W C T R L . C P P - * BRL-CAD - * - * Copyright (c) 2022-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QViewCtrl.cpp - * - * Qt BRL-CAD View Control button panel implementation - * - */ - -#include "common.h" - -#include "bu/env.h" -#include "qtcad/QViewCtrl.h" -#include "qtcad/SignalFlags.h" - - -QViewCtrl::QViewCtrl(QWidget *pparent, struct ged *pgedp) : QToolBar(pparent) -{ - gedp = pgedp; - - this->setStyleSheet("QToolButton{margin:0px;}"); - - sca = addAction(QIcon(QPixmap(":images/view/view_scale.png")), "Scale"); - rot = addAction(QIcon(QPixmap(":images/view/view_rotate.png")), "Rotate"); - tra = addAction(QIcon(QPixmap(":images/view/view_translate.png")), "Translate"); - center = addAction(QIcon(QPixmap(":images/view/view_center.png")), "Center"); - - addSeparator(); - - raytrace = addAction(QIcon(QPixmap(":images/view/raytrace.png")), "Raytrace"); - fb_mode = addAction(QIcon(QPixmap(":images/view/framebuffer_off.png")), "Framebuffer Off/Overlay/Underlay"); - fb_clear = addAction(QIcon(QPixmap(":images/view/framebuffer_clear.png")), "Clear Framebuffer"); - - // Connect buttons to standard actions - connect(sca, &QAction::triggered, this, &QViewCtrl::sca_mode); - connect(rot, &QAction::triggered, this, &QViewCtrl::rot_mode); - connect(tra, &QAction::triggered, this, &QViewCtrl::tra_mode); - connect(center, &QAction::triggered, this, &QViewCtrl::center_mode); - connect(raytrace, &QAction::triggered, this, &QViewCtrl::raytrace_cmd); - connect(fb_clear, &QAction::triggered, this, &QViewCtrl::fbclear_cmd); - connect(fb_mode, &QAction::triggered, this, &QViewCtrl::fb_mode_cmd); -} - -QViewCtrl::~QViewCtrl() -{ -} - -void -QViewCtrl::sca_mode() -{ - emit lmouse_mode(BV_SCALE); -} - -void -QViewCtrl::rot_mode() -{ - emit lmouse_mode(BV_ROT); -} - -void -QViewCtrl::tra_mode() -{ - emit lmouse_mode(BV_TRANS); -} - -void -QViewCtrl::center_mode() -{ - emit lmouse_mode(BV_CENTER); -} - - -void -QViewCtrl::fbclear_cmd() -{ - bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); - const char *av[2] = {NULL}; - av[0] = "fbclear"; - ged_exec(gedp, 1, (const char **)av); - emit view_changed(QTCAD_VIEW_REFRESH); -} - -void -QViewCtrl::fb_mode_cmd() -{ - if (!gedp->ged_gvp) - return; - struct bview *v = gedp->ged_gvp; - switch (v->gv_s->gv_fb_mode) { - case 0: - v->gv_s->gv_fb_mode = 2; - break; - case 2: - v->gv_s->gv_fb_mode = 1; - break; - case 1: - v->gv_s->gv_fb_mode = 0; - break; - default: - bu_log("Error - invalid fb mode: %d\n", v->gv_s->gv_fb_mode); - } - emit view_changed(QTCAD_VIEW_REFRESH); -} - -void -QViewCtrl::do_view_update(unsigned long long flags) -{ - if (!gedp->ged_gvp || !flags) - return; - struct bview *v = gedp->ged_gvp; - switch (v->gv_s->gv_fb_mode) { - case 0: - fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer_off.png"))); - break; - case 1: - fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer.png"))); - break; - case 2: - fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer_underlay.png"))); - break; - default: - bu_log("Error - invalid fb mode: %d\n", v->gv_s->gv_fb_mode); - } -} - -void rt_cmd_start(int pid, void *ctx) -{ - QViewCtrl *vctrl = (QViewCtrl *)ctx; - vctrl->raytrace_start(pid); -} - -void rt_cmd_done(int pid, void *ctx) -{ - QViewCtrl *vctrl = (QViewCtrl *)ctx; - vctrl->raytrace_done(pid); -} - -void -QViewCtrl::raytrace_cmd() -{ - bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); - const char *av[4] = {NULL}; - struct bu_vls pid_str = BU_VLS_INIT_ZERO; - - gedp->ged_subprocess_init_callback = &rt_cmd_start; - gedp->ged_subprocess_end_callback = &rt_cmd_done; - gedp->ged_subprocess_clbk_context = (void *)this; - - if (raytrace_running) { - if (pid < 0) - goto cmd_cleanup; - bu_vls_sprintf(&pid_str, "%d", pid); - av[0] = "process"; - av[1] = "pabort"; - av[2] = bu_vls_cstr(&pid_str); - ged_exec(gedp, 3, (const char **)av); - goto cmd_cleanup; - } - - av[0] = "ert"; - ged_exec(gedp, 1, (const char **)av); - emit view_changed(QTCAD_VIEW_REFRESH); - -cmd_cleanup: - gedp->ged_subprocess_init_callback = NULL; - gedp->ged_subprocess_end_callback =NULL; - gedp->ged_subprocess_clbk_context = NULL; - bu_vls_free(&pid_str); -} - -void -QViewCtrl::raytrace_start(int rpid) -{ - raytrace->setIcon(QIcon(QPixmap(":images/view/raytrace_abort.png"))); - raytrace_running = true; - pid = rpid; -} - -void -QViewCtrl::raytrace_done(int) -{ - raytrace->setIcon(QIcon(QPixmap(":images/view/raytrace.png"))); - raytrace_running = false; - pid = -1; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - - diff --git a/src/libqtcad/QgAccordion.cpp b/src/libqtcad/QgAccordion.cpp new file mode 100644 index 00000000000..5765972a164 --- /dev/null +++ b/src/libqtcad/QgAccordion.cpp @@ -0,0 +1,120 @@ +/* Q A C C O R D I O N . C P P + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgAccordion.cpp + * + * Simple accordion widget + * + */ + +#include "common.h" + +#include "qtcad/QgAccordion.h" + +QgAccordionObject::QgAccordionObject(QWidget *pparent, QWidget *object, QString header_title) + : QWidget(pparent) +{ + title = header_title; + toggle = new QPushButton(title, this); + toggle->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + objscrollarea= new QScrollArea(); + objscrollarea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + objlayout = new QVBoxLayout(this); + objlayout->setSpacing(0); + objlayout->setContentsMargins(0,0,0,0); + objlayout->setAlignment(Qt::AlignTop); + objlayout->addWidget(toggle); + objscrollarea->setWidget(object); + objscrollarea->setWidgetResizable(true); + objlayout->addWidget(objscrollarea); + this->setLayout(objlayout); + + QObject::connect(toggle, &QPushButton::clicked, this, &QgAccordionObject::toggleVisibility); +} + +QgAccordionObject::~QgAccordionObject() +{ +} + +void +QgAccordionObject::toggleVisibility() +{ + QTCAD_SLOT("QgAccordionObject::toggleVisibility", 1); + emit select(this); +} + + +QgAccordion::QgAccordion(QWidget *pparent) : QWidget(pparent) +{ + mlayout = new QVBoxLayout(); + mlayout->setSpacing(0); + mlayout->setContentsMargins(1,1,1,1); + this->setLayout(mlayout); +} + +QgAccordion::~QgAccordion() +{ +} + +void +QgAccordion::addObject(QgAccordionObject *o) +{ + if (!selected) { + selected = o; + } + objs.insert(o); + foreach(QgAccordionObject *obj, objs) { + if (obj == selected) { + obj->objscrollarea->show(); + } else { + obj->objscrollarea->hide(); + } + } + mlayout->addWidget(o); + QObject::connect(o, &QgAccordionObject::select, this, &QgAccordion::open); +} + +void +QgAccordion::open(QgAccordionObject *o) +{ + if (selected == o) + return; + + selected = o; + + foreach(QgAccordionObject *obj, objs) { + if (obj == selected) { + obj->objscrollarea->show(); + } else { + obj->objscrollarea->hide(); + } + } +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + + diff --git a/src/libqtcad/QgAppExecDialog.cpp b/src/libqtcad/QgAppExecDialog.cpp new file mode 100644 index 00000000000..5b362b0c5d8 --- /dev/null +++ b/src/libqtcad/QgAppExecDialog.cpp @@ -0,0 +1,112 @@ +/* Q G A P P E X E C D I A L O G . C P P + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgAppExecDialog.cpp + * + * Support for running external applications and viewing the output + * stream in a console widget embedded in a dialog window. + * + */ + +#include +#include +#include +#include +#include "qtcad/QgAppExecDialog.h" + +QgAppExecDialog::QgAppExecDialog(QWidget *pparent, QString executable, QStringList args, QString lfile) : QDialog(pparent) +{ + QVBoxLayout *dlayout = new QVBoxLayout; + buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel); + QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QgAppExecDialog::process_abort); + console = new QgConsole(this); + console->prompt(""); + setLayout(dlayout); + dlayout->addWidget(console); + dlayout->addWidget(buttonBox); + logfile = NULL; + if (lfile.length() > 0) { + logfile = new QFile(lfile); + if (!logfile->open(QIODevice::Append | QIODevice::Text)) { + logfile = NULL; + return; + } + QTextStream log_stream(logfile); + log_stream << executable << " " << args.join(" ") << "\n"; + } +} + +void QgAppExecDialog::read_stdout() +{ + QTCAD_SLOT("QgAppExecDialog::read_stdout", 1); + QString std_output = proc->readAllStandardOutput(); + console->printString(std_output); + if (logfile) { + QTextStream log_stream(logfile); + log_stream << std_output; + logfile->flush(); + } +} + +void QgAppExecDialog::read_stderr() +{ + QTCAD_SLOT("QgAppExecDialog::read_stderr", 1); + QString err_output = proc->readAllStandardError(); + console->printString(err_output); + if (logfile) { + QTextStream log_stream(logfile); + log_stream << err_output; + logfile->flush(); + } +} + +void QgAppExecDialog::process_abort() +{ + QTCAD_SLOT("QgAppExecDialog::process_abort", 1); + proc->kill(); + console->printString("\nAborted!\n"); + if (logfile) { + QTextStream log_stream(logfile); + log_stream << "\nAborted!\n"; + logfile->flush(); + } + process_done(0, QProcess::NormalExit); +} + +void QgAppExecDialog::process_done(int , QProcess::ExitStatus) +{ + QTCAD_SLOT("QgAppExecDialog::process_done", 1); + if (logfile) logfile->close(); + buttonBox->clear(); + buttonBox->addButton(QDialogButtonBox::Ok); + QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &QgAppExecDialog::accept); + setWindowTitle("Process Finished"); +} + +/* + * Local Variables: + * mode: C++ + * tab-width: 8 + * c-basic-offset: 4 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/src/libqtcad/QgAttributesModel.cpp b/src/libqtcad/QgAttributesModel.cpp new file mode 100644 index 00000000000..5c8bccac389 --- /dev/null +++ b/src/libqtcad/QgAttributesModel.cpp @@ -0,0 +1,220 @@ +/* Q G A T T R I B U T E S M O D E L . C P P + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgAttributesModel.cpp + * + */ + +#include "common.h" +#include +#include +#include + +#include "bu/sort.h" +#include "bu/avs.h" +#include "bu/malloc.h" +#include "qtcad/QgAttributesModel.h" +#include "qtcad/QgModel.h" + +QgAttributesModel::QgAttributesModel(QObject *parentobj, struct db_i *dbip, struct directory *dp, int show_standard, int show_user) + : QgKeyValModel(parentobj) +{ + int i = 0; + current_dbip = dbip; + current_dp = dp; + if (show_standard) { + std_visible = 1; + } else { + std_visible = 0; + } + if (show_user) { + user_visible = 1; + } else { + user_visible = 0; + } + m_root = new QgKeyValNode(); + BU_GET(avs, struct bu_attribute_value_set); + bu_avs_init_empty(avs); + if (std_visible) { + while (i != ATTR_NULL) { + add_pair(db5_standard_attribute(i), "", m_root, i); + i++; + } + } + if (dbip != DBI_NULL && dp != RT_DIR_NULL) { + update(dbip, dp); + } +} + +QgAttributesModel::~QgAttributesModel() +{ + bu_avs_free(avs); + BU_PUT(avs, struct bu_attribute_value_set); +} + +static int +attr_children(const char *attr) +{ + if (BU_STR_EQUAL(attr, "color")) return 3; + return 0; +} + + +bool QgAttributesModel::canFetchMore(const QModelIndex &idx) const +{ + QgKeyValNode *curr_node = IndexNode(idx); + if (curr_node == m_root) return false; + if (rowCount(idx)) { + return false; + } + int cnt = attr_children(curr_node->name.toLocal8Bit()); + if (cnt > 0) return true; + return false; +} + +void +QgAttributesModel::add_Children(const char *name, QgKeyValNode *curr_node) +{ + if (BU_STR_EQUAL(name, "color")) { + QString val(bu_avs_get(avs, name)); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QStringList vals = val.split(QRegExp("/")); +#else + QStringList vals = val.split(QRegularExpression("/")); +#endif + (void)add_pair("r", vals.at(0).toLocal8Bit(), curr_node, db5_standardize_attribute(name)); + (void)add_pair("g", vals.at(1).toLocal8Bit(), curr_node, db5_standardize_attribute(name)); + (void)add_pair("b", vals.at(2).toLocal8Bit(), curr_node, db5_standardize_attribute(name)); + return; + } + (void)add_pair(name, bu_avs_get(avs, name), curr_node, db5_standardize_attribute(name)); +} + + +void QgAttributesModel::fetchMore(const QModelIndex &idx) +{ + QgKeyValNode *curr_node = IndexNode(idx); + if (curr_node == m_root) return; + int cnt = attr_children(curr_node->name.toLocal8Bit()); + if (cnt) { // && !idx.child(cnt-1, 0).isValid()) { + beginInsertRows(idx, 0, cnt); + add_Children(curr_node->name.toLocal8Bit(),curr_node); + endInsertRows(); + } +} + +bool QgAttributesModel::hasChildren(const QModelIndex &idx) const +{ + QgKeyValNode *curr_node = IndexNode(idx); + if (curr_node == m_root) return true; + if (curr_node->value == QString("")) return false; + int cnt = attr_children(curr_node->name.toLocal8Bit()); + if (cnt > 0) return true; + return false; +} + +int QgAttributesModel::update(struct db_i *new_dbip, struct directory *new_dp) +{ + current_dp = new_dp; + current_dbip = new_dbip; + if (current_dbip != DBI_NULL && current_dp != RT_DIR_NULL) { + QMap standard_nodes; + int i = 0; + m_root = new QgKeyValNode(); + beginResetModel(); + struct bu_attribute_value_pair *avpp; + for (BU_AVS_FOR(avpp, avs)) { + bu_avs_remove(avs, avpp->name); + } + (void)db5_get_attributes(current_dbip, avs, current_dp); + + if (std_visible) { + while (i != ATTR_NULL) { + standard_nodes.insert(db5_standard_attribute(i), add_pair(db5_standard_attribute(i), "", m_root, i)); + i++; + } + for (BU_AVS_FOR(avpp, avs)) { + if (db5_is_standard_attribute(avpp->name)) { + if (standard_nodes.find(avpp->name) != standard_nodes.end()) { + QString new_value(avpp->value); + QgKeyValNode *snode = standard_nodes.find(avpp->name).value(); + snode->value = new_value; + } else { + add_pair(avpp->name, avpp->value, m_root, db5_standardize_attribute(avpp->name)); + } + } + } + } + if (user_visible) { + for (BU_AVS_FOR(avpp, avs)) { + if (!db5_is_standard_attribute(avpp->name)) { + add_pair(avpp->name, avpp->value, m_root, ATTR_NULL); + } + } + } + endResetModel(); + } else { + m_root = new QgKeyValNode(); + beginResetModel(); + endResetModel(); + } + return 0; +} + +void +QgAttributesModel::refresh(const QModelIndex &idx) +{ + QTCAD_SLOT("QgAttributesModel::refresh", 1); + current_dp = (struct directory *)(idx.data(QgModel::DirectoryInternalRole).value()); + update(current_dbip, current_dp); +} + +void +QgAttributesModel::db_change_refresh() +{ + QTCAD_SLOT("QgAttributesModel::db_change_refresh", 1); + update(current_dbip, current_dp); +} + +void +QgAttributesModel::do_dbi_update(struct db_i *dbip) +{ + QTCAD_SLOT("QgAttributesModel::do_dbi_update", 1); + current_dbip = dbip; + m_root = new QgKeyValNode(); + beginResetModel(); + endResetModel(); + if (std_visible) { + int i = 0; + while (i != ATTR_NULL) { + add_pair(db5_standard_attribute(i), "", m_root, i); + i++; + } + } +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libqtcad/QgColorRGB.cpp b/src/libqtcad/QgColorRGB.cpp new file mode 100644 index 00000000000..20c9d0e46e0 --- /dev/null +++ b/src/libqtcad/QgColorRGB.cpp @@ -0,0 +1,142 @@ +/* Q G C O L O R R G B . C P P + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgColorRGB.cpp + * + * Color selection widget + * + */ + +#include "common.h" + +#include +#include "bu/malloc.h" +#include "bu/str.h" +#include "qtcad/QgColorRGB.h" + +QgColorRGB::QgColorRGB(QWidget *p, QString lstr, QColor dcolor) : QWidget(p) +{ + mlayout = new QHBoxLayout(); + mlayout->setSpacing(0); + mlayout->setContentsMargins(1,1,1,1); + + QString lstrm = QString("%1").arg(lstr); + QLabel *clbl = new QLabel(lstrm); + + + rgbcolor = new QPushButton(""); + rgbcolor->setMinimumWidth(30); + rgbcolor->setMaximumWidth(30); + rgbcolor->setMinimumHeight(30); + rgbcolor->setMaximumHeight(30); + + + qc = dcolor; + + QFont f(""); + f.setStyleHint(QFont::Monospace); + QString rgbstr = QString("%1/%2/%3").arg(qc.red()).arg(qc.green()).arg(qc.blue()); + rgbtext = new QLineEdit(rgbstr); + rgbtext->setFont(f); + set_color_from_text(); + + mlayout->addWidget(clbl); + mlayout->addWidget(rgbtext); + mlayout->addWidget(rgbcolor); + + this->setLayout(mlayout); + + QObject::connect(rgbcolor, &QPushButton::clicked, this, &QgColorRGB::set_color_from_button); + QObject::connect(rgbtext, &QLineEdit::returnPressed, this, &QgColorRGB::set_color_from_text); +} + +QgColorRGB::~QgColorRGB() +{ +} + +void +QgColorRGB::set_color_from_button() +{ + QTCAD_SLOT("QgColorRGB::set_color_from_button", 1); + + QColor nc = QColorDialog::getColor(qc); + if (nc.isValid() && nc != qc) { + qc = nc; + QString rgbstr = QString("%1/%2/%3").arg(qc.red()).arg(qc.green()).arg(qc.blue()); + rgbtext->setText(rgbstr); + QString qss = QString("background-color: rgb(%1, %2, %3);").arg(qc.red()).arg(qc.green()).arg(qc.blue()); + rgbcolor->setStyleSheet(qss); + + // Sync bu_color + QString colstr = rgbtext->text(); + char *ccstr = bu_strdup(colstr.toLocal8Bit().data()); + bu_opt_color(NULL, 1, (const char **)&ccstr, (void *)&bc); + bu_free(ccstr, "ccstr"); + + emit color_changed(&bc); + } +} + +void +QgColorRGB::set_color_from_text() +{ + QTCAD_SLOT("QgColorRGB::set_color_from_text", 1); + + QString colstr = rgbtext->text(); + if (!colstr.length()) + return; + + // We need a C string to send into the libbu routines - directly referencing + // QString data isn't stable. Also, split into argv array, in case of spaces + char *ccstr = bu_strdup(colstr.toLocal8Bit().data()); + char **av = (char **)bu_calloc(strlen(ccstr) + 1, sizeof(char *), "argv array"); + int nargs = bu_argv_from_string(av, strlen(ccstr), ccstr); + int acnt = bu_opt_color(NULL, nargs, (const char **)av, (void *)&bc); + bu_free(av, "av"); + bu_free(ccstr, "ccstr"); + + if (acnt != 1) + return; + + int rgb[3]; + if (!bu_color_to_rgb_ints(&bc, &rgb[0], &rgb[1], &rgb[2])) + return; + + QColor nc(rgb[0], rgb[1], rgb[2]); + + if (nc.isValid()) { + qc = nc; + QString qss = QString("background-color: rgb(%1, %2, %3);").arg(qc.red()).arg(qc.green()).arg(qc.blue()); + rgbcolor->setStyleSheet(qss); + + emit color_changed(&bc); + } +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + + diff --git a/src/libqtcad/QgConsole.cpp b/src/libqtcad/QgConsole.cpp new file mode 100644 index 00000000000..059595bfa9f --- /dev/null +++ b/src/libqtcad/QgConsole.cpp @@ -0,0 +1,831 @@ +/* + * Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc. + All rights reserved. + * + * Sandia National Laboratories, New Mexico PO Box 5800 Albuquerque, NM 87185 + * + * Kitware Inc. + * 28 Corporate Drive + * Clifton Park, NY 12065 + * USA + * + * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license + * for use of this work by or on behalf of the U.S. Government. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Kitware nor the names of any contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * This widget is based off of ParaView's QgConsole + */ + +#include "common.h" + +#include "qtcad/QgConsole.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bu.h" +#include "ged.h" + +GEDShellCompleter::GEDShellCompleter( + QWidget* parent, struct ged *ged_ptr) +{ + setParent(parent); + gedp = ged_ptr; +} + +void +GEDShellCompleter::updateCompletionModel(const QString& console_txt) +{ + setModel(NULL); + if (console_txt.isEmpty()) + return; + + // If the last char is a space, don't offer any completions - the prior + // contents are presumed to be complete + if (console_txt.at(console_txt.length() - 1) == ' ') + return; + + // We're going to be splitting up and processing this string's components + // with libged C style, so get the data out of QString into a stable form + char *ct = bu_strdup(console_txt.toLocal8Bit().constData()); + + // Break the console text down into an argc/argv array, so we can examine + // the components + int ac = 0; + char **av = NULL; + av = (char **)bu_calloc(strlen(ct) + 1, sizeof(char *), "av array"); + ac = bu_argv_from_string(av, strlen(ct), ct); + if (!ac) { + bu_free(ct, "strcpy"); + bu_free(av, "av"); + return; + } + + // If we only have 1 argument, it needs to be a command of some sort + if (ac == 1) { + char *seed = av[0]; + const char **completions = NULL; + int completion_cnt = ged_cmd_completions(&completions, seed); + QStringList clist = QStringList(); + for (int i = 0; i < completion_cnt; i++) { + clist.append(QString(completions[i])); + } + bu_argv_free(completion_cnt, (char **)completions); + if (!clist.isEmpty()) { + setCompletionMode(QCompleter::PopupCompletion); + setModel(new QStringListModel(clist, this)); + setCaseSensitivity(Qt::CaseSensitive); + setCompletionPrefix(QString(seed)); + if (popup()) + popup()->setCurrentIndex(completionModel()->index(0, 0)); + } + bu_free(ct, "strcpy"); + bu_free(av, "av"); + return; + } + + // If we've got more than one argument, the last element (the one we are + // looking to complete) is some sort of db geometry object/path element. + // TODO - does QComplete allow for mid-string insertions? + + if (!gedp) + return; + + char *seed = av[ac - 1]; + const char **completions = NULL; + struct bu_vls prefix = BU_VLS_INIT_ZERO; + int completion_cnt = ged_geom_completions(&completions, &prefix, gedp->dbip, seed); + ((QgConsole *)(parent()))->split_slash = 0; + if (!BU_STR_EQUAL(bu_vls_cstr(&prefix), seed)) + ((QgConsole *)(parent()))->split_slash = 1; + QStringList clist = QStringList(); + for (int i = 0; i < completion_cnt; i++) { + clist.append(QString(completions[i])); + } + bu_argv_free(completion_cnt, (char **)completions); + if (!clist.isEmpty()) { + setCompletionMode(QCompleter::PopupCompletion); + setModel(new QStringListModel(clist, this)); + setCaseSensitivity(Qt::CaseSensitive); + setCompletionPrefix(QString(bu_vls_cstr(&prefix))); + if (popup()) + popup()->setCurrentIndex(completionModel()->index(0, 0)); + } + bu_vls_free(&prefix); + bu_free(ct, "strcpy"); + bu_free(av, "av"); +} + +///////////////////////////////////////////////////////////////////////// +// QgConsole::pqImplementation + +class QgConsole::pqImplementation : + public QPlainTextEdit +{ + public: + pqImplementation(QgConsole& p) : + QPlainTextEdit(&p), + Parent(p), + InteractivePosition(documentEnd()) + { + this->setTabChangesFocus(false); + this->setAcceptDrops(false); + this->setUndoRedoEnabled(false); + this->setMinimumHeight(200); + this->setMaximumBlockCount(10000); + + QFont f("Courier"); + f.setStyleHint(QFont::TypeWriter); + f.setFixedPitch(true); + this->setFont(f); + + this->CommandHistory.append(""); + this->CommandPosition = 0; + } + + void setFont(const QFont& i_font) + { + QPlainTextEdit::setFont(i_font); + } + + QFont getFont() + { + return this->font(); + } + + // TODO - figure out how to implement this... + bool consolidateHistory(size_t start, size_t end) + { + if (start > end) + return false; + QString nline; + for (size_t i = start; i < end; i++) { + nline.append(CommandHistory.at(i)); + if (i != end - 1) + nline.append(" "); + } + while (CommandHistory.count() > (int)start) { + CommandHistory.pop_back(); + } + CommandHistory.push_back(nline); + CommandHistory.push_back(""); + CommandPosition = CommandHistory.size() - 1; + return true; + } + + std::string historyAt(size_t ind) + { + const char *cmd = CommandHistory.at(ind).toLocal8Bit().data(); + std::string scmd(cmd); + return scmd; + } + + // Try to keep the scrollbar slider from getting too small to be usable + void resizeEvent(QResizeEvent *e) + { + this->setMaximumBlockCount(2*this->height()); + QPlainTextEdit::resizeEvent(e); + } + + void insertFromMimeData(const QMimeData * s) + { + QTextCursor text_cursor = this->textCursor(); + + // Set to true if the cursor overlaps the history area + const bool history_area = + text_cursor.anchor() < this->InteractivePosition + || text_cursor.position() < this->InteractivePosition; + + // Avoid pasting into history + if (history_area) { + return; + } + + QPlainTextEdit::insertFromMimeData(s); + + // The text changed - make sure the command buffer knows + this->updateCommandBuffer(); + } + + void keyPressEvent(QKeyEvent* e) + { + if (this->Completer && this->Completer->popup()->isVisible()) { + // The following keys are forwarded by the completer to the widget + switch (e->key()) { + case Qt::Key_Tab: + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Backtab: + e->ignore(); + return; // let the completer do default behavior + default: + break; + } + } + + QTextCursor text_cursor = this->textCursor(); + + // Set to true if there's a current selection + const bool selection = text_cursor.anchor() != text_cursor.position(); + // Set to true if the cursor overlaps the history area + const bool history_area = + text_cursor.anchor() < this->InteractivePosition + || text_cursor.position() < this->InteractivePosition; + + // Allow copying anywhere in the console ... + if (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier) { + if (selection) { + this->copy(); + } + + e->accept(); + return; + } + + // Allow cut only if the selection is limited to the interactive area ... + if (e->key() == Qt::Key_X && e->modifiers() == Qt::ControlModifier) { + if (selection && !history_area) { + this->cut(); + } + + e->accept(); + return; + } + + // Allow paste only if the selection is in the interactive area ... + if (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier) { + if (!history_area) { + const QMimeData* const clipboard = QApplication::clipboard()->mimeData(); + const QString text = clipboard->text(); + if (!text.isNull()) { + text_cursor.insertText(text); + this->updateCommandBuffer(); + } + } + + e->accept(); + return; + } + + // Force the cursor back to the interactive area + if (history_area && e->key() != Qt::Key_Control) { + text_cursor.setPosition(this->documentEnd()); + this->setTextCursor(text_cursor); + } + + switch (e->key()) { + case Qt::Key_Up: + e->accept(); + if (this->CommandPosition > 0) { + this->replaceCommandBuffer(this->CommandHistory[--this->CommandPosition]); + } + break; + + case Qt::Key_Down: + e->accept(); + if (this->CommandPosition < this->CommandHistory.size() - 2) { + this->replaceCommandBuffer(this->CommandHistory[++this->CommandPosition]); + } else { + this->CommandPosition = this->CommandHistory.size()-1; + this->replaceCommandBuffer(""); + } + break; + + case Qt::Key_Left: + if (text_cursor.position() > this->InteractivePosition) { + QPlainTextEdit::keyPressEvent(e); + } else { + e->accept(); + } + break; + + + case Qt::Key_Delete: + e->accept(); + QPlainTextEdit::keyPressEvent(e); + this->updateCommandBuffer(); + break; + + case Qt::Key_Backspace: + e->accept(); + if (text_cursor.position() > this->InteractivePosition) { + QPlainTextEdit::keyPressEvent(e); + this->updateCommandBuffer(); + this->updateCompleterIfVisible(); + } + break; + + case Qt::Key_Tab: + e->accept(); + { + int anchor = text_cursor.anchor(); + int position = text_cursor.position(); + text_cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + text_cursor.setPosition(position, QTextCursor::KeepAnchor); + QString text = text_cursor.selectedText().trimmed(); + text_cursor.setPosition(anchor, QTextCursor::MoveAnchor); + text_cursor.setPosition(position, QTextCursor::KeepAnchor); + if (text == ">>>" || text == "...") { + text_cursor.insertText(" "); + } else { + this->updateCompleter(); + this->selectCompletion(); + } + } + break; + + case Qt::Key_Home: + e->accept(); + text_cursor.setPosition(this->InteractivePosition); + this->setTextCursor(text_cursor); + break; + + case Qt::Key_Return: + case Qt::Key_Enter: + e->accept(); + + text_cursor.setPosition(this->documentEnd()); + this->setTextCursor(text_cursor); + + this->internalExecuteCommand(); + break; + + default: + e->accept(); + QPlainTextEdit::keyPressEvent(e); + this->updateCommandBuffer(); + this->updateCompleterIfVisible(); + break; + } + } + + /// Returns the end of the document + int documentEnd() + { + QTextCursor c(this->document()); + c.movePosition(QTextCursor::End); + return c.position(); + } + + void focusOutEvent(QFocusEvent *e) + { + QPlainTextEdit::focusOutEvent(e); + + // For some reason the QCompleter tries to set the focus policy to + // NoFocus, set let's make sure we set it back to the default WheelFocus. + this->setFocusPolicy(Qt::WheelFocus); + } + + + void updateCompleterIfVisible() + { + if (this->Completer && this->Completer->popup()->isVisible()) { + this->updateCompleter(); + } + } + + /// If there is exactly 1 completion, insert it and hide the completer, + /// else do nothing. + void selectCompletion() + { + if (this->Completer && this->Completer->completionCount() == 1) { + this->Parent.insertCompletion(this->Completer->currentCompletion()); + this->Completer->popup()->hide(); + } + } + + void updateCompleter() + { + if (this->Completer) { + // Get the text between the current cursor position + // and the start of the line + QTextCursor text_cursor = this->textCursor(); + text_cursor.setPosition(this->InteractivePosition, QTextCursor::KeepAnchor); + QString commandText = text_cursor.selectedText(); + + // Call the completer to update the completion model + this->Completer->updateCompletionModel(commandText); + + // Place and show the completer if there are available completions + if (this->Completer->completionCount()) { + // Get a QRect for the cursor at the start of the + // current word and then translate it down 8 pixels. + text_cursor = this->textCursor(); + text_cursor.movePosition(QTextCursor::StartOfWord); + QRect cr = this->cursorRect(text_cursor); + cr.translate(0, 8); + cr.setWidth(this->Completer->popup()->sizeHintForColumn(0) + + this->Completer->popup()->verticalScrollBar()->sizeHint().width()); + this->Completer->complete(cr); + } else { + this->Completer->popup()->hide(); + } + } + } + + /// Update the contents of the command buffer from the contents of the widget + void updateCommandBuffer() + { + this->commandBuffer() = this->toPlainText().mid(this->InteractivePosition); + } + + /// Replace the contents of the command buffer, updating the display + void replaceCommandBuffer(const QString& Text) + { + this->commandBuffer() = Text; + + QTextCursor c(this->document()); + c.setPosition(this->InteractivePosition); + c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + c.removeSelectedText(); + c.insertText(Text); + } + + /// References the buffer where the current un-executed command is stored + QString& commandBuffer() + { + return this->CommandHistory.back(); + } + + /// Implements command-execution + void internalExecuteCommand() + { + // First update the history cache. It's essential to update the + // this->CommandPosition before calling internalExecuteCommand() since that + // can result in a clearing of the current command (BUG #8765). + QString command = this->commandBuffer(); + if (!command.isEmpty()) { // Don't store empty commands in the history + this->CommandHistory.push_back(""); + this->CommandPosition = this->CommandHistory.size() - 1; + } + QTextCursor c(this->document()); + c.movePosition(QTextCursor::End); + c.insertText("\n"); + + this->InteractivePosition = this->documentEnd(); + this->Parent.internalExecuteCommand(command); + } + + void setCompleter(QgConsoleWidgetCompleter* completer) + { + if (this->Completer) { + this->Completer->setWidget(nullptr); + QObject::disconnect(this->Completer, QOverload::of(&QCompleter::activated), &this->Parent, &QgConsole::insertCompletion); + } + this->Completer = completer; + if (this->Completer) { + this->Completer->setWidget(this); + QObject::connect(this->Completer, QOverload::of(&QCompleter::activated), &this->Parent, &QgConsole::insertCompletion); + } + } + + /// Stores a back-reference to our owner + QgConsole& Parent; + + /// A custom completer + QPointer Completer; + + /** Stores the beginning of the area of interactive input, outside which + changes can't be made to the text edit contents */ + int InteractivePosition; + /// Stores command-history, plus the current command buffer + QStringList CommandHistory; + /// Stores the current position in the command-history + int CommandPosition; +}; + +///////////////////////////////////////////////////////////////////////// +// QgConsole + +QgConsole::QgConsole(QWidget* Parent) : + QWidget(Parent), + Implementation(new pqImplementation(*this)) +{ + QVBoxLayout* const l = new QVBoxLayout(this); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + // TODO - figure out what to do for Qt6 here... + l->setMargin(0); +#endif + l->addWidget(this->Implementation); + QObject::connect(this, &QgConsole::queued_log, this, &QgConsole::printStringBeforePrompt); +} + +//----------------------------------------------------------------------------- +QgConsole::~QgConsole() +{ + delete this->Implementation; +} + +//----------------------------------------------------------------------------- +QFont QgConsole::getFont() +{ + return this->Implementation->getFont(); +} + +//----------------------------------------------------------------------------- +bool QgConsole::consolidateHistory(size_t start, size_t end) +{ + return this->Implementation->consolidateHistory(start, end); +} + +//----------------------------------------------------------------------------- +size_t QgConsole::historyCount() +{ + return this->Implementation->CommandHistory.count(); +} + +//----------------------------------------------------------------------------- +std::string QgConsole::historyAt(size_t ind) +{ + return this->Implementation->historyAt(ind); +} + +//----------------------------------------------------------------------------- +void QgConsole::setFont(const QFont& i_font) +{ + this->Implementation->setFont(i_font); +} + +//----------------------------------------------------------------------------- +QPoint QgConsole::getCursorPosition() +{ + QTextCursor tc = this->Implementation->textCursor(); + + return this->Implementation->cursorRect(tc).topLeft(); +} + +//----------------------------------------------------------------------------- +void QgConsole::listen(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d) +{ + QConsoleListener *l = new QConsoleListener(fd, p, t, c, d); + bu_log("Start listening: %d\n", (int)t); + QObject::connect(l, &QConsoleListener::newLine, this, &QgConsole::printStringBeforePrompt); + QObject::connect(l, &QConsoleListener::is_finished, this, &QgConsole::detach); + listeners[std::make_pair(p, t)] = l; +} +void QgConsole::detach(struct ged_subprocess *p, int t) +{ + QTCAD_SLOT("QgConsole::detach", 1); + std::map, QConsoleListener *>::iterator l_it, si_it, so_it, e_it; + l_it = listeners.find(std::make_pair(p,t)); + + struct ged_subprocess *process = NULL; + ged_io_func_t callback = NULL; + void *gdata = NULL; + + if (l_it != listeners.end()) { + bu_log("Stop listening: %d\n", (int)t); + QConsoleListener *l = l_it->second; + process = l->process; + callback = l->callback; + gdata = l->data; + listeners.erase(l_it); + delete l; + } + + if (process) { + si_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDIN)); + so_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDOUT)); + e_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDERR)); + + // We don't want to destroy the process until all the listeners are removed. + // If they all have been, do a final callback call with -1 key to instruct + // the callback to finalize process and memory removal. + if (si_it == listeners.end() && so_it == listeners.end() && e_it == listeners.end() && callback) { + (*callback)(gdata, -1); + // This is also the point at which we know any output from the subprocess + // is at an end. Finalize the before-prompt printing. + log_timestamp = 0; + QString estr(""); + printStringBeforePrompt(estr); + } + } +} + +//----------------------------------------------------------------------------- +void QgConsole::setCompleter(QgConsoleWidgetCompleter* completer) +{ + this->Implementation->setCompleter(completer); +} + +//----------------------------------------------------------------------------- +void QgConsole::insertCompletion(const QString& completion) +{ + QTCAD_SLOT("QgConsole::insertCompletion", 1); + QTextCursor tc = this->Implementation->textCursor(); + tc.setPosition(tc.position(), QTextCursor::MoveAnchor); + QString text = tc.selectedText(); + //const char *txt = text.toLocal8Bit().data(); + //bu_log("txt: %s\n", txt); + while (tc.position() > 0 && (!text.length() || (text.at(0) != ' ' && (!split_slash || text.at(0) != '/')))) { + tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor); + text = tc.selectedText(); + //txt = text.toLocal8Bit().data(); + //bu_log("txt: %s\n", txt); + } + if (tc.selectedText() == ".") { + tc.insertText(QString(".") + completion); + } else { + tc.setPosition(tc.position()+1, QTextCursor::MoveAnchor); + tc.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + tc.insertText(completion); + this->Implementation->setTextCursor(tc); + } + this->Implementation->updateCommandBuffer(); +} + + +//----------------------------------------------------------------------------- +void QgConsole::printString(const QString& Text) +{ + QTCAD_SLOT("QgConsole::printString", 1); + QTextCursor text_cursor = this->Implementation->textCursor(); + text_cursor.setPosition(this->Implementation->documentEnd()); + this->Implementation->setTextCursor(text_cursor); + text_cursor.insertText(Text); + + this->Implementation->InteractivePosition = this->Implementation->documentEnd(); + this->Implementation->ensureCursorVisible(); +} + +//----------------------------------------------------------------------------- +// This style of insertion is is too slow to just attempt it every time the +// subprocesses send output (Goliath rtcheck is an example.) Instead, we +// keep track of the last time we updated and if not enough time has passed +// we just queue up the text for later insertion. +// +// This approach also depends on the listener clean-up finalizing the string - +// otherwise there would be a chance of losing some printing due to timing +// issues if the last bits of the output come in right after an insertion. +// +// TODO: It would be better if the input prompt and command were one +// QPlainTextEdit and the output another, so they could operate independently - +// this approach will still introduce brief periods where the input prompt +// disappears and reappears during updating. However, that would +// require restructuring QgConsole's widget design - for now this functions, +// and if this becomes the production solution we can/should revisit it later. +void QgConsole::printStringBeforePrompt(const QString& Text) +{ + QTCAD_SLOT("QgConsole::printStringBeforePrompt", 1); + logbuf.append(Text); + int64_t ctime = bu_gettime(); + double elapsed = ((double)ctime - (double)log_timestamp)/1000000.0; + if (elapsed > 0.1 && logbuf.length()) { + // Make a local printing copy and clear the buffer + QString llogbuf = logbuf; + logbuf.clear(); + + log_timestamp = bu_gettime(); + + // While we're manipulating the console contents, we don't want + // the user modifying anything. + this->Implementation->setReadOnly(true); + + // Make a copy of the text cursor on which to operate. Note that this + // is not the actual cursor being used for editing and we need to use + // setTextCursor to impact that cursor. For most of this operation we + // don't need to, but it's important for restoring the editing state + // to the user at the end. + QTextCursor tc = this->Implementation->textCursor(); + + // Store the current editing point relative to the prompt (it may not + // be the end of the command, if the user is editing mid-command.) + int curr_pos_offset = tc.position() - (prompt_start + prompt_str.length()); + + // Before appending new content to the log, clear the old prompt and + // command string. We restore them after the new log content is added. + tc.setPosition(prompt_start); + tc.setPosition(this->Implementation->documentEnd(), QTextCursor::KeepAnchor); + tc.removeSelectedText(); + + // Print the accumulated logged output to the command window. + this->Implementation->insertPlainText(llogbuf); + + // Before we re-add the prompt and command buffer, store the new prompt + // starting point for use in the next write cycle. + prompt_start = tc.position(); + + // Restore the prompt and the next command (if any) + this->Implementation->insertPlainText(prompt_str); + this->Implementation->textCursor().insertText(this->Implementation->commandBuffer()); + + // Denote the interactive portion of the new state of the buffer as starting after + // the new prompt. + this->Implementation->InteractivePosition = prompt_start + prompt_str.length(); + + // Make sure the scrolling is set to view the new prompt + this->Implementation->ensureCursorVisible(); + + // The final touch - in case the cursor was not at the end of the command buffer, + // restore it to its prior offset from the prompt. Since we are altering the + // user-interactive editing cursor this time, and not just manipulating the text, + // we must use setTextCursor to apply the change. + tc.setPosition(prompt_start + prompt_str.length() + curr_pos_offset); + this->Implementation->setTextCursor(tc); + + // All done - unlock + this->Implementation->setReadOnly(false); + } + + // If there is anything queued up, we need to make sure we print it soon(ish) + if (logbuf.length()) { + QTimer::singleShot(1000, this, &QgConsole::emit_queued); + } +} + +//----------------------------------------------------------------------------- +void QgConsole::printCommand(const QString& cmd) +{ + QTCAD_SLOT("QgConsole::printCommand", 1); + this->Implementation->textCursor().insertText(cmd); + this->Implementation->updateCommandBuffer(); +} + +//----------------------------------------------------------------------------- +void QgConsole::prompt(const QString& text) +{ + QTCAD_SLOT("QgConsole::prompt", 1); + QTextCursor text_cursor = this->Implementation->textCursor(); + + // if the cursor is currently on a clean line, do nothing, otherwise we move + // the cursor to a new line before showing the prompt. + text_cursor.movePosition(QTextCursor::StartOfLine); + int startpos = text_cursor.position(); + text_cursor.movePosition(QTextCursor::EndOfLine); + int endpos = text_cursor.position(); + if (endpos != startpos) { + this->Implementation->textCursor().insertText("\n"); + } + + prompt_start = text_cursor.position(); + prompt_str = text; + + this->Implementation->textCursor().insertText(text); + this->Implementation->InteractivePosition = this->Implementation->documentEnd(); + this->Implementation->ensureCursorVisible(); +} + +//----------------------------------------------------------------------------- +void QgConsole::clear() +{ + QTCAD_SLOT("QgConsole::clear", 1); + this->Implementation->clear(); + + // For some reason the QCompleter tries to set the focus policy to + // NoFocus, set let's make sure we set it back to the default WheelFocus. + this->Implementation->setFocusPolicy(Qt::WheelFocus); +} + +//----------------------------------------------------------------------------- +void QgConsole::internalExecuteCommand(const QString& Command) +{ + emit this->executeCommand(Command); +} + +//----------------------------------------------------------------------------- + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgConsoleListener.cpp b/src/libqtcad/QgConsoleListener.cpp new file mode 100644 index 00000000000..f40df6824d6 --- /dev/null +++ b/src/libqtcad/QgConsoleListener.cpp @@ -0,0 +1,105 @@ +/* + * MIT License + * + * Copyright (c) 2018 Juan Gonzalez Burgos + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Originally from https://github.com/juangburgos/QConsoleListener + */ + +#include "common.h" + +#include +#include "qtcad/QgConsoleListener.h" + +#define RT_MAXLINE 10240 + +void noMessageOutput(QtMsgType, const QMessageLogContext&, const QString&) {} + +QConsoleListener::QConsoleListener(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d) +{ + this->process = p; + this->callback = c; + this->data = d; + this->type = t; + QObject::connect( + this, &QConsoleListener::finishedGetLine, + this, &QConsoleListener::on_finishedGetLine, + Qt::QueuedConnection + ); +#ifdef Q_OS_WIN + HANDLE h = (fd < 0) ? GetStdHandle(STD_INPUT_HANDLE) : (HANDLE)_get_osfhandle(fd); + m_notifier = new QWinEventNotifier(h); +#else + int lfd = (fd < 0) ? fileno(stdin) : fd; + m_notifier = new QSocketNotifier(lfd, QSocketNotifier::Read); +#endif + // NOTE : move to thread to avoid blocking, then sync with + // main thread using a QueuedConnection with finishedGetLine + m_notifier->moveToThread(&m_thread); + QObject::connect(&m_thread , &QThread::finished, m_notifier, &QObject::deleteLater); +#ifdef Q_OS_WIN + QObject::connect(m_notifier, &QWinEventNotifier::activated, m_notifier, +#else + QObject::connect(m_notifier, &QSocketNotifier::activated, m_notifier, +#endif + [this]() { + if (callback) { + size_t s1 = bu_vls_strlen(process->gedp->ged_result_str); + (*callback)(data, (int)type); + size_t s2 = bu_vls_strlen(process->gedp->ged_result_str); + if (s1 != s2) { + struct bu_vls nstr = BU_VLS_INIT_ZERO; + bu_vls_substr(&nstr, process->gedp->ged_result_str, s1, s2 - s1); + QString strLine = QString::fromStdString(std::string(bu_vls_cstr(&nstr))); + bu_vls_free(&nstr); + Q_EMIT this->finishedGetLine(strLine); + } + } + }); + m_thread.start(); +} + +QConsoleListener::~QConsoleListener() +{ + m_notifier->disconnect(); + m_thread.quit(); + m_thread.wait(); +} + +void QConsoleListener::on_finishedGetLine(const QString &strNewLine) +{ + Q_EMIT this->newLine(strNewLine); +} + +void QConsoleListener::on_finished() +{ + Q_EMIT this->is_finished(this->process, (int)this->type); +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libqtcad/QgDockWidget.cpp b/src/libqtcad/QgDockWidget.cpp index 609dea1fbd3..424beba2a9b 100644 --- a/src/libqtcad/QgDockWidget.cpp +++ b/src/libqtcad/QgDockWidget.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "qtcad/QgDockWidget.h" QgDockWidget::QgDockWidget(const QString &title, QWidget *parent) @@ -36,6 +37,8 @@ QgDockWidget::QgDockWidget(const QString &title, QWidget *parent) void QgDockWidget::toWindow(bool floating) { + QTCAD_SLOT("QgDockWidget::toWindow", 1); + if (floating) { setWindowFlags( Qt::CustomizeWindowHint | @@ -62,10 +65,10 @@ QgDockWidget::event(QEvent *e) moving = false; return QDockWidget::event(e); } -#ifdef USE_QT6 - QPoint gpos = m_e->globalPosition().toPoint(); -#else +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPoint gpos = m_e->globalPos(); +#else + QPoint gpos = m_e->globalPosition().toPoint(); #endif QRect trect = this->geometry(); if (!trect.contains(gpos)) diff --git a/src/libqtcad/QgFlowLayout.cpp b/src/libqtcad/QgFlowLayout.cpp new file mode 100644 index 00000000000..817fafde376 --- /dev/null +++ b/src/libqtcad/QgFlowLayout.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "common.h" + +#include +#include +#include +#include +#include "qtcad/QgFlowLayout.h" + +QgFlowLayout::QgFlowLayout(QWidget *pparent, int mmargin, int hSpacing, int vSpacing) + : QLayout(pparent), m_hSpace(hSpacing), m_vSpace(vSpacing) +{ + setContentsMargins(mmargin, mmargin, mmargin, mmargin); +} + +QgFlowLayout::QgFlowLayout(int mmargin, int hSpacing, int vSpacing) + : m_hSpace(hSpacing), m_vSpace(vSpacing) +{ + setContentsMargins(mmargin, mmargin, mmargin, mmargin); +} + +QgFlowLayout::~QgFlowLayout() +{ + QLayoutItem *item; + while ((item = takeAt(0))) + delete item; +} + +void QgFlowLayout::addItem(QLayoutItem *item) +{ + itemList.append(item); +} + +int QgFlowLayout::horizontalSpacing() const +{ + if (m_hSpace >= 0) { + return m_hSpace; + } else { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } +} + +int QgFlowLayout::verticalSpacing() const +{ + if (m_vSpace >= 0) { + return m_vSpace; + } else { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } +} + +void QgFlowLayout::setHorizontalSpacing(int hspacing) +{ + m_hSpace = hspacing; +} + +void QgFlowLayout::setVerticalSpacing(int vspacing) +{ + m_vSpace = vspacing; +} + +int QgFlowLayout::count() const +{ + return itemList.size(); +} + +QLayoutItem *QgFlowLayout::itemAt(int index) const +{ + return itemList.value(index); +} + +QLayoutItem *QgFlowLayout::takeAt(int index) +{ + if (index >= 0 && index < itemList.size()) + return itemList.takeAt(index); + else + return 0; +} + +Qt::Orientations QgFlowLayout::expandingDirections() const +{ + return Qt::Orientations{}; +} + +bool QgFlowLayout::hasHeightForWidth() const +{ + return true; +} + +int QgFlowLayout::heightForWidth(int width) const +{ + int height = doLayout(QRect(0, 0, width, 0), true); + return height; +} + +void QgFlowLayout::setGeometry(const QRect &rect) +{ + QLayout::setGeometry(rect); + doLayout(rect, false); +} + +QSize QgFlowLayout::sizeHint() const +{ + return minimumSize(); +} + +QSize QgFlowLayout::minimumSize() const +{ + QSize size; + QLayoutItem *item; + foreach (item, itemList) + size = size.expandedTo(item->minimumSize()); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + // TODO - figure out the right Qt6 logic here... + size += QSize(2*margin(), 2*margin()); +#endif + return size; +} + +int QgFlowLayout::doLayout(const QRect &rect, bool testOnly) const +{ + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; + + QLayoutItem *item; + foreach (item, itemList) { + QWidget *wid = item->widget(); + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); + int nextX = x + item->sizeHint().width() + spaceX; + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { + x = effectiveRect.x(); + y = y + lineHeight + spaceY; + nextX = x + item->sizeHint().width() + spaceX; + lineHeight = 0; + } + + if (!testOnly) + item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + + x = nextX; + lineHeight = qMax(lineHeight, item->sizeHint().height()); + } + return y + lineHeight - rect.y() + bottom; +} +int QgFlowLayout::smartSpacing(QStyle::PixelMetric pm) const +{ + QObject *pparent = this->parent(); + if (!pparent) { + return -1; + } else if (pparent->isWidgetType()) { + QWidget *pw = static_cast(pparent); + return pw->style()->pixelMetric(pm, 0, pw); + } else { + return static_cast(pparent)->spacing(); + } +} diff --git a/src/libqtcad/QgGL.cpp b/src/libqtcad/QgGL.cpp new file mode 100644 index 00000000000..d6951c8652a --- /dev/null +++ b/src/libqtcad/QgGL.cpp @@ -0,0 +1,447 @@ +/* Q G G L . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgGL.cpp + * + * Use a QOpenGLWidget to display libdm drawing content. + * + */ + +#include "common.h" + +#include +#include + +extern "C" { +#include "bu/malloc.h" +} +#include "bindings.h" +#include "qtcad/QgGL.h" + +// FROM MGED +#define XMIN (-2048) +#define XMAX (2047) +#define YMIN (-2048) +#define YMAX (2047) + +// from GED_MIN and GED_MAX +#define QTGL_ZMIN -2048 +#define QTGL_ZMAX 2047 + +QgGL::QgGL(QWidget *parent, struct fb *fbp) + : QOpenGLWidget(parent), ifp(fbp) +{ + // Provide a view specific to this widget - set gedp->ged_gvp to v + // if this is the current view + BU_GET(local_v, struct bview); + bv_init(local_v, NULL); + bu_vls_sprintf(&local_v->gv_name, "qtgl"); + v = local_v; + + // We can't initialize dmp successfully until more of the OpenGL + // initialization is complete + dmp = NULL; + + // If we weren't supplied with a framebuffer, allocate one. + // We don't open it until we have the dmp. + if (!ifp) { + ifp = fb_raw("qtgl"); + fb_set_standalone(ifp, 0); + } + + // This is an important Qt setting for interactivity - it allowing key + // bindings to propagate to this widget and trigger actions such as + // resolution scaling, rotation, etc. + setFocusPolicy(Qt::WheelFocus); +} + +QgGL::~QgGL() +{ + if (dmp) + dm_close(dmp); + if (ifp && !fb_get_standalone(ifp)) { + fb_close_existing(ifp); + } + BU_PUT(local_v, struct bv); +} + + +void QgGL::paintGL() +{ + int w = width(); + int h = height(); + // Zero size == nothing to do + if (!w || !h) + return; + + if (!m_init) { + + if (!dmp) { + + // This is needed so we can work with Qt's OpenGL widget + // using standard OpenGL functions. + initializeOpenGLFunctions(); + + // Do the standard libdm attach to get our rendering backend. + const char *acmd = "attach"; + dmp = dm_open((void *)this, NULL, "qtgl", 1, &acmd); + if (!dmp) + return; + + // If we have a framebuffer, now we can open it + if (ifp) { + struct fb_platform_specific *fbps = fb_get_platform_specific(FB_QTGL_MAGIC); + fbps->data = (void *)dmp; + fb_setup_existing(ifp, dm_get_width(dmp), dm_get_height(dmp), fbps); + fb_put_platform_specific(fbps); + } + + dm_set_pathname(dmp, "QTDM"); + } + + // QTGL_ZMIN and QTGL_ZMAX are historical - need better + // documentation on why those specific values are used. + //fastf_t windowbounds[6] = { XMIN, XMAX, YMIN, YMAX, QTGL_ZMIN, QTGL_ZMAX }; + fastf_t windowbounds[6] = { -1, 1, -1, 1, QTGL_ZMIN, QTGL_ZMAX }; + dm_set_win_bounds(dmp, windowbounds); + + if (v) { + // Associate the view scale with the dmp + dm_set_vp(dmp, &v->gv_scale); + + // Let the view know it now has an associated display manager + v->dmp = dmp; + + // Set the view width and height to match the dm + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + } + + // If we have a ptbl defining the current dm set and/or an unset + // pointer to indicate the current dm, go ahead and set them. + if (dm_set) + bu_ptbl_ins_unique(dm_set, (long int *)dmp); + + // Ready to go + m_init = true; + emit init_done(); + } + + if (!m_init || !dmp || !v) + return; + + // Re-draw the background to clear any previous drawing + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + + // Go ahead and set the flag, but (unlike the rendering thread + // implementation) we need to do the draw routine every time in paintGL, or + // we end up with unrendered frames. + dm_set_dirty(dmp, 0); + dm_draw_objs(v, draw_custom, draw_udata); + dm_draw_end(dmp); +} + +void QgGL::resizeGL(int, int) +{ + if (!dmp || !v) + return; + dm_configure_win(dmp, 0); + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + if (ifp) { + fb_configure_window(ifp, v->gv_width, v->gv_height); + } + if (dmp) + dm_set_dirty(dmp, 1); + emit changed(); +} + +void QgGL::resizeEvent(QResizeEvent *e) +{ + QOpenGLWidget::resizeEvent(e); + if (!dmp || !v) + + return; + dm_set_width(dmp, width()); + dm_set_height(dmp, height()); + v->gv_width = width(); + v->gv_height = height(); + dm_configure_win(dmp, 0); + if (ifp) { + fb_configure_window(ifp, v->gv_width, v->gv_height); + } + if (dmp) + dm_set_dirty(dmp, 1); + emit changed(); +} + +void QgGL::need_update() +{ + bv_log(4, "QgGL::need_update"); + QTCAD_SLOT("QgGL::need_update", 1); + if (!dmp) + return; + dm_set_dirty(dmp, 1); + update(); +} + +void QgGL::keyPressEvent(QKeyEvent *k) { + + if (!dmp || !v || !current || !use_default_keybindings) { + QOpenGLWidget::keyPressEvent(k); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADkeyPressEvent(v, x_prev, y_prev, k)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QOpenGLWidget::keyPressEvent(k); +} + +void QgGL::mousePressEvent(QMouseEvent *e) { + + if (!dmp || !v || !current || !use_default_mousebindings) { + QOpenGLWidget::mousePressEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADmousePressEvent(v, x_prev, y_prev, e)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + x_press_pos = (double)e->x(); + y_press_pos = (double)e->y(); +#else + x_press_pos = e->position().x(); + y_press_pos = e->position().y(); +#endif + //bu_log("X,Y: %g, %g\n", x_press_pos, y_press_pos); + + QOpenGLWidget::mousePressEvent(e); +} + +void QgGL::mouseReleaseEvent(QMouseEvent *e) { + + if (!v) { + QOpenGLWidget::mouseReleaseEvent(e); + return; + } + + // To avoid an abrupt jump in scene motion the next time movement is + // started with the mouse, after we release we return to the default state. + x_prev = -INT_MAX; + y_prev = -INT_MAX; + + if (CADmouseReleaseEvent(v, x_press_pos, y_press_pos, x_prev, y_prev, e, lmouse_mode)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QOpenGLWidget::mouseReleaseEvent(e); +} + +void QgGL::mouseMoveEvent(QMouseEvent *e) +{ + if (!dmp || !v || !current || !use_default_mousebindings) { + QOpenGLWidget::mouseMoveEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADmouseMoveEvent(v, x_prev, y_prev, e, lmouse_mode)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + // Current positions are the new previous positions +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + x_prev = e->x(); + y_prev = e->y(); +#else + x_prev = e->position().x(); + y_prev = e->position().y(); +#endif + + QOpenGLWidget::mouseMoveEvent(e); +} + +void QgGL::wheelEvent(QWheelEvent *e) { + + if (!dmp || !v || !current || !use_default_mousebindings) { + QOpenGLWidget::wheelEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADwheelEvent(v, e)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QOpenGLWidget::wheelEvent(e); +} + +void QgGL::stash_hashes() +{ + if (!dmp) { + prev_dhash = 0; + } else { + prev_dhash = dm_hash(dmp); + } + prev_vhash = bv_hash(v); +} + +bool QgGL::diff_hashes() +{ + bool ret = false; + unsigned long long c_dhash = 0; + unsigned long long c_vhash = 0; + + if (dmp) + c_dhash = dm_hash(dmp); + c_vhash = bv_hash(v); + + if (dmp && dm_get_dirty(dmp)) + ret = true; + + if (prev_dhash != c_dhash) { + if (dmp) + dm_set_dirty(dmp, 1); + ret = true; + } + if (prev_vhash != c_vhash) { + if (dmp) + dm_set_dirty(dmp, 1); + ret = true; + } + + if (ret) { + need_update(); + emit changed(); + } + + return ret; +} + +void QgGL::save_image() { + QImage image = this->grabFramebuffer(); + image.save("file.png"); +} + +void QgGL::aet(double a, double e, double t) +{ + if (!v) + return; + + fastf_t aet[3]; + double aetd[3]; + aetd[0] = a; + aetd[1] = e; + aetd[2] = t; + + /* convert from double to fastf_t */ + VMOVE(aet, aetd); + + VMOVE(v->gv_aet, aet); + + /* TODO - based on the suspect bv_mat_aet... */ + mat_t tmat; + fastf_t twist; + fastf_t c_twist; + fastf_t s_twist; + bn_mat_angles(v->gv_rotation, 270.0 + v->gv_aet[1], 0.0, 270.0 - v->gv_aet[0]); + twist = -v->gv_aet[2] * DEG2RAD; + c_twist = cos(twist); + s_twist = sin(twist); + bn_mat_zrot(tmat, s_twist, c_twist); + bn_mat_mul2(tmat, v->gv_rotation); + + bv_update(v); +} + +void +QgGL::enableDefaultKeyBindings() +{ + use_default_keybindings = true; +} + +void +QgGL::disableDefaultKeyBindings() +{ + use_default_keybindings = false; +} + +void +QgGL::enableDefaultMouseBindings() +{ + use_default_mousebindings = true; +} + +void +QgGL::disableDefaultMouseBindings() +{ + use_default_mousebindings = false; +} + +void +QgGL::set_lmouse_move_default(int mm) +{ + QTCAD_SLOT("QgGL::set_lmouse_move_default", 1); + lmouse_mode = mm; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libqtcad/QgGeomImport.cpp b/src/libqtcad/QgGeomImport.cpp new file mode 100644 index 00000000000..604c1d4166d --- /dev/null +++ b/src/libqtcad/QgGeomImport.cpp @@ -0,0 +1,375 @@ +/* Q G G E O M I M P O R T . C P P + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgGeomImport.cpp + * + */ + +#include +#include +#include +#include "qtcad/QgAppExecDialog.h" +#include "qtcad/QgGeomImport.h" + +ASCImportDialog::ASCImportDialog(QString filename, QString g_path, QString l_path) +{ + input_file = filename; + + db_path = new QLineEdit; + db_path->insert(g_path); + log_path = new QLineEdit; + log_path->insert(l_path); + + formGroupBox = new QGroupBox("Import Options"); + QFormLayout *flayout = new QFormLayout; + flayout->addRow(new QLabel("Output File"), db_path); + flayout->addRow(new QLabel("Log File"), log_path); + formGroupBox->setLayout(flayout); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &ASCImportDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ASCImportDialog::reject); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(formGroupBox); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + resize(600,300); + setWindowTitle(tr("BRL-CAD ASCII Importer")); +} + +QString +ASCImportDialog::command() +{ + QString prog_name(bu_dir(NULL, 0, BU_DIR_BIN, "gcv", BU_DIR_EXT, NULL)); + return prog_name; +} + + +QStringList +ASCImportDialog::options() +{ + QStringList process_args; + + process_args.append(input_file); + process_args.append(db_path->text()); + + return process_args; +} + +RhinoImportDialog::RhinoImportDialog(QString filename, QString g_path, QString l_path) +{ + input_file = filename; + + db_path = new QLineEdit; + db_path->insert(g_path); + log_path = new QLineEdit; + log_path->insert(l_path); + scaling_factor = new QLineEdit; + tolerance = new QLineEdit; + verbosity = new QLineEdit; + debug_printing = new QCheckBox; + random_colors = new QCheckBox; + uuid = new QCheckBox; + + formGroupBox = new QGroupBox("Import Options"); + QFormLayout *flayout = new QFormLayout; + flayout->addRow(new QLabel("Output File"), db_path); + flayout->addRow(new QLabel("Print Debugging Info"), debug_printing); + flayout->addRow(new QLabel("Printing Verbosity"), verbosity); + flayout->addRow(new QLabel("Scaling Factor"), scaling_factor); + flayout->addRow(new QLabel("Tolerance"), tolerance); + flayout->addRow(new QLabel("Randomize Colors"), random_colors); + flayout->addRow(new QLabel("Use Universally Unique Identifiers\n(UUIDs) for Object Names"), uuid); + flayout->addRow(new QLabel("Log File"), log_path); + formGroupBox->setLayout(flayout); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &RhinoImportDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &RhinoImportDialog::reject); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(formGroupBox); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + resize(600,300); + setWindowTitle(tr("Rhino 3DM Importer (3dm-g)")); +} + +QString +RhinoImportDialog::command() +{ + QString prog_name(bu_dir(NULL, 0, BU_DIR_BIN, "3dm-g", BU_DIR_EXT, NULL)); + return prog_name; +} + + +QStringList +RhinoImportDialog::options() +{ + QStringList process_args; + + if (debug_printing->isChecked()) process_args.append(" -d"); + if (verbosity->text().length() > 0) { + process_args.append("-v"); + process_args.append(verbosity->text()); + } + if (scaling_factor->text().length() > 0) { + process_args.append("-s"); + process_args.append(scaling_factor->text()); + } + if (tolerance->text().length() > 0) { + process_args.append("-t"); + process_args.append(tolerance->text()); + } + if (random_colors->isChecked()) process_args.append("-r"); + if (uuid->isChecked()) process_args.append("-u"); + + process_args.append("-o"); + process_args.append(db_path->text()); + + process_args.append(input_file); + + return process_args; +} + +STEPImportDialog::STEPImportDialog(QString filename, QString g_path, QString l_path) +{ + input_file = filename; + + db_path = new QLineEdit; + db_path->insert(g_path); + log_path = new QLineEdit; + log_path->insert(l_path); + verbosity = new QCheckBox; + verbosity->setCheckState(Qt::Checked); + + formGroupBox = new QGroupBox("Import Options"); + QFormLayout *flayout = new QFormLayout; + flayout->addRow(new QLabel("Output File"), db_path); + flayout->addRow(new QLabel("Printing Verbosity"), verbosity); + flayout->addRow(new QLabel("Log File"), log_path); + formGroupBox->setLayout(flayout); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &STEPImportDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &STEPImportDialog::reject); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(formGroupBox); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + resize(600,300); + setWindowTitle(tr("AP203 STEP Importer (step-g)")); + +} + +QString +STEPImportDialog::command() +{ + QString prog_name(bu_dir(NULL, 0, BU_DIR_BIN, "step-g", BU_DIR_EXT, NULL)); + return prog_name; +} + + +QStringList +STEPImportDialog::options() +{ + QStringList process_args; + + if (verbosity->isChecked()) process_args.append("-v"); + + process_args.append("-o"); + process_args.append(db_path->text()); + + process_args.append(input_file); + + return process_args; +} + +QgGeomImport::QgGeomImport(QWidget *pparent) : QObject(pparent) +{ +} + +QgGeomImport::~QgGeomImport() +{ + bu_vls_free(&conv_msg); +} + +int +QgGeomImport::exec_console_app_in_window(QString command, QStringList options, QString lfile) +{ + if (command.length() > 0) { + + QgAppExecDialog *out_win = new QgAppExecDialog(0, command, options, lfile); + QString win_title("Running "); + win_title.append(command); + out_win->setWindowTitle(win_title); + out_win->proc = new QProcess(out_win); + out_win->console->setMinimumHeight(800); + out_win->console->setMinimumWidth(800); + out_win->console->printString(command); + out_win->console->printString(QString(" ")); + out_win->console->printString(options.join(" ")); + out_win->console->printString(QString("\n")); + out_win->proc->setProgram(command); + out_win->proc->setArguments(options); + connect(out_win->proc, &QProcess::readyReadStandardOutput, out_win, &QgAppExecDialog::read_stdout); + connect(out_win->proc, &QProcess::readyReadStandardError, out_win, &QgAppExecDialog::read_stderr); + connect(out_win->proc, static_cast(&QProcess::finished), out_win, &QgAppExecDialog::process_done); + out_win->proc->start(); + out_win->exec(); + } + return 0; +} + +static int +uniq_test(struct bu_vls *p, void *UNUSED(data)) +{ + if (!p) + return 1; + if (bu_file_exists(bu_vls_cstr(p), NULL)) + return 0; + return 1; +} + +QString +QgGeomImport::gfile(const char *tfile) +{ + if (tfile) { + fileName = QString(tfile); + } else { + const char *file_filters = + "BRL-CAD (*.g);;" + "BRL-CAD ASCII (*.asc);;" + "Rhino (*.3dm);;" + "STEP (*.stp *.step);;" + "All Files (*)"; + fileName = QFileDialog::getOpenFileName((QWidget *)this->parent(), + "Open Geometry File", + QCoreApplication::applicationDirPath(), + file_filters, + NULL, + QFileDialog::DontUseNativeDialog); + } + + if (fileName.isEmpty()) + return QString(); + + QFileInfo fileinfo(fileName); + + // TODO - at least do a basic validity check... just checking for a .g + // suffix is pretty weak... + if (!fileinfo.suffix().compare("g", Qt::CaseSensitive)) + return fileName; + + // If it's not a .g, check if the calling program wants us to + // go any further first. + if (!enable_conversion) { + bu_vls_sprintf(&conv_msg, "%s does not appear to be a .g file\n", fileName.toLocal8Bit().data()); + return QString(); + } + + /* If we don't already have a filename that claims to be a .g file, see + * about a conversion. No matter what we're doing, we'll want a target + * .g filename. */ + QString g_path(fileinfo.path()); + g_path.append("/"); + g_path.append(fileinfo.baseName()); + + /* Try to find a target name that doesn't already exist */ + struct bu_vls u_name = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&u_name, "%s.g", g_path.toLocal8Bit().data()); + if (bu_file_exists(bu_vls_cstr(&u_name), NULL)) { + bu_vls_sprintf(&u_name, "%s0.g", g_path.toLocal8Bit().data()); + if (bu_vls_incr(&u_name, NULL, "4:0:0:0:_", &uniq_test, NULL) < 0) { + bu_vls_free(&u_name); + bu_vls_sprintf(&conv_msg, "unable to generate a conversion output name for %s\n", fileName.toLocal8Bit().data()); + return QString(); + } + } + g_path = QString(bu_vls_cstr(&u_name)); + + /* Also specify a logging filename */ + QString l_path(bu_vls_cstr(&u_name)); + l_path.append(".log"); + + + /* Now, we need to handle the format specific aspects of conversion options. */ + + // ASC - BRL-CAD ASCII data + if (!fileinfo.suffix().compare("asc", Qt::CaseSensitive)) { + ASCImportDialog dialog(fileName, g_path, l_path); + dialog.exec(); + g_path = dialog.db_path->text(); + l_path = dialog.log_path->text(); + exec_console_app_in_window(dialog.command(),dialog.options(), l_path); + bu_vls_sprintf(&u_name, "%s", g_path.toLocal8Bit().data()); + if (!bu_file_exists(bu_vls_cstr(&u_name), NULL)) { + bu_vls_free(&u_name); + bu_vls_sprintf(&conv_msg, "ASC import failed for %s\n", fileName.toLocal8Bit().data()); + return QString(); + } + } + + // Rhino / 3DM + if (!fileinfo.suffix().compare("3dm", Qt::CaseInsensitive)) { + RhinoImportDialog dialog(fileName, g_path, l_path); + dialog.exec(); + g_path = dialog.db_path->text(); + l_path = dialog.log_path->text(); + exec_console_app_in_window(dialog.command(), dialog.options(), l_path); + bu_vls_sprintf(&u_name, "%s", g_path.toLocal8Bit().data()); + if (!bu_file_exists(bu_vls_cstr(&u_name), NULL)) { + bu_vls_free(&u_name); + bu_vls_sprintf(&conv_msg, "3DM import failed for %s\n", fileName.toLocal8Bit().data()); + return QString(); + } + } + + // STEP + if (!fileinfo.suffix().compare("stp", Qt::CaseInsensitive) || !fileinfo.suffix().compare("step", Qt::CaseInsensitive)) { + STEPImportDialog dialog(fileName, g_path, l_path); + dialog.exec(); + g_path = dialog.db_path->text(); + l_path = dialog.log_path->text(); + exec_console_app_in_window(dialog.command(),dialog.options(), l_path); + bu_vls_sprintf(&u_name, "%s", g_path.toLocal8Bit().data()); + if (!bu_file_exists(bu_vls_cstr(&u_name), NULL)) { + bu_vls_free(&u_name); + bu_vls_sprintf(&conv_msg, "STEP import failed for %s\n", fileName.toLocal8Bit().data()); + return QString(); + } + } + + bu_vls_free(&u_name); + return g_path; +} + +/* + * Local Variables: + * mode: C++ + * tab-width: 8 + * c-basic-offset: 4 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ + diff --git a/src/libqtcad/QgKeyVal.cpp b/src/libqtcad/QgKeyVal.cpp new file mode 100644 index 00000000000..183584a2937 --- /dev/null +++ b/src/libqtcad/QgKeyVal.cpp @@ -0,0 +1,184 @@ +/* Q G K E Y V A L . C P P + * BRL-CAD + * + * Copyright (c) 2020-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgKeyVal.cpp + * + */ + +#include + +#include "qtcad/QgKeyVal.h" + +// *********** Node ************** + +QgKeyValNode::QgKeyValNode(QgKeyValNode *aParent) +: parent(aParent) +{ + if(parent) { + parent->children.append(this); + } +} + +QgKeyValNode::~QgKeyValNode() +{ + qDeleteAll(children); +} + +// *********** Model ************** + +QgKeyValModel::QgKeyValModel(QObject *aParent) +: QAbstractItemModel(aParent) +{ +} + +QgKeyValModel::~QgKeyValModel() +{ +} + +QVariant +QgKeyValModel::headerData(int section, Qt::Orientation, int role) const +{ + if (role != Qt::DisplayRole) return QVariant(); + if (section == 0) return QString("Property"); + if (section == 1) return QString("Value"); + return QVariant(); +} + +QVariant +QgKeyValModel::data(const QModelIndex & idx, int role) const +{ + if (!idx.isValid()) return QVariant(); + QgKeyValNode *curr_node = IndexNode(idx); + if (role == Qt::DisplayRole && idx.column() == 0) return QVariant(curr_node->name); + if (role == Qt::DisplayRole && idx.column() == 1) return QVariant(curr_node->value); + return QVariant(); +} + +bool +QgKeyValModel::setData(const QModelIndex & idx, const QVariant & value, int role) +{ + if (!idx.isValid()) return false; + QVector roles; + bool ret = false; + QgKeyValNode *curr_node = IndexNode(idx); + if (role == Qt::DisplayRole) { + curr_node->name = value.toString(); + roles.append(Qt::DisplayRole); + ret = true; + } + if (ret) emit dataChanged(idx, idx, roles); + return ret; +} + +void QgKeyValModel::setRootNode(QgKeyValNode *root) +{ + m_root = root; + beginResetModel(); + endResetModel(); +} + +QModelIndex QgKeyValModel::index(int row, int column, const QModelIndex &parent_idx) const +{ + if (hasIndex(row, column, parent_idx)) { + QgKeyValNode *cnode = IndexNode(parent_idx)->children.at(row); + return createIndex(row, column, cnode); + } + return QModelIndex(); +} + +QModelIndex QgKeyValModel::parent(const QModelIndex &child) const +{ + QgKeyValNode *pnode = IndexNode(child)->parent; + if (pnode == m_root) return QModelIndex(); + return createIndex(NodeRow(pnode), 0, pnode); +} + +int QgKeyValModel::rowCount(const QModelIndex &parent_idx) const +{ + return IndexNode(parent_idx)->children.count(); +} + +int QgKeyValModel::columnCount(const QModelIndex &parent_idx) const +{ + Q_UNUSED(parent_idx); + return 2; +} + +QModelIndex QgKeyValModel::NodeIndex(QgKeyValNode *node) const +{ + if (node == m_root) return QModelIndex(); + return createIndex(NodeRow(node), 0, node); +} + +QgKeyValNode * QgKeyValModel::IndexNode(const QModelIndex &idx) const +{ + if (idx.isValid()) { + return static_cast(idx.internalPointer()); + } + return m_root; +} + +int QgKeyValModel::NodeRow(QgKeyValNode *node) const +{ + return node->parent->children.indexOf(node); +} + +QgKeyValNode * +QgKeyValModel::add_pair(const char *name, const char *value, QgKeyValNode *curr_node, int type) +{ + QgKeyValNode *new_node = new QgKeyValNode(curr_node); + new_node->name = name; + new_node->value = value; + new_node->attr_type = type; + return new_node; +} + + +// *********** View ************** +void QgKeyValDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QString text = index.data().toString(); + painter->drawText(option.rect, text, QTextOption(Qt::AlignLeft)); +} + +QSize QgKeyValDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QSize name_size = option.fontMetrics.size(Qt::TextSingleLine, index.data().toString()); + return name_size; +} + + +QgKeyValView::QgKeyValView(QWidget *pparent, int tree_decorate) : QTreeView(pparent) +{ + //this->setContextMenuPolicy(Qt::CustomContextMenu); + if (!tree_decorate) { + setRootIsDecorated(false); + } +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + + diff --git a/src/libqtcad/QgMeasureFilter.cpp b/src/libqtcad/QgMeasureFilter.cpp new file mode 100644 index 00000000000..697b41bad7f --- /dev/null +++ b/src/libqtcad/QgMeasureFilter.cpp @@ -0,0 +1,453 @@ +/* Q G M E A S U R E F I L T E R . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgMeasureFilter.cpp + * + * Measurement tool for Qt views. + * + */ + +#include "common.h" + +extern "C" { +#include "bu/malloc.h" +#include "bv.h" +#include "raytrace.h" +} + +#include "qtcad/QgMeasureFilter.h" +#include "qtcad/QgSignalFlags.h" + +QMouseEvent * +QgMeasureFilter::view_sync(QEvent *e) +{ + if (!v) + return NULL; + + // If we don't have one of the relevant mouse operations, there's nothing to do + QMouseEvent *m_e = NULL; + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove) + m_e = (QMouseEvent *)e; + if (!m_e) + return NULL; + + // We're going to need the mouse position + int e_x, e_y; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + e_x = m_e->x(); + e_y = m_e->y(); +#else + e_x = m_e->position().x(); + e_y = m_e->position().y(); +#endif + + // Update relevant bview variables + v->gv_prevMouseX = v->gv_mouse_x; + v->gv_prevMouseY = v->gv_mouse_y; + v->gv_mouse_x = e_x; + v->gv_mouse_y = e_y; + bv_screen_pt(&v->gv_point, e_x, e_y, v); + + // If we have modifiers, we're most likely doing shift grips + if (m_e->modifiers() != Qt::NoModifier) + return NULL; + + return m_e; +} + +double +QgMeasureFilter::length1() +{ + return DIST_PNT_PNT(p1, p2); +} + +double +QgMeasureFilter::length2() +{ + if (mode < 3) + return 0.0; + + return DIST_PNT_PNT(p2, p3); +} + +double +QgMeasureFilter::angle(bool radians) +{ + if (mode < 3) + return 0.0; + + vect_t v1, v2; + VSUB2(v1, p1, p2); + VSUB2(v2, p3, p2); + VUNITIZE(v1); + VUNITIZE(v2); + double a = acos(VDOT(v1, v2)); + if (radians) + return a*180/M_PI; + return a; +} + +void +QgMeasureFilter::update_color(struct bu_color *c) +{ + if (!s || !c) + return; + bu_color_to_rgb_chars(c, s->s_color); +} + +bool +QgMeasureFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + if (e->type() == QEvent::MouseButtonPress) { + if (m_e->button() == Qt::RightButton) { + if (s) + bv_obj_put(s); + mode = 0; + VSETALL(p1, 0.0); + VSETALL(p2, 0.0); + VSETALL(p3, 0.0); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + if (mode == 4) { + if (s) + bv_obj_put(s); + mode = 0; + emit view_updated(QG_VIEW_REFRESH); + return true; + } + if (!mode) { + if (!get_point()) + return true; + + VSETALL(p1, 0.0); + VSETALL(p2, 0.0); + VSETALL(p3, 0.0); + + if (s) + bv_obj_put(s); + s = bv_obj_get(v, BV_VIEW_OBJS); + + mode = 1; + VMOVE(p1, mpnt); + VMOVE(p2, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", oname.c_str()); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + if (mode == 1) { + if (!get_point()) + return true; + + VMOVE(p2, mpnt); + return true; + } + if (mode == 2) { + if (!get_point()) + return true; + mode = 3; + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p2, BV_VLIST_LINE_DRAW); + VMOVE(p3, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p3, BV_VLIST_LINE_DRAW); + emit view_updated(QG_VIEW_REFRESH); + } + return true; + } + + if (e->type() == QEvent::MouseMove) { + if (!mode) + return false; + if (mode == 1) { + if (!get_point()) + return true; + + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + VMOVE(p2, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p2, BV_VLIST_LINE_DRAW); + emit view_updated(QG_VIEW_REFRESH); + } + if (mode == 3) { + if (!get_point()) + return true; + + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p2, BV_VLIST_LINE_DRAW); + VMOVE(p3, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p3, BV_VLIST_LINE_DRAW); + emit view_updated(QG_VIEW_REFRESH); + } + return true; + } + + if (e->type() == QEvent::MouseButtonRelease) { + if (m_e->button() == Qt::RightButton) { + mode = 0; + if (s) { + bv_obj_put(s); + emit view_updated(QG_VIEW_REFRESH); + } + s = NULL; + return true; + } + if (!mode) + return false; + if (mode == 1 && DIST_PNT_PNT(p1, p2) < SMALL_FASTF) { + return true; + } + if (mode == 1) { + if (!get_point()) + return true; + + if (length_only) { + // Angle measurement disabled, starting over + mode = 0; + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + mode = 2; + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + VMOVE(p2, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p2, BV_VLIST_LINE_DRAW); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + if (mode == 3) { + if (!get_point()) + return true; + mode = 4; + BV_FREE_VLIST(s->vlfree, &s->s_vlist); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p1, BV_VLIST_LINE_MOVE); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p2, BV_VLIST_LINE_DRAW); + VMOVE(p3, mpnt); + BV_ADD_VLIST(s->vlfree, &s->s_vlist, p3, BV_VLIST_LINE_DRAW); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + return true; + } + + // Shouldn't get here + return false; +} + +bool +QMeasure2DFilter::get_point() +{ + fastf_t vx, vy; + bv_screen_to_view(v, &vx, &vy, v->gv_mouse_x, v->gv_mouse_y); + point_t vpnt; + VSET(vpnt, vx, vy, 0); + MAT4X3PNT(mpnt, v->gv_view2model, vpnt); + return true; +} + +bool +QMeasure2DFilter::eventFilter(QObject *o, QEvent *e) +{ + return QgMeasureFilter::eventFilter(o, e); +} + +QMeasure3DFilter::QMeasure3DFilter() +{ +} + +QMeasure3DFilter::~QMeasure3DFilter() +{ + bu_ptbl_free(&scene_obj_set); +} + +struct measure_rec_state { + double cdist; + point_t pt; +}; + +static int +_cpnt_hit(struct application *ap, struct partition *p_hp, struct seg *UNUSED(segs)) +{ + struct measure_rec_state *rc = (struct measure_rec_state *)ap->a_uptr; + for (struct partition *pp = p_hp->pt_forw; pp != p_hp; pp = pp->pt_forw) { + struct hit *hitp = pp->pt_inhit; + if (hitp->hit_dist < rc->cdist) { + rc->cdist = hitp->hit_dist; + VJOIN1(rc->pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir); + } + } + return 1; +} + +static int +_cpnt_ovlp(struct application *ap, struct partition *pp, struct region *UNUSED(reg1), struct region *UNUSED(reg2), struct partition *UNUSED(ihp)) +{ + struct measure_rec_state *rc = (struct measure_rec_state *)ap->a_uptr; + struct hit *hitp = pp->pt_inhit; + rc->cdist = hitp->hit_dist; + VJOIN1(rc->pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir); + return 1; +} + +bool +QMeasure3DFilter::get_point() +{ + if (!dbip) + return false; + + fastf_t vx, vy; + bv_screen_to_view(v, &vx, &vy, v->gv_mouse_x, v->gv_mouse_y); + point_t vpnt; + VSET(vpnt, vx, vy, 0); + MAT4X3PNT(mpnt, v->gv_view2model, vpnt); + + // With this filter we want a 3D point based on scene geometry (hard case) + // - need to interrogate the scene with the raytracer. + // + // Rather than prepping the whole of what is drawn, we will instead prep + // only those objects whose bounding boxes are currently under the mouse. + // Under most circumstances that should substantially cut down the + // interrogation time for large models. + struct bu_ptbl sset = BU_PTBL_INIT_ZERO; + int scnt = bv_view_objs_select(&sset, v, v->gv_mouse_x, v->gv_mouse_y); + + // If we didn't see anything, we have a no-op + if (!scnt) { + prev_cnt = scnt; + bu_ptbl_free(&sset); + return false; + } + + bool need_prep = (!ap || !rtip || !resp) ? true : false; + if (need_prep || prev_cnt != scnt || scnt != (int)BU_PTBL_LEN(&scene_obj_set)) { + // Something changed - need to reset the raytrace data + bu_ptbl_reset(&scene_obj_set); + bu_ptbl_cat(&scene_obj_set, &sset); + need_prep = true; + } + if (!need_prep) { + // We may be able to reuse the existing prep - make sure the scene obj + // sets match. The above check should ensure that the lengths of sset + // and scene_obj_set match - if they don't, we already know we need to + // re-prep. + for (size_t i = 0; i < BU_PTBL_LEN(&scene_obj_set); i++) { + if (BU_PTBL_GET(&sset, i) != BU_PTBL_GET(&scene_obj_set, i)) { + need_prep = true; + break; + } + } + } + + prev_cnt = scnt; + + if (need_prep) { + if (!ap) { + BU_GET(ap, struct application); + RT_APPLICATION_INIT(ap); + ap->a_onehit = 1; + ap->a_hit = _cpnt_hit; + ap->a_miss = NULL; + ap->a_overlap = _cpnt_ovlp; + ap->a_logoverlap = NULL; + } + if (rtip) { + rt_free_rti(rtip); + rtip = NULL; + } + rtip = rt_new_rti(dbip); + if (resp) { + // TODO - do we need more here? + BU_PUT(resp, struct resource); + } + BU_GET(resp, struct resource); + rt_init_resource(resp, 0, rtip); + ap->a_resource = resp; + ap->a_rt_i = rtip; + + const char **objs = (const char **)bu_calloc(BU_PTBL_LEN(&scene_obj_set) + 1, sizeof(char *), "objs"); + for (size_t i = 0; i < BU_PTBL_LEN(&scene_obj_set); i++) { + struct bv_scene_obj *l_s = (struct bv_scene_obj *)BU_PTBL_GET(&scene_obj_set, i); + objs[i] = bu_vls_cstr(&l_s->s_name); + } + if (rt_gettrees_and_attrs(rtip, NULL, scnt, objs, 1)) { + bu_free(objs, "objs"); + rt_free_rti(rtip); + rtip = NULL; + BU_PUT(resp, struct resource); + resp = NULL; + bu_ptbl_free(&sset); + return false; + } + size_t ncpus = bu_avail_cpus(); + rt_prep_parallel(rtip, (int)ncpus); + bu_free(objs, "objs"); + } + + bu_ptbl_free(&sset); + + // Set up data container for result + struct measure_rec_state rc; + rc.cdist = INFINITY; + ap->a_uptr = (void *)&rc; + + // Set up the ray itself + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, v->radius); + VADD2(ap->a_ray.r_pt, mpnt, dir); + VUNITIZE(dir); + VSCALE(ap->a_ray.r_dir, dir, -1); + + (void)rt_shootray(ap); + + if (rc.cdist < INFINITY) { + VMOVE(mpnt, rc.pt); + return true; + } + + return false; +} + +bool +QMeasure3DFilter::eventFilter(QObject *o, QEvent *e) +{ + return QgMeasureFilter::eventFilter(o, e); +} + + + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgModel.cpp b/src/libqtcad/QgModel.cpp index d45b5748efa..45797871444 100644 --- a/src/libqtcad/QgModel.cpp +++ b/src/libqtcad/QgModel.cpp @@ -29,12 +29,12 @@ * instances, and we can tell via a failed lookup whether a particular instance * in the QgItem is still valid. * - * QgItems form the explicit hierarchical representation implied by the gInstances, - * which means gInstance changes have potentially global impacts on the QgItems - * hierarchy and it must be fully checked for validity (and repaired as appropriate) - * after each cycle. A validity check would be something like: 1) check the hash - * of the QgItem against the gInstance array to see if it is still a valid instance. - * If not, it must be either removed or replaced + * QgItems form the explicit hierarchical representation implied by the instances, + * which means instance changes have potentially global impacts on the QgItems + * hierarchy and it must be fully checked for validity (and repaired as + * appropriate) after each cycle. A validity check would be something like: + * 1) check the hash of the QgItem against the DbiState sets to see if it is + * still valid. If not, it must be either removed or replaced */ #include "common.h" @@ -46,18 +46,19 @@ #include #include +#define XXH_STATIC_LINKING_ONLY +#define XXH_IMPLEMENTATION #include "xxhash.h" #include "bu/env.h" #include "bu/sort.h" -#include "bg/lod.h" +#include "bv/lod.h" #define ALPHANUM_IMPL #include "../libged/alphanum.h" #include "raytrace.h" -#include "qtcad/gInstance.h" #include "qtcad/QgModel.h" #include "qtcad/QgUtil.h" -#include "qtcad/SignalFlags.h" +#include "qtcad/QgSignalFlags.h" struct QgItem_cmp { inline bool operator() (const QgItem *i1, const QgItem *i2) @@ -75,13 +76,15 @@ struct QgItem_cmp { if (i1->ihash && !i2->ihash) return false; - gInstance *inst1 = NULL; - gInstance *inst2 = NULL; - if (i1->ctx->instances->find(i1->ihash) != i1->ctx->instances->end()) { - inst1 = (*i1->ctx->instances)[i1->ihash]; + struct directory *inst1 = NULL; + struct directory *inst2 = NULL; + DbiState *ctx1 = i1->mdl->gedp->dbi_state; + DbiState *ctx2 = i2->mdl->gedp->dbi_state; + if (ctx1->d_map.find(i1->ihash) != ctx1->d_map.end()) { + inst1 = ctx1->d_map[i1->ihash]; } - if (i2->ctx->instances->find(i2->ihash) != i2->ctx->instances->end()) { - inst2 = (*i2->ctx->instances)[i2->ihash]; + if (ctx2->d_map.find(i2->ihash) != ctx2->d_map.end()) { + inst2 = ctx2->d_map[i2->ihash]; } if (!inst1 && !inst2) @@ -91,15 +94,8 @@ struct QgItem_cmp { if (inst1 && !inst2) return false; - if (!inst1->dp_name.length() && !inst2->dp_name.length()) - return false; - if (!inst1->dp_name.length() && inst2->dp_name.length()) - return true; - if (inst1->dp_name.length() && !inst2->dp_name.length()) - return false; - - const char *n1 = inst1->dp_name.c_str(); - const char *n2 = inst2->dp_name.c_str(); + const char *n1 = inst1->d_namep; + const char *n2 = inst2->d_namep; if (alphanum_impl(n1, n2, NULL) < 0) return true; @@ -107,22 +103,28 @@ struct QgItem_cmp { } }; -QgItem::QgItem(gInstance *g, QgModel *ictx) +QgItem::QgItem(unsigned long long hash, QgModel *ictx) { - ctx = ictx; - if (g) { - parentItem = NULL; - c_count = g->children(ictx->instances).size(); - ihash = g->hash; - // TODO - these copies may be moot - the child relationship needs - // the gInstance, so we may have to just ensure gInstances aren't - // removed until after the QgItems are updated. If that's the case, - // there's no point in these copies. - bu_vls_sprintf(&name, "%s", g->dp_name.c_str()); - icon = QgIcon(g->dp, g->dbip); - op = g->op; - dp = g->dp; + mdl = ictx; + DbiState *ctx = mdl->gedp->dbi_state; + ihash = hash; + parentItem = NULL; + if (!ctx) + return; + + // Get the child count from the .g info + std::unordered_map>::iterator pc_it; + pc_it = ctx->p_c.find(ihash); + if (pc_it != ctx->p_c.end()) { + c_count = pc_it->second.size(); + } else { + c_count = 0; } + + // Local item information + ctx->print_hash(&name, ihash); + dp = ctx->get_hdp(ihash); + icon = QgIcon(dp, ictx->gedp->dbip); } QgItem::~QgItem() @@ -133,11 +135,11 @@ QgItem::~QgItem() void QgItem::open() { - if (!ctx) + if (!mdl) return; open_itm = true; - QModelIndex ind = ctx->NodeIndex(this); - ctx->fetchMore(ind); + QModelIndex ind = mdl->NodeIndex(this); + mdl->fetchMore(ind); } @@ -147,20 +149,6 @@ QgItem::close() open_itm = false; } -gInstance * -QgItem::instance() -{ - if (!ctx) - return NULL; - - std::unordered_map::iterator g_it; - g_it = ctx->instances->find(ihash); - if (g_it == ctx->instances->end()) - return NULL; - - return g_it->second; -} - void QgItem::appendChild(QgItem *c) { @@ -179,10 +167,10 @@ QgItem::child(int n) int QgItem::childCount() const { - if (!ctx) + if (!mdl) return 0; - if (this == ctx->root()) + if (this == mdl->root()) return children.size(); return (int)c_count; @@ -214,101 +202,29 @@ QgItem::childNumber() const return 0; } -struct db_full_path * -QgItem::fp() +std::vector +QgItem::path_items() { - std::vector path_items; + std::vector pitems; QgItem *citem = this; - path_items.push_back(this); - while (citem->parent() && citem->parent()->instance()) { + pitems.push_back(this->ihash); + while (citem->parent()) { citem = citem->parent(); - path_items.push_back(citem); - } - std::reverse(path_items.begin(), path_items.end()); - if (!path_items[0]->instance()) - return NULL; - struct db_full_path *ifp; - BU_GET(ifp, struct db_full_path); - db_full_path_init(ifp); - for (size_t i = 0; i < path_items.size(); i++) { - db_add_node_to_full_path(ifp, path_items[i]->dp); - DB_FULL_PATH_SET_CUR_COMB_INST(ifp, path_items[i]->instance()->icnt); + if (citem->ihash) + pitems.push_back(citem->ihash); } - return ifp; + std::reverse(pitems.begin(), pitems.end()); + return pitems; } - -QString -QgItem::toString() +unsigned long long +QgItem::path_hash() { - std::vector path_items; - QgItem *citem = this; - path_items.push_back(this); - while (citem->parent() && citem->parent()->instance()) { - citem = citem->parent(); - path_items.push_back(citem); - } - std::reverse(path_items.begin(), path_items.end()); - struct db_full_path *ifp = fp(); - if (!ifp) - return QString(); - struct bu_vls fpstr = BU_VLS_INIT_ZERO; - db_path_to_vls(&fpstr, ifp); - QString fpqstr(bu_vls_cstr(&fpstr)); - bu_vls_free(&fpstr); - db_free_full_path(ifp); - BU_PUT(ifp, struct db_full_path); - return fpqstr; -} - -// 0 = exact, 1 = name + op, 2 = name + mat, 3 = name only, -1 name mismatch -int -qgitem_cmp_score(QgItem *i1, QgItem *i2) -{ - int ret = -1; - if (!i1 || !i2 || !i1->ihash || !i2->ihash) - return ret; - - gInstance *inst1 = (*i1->ctx->instances)[i1->ihash]; - gInstance *inst2 = (*i2->ctx->instances)[i2->ihash]; - if (inst1->dp_name != inst2->dp_name) - return ret; - - // Names match - ret = 3; - - // Look for a matrix match - struct bn_tol mtol = BN_TOL_INIT_TOL; - if (bn_mat_is_equal(inst1->c_m, inst2->c_m, &mtol)) - ret = 2; - - // Look for a boolean op match - if (inst1->op == inst2->op) - ret = (ret == 2) ? 0 : 1; - - return ret; -} - - -QgItem * -find_similar_qgitem(QgItem *c, std::vector &v) -{ - QgItem *m = NULL; - int lret = INT_MAX; - for (size_t i = 0; i < v.size(); i++) { - int score = qgitem_cmp_score(c, v[i]); - if (score < 0) - continue; - m = (score < lret) ? v[i] : m; - if (!score) - return m; - } - - return m; + std::vector pitems = path_items(); + unsigned long long phash = mdl->gedp->dbi_state->path_hash(pitems, 0); + return phash; } - - extern "C" void qgmodel_update_nref_callback(struct db_i *UNUSED(dbip), struct directory *parent_dp, struct directory *child_dp, const char *child_name, db_op_t op, matp_t m, void *u_data) { @@ -334,48 +250,41 @@ qgmodel_update_nref_callback(struct db_i *UNUSED(dbip), struct directory *parent extern "C" void qgmodel_changed_callback(struct db_i *UNUSED(dbip), struct directory *dp, int mode, void *u_data) { - std::queue::iterator> rmq; - std::unordered_map::iterator i_it, trm_it; - QgModel *ctx = (QgModel *)u_data; - gInstance *inst = NULL; - ctx->need_update_nref = true; - ctx->changed_db_flag = 1; + XXH64_state_t h_state; + unsigned long long hash; + QgModel *mdl = (QgModel *)u_data; + DbiState *ctx = mdl->gedp->dbi_state; + mdl->need_update_nref = true; + mdl->changed_db_flag = 1; + + // Clear cached GED drawing data and update + ctx->clear_cache(dp); // Need to invalidate any LoD caches associated with this dp if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_BOT && ctx->gedp) { - unsigned long long key = bg_mesh_lod_key_get(ctx->gedp->ged_lod, dp->d_namep); + unsigned long long key = bv_mesh_lod_key_get(ctx->gedp->ged_lod, dp->d_namep); if (key) { - bg_mesh_lod_clear_cache(ctx->gedp->ged_lod, key); - bg_mesh_lod_key_put(ctx->gedp->ged_lod, dp->d_namep, 0); + bv_mesh_lod_clear_cache(ctx->gedp->ged_lod, key); + bv_mesh_lod_key_put(ctx->gedp->ged_lod, dp->d_namep, 0); } } switch(mode) { case 0: - // The view needs to regenerate the wireframe(s) for anything drawn - // using this dp, as it may have changed - ctx->changed_dp.insert(dp); - + ctx->changed.insert(dp); break; case 1: - // If we have any name-only references that can now point to a dp, update them - for (i_it = ctx->instances->begin(); i_it != ctx->instances->end(); i_it++) { - inst = i_it->second; - if (!inst->dp && inst->dp_name == std::string(dp->d_namep)) { - inst->dp = dp; - } - } - + ctx->added.insert(dp); break; case 2: - // invalidate the dps in any instances where they match. - for (i_it = ctx->instances->begin(); i_it != ctx->instances->end(); i_it++) { - inst = i_it->second; - if (inst->dp == dp) - inst->dp = NULL; - } - - ctx->changed_dp.insert(dp); + // When this callback is made, dp is still valid, but in subsequent + // processing it will not be. We need to capture everything we + // will need from this dp now, for later use when updating state + XXH64_reset(&h_state, 0); + XXH64_update(&h_state, dp->d_namep, strlen(dp->d_namep)*sizeof(char)); + hash = (unsigned long long)XXH64_digest(&h_state); + ctx->removed.insert(hash); + ctx->old_names[hash] = std::string(dp->d_namep); break; default: bu_log("changed callback mode error: %d\n", mode); @@ -399,19 +308,14 @@ QgModel::QgModel(QObject *p, const char *npath) // with commands needing a view. BU_GET(empty_gvp, struct bview); bv_init(empty_gvp, &gedp->ged_views); + bv_set_add_view(&gedp->ged_views, empty_gvp); gedp->ged_gvp = empty_gvp; bu_vls_sprintf(&gedp->ged_gvp->gv_name, "default"); gedp->ged_gvp->independent = 0; // Set up the root item - rootItem = new QgItem(NULL, this); - rootItem->ctx = this; - - // Initialize the instance containers - tops_instances = new std::unordered_map; - tops_instances->clear(); - instances = new std::unordered_map; - instances->clear(); + rootItem = new QgItem(0, this); + rootItem->mdl = this; items = new std::unordered_set; items->clear(); @@ -436,8 +340,6 @@ QgModel::QgModel(QObject *p, const char *npath) QgModel::~QgModel() { delete items; - delete tops_instances; - delete instances; bv_free(empty_gvp); BU_PUT(empty_gvp, struct bview); @@ -458,77 +360,47 @@ QgModel::item_rebuild(QgItem *item) return; } + unsigned long long chash = item->ihash; + if (gedp->dbi_state->p_v.find(chash) == gedp->dbi_state->p_v.end()) { + // TODO - invalid hash + return; + } + + // Get the current child instances + std::vector &nh = gedp->dbi_state->p_v[chash]; + // If we have no cached children, update only the child count - fetchMore // will populate it if and when it is expanded, and there will be no // QgItems we need to re-use. However, an edit operation may have // invalidated the original c_count stored when the item was created. if (!item->children.size()) { - std::unordered_map::iterator g_it; - gInstance *g = NULL; - g_it = instances->find(item->ihash); - if (g_it != instances->end()) { - g = g_it->second; - item->c_count = g->children(instances).size(); - } else { - item->c_count = 0; - } + item->c_count = gedp->dbi_state->p_v[chash].size(); return; } - // Get the current child instances - std::vector nh = (*instances)[item->ihash]->children(instances); - - // Note that the ordering is important here - when we "pop" off the queue - // in the next step, we need consistent ordering so repeated fetchMore - // calls don't end up swapping around QgItems unnecessarily. Remember - - // the gInstance hashes are not unique by themselves, so they are not - // enough to ensure stable ordering. When we pushed these into the oc - // containers the wrong way, trying to expand havoc's - // havoc/havoc_front/nose_skin/r.nos1 made a mess out of the model and - // display due to multiple instances of s.rad1 subtractions being present. - std::unordered_map> oc; + std::unordered_map oc; for (size_t i = 0; i < item->children.size(); i++) { QgItem *qii = item->children[i]; - oc[qii->ihash].push(qii); + oc[qii->ihash] = qii; } - // Iterate the gInstance's array of child hashes, building up the + // Iterate the instance's array of child hashes, building up the // corresponding QgItems array using either the stored QgItems from the - // previous state or new items. Remember, all QgItems in a queue - // correspond to the same gInstance (i.e. their parent, bool op, matrix - // and child obj are all identical) so if there are multiple QgItems in the - // same queue it doesn't matter what "order" the QgItems are re-added in as - // far as the correctness of the tree is concerned. We are attempting to - // preserve the "open/closed" state of the items via the queue ordering, - // but that won't always be possible. "Preserving" an existing open state - // after a tree change isn't always well defined - if, for example, we have - // two QgItems that both point to the same instance and were duplicated in - // the same child list, but only one of them was opened, if the tree - // rebuild now only has one QgItem being produced you could make the case - // that either of the previous QgItems was the one being removed. So if we - // do hit that duplicate case, the QgItems that are left over in the queues - // once the new state is built up are the ones removed. This is arbitrary, - // but that arbitrariness is an accurate reflection of the underlying data - // model. + // previous state or new items. std::vector nc; - for (size_t i = 0; i < nh.size(); i++) { + std::vector::reverse_iterator nh_it; + for (nh_it = nh.rbegin(); nh_it != nh.rend(); nh_it++) { // For each new child, look up its instance in the original data to see // if we have a corresponding QgItem available. - if (oc.find(nh[i]) != oc.end() && !oc[nh[i]].empty()) { + if (oc.find(*nh_it) != oc.end()) { // We have a viable QgItem from the previous state - reuse it - QgItem *itm = oc[nh[i]].front(); - oc[nh[i]].pop(); - nc.push_back(itm); + nc.push_back(oc[*nh_it]); } else { // Previous tree did not have an appropriate QgItem - // make a new one - std::unordered_map::iterator g_it; - gInstance *g = NULL; - g_it = instances->find(nh[i]); - if (g_it != instances->end()) - g = g_it->second; - QgItem *nitem = new QgItem(g, this); + QgItem *nitem = new QgItem(*nh_it, this); nitem->parentItem = item; + nitem->op = gedp->dbi_state->bool_op(item->ihash, *nh_it); nc.push_back(nitem); items->insert(nitem); } @@ -547,7 +419,6 @@ QgModel::item_rebuild(QgItem *item) item->c_noderow[nc[i]] = i; } } - } void @@ -568,15 +439,20 @@ QgModel::g_update(struct db_i *n_dbip) if (!n_dbip) { // if we have no dbip, clear out everything beginResetModel(); - sync_instances(tops_instances, instances, n_dbip, flatten_hierarchy); std::unordered_set::iterator s_it; for (s_it = items->begin(); s_it != items->end(); s_it++) { QgItem *itm = *s_it; delete itm; } + // Deleted all items, but we need a root item regardless + // of whether a .g is open - recreate it + rootItem = new QgItem(0, this); + rootItem->mdl = this; + items->clear(); tops_items.clear(); emit mdl_changed_db((void *)gedp); + emit view_change(QG_VIEW_DRAWN); emit layoutChanged(); changed_db_flag = 0; endResetModel(); @@ -589,7 +465,7 @@ QgModel::g_update(struct db_i *n_dbip) // Step 1 - make sure our instances are current - i.e. they match the // .g database state - sync_instances(tops_instances, instances, n_dbip, flatten_hierarchy); + gedp->dbi_state->update(); // Clear out any QgItems with invalid info. We need to be fairly // aggressive here - first we find all the existing invalid ones, and @@ -600,19 +476,18 @@ QgModel::g_update(struct db_i *n_dbip) std::unordered_set::iterator s_it; for (s_it = items->begin(); s_it != items->end(); s_it++) { QgItem *itm = *s_it; - if (instances->find(itm->ihash) == instances->end()) { - invalid.insert(itm); + if (gedp->dbi_state->p_v.find(itm->ihash) == gedp->dbi_state->p_v.end() && + gedp->dbi_state->d_map.find(itm->ihash) == gedp->dbi_state->d_map.end()) + to_clear.push(itm); + if (!itm->dp && gedp->dbi_state->get_hdp(itm->ihash)) to_clear.push(itm); - } } while (!to_clear.empty()) { QgItem *i_itm = to_clear.front(); to_clear.pop(); - for (size_t i = 0; i < i_itm->children.size(); i++) { - QgItem *itm = i_itm->children[i]; - invalid.insert(itm); - to_clear.push(itm); - } + invalid.insert(i_itm); + for (size_t i = 0; i < i_itm->children.size(); i++) + to_clear.push(i_itm->children[i]); } for (s_it = items->begin(); s_it != items->end(); s_it++) { @@ -634,11 +509,13 @@ QgModel::g_update(struct db_i *n_dbip) item_rebuild(i_itm); } - // Validate existing tops QgItems based on the now-updated tops_instances data. + // Validate existing tops QgItems based on the tops data. + std::vector tops = gedp->dbi_state->tops(true); + std::unordered_set tset(tops.begin(), tops.end()); std::unordered_map vtops_items; for (size_t i = 0; i < tops_items.size(); i++) { QgItem *titem = tops_items[i]; - if (tops_instances->find(titem->ihash) != tops_instances->end()) { + if (tset.find(titem->ihash) != tset.end()) { // Still a tops item vtops_items[titem->ihash] = titem; } @@ -647,16 +524,16 @@ QgModel::g_update(struct db_i *n_dbip) // Using tops_instances, construct a new tops vector. Reuse any still valid // QgItems, and make new ones std::vector ntops_items; - std::unordered_map::iterator i_it; - for (i_it = tops_instances->begin(); i_it != tops_instances->end(); i_it++) { + + for (size_t i = 0; i < tops.size(); i++) { std::unordered_map::iterator v_it; - v_it = vtops_items.find(i_it->first); + v_it = vtops_items.find(tops[i]); if (v_it != vtops_items.end()) { ntops_items.push_back(v_it->second); } else { - gInstance *ninst = i_it->second; - QgItem *nitem = new QgItem(ninst, this); + QgItem *nitem = new QgItem(tops[i], this); nitem->parentItem = rootItem; + nitem->op = gedp->dbi_state->bool_op(0, tops[i]); ntops_items.push_back(nitem); items->insert(nitem); } @@ -730,13 +607,13 @@ QgModel::canFetchMore(const QModelIndex &idx) const if (item == rootItem) return false; - // If we are trying to update a QgItem and it references an - // invalid instance, there's nothing to update. - if (instances->find(item->ihash) == instances->end()) { - return false; + // If there are children to be fetched, we can fetch them + if (gedp->dbi_state->p_v.find(item->ihash) != gedp->dbi_state->p_v.end()) { + if (gedp->dbi_state->p_v[item->ihash].size()) + return true; } - return (*instances)[item->ihash]->has_children(); + return false; } void @@ -755,41 +632,19 @@ QgModel::fetchMore(const QModelIndex &idx) if (item->children.size()) return; - // We need the QgItem child array to reflect the current state of the comb - // tree, but we also want to keep the old QgItems to minimize disturbances - // to the model that aren't necessary due to .g changes. However, unlike - // the tops case we can't just alphanum sort and compare old to new - we - // need to use the ordering derived from the comb tree. Moreover, we have - // to add new QgItems for new instances *at the right point in the array* - // to reflect the tree ordering - we can't just tack them on at the end. - // To make it even more complicated, we don't have a uniqueness guarantee - // for instance hashes - we may have the same hash in multiple distinct - // QgItems. - // - // To manage this, we make a map of queues and iterate over the old QgItems - // array, queueing up the old items in a manner that allows us to look them - // up using their hash and pop the item closest to the "top" of the tree - // off the queue. This way, whenever we need a particular item, we are - // trying to keep the ordering of the childern close to the previous - // positions. - - // We depend on the instance's set of child hashes being current, either - // from initialization or from the per-object editing callback. If this - // set is not current, we need to fix logic elsewhere to ensure that list - // IS correct before this logic is called - we're not going to try and fix - // it here. - std::vector nh = (*instances)[item->ihash]->children(instances); + unsigned long long chash = item->ihash; + if (gedp->dbi_state->p_v.find(chash) == gedp->dbi_state->p_v.end()) { + // TODO - invalid hash + return; + } + + std::vector &nh = gedp->dbi_state->p_v[chash]; std::vector nc; - for (size_t i = 0; i < nh.size(); i++) { - // For each new child, look up its instance in the original data to see - // if we have a corresponding QgItem available. - std::unordered_map::iterator g_it; - gInstance *g = NULL; - g_it = instances->find(nh[i]); - if (g_it != instances->end()) - g = g_it->second; - QgItem *nitem = new QgItem(g, this); + std::vector::reverse_iterator nh_it; + for (nh_it = nh.rbegin(); nh_it != nh.rend(); nh_it++) { + QgItem *nitem = new QgItem(*nh_it, this); nitem->parentItem = item; + nitem->op = gedp->dbi_state->bool_op(item->ihash, *nh_it); nc.push_back(nitem); items->insert(nitem); } @@ -804,7 +659,7 @@ QgModel::fetchMore(const QModelIndex &idx) } endInsertRows(); emit check_highlights(); - emit item->ctx->opened_item(item); + emit item->mdl->opened_item(item); } @@ -886,15 +741,41 @@ QgModel::data(const QModelIndex &index, int role) const return QVariant(qi->op); if (role == DirectoryInternalRole) return QVariant::fromValue((void *)(qi->dp)); - if (role == DrawnDisplayRole) - return QVariant(qi->draw_state); - if (role == SelectDisplayRole) - return QVariant(qi->select_state); + if (role == DrawnDisplayRole) { + BViewState *vs = qi->mdl->gedp->dbi_state->get_view_state(gedp->ged_gvp); + return QVariant(vs->is_hdrawn(-1, qi->path_hash())); + } + if (role == SelectDisplayRole) { + BSelectState *ss = qi->mdl->gedp->dbi_state->find_selected_state(NULL); + if (ss) + return QVariant(ss->is_selected(qi->path_hash())); + } if (role == TypeIconDisplayRole) return QVariant(qi->icon); + if (role == HighlightDisplayRole) { - return qi->instance()->active_flag; + BSelectState *ss = qi->mdl->gedp->dbi_state->find_selected_state(NULL); + if (!ss) + return QVariant(); + switch (qi->mdl->interaction_mode) { + case 0: + if (qi->open_itm == false && ss->is_active_parent(qi->path_hash())) + return QVariant(1); + return QVariant(0); + case 1: + if (ss->is_parent_obj(qi->ihash)) + return QVariant(2); + return QVariant(0); + case 2: + if (ss->is_immediate_parent_obj(qi->ihash)) + return QVariant(3); + if (ss->is_grand_parent_obj(qi->ihash)) + return QVariant(2); + return QVariant(0); + default: + return QVariant(0); + } } return QVariant(); @@ -994,20 +875,25 @@ QgModel::run_cmd(struct bu_vls *msg, int argc, const char **argv) int QgModel::draw_action() { + QTCAD_SLOT("QgModel::draw_action", 1); // https://stackoverflow.com/a/28647342/2037687 QAction *a = qobject_cast(sender()); QVariant v = a->data(); QgItem *cnode = (QgItem *) v.value(); if (!cnode) return BRLCAD_ERROR; - QString cnode_str = cnode->toString(); - return draw(cnode_str); + std::vector path_hashes = cnode->path_items(); + struct bu_vls path_str = BU_VLS_INIT_ZERO; + gedp->dbi_state->print_path(&path_str, path_hashes); + int ret = draw(bu_vls_cstr(&path_str)); + bu_vls_free(&path_str); + return ret; } int -QgModel::draw(QString &qpath) +QgModel::draw(const char *inst_path) { - const char *inst_path = bu_strdup(qpath.toLocal8Bit().data()); + QTCAD_SLOT("QgModel::draw", 1); const char *argv[2]; argv[0] = "draw"; argv[1] = inst_path; @@ -1015,29 +901,32 @@ QgModel::draw(QString &qpath) bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); int ret = ged_exec(gedp, 2, argv); - bu_free((void *)inst_path, "inst_path"); - - emit view_change(QTCAD_VIEW_DRAWN); + emit view_change(QG_VIEW_DRAWN); return ret; } int QgModel::erase_action() { + QTCAD_SLOT("QgModel::erase_action", 1); // https://stackoverflow.com/a/28647342/2037687 QAction *a = qobject_cast(sender()); QVariant v = a->data(); QgItem *cnode = (QgItem *) v.value(); if (!cnode) return BRLCAD_ERROR; - QString cnode_str = cnode->toString(); - return erase(cnode_str); + std::vector path_hashes = cnode->path_items(); + struct bu_vls path_str = BU_VLS_INIT_ZERO; + gedp->dbi_state->print_path(&path_str, path_hashes); + int ret = erase(bu_vls_cstr(&path_str)); + bu_vls_free(&path_str); + return ret; } int -QgModel::erase(QString &qpath) +QgModel::erase(const char *inst_path) { - const char *inst_path = bu_strdup(qpath.toLocal8Bit().data()); + QTCAD_SLOT("QgModel::erase", 1); const char *argv[2]; argv[0] = "erase"; argv[1] = inst_path; @@ -1045,15 +934,14 @@ QgModel::erase(QString &qpath) bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); int ret = ged_exec(gedp, 2, argv); - bu_free((void *)inst_path, "inst_path"); - - emit view_change(QTCAD_VIEW_DRAWN); + emit view_change(QG_VIEW_DRAWN); return ret; } void QgModel::toggle_hierarchy() { + QTCAD_SLOT("QgModel::toggle_hierarchy", 1); if (!gedp || !gedp->dbip) return; @@ -1065,6 +953,7 @@ QgModel::toggle_hierarchy() void QgModel::item_collapsed(const QModelIndex &index) { + QTCAD_SLOT("QgModel::item_collapsed", 1); QgItem *itm = getItem(index); itm->open_itm = false; } @@ -1072,6 +961,7 @@ QgModel::item_collapsed(const QModelIndex &index) void QgModel::item_expanded(const QModelIndex &index) { + QTCAD_SLOT("QgModel::item_expanded", 1); QgItem *itm = getItem(index); itm->open_itm = true; } diff --git a/src/libqtcad/QgPolyFilter.cpp b/src/libqtcad/QgPolyFilter.cpp new file mode 100644 index 00000000000..ffef72d1213 --- /dev/null +++ b/src/libqtcad/QgPolyFilter.cpp @@ -0,0 +1,455 @@ +/* Q G P O L Y F I L T E R . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgPolyFilter.cpp + * + * Polygon interaction logic for Qt views. + * + */ + +#include "common.h" + +extern "C" { +#include "bu/malloc.h" +#include "bg/polygon.h" +#include "bv.h" +#include "raytrace.h" // For finalize polygon sketch export functionality (TODO - need to move...) +} + +#include "qtcad/QgPolyFilter.h" +#include "qtcad/QgSignalFlags.h" + +QMouseEvent * +QgPolyFilter::view_sync(QEvent *e) +{ + if (!v) + return NULL; + + // If we don't have one of the relevant mouse operations, there's nothing to do + QMouseEvent *m_e = NULL; + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove) + m_e = (QMouseEvent *)e; + if (!m_e) + return NULL; + + // We're going to need the mouse position + int e_x, e_y; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + e_x = m_e->x(); + e_y = m_e->y(); +#else + e_x = m_e->position().x(); + e_y = m_e->position().y(); +#endif + + // Update relevant bview variables + v->gv_prevMouseX = v->gv_mouse_x; + v->gv_prevMouseY = v->gv_mouse_y; + v->gv_mouse_x = e_x; + v->gv_mouse_y = e_y; + bv_screen_pt(&v->gv_point, e_x, e_y, v); + + // If we have modifiers, we're most likely doing shift grips + if (m_e->modifiers() != Qt::NoModifier) + return NULL; + + return m_e; +} + +bool +QgPolyFilter::close_polygon() +{ + // Close the general polygon - if that's what we're creating, + // at this point it will still be open. + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip && ip->polygon.contour[0].open) { + + if (ip->polygon.contour[0].num_points < 3) { + // If we're trying to finalize and we have less than + // three points, just remove - we didn't get enough + // to make a closed polygon. + bg_polygon_free(&ip->polygon); + BU_PUT(ip, struct bv_polygon); + bv_obj_put(wp); + wp = NULL; + return false; + } + + ip->polygon.contour[0].open = 0; + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_DEFAULT); + } + + return true; +} + +bool +QPolyCreateFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + + // Handle Left Click + if (m_e->type() == QEvent::MouseButtonPress && m_e->buttons().testFlag(Qt::LeftButton)) { + + if (!wp) { + + bv_screen_pt(&v->gv_point, v->gv_mouse_x, v->gv_mouse_y, v); + + wp = bv_create_polygon(v, BV_VIEW_OBJS, ptype, v->gv_point); + wp->s_v = v; + + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ptype == BV_POLYGON_GENERAL) { + // For general polygons, we need to identify the active contour + // for update operations to work. + // + // TODO: At some point we'll need to add support for adding and + // removing contours... + ip->curr_contour_i = 0; + } + + // Get edge color + bu_color_to_rgb_chars(&edge_color, wp->s_color); + + // fill color + BU_COLOR_CPY(&ip->fill_color, &fill_color); + + // fill settings + vect2d_t vdir = V2INIT_ZERO; + vdir[0] = fill_slope_x; + vdir[1] = fill_slope_y; + V2MOVE(ip->fill_dir, vdir); + ip->fill_delta = fill_density; + + // Z offset + ip->vZ = vZ; + + // Set fill + if (fill_poly && !ip->fill_flag) { + ip->fill_flag = 1; + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_PROPS_ONLY); + } + if (!fill_poly && ip->fill_flag) { + ip->fill_flag = 0; + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_DEFAULT); + } + + // Name appropriately + bu_vls_init(&wp->s_name); + + // It doesn't get a "proper" name until its finalized + bu_vls_printf(&wp->s_name, "_tmp_view_polygon"); + + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + // If we don't have a polygon at this point, we're done - subsequent logic assumes it + if (!wp) + return true; + + // If we are in the process of creating a general polygon, after the initial creation + // left clicks will append new points + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip->type == BV_POLYGON_GENERAL) { + wp->s_v->gv_mouse_x = v->gv_mouse_x; + wp->s_v->gv_mouse_y = v->gv_mouse_y; + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_PT_APPEND); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + // When we're dealing with polygons stray left clicks shouldn't zoom - just + // consume them if we're not using them above. + return true; + } + + if (m_e->type() == QEvent::MouseButtonPress && m_e->buttons().testFlag(Qt::RightButton)) { + // No-op if we're not in the process of creating a polygon + if (!wp) + return true; + + // Non-general polygon creation doesn't use right click. + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip->type != BV_POLYGON_GENERAL) + return true; + + // When creating a general polygon, right click indicates we're done. + finalize(true); + + return true; + } + + if (m_e->type() == QEvent::MouseButtonPress) { + // We don't want other stray mouse clicks to do something surprising + return true; + } + + // During initial add/creation of non-general polygons, mouse movement + // adjusts the shape + if (m_e->type() == QEvent::MouseMove) { + // No-op if no current polygon is defined + if (!wp) + return true; + + // General polygon creation doesn't use mouse movement. + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip->type == BV_POLYGON_GENERAL) + return true; + + // For every other polygon type, call the libbv update routine + // with the view's x,y coordinates + if (m_e->buttons().testFlag(Qt::LeftButton) && m_e->modifiers() == Qt::NoModifier) { + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_DEFAULT); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + } + + // For the constrained polygon shapes, we're done creating once we release + // the mouse button (i.e. a "click, hold and move" creation paradigm) + if (m_e->type() == QEvent::MouseButtonRelease) { + + // No-op if no current polygon is defined + if (!wp) + return true; + + // General polygons are finalized by a right-click close, since + // appending multiple points requires multiple mouse click-and-release + // operations + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip && ip->type == BV_POLYGON_GENERAL) + return true; + + // For all non-general polygons, mouse release is the signal + // to finish up. + finalize(true); + wp = NULL; + + return true; + } + + return false; +} + +void +QPolyCreateFilter::finalize(bool) +{ + int icnt = 0; + + if (!wp) + return; + + if (!close_polygon()) + return; + + if (op == bg_None || !BU_PTBL_LEN(&bool_objs)) { + // No interactions, so we're keeping it - assign a proper name + bu_vls_sprintf(&wp->s_name, "%s", vname.c_str()); + } else { + + for (size_t i = 0; i < BU_PTBL_LEN(&bool_objs); i++) { + struct bv_scene_obj *target = (struct bv_scene_obj *)BU_PTBL_GET(&bool_objs, i); + icnt += bv_polygon_csg(target, wp, op); + } + + // When doing boolean operations, the convention is if there were one + // or more interactions with other polygons, the original polygon is + // not retained + if (icnt || op == bg_Difference || op == bg_Intersection) { + bv_obj_put(wp); + wp = NULL; + } else { + // No interactions, so we're keeping it - assign a proper name + bu_vls_sprintf(&wp->s_name, "%s", vname.c_str()); + } + } + + // No longer need mouse movements to adjust parameters - turn off callback + if (wp) + wp->s_update_callback = NULL; + + emit view_updated(QG_VIEW_REFRESH); + emit finalized((icnt > 0) ? true : false); +} + +bool +QPolyUpdateFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + // The update filter needs an active polygon to operate on + if (!wp) + return false; + + // We don't want other stray mouse clicks to do something surprising + if (m_e->type() == QEvent::MouseButtonPress || m_e->type() == QEvent::MouseButtonRelease) { + return true; + } + + if (m_e->type() == QEvent::MouseMove) { + + // General polygon creation doesn't use mouse movement. + struct bv_polygon *ip = (struct bv_polygon *)wp->s_i_data; + if (ip->type == BV_POLYGON_GENERAL) + return true; + + // For every other polygon type, call the libbv update routine + // with the view's x,y coordinates + if (m_e->buttons().testFlag(Qt::LeftButton) && m_e->modifiers() == Qt::NoModifier) { + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_DEFAULT); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + } + + return false; +} + +bool +QPolySelectFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + + // Handle Left Click + if (m_e->type() == QEvent::MouseButtonPress && m_e->buttons().testFlag(Qt::LeftButton)) { + struct bu_ptbl *view_objs = bv_view_objs(v, BV_VIEW_OBJS); + if (view_objs) { + wp = bv_select_polygon(view_objs, v->gv_point); + if (!wp) + return true; + struct bv_polygon *vp = (struct bv_polygon *)wp->s_i_data; + ptype = vp->type; + close_general_poly = (vp->polygon.contour) ? vp->polygon.contour[0].open : 1; + // TODO - either set or sync other C++ class setting copies (color, fill, etc.) + } + + return true; + } + + // We also don't want other stray mouse clicks to do something surprising + if (m_e->type() == QEvent::MouseButtonPress || m_e->type() == QEvent::MouseButtonRelease) + return true; + + return false; +} + +bool +QPolyPointFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + // The point filter needs an active general polygon to operate on + if (!wp || ptype != BV_POLYGON_GENERAL) + return false; + + struct bv_polygon *vp = (struct bv_polygon *)wp->s_i_data; + + // If we have a Left release, clear point selection + if (m_e->type() == QEvent::MouseButtonRelease) { + vp->curr_point_i = -1; + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_PT_SELECT_CLEAR); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + // Left press selects a point + if (m_e->type() == QEvent::MouseButtonPress && m_e->buttons().testFlag(Qt::LeftButton)) { + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_PT_SELECT); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + // We also don't want other stray mouse clicks to do something surprising + if (m_e->type() == QEvent::MouseButtonPress || m_e->type() == QEvent::MouseButtonRelease) + return true; + + // Handle Mouse Move - move selected point with a left button click-and-hold + if (m_e->type() == QEvent::MouseMove) { + if (vp->curr_point_i < 0) { + // No selected point + return true; + } + if (m_e->buttons().testFlag(Qt::LeftButton) && m_e->modifiers() == Qt::NoModifier) { + bv_update_polygon(wp, wp->s_v, BV_POLYGON_UPDATE_PT_MOVE); + emit view_updated(QG_VIEW_REFRESH); + return true; + } + + return true; + } + + return false; +} + +bool +QPolyMoveFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + // The move filter needs an active polygon to operate on + if (!wp && !BU_PTBL_LEN(&move_objs)) + return false; + + // We don't want other stray mouse clicks to do something surprising + if (m_e->type() == QEvent::MouseButtonPress || m_e->type() == QEvent::MouseButtonRelease) { + VMOVE(v->gv_prev_point, v->gv_point); + return true; + } + + // If we're clicking-and-holding, it's time to move + if (m_e->type() == QEvent::MouseMove) { + if (m_e->buttons().testFlag(Qt::LeftButton) && m_e->modifiers() == Qt::NoModifier) { + if (BU_PTBL_LEN(&move_objs)) { + for (size_t i = 0; i < BU_PTBL_LEN(&move_objs); i++) { + struct bv_scene_obj *mpoly = (struct bv_scene_obj *)BU_PTBL_GET(&move_objs, i); + bv_move_polygon(mpoly, v->gv_point, v->gv_prev_point); + } + } else { + bv_move_polygon(wp, v->gv_point, v->gv_prev_point); + } + emit view_updated(QG_VIEW_REFRESH); + } + VMOVE(v->gv_prev_point, v->gv_point); + return true; + } + + return false; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgQuadView.cpp b/src/libqtcad/QgQuadView.cpp new file mode 100644 index 00000000000..74178030815 --- /dev/null +++ b/src/libqtcad/QgQuadView.cpp @@ -0,0 +1,628 @@ +/* Q T C A D Q U A D . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgQuadView.cpp + * + * TODO - initialize non-current views to the standard views (check MGED for + * what the defaults should be.) Also, need to implement an event filter for + * this widget (I think there is an example in qged...) Events should pass + * through to the current selected widget when they are either key based or + * take place with the xy coordinates matching the current widget. However, a + * mouse click over the quad widget but NOT located with xy coordinates over + * the currently selected view should change the selected view (updating + * gedp->ged_gvp, perhaps changing the background or some other visual + * signature of which widget is currently active. + * + * One open question is whether the faceplate settings of the previous + * selection should be copied/transferred to the new current selection (in + * effect, making the faceplate settings independent of the specific view + * selected.) Maybe this should be a widget setting, since there are arguments + * that could be made either way... that we we wouldn't be locked into one + * approach at the app level. + * + */ + +#include "common.h" + +#include +#include + +#include "bu/str.h" +#include "bv.h" +#include "ged/defines.h" +#include "ged/commands.h" +#include "qtcad/QgQuadView.h" + +static const char *VIEW_NAMES[] = {"Q1", "Q2", "Q3", "Q4"}; + +/** + * @brief Construct a new Qt C A D Quad:: Qt C A D Quad object + * + * @param parent Parent Qt widget + * @param gedpRef Associated GED struct + * @param type Requesting either a GL or SWRAST display mechanism + */ +QgQuadView::QgQuadView(QWidget *parent, struct ged *gedpRef, int type) : QWidget(parent) +{ + gedp = gedpRef; + graphicsType = type; + + views[UPPER_RIGHT_QUADRANT] = createView(UPPER_RIGHT_QUADRANT); + bv_set_add_view(&gedp->ged_views, views[UPPER_RIGHT_QUADRANT]->view()); + gedp->ged_gvp = views[UPPER_RIGHT_QUADRANT]->view(); + + views[UPPER_RIGHT_QUADRANT]->set_current(1); + currentView = views[UPPER_RIGHT_QUADRANT]; + + default_views(1); +} + +QgQuadView::~QgQuadView() +{ + for (int i = 0; i < 4; i++) { + if (views[i] != nullptr) { + delete views[i]; + views[i] = nullptr; + } + } + + if (spacerTop) + delete spacerTop; + if (spacerBottom) + delete spacerBottom; + if (spacerLeft) + delete spacerLeft; + if (spacerRight) + delete spacerRight; + if (spacerCenter) + delete spacerCenter; +} + +QgView * +QgQuadView::curr_view() +{ + int s = get_selected(); + return get(s); +} + +/** + * @brief Creates a view for the viewport. Convenience method of common things that need to be done to the view. + * + * @param index of the view names to use from the constant list of names + * @return QgView* + */ +QgView * +QgQuadView::createView(unsigned int index) +{ + QgView *view = new QgView(this, graphicsType); + bu_vls_sprintf(&view->view()->gv_name, "%s", VIEW_NAMES[index]); + view->set_current(0); + view->installEventFilter(this); + + view->view()->vset = &gedp->ged_views; + view->view()->independent = 0; + + QObject::connect(view, &QgView::changed, this, &QgQuadView::do_view_changed); + QObject::connect(view, &QgView::init_done, this, &QgQuadView::do_init_done); + return view; +} + +/** + * @brief Convenience method to create the layout and set common parameters. + * + * @return QGridLayout* + */ +QGridLayout * +QgQuadView::createLayout() +{ + QGridLayout *layout = new QGridLayout(this); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->setAlignment(Qt::AlignTop | Qt::AlignLeft); + + this->setLayout(layout); + + if (currentLayout != nullptr) { + delete currentLayout; + } + currentLayout = layout; + + return layout; +} + +/** + * @brief Changes the viewport layout to only have the single view. We destroy the other views if needed and the flag is set + * + */ +void +QgQuadView::changeToSingleFrame() +{ + QGridLayout *layout = (QGridLayout *)this->layout(); + if (layout == nullptr) { + layout = createLayout(); + } + while (layout->takeAt(0) != NULL); + layout->addWidget(views[UPPER_RIGHT_QUADRANT], 0, 2); + + for (int i = 1; i < 4; i++) { + // Don't want use cpu for views that are not visible + if (views[i] != nullptr) { + views[i]->disconnect(); + bv_set_rm_view(&gedp->ged_views, views[i]->view()); + delete views[i]; + views[i] = nullptr; + } + } + + views[UPPER_RIGHT_QUADRANT]->set_current(1); + currentView = views[UPPER_RIGHT_QUADRANT]; + + // No need to indicate active quad + delete spacerTop; + delete spacerBottom; + delete spacerLeft; + delete spacerRight; + delete spacerCenter; + spacerTop = nullptr; + spacerBottom = nullptr; + spacerLeft = nullptr; + spacerRight = nullptr; + spacerCenter = nullptr; + + default_views(0); +} + +/** + * @brief Changes the viewport layout to have 4 views the views will be equal size and not resizeable. This will create the extra view if needed. + * + */ +void +QgQuadView::changeToQuadFrame() +{ + for (int i = UPPER_RIGHT_QUADRANT + 1; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] == nullptr) { + // Make the new view + views[i] = createView(i); + + // Out of the gate, have the new view units match the first view's + // units (which should usually be based on the database units) + views[i]->view()->gv_base2local = views[0]->view()->gv_base2local; + views[i]->view()->gv_local2base = views[0]->view()->gv_local2base; + + // For initial layout calculations, we need to set a screen width + // and height. This won't be right in the end, but it gives + // bv_view_bounds something to work with + views[i]->view()->gv_width = views[UPPER_RIGHT_QUADRANT]->view()->gv_width; + views[i]->view()->gv_height = views[UPPER_RIGHT_QUADRANT]->view()->gv_height; + } + // Turn on adaptive mesh for all new views, if the existing view has it + // enabled - we lose the memory and performance benefits if we have to + // load a full-sized mesh in one of them. + views[i]->view()->gv_s->adaptive_plot_mesh = views[UPPER_RIGHT_QUADRANT]->view()->gv_s->adaptive_plot_mesh; + // For consistency, do the same with CSG lod - this actually cuts against + // us in memory usage as a rule, but default to matching the mesh setting + // behavior + views[i]->view()->gv_s->adaptive_plot_csg = views[UPPER_RIGHT_QUADRANT]->view()->gv_s->adaptive_plot_csg; + bv_set_add_view(&gedp->ged_views, views[i]->view()); + } + + // Define the spacers + spacerTop = new QWidget; + spacerTop->setMinimumWidth(1); + spacerTop->setMaximumWidth(1); + spacerTop->setStyleSheet(""); + spacerBottom = new QWidget; + spacerBottom->setMinimumWidth(1); + spacerBottom->setMaximumWidth(1); + spacerBottom->setStyleSheet(""); + spacerLeft = new QWidget; + spacerLeft->setMinimumHeight(1); + spacerLeft->setMaximumHeight(1); + spacerLeft->setStyleSheet(""); + spacerRight = new QWidget; + spacerRight->setMinimumHeight(1); + spacerRight->setMaximumHeight(1); + spacerRight->setStyleSheet(""); + spacerCenter = new QWidget; + spacerCenter->setMinimumSize(1,1); + spacerCenter->setMaximumSize(1,1); + // Something is always selected, so the center widget is always colored + // accordingly. + spacerCenter->setStyleSheet("background-color:yellow;"); + + QGridLayout *layout = (QGridLayout *)this->layout(); + if (layout == nullptr) { + layout = createLayout(); + } + while (layout->takeAt(0) != NULL); + + layout->addWidget(views[UPPER_LEFT_QUADRANT], 0, 0); + layout->addWidget(spacerTop, 0, 1); + layout->addWidget(views[UPPER_RIGHT_QUADRANT], 0, 2); + layout->addWidget(spacerLeft, 1, 0); + layout->addWidget(spacerCenter, 1, 1); + layout->addWidget(spacerRight, 1, 2); + layout->addWidget(views[LOWER_LEFT_QUADRANT], 2, 0); + layout->addWidget(spacerBottom, 2, 1); + layout->addWidget(views[LOWER_RIGHT_QUADRANT], 2, 2); + + default_views(0); + + // Not sure if this is the right way to do this but need to autoset each of the views + // and make sure the common geometry visible in the first quadrant is also drawn in the + // others. This happens more or less automatically when we're not doing per-view + // adaptive drawing, but it's a different story when each view needs its own view + // specific version of the object. The refresh cycle will populate this eventually, + // but if we don't do it here we'll start out with blank windows until something notifies + // the draw logic it needs to do updates. + for (int i = UPPER_RIGHT_QUADRANT + 1; i < LOWER_RIGHT_QUADRANT + 1; i++) { + bv_autoview(views[i]->view(), BV_AUTOVIEW_SCALE_DEFAULT, 0); + bv_view_bounds(views[i]->view()); + } + struct bu_ptbl *db_objs = bv_view_objs(views[UPPER_RIGHT_QUADRANT]->view(), BV_DB_OBJS); + if (db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(db_objs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(db_objs, i); + for (int j = UPPER_RIGHT_QUADRANT + 1; j < LOWER_RIGHT_QUADRANT + 1; j++) { + draw_scene(so, views[j]->view()); + } + } + } + struct bu_ptbl *local_db_objs = bv_view_objs(views[UPPER_RIGHT_QUADRANT]->view(), BV_DB_OBJS | BV_LOCAL_OBJS); + if (local_db_objs) { + for (size_t i = 0; i < BU_PTBL_LEN(local_db_objs); i++) { + struct bv_scene_obj *so = (struct bv_scene_obj *)BU_PTBL_GET(local_db_objs, i); + for (int j = UPPER_RIGHT_QUADRANT + 1; j < LOWER_RIGHT_QUADRANT + 1; j++) { + draw_scene(so, views[j]->view()); + } + } + } + + for (int i = UPPER_RIGHT_QUADRANT + 1; i < LOWER_RIGHT_QUADRANT + 1; i++) { + views[i]->view()->gv_width = views[UPPER_RIGHT_QUADRANT]->view()->gv_width; + views[i]->view()->gv_height = views[UPPER_RIGHT_QUADRANT]->view()->gv_height; + } + + // Current view selection pieces + select(UPPER_RIGHT_QUADRANT); + gedp->ged_gvp = views[UPPER_RIGHT_QUADRANT]->view(); + views[UPPER_RIGHT_QUADRANT]->set_current(1); + currentView = views[UPPER_RIGHT_QUADRANT]; +} + +void +QgQuadView::do_view_changed() +{ + QTCAD_SLOT("QgQuadView::do_view_changed", 1); + emit changed(currentView); +} + +bool +QgQuadView::isValid() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr && !views[i]->isValid()) + return false; + } + return true; +} + +bool +QgQuadView::eventFilter(QObject *t, QEvent *e) +{ + if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress) { + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr && t == views[i]) { + select(i); + break; + } + } + } + return false; +} + +void +QgQuadView::default_views(int all_views) +{ + if (all_views && views[UPPER_RIGHT_QUADRANT] != nullptr) { + if (views[UPPER_LEFT_QUADRANT] == nullptr) { + views[UPPER_RIGHT_QUADRANT]->aet(270, 90, 0); + } + else { + views[UPPER_RIGHT_QUADRANT]->aet(35, 25, 0); + } + } + if (views[UPPER_LEFT_QUADRANT] != nullptr) { + views[UPPER_LEFT_QUADRANT]->aet(0, 90, 0); + } + if (views[LOWER_LEFT_QUADRANT] != nullptr) { + views[LOWER_LEFT_QUADRANT]->aet(0, 0, 0); + } + if (views[LOWER_RIGHT_QUADRANT] != nullptr) { + views[LOWER_RIGHT_QUADRANT]->aet(90, 0, 0); + } +} + +struct bview * +QgQuadView::view(int quadrantId) +{ + if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; + + if (views[quadrantId] != nullptr) { + return views[quadrantId]->view(); + } + + return currentView->view(); +} + +QgView * +QgQuadView::get(int quadrantId) +{ + if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; + + if (views[quadrantId] != nullptr) { + return views[quadrantId]; + } + + return currentView; +} + +QgView * +QgQuadView::get(const QPoint &gpos) +{ + QgView *retv = NULL; + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + QgView *cv = views[i]; + if (cv == nullptr) + continue; + QWidget *cw = (QWidget *)cv; + QRect br = cw->geometry(); + QWidget *pcw = (QWidget *)cw->parent(); + QPoint lp = pcw->mapFromGlobal(gpos); + if (br.contains(lp)) { + retv = cv; + break; + } + } + + return retv; +} + +QgView * +QgQuadView::get(QEvent *e) +{ + if (e->type() != QEvent::MouseButtonPress) + return NULL; + QMouseEvent *m_e = (QMouseEvent *)e; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QPoint gpos = m_e->globalPos(); +#else + QPoint gpos = m_e->globalPosition().toPoint(); +#endif + return get(gpos); +} + +void +QgQuadView::select(int quadrantId) +{ + if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; + + QgView *oc = currentView; + + // Set new selection + if (views[quadrantId] != nullptr) { + currentView = views[quadrantId]; + } + + // Clear any old selections + if (spacerTop) + spacerTop->setStyleSheet(""); + if (spacerBottom) + spacerBottom->setStyleSheet(""); + if (spacerLeft) + spacerLeft->setStyleSheet(""); + if (spacerRight) + spacerRight->setStyleSheet(""); + + // If we're not in Quad mode, done + if (views[1] == nullptr) + return; + + // If we're in quad mode, more work to do + currentView->set_current(1); + + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (i == quadrantId) + continue; + if (views[i] != nullptr) { + views[i]->set_current(0); + } + } + + if (quadrantId == UPPER_RIGHT_QUADRANT) { + spacerTop->setStyleSheet("background-color:yellow;"); + spacerRight->setStyleSheet("background-color:yellow;"); + } + + if (quadrantId == UPPER_LEFT_QUADRANT) { + spacerTop->setStyleSheet("background-color:yellow;"); + spacerLeft->setStyleSheet("background-color:yellow;"); + } + + if (quadrantId == LOWER_LEFT_QUADRANT) { + spacerBottom->setStyleSheet("background-color:yellow;"); + spacerLeft->setStyleSheet("background-color:yellow;"); + } + + if (quadrantId == LOWER_RIGHT_QUADRANT) { + spacerBottom->setStyleSheet("background-color:yellow;"); + spacerRight->setStyleSheet("background-color:yellow;"); + } + + if (oc != currentView) + emit selected(currentView); +} + +void +QgQuadView::select(const char *quadrant_id) +{ + if (BU_STR_EQUIV(quadrant_id, "ur")) { + select(UPPER_RIGHT_QUADRANT); + return; + } + if (BU_STR_EQUIV(quadrant_id, "ul")) { + select(UPPER_LEFT_QUADRANT); + return; + } + if (BU_STR_EQUIV(quadrant_id, "ll")) { + select(LOWER_LEFT_QUADRANT); + return; + } + if (BU_STR_EQUIV(quadrant_id, "lr")) { + select(LOWER_RIGHT_QUADRANT); + return; + } +} + + +int +QgQuadView::get_selected() +{ + if (currentView == views[UPPER_RIGHT_QUADRANT]) { + return 0; + } + if (currentView == views[UPPER_LEFT_QUADRANT]) { + return 1; + } + if (currentView == views[LOWER_LEFT_QUADRANT]) { + return 2; + } + if (currentView == views[LOWER_RIGHT_QUADRANT]) { + return 3; + } + + return 0; +} + +void +QgQuadView::do_view_update(unsigned long long flags) +{ + bv_log(4, "QgQuadView::do_view_update"); + QTCAD_SLOT("QgQuadView::do_view_update", 1); + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->need_update(flags); + } + } +} + +void +QgQuadView::stash_hashes() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->stash_hashes(); + } + } +} + +bool +QgQuadView::diff_hashes() +{ + bool ret = false; + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + if (views[i]->diff_hashes()) { + ret = true; + } + } + } + + return ret; +} + +void +QgQuadView::enableDefaultKeyBindings() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->enableDefaultKeyBindings(); + } + } +} + +void +QgQuadView::disableDefaultKeyBindings() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->disableDefaultKeyBindings(); + } + } +} + +void +QgQuadView::enableDefaultMouseBindings() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->enableDefaultMouseBindings(); + } + } +} + +void +QgQuadView::disableDefaultMouseBindings() +{ + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->disableDefaultMouseBindings(); + } + } +} + +void +QgQuadView::set_lmouse_move_default(int mm) +{ + QTCAD_SLOT("QgQuadView::set_lmouse_move_default", 1); + for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { + if (views[i] != nullptr) { + views[i]->set_lmouse_move_default(mm); + } + } +} + +void +QgQuadView::do_init_done() +{ + QTCAD_SLOT("QgQuadView::do_init_done", 1); + if (!init_done_flag) { + init_done_flag = true; + emit init_done(); + } +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgSW.cpp b/src/libqtcad/QgSW.cpp new file mode 100644 index 00000000000..03ab2baeee9 --- /dev/null +++ b/src/libqtcad/QgSW.cpp @@ -0,0 +1,450 @@ +/* Q G S W . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgSW.cpp + * + * Qt widget for visualizing libosmesa OpenGL software rasterizer output. + */ + +#define USE_MGL_NAMESPACE 1 + +#include "common.h" + +#include +#include +#include + +extern "C" { +#include "bu/malloc.h" +} +#include "bindings.h" +#include "qtcad/QgSW.h" + +// Using the full GED_MIN/GED_MAX was causing drawing artifacts with moss I +// in shaded mode (I think I was seeing the "Z-fighting" problem: +// https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html ) +// +// Setting to (-1,1) clips geometry too quickly as we start to zoom in. +// -100,100 seems to work, but may need a better long term solution to +// this... maybe basing it on the currently visible object bounds? +#define QTSW_ZMIN -100 +#define QTSW_ZMAX 100 + +QgSW::QgSW(QWidget *parent, struct fb *fbp) + : QWidget(parent), ifp(fbp) +{ + // Provide a view specific to this widget - set gedp->ged_gvp to v + // if this is the current view + BU_GET(local_v, struct bview); + bv_init(local_v, NULL); + bu_vls_sprintf(&local_v->gv_name, "swrast"); + v = local_v; + + // Don't dm_open until we have the view. + dmp = NULL; + + // If we weren't supplied with a framebuffer, allocate one. + // We don't open it until we have the dmp. + if (!ifp) { + ifp = fb_raw("swrast"); + fb_set_standalone(ifp, 0); + } + + // This is an important Qt setting for interactivity - it allowing key + // bindings to propagate to this widget and trigger actions such as + // resolution scaling, rotation, etc. + setFocusPolicy(Qt::WheelFocus); +} + +QgSW::~QgSW() +{ + if (dmp) + dm_close(dmp); + if (ifp && !fb_get_standalone(ifp)) { + fb_close_existing(ifp); + } + BU_PUT(local_v, struct bv); +} + +void QgSW::need_update() +{ + QTCAD_SLOT("QgSW::need_update", 1); + dm_set_dirty(dmp, 1); + update(); +} + +void QgSW::paintEvent(QPaintEvent *e) +{ + // Go ahead and set the flag, but (unlike the rendering thread + // implementation) we need to do the draw routine every time in paintGL, or + // we end up with unrendered frames. + dm_set_dirty(dmp, 0); + + // Without a view, SWrast can't work + if (!v) + return; + + if (!m_init) { + + if (!dmp) { + // swrast will need to know the window size + v->gv_width = width(); + v->gv_height = height(); + + // Do the standard libdm attach to get our rendering backend. + const char *acmd = "attach"; + dmp = dm_open((void *)v, NULL, "swrast", 1, &acmd); + if (!dmp) + return; + + // Let dmp know what the app level widget is (needed so we can + // connect framebuffer drawing events to the widget redraw logic.) + dm_set_udata(dmp, this); + + // If we have a framebuffer, now we can open it + if (ifp) { + struct fb_platform_specific *fbps = fb_get_platform_specific(FB_QTGL_MAGIC); + fbps->data = (void *)dmp; + fb_setup_existing(ifp, dm_get_width(dmp), dm_get_height(dmp), fbps); + fb_put_platform_specific(fbps); + } + } + + dm_configure_win(dmp, 0); + dm_set_pathname(dmp, "SWDM"); + dm_set_zbuffer(dmp, 1); + + fastf_t windowbounds[6] = { -1, 1, -1, 1, QTSW_ZMIN, QTSW_ZMAX }; + dm_set_win_bounds(dmp, windowbounds); + + // Associate the view scale with the dmp + dm_set_vp(dmp, &v->gv_scale); + + // Let the view know it has an associated dm. + v->dmp = dmp; + + // Set the view width and height to match the dm + v->gv_width = dm_get_width(dmp); + v->gv_height = dm_get_height(dmp); + + // If we have a ptbl defining the current dm set and/or an unset + // pointer to indicate the current dm, go ahead and set them. + if (dm_set) + bu_ptbl_ins_unique(dm_set, (long int *)dmp); + + // Ready to go + m_init = true; + + emit init_done(); + } + + if (!m_init || !dmp) + return; + + unsigned char *dm_bg1; + unsigned char *dm_bg2; + dm_get_bg(&dm_bg1, &dm_bg2, dmp); + dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); + + matp_t mat = v->gv_model2view; + dm_loadmatrix(dmp, mat, 0); + dm_draw_begin(dmp); + dm_draw_objs(v, draw_custom, draw_udata); + dm_draw_end(dmp); + + // Set up a QImage with the rendered output.. + unsigned char *dm_image; + if (dm_get_display_image(dmp, &dm_image, 1, 1)) { + return; + } + QImage image(dm_image, dm_get_width(dmp), dm_get_height(dmp), QImage::Format_RGBA8888); + QImage img32 = image.convertToFormat(QImage::Format_RGB32); + QPainter painter(this); + painter.drawImage(this->rect(), img32); + bu_free(dm_image, "copy of backend image"); + QWidget::paintEvent(e); +} + +void QgSW::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + if (dmp && v) { + dm_set_width(dmp, width()); + dm_set_height(dmp, height()); + v->gv_width = width(); + v->gv_height = height(); + dm_configure_win(dmp, 0); + if (ifp) { + fb_configure_window(ifp, v->gv_width, v->gv_height); + } + dm_set_dirty(dmp, 1); + emit changed(); + } +} + +void QgSW::keyPressEvent(QKeyEvent *k) { + + if (!dmp || !v || !current || !use_default_keybindings) { + QWidget::keyPressEvent(k); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADkeyPressEvent(v, x_prev, y_prev, k)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QWidget::keyPressEvent(k); +} + +void QgSW::mousePressEvent(QMouseEvent *e) { + + if (!dmp || !v || !current || !use_default_mousebindings) { + QWidget::mousePressEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADmousePressEvent(v, x_prev, y_prev, e)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + x_press_pos = (double)e->x(); + y_press_pos = (double)e->y(); +#else + x_press_pos = e->position().x(); + y_press_pos = e->position().y(); +#endif + //bu_log("X,Y: %g, %g\n", x_press_pos, y_press_pos); + + QWidget::mousePressEvent(e); +} + +void QgSW::mouseReleaseEvent(QMouseEvent *e) { + if (!v) { + QWidget::mouseReleaseEvent(e); + return; + } + + // To avoid an abrupt jump in scene motion the next time movement is + // started with the mouse, after we release we return to the default state. + x_prev = -INT_MAX; + y_prev = -INT_MAX; + + if (CADmouseReleaseEvent(v, x_press_pos, y_press_pos, x_prev, y_prev, e, lmouse_mode)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QWidget::mouseReleaseEvent(e); +} + + +void QgSW::mouseMoveEvent(QMouseEvent *e) +{ + if (!dmp || !v || !current || !use_default_mousebindings) { + QWidget::mouseMoveEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADmouseMoveEvent(v, x_prev, y_prev, e, lmouse_mode)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + // Current positions are the new previous positions +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + x_prev = e->x(); + y_prev = e->y(); +#else + x_prev = e->position().x(); + y_prev = e->position().y(); +#endif + + QWidget::mouseMoveEvent(e); +} + +void QgSW::wheelEvent(QWheelEvent *e) { + + if (!dmp || !v || !current || !use_default_mousebindings) { + QWidget::wheelEvent(e); + return; + } + + // Let bv know what the current view width and height are, in + // case the dx/dy mouse translations need that information + v->gv_width = width(); + v->gv_height = height(); + + if (CADwheelEvent(v, e)) { + dm_set_dirty(dmp, 1); + update(); + emit changed(); + } + + QWidget::wheelEvent(e); +} + +void QgSW::stash_hashes() +{ + if (!dmp) { + prev_dhash = 0; + } else { + prev_dhash = dm_hash(dmp); + } + prev_vhash = bv_hash(v); +} + +bool QgSW::diff_hashes() +{ + bool ret = false; + unsigned long long c_dhash = 0; + unsigned long long c_vhash = 0; + + if (dmp) { + c_dhash = dm_hash(dmp); + } + if (v) { + c_vhash = bv_hash(v); + } + + if (dmp && dm_get_dirty(dmp)) + ret = true; + + if (prev_dhash != c_dhash) { + if (dmp) + dm_set_dirty(dmp, 1); + ret = true; + } + if (prev_vhash != c_vhash) { + if (dmp) + dm_set_dirty(dmp, 1); + ret = true; + } + + if (ret) { + need_update(); + emit changed(); + } + + return ret; +} + +void QgSW::save_image() { + // Set up a QImage with the rendered output.. + unsigned char *dm_image; + if (dm_get_display_image(dmp, &dm_image, 1, 1)) { + return; + } + QImage image(dm_image, dm_get_width(dmp), dm_get_height(dmp), QImage::Format_RGBA8888); + QImage img32 = image.convertToFormat(QImage::Format_RGB32); + img32.save("file.png"); +} + +void QgSW::aet(double a, double e, double t) +{ + if (!v) + return; + + fastf_t aet[3]; + double aetd[3]; + aetd[0] = a; + aetd[1] = e; + aetd[2] = t; + + /* convert from double to fastf_t */ + VMOVE(aet, aetd); + + VMOVE(v->gv_aet, aet); + + /* TODO - based on the suspect bv_mat_aet... */ + mat_t tmat; + fastf_t twist; + fastf_t c_twist; + fastf_t s_twist; + bn_mat_angles(v->gv_rotation, 270.0 + v->gv_aet[1], 0.0, 270.0 - v->gv_aet[0]); + twist = -v->gv_aet[2] * DEG2RAD; + c_twist = cos(twist); + s_twist = sin(twist); + bn_mat_zrot(tmat, s_twist, c_twist); + bn_mat_mul2(tmat, v->gv_rotation); + + bv_update(v); +} + +void +QgSW::enableDefaultKeyBindings() +{ + use_default_keybindings = true; +} + +void +QgSW::disableDefaultKeyBindings() +{ + use_default_keybindings = false; +} + +void +QgSW::enableDefaultMouseBindings() +{ + use_default_mousebindings = true; +} + +void +QgSW::disableDefaultMouseBindings() +{ + use_default_mousebindings = false; +} + +void +QgSW::set_lmouse_move_default(int mm) +{ + QTCAD_SLOT("QgSW::set_lmouse_move_default", 1); + lmouse_mode = mm; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + diff --git a/src/libqtcad/QgSelectFilter.cpp b/src/libqtcad/QgSelectFilter.cpp new file mode 100644 index 00000000000..7105c2f2dcf --- /dev/null +++ b/src/libqtcad/QgSelectFilter.cpp @@ -0,0 +1,396 @@ +/* Q G S E L E C T F I L T E R . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgSelectFilter.cpp + * + * Graphical selection tool for Qt views. + * + */ + +#include "common.h" + +extern "C" { +#include "bu/malloc.h" +#include "bg/aabb_ray.h" +#include "bv.h" +#include "raytrace.h" +} + +#include +#include "qtcad/QgSelectFilter.h" +#include "qtcad/QgSignalFlags.h" + +// Find the first bbox intersection under the XY view point. +static struct bv_scene_obj * +closest_obj_bbox(struct bu_ptbl *sset, struct bview *v) +{ + fastf_t vx = -FLT_MAX; + fastf_t vy = -FLT_MAX; + struct bv_scene_obj *s_closest = NULL; + double dist = DBL_MAX; + bv_screen_to_view(v, &vx, &vy, v->gv_mouse_x, v->gv_mouse_y); + point_t vpnt, mpnt; + VSET(vpnt, vx, vy, 0); + MAT4X3PNT(mpnt, v->gv_view2model, vpnt); + point_t rmin, rmax; + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, v->radius); + VADD2(mpnt, mpnt, dir); + VUNITIZE(dir); + bg_ray_invdir(&dir, dir); + for (size_t i = 0; i < BU_PTBL_LEN(sset); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(sset, i); + if (bg_isect_aabb_ray(rmin, rmax, mpnt, dir, s->bmin, s->bmax)){ + double ndist = DIST_PNT_PNT(rmin, v->gv_vc_backout); + if (ndist < dist) { + dist = ndist; + s_closest = s; + } + } + } + + return s_closest; +} + +QMouseEvent * +QgSelectFilter::view_sync(QEvent *e) +{ + if (!v) + return NULL; + + // If we don't have one of the relevant mouse operations, there's nothing to do + QMouseEvent *m_e = NULL; + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove) + m_e = (QMouseEvent *)e; + if (!m_e) + return NULL; + + // We're going to need the mouse position + int e_x, e_y; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + e_x = m_e->x(); + e_y = m_e->y(); +#else + e_x = m_e->position().x(); + e_y = m_e->position().y(); +#endif + + // Update relevant bview variables + v->gv_prevMouseX = v->gv_mouse_x; + v->gv_prevMouseY = v->gv_mouse_y; + v->gv_mouse_x = e_x; + v->gv_mouse_y = e_y; + bv_screen_pt(&v->gv_point, e_x, e_y, v); + + // If we have modifiers, we're most likely doing shift grips + if (m_e->modifiers() != Qt::NoModifier) + return NULL; + + return m_e; +} + + +bool +QgSelectPntFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + + // Eat everything except the mouse release + if (e->type() != QEvent::MouseButtonRelease) + return true; + + // Left mouse button only + if (m_e->button() != Qt::LeftButton) + return true; + + // If we don't have a view there's nothing we can do... + if (!v) + return true; + + // Do the actual selection, using a one pixel sized box projected into the + // scene. This is faster than the raytrace-based test in some situations, + // but trades off that speed by only producing an approximate answer based + // on bounding boxes. + int scnt = bv_view_objs_select(&selected_set, v, v->gv_mouse_x, v->gv_mouse_y); + + // If the caller wants everything, or we got less than 2 objs, we're done + if (scnt < 2 || !first_only) + return true; + + // If we want only the closest object (or more precisely, in this mode, the + // object with the closest bounding box) there's more work to do. + struct bv_scene_obj *s_closest = closest_obj_bbox(&selected_set, v); + bu_ptbl_reset(&selected_set); + bu_ptbl_ins(&selected_set, (long *)s_closest); + + return true; +} + +bool +QgSelectBoxFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + if (!v) + return false; + + // Eat double clicks + if (e->type() == QEvent::MouseButtonDblClick) + return true; + + // Left mouse button and move events are the ones of interest + if (m_e->button() != Qt::LeftButton && e->type() != QEvent::MouseMove) + return true; + + if (e->type() == QEvent::MouseButtonPress) { + px = v->gv_mouse_x; + py = v->gv_mouse_y; + struct bv_interactive_rect_state *grsp = &v->gv_s->gv_rect; + grsp->line_width = 1; + grsp->dim[0] = 0; + grsp->dim[1] = 0; + grsp->x = px; + grsp->y = v->gv_height - py; + grsp->pos[0] = grsp->x; + grsp->pos[1] = grsp->y; + grsp->cdim[0] = v->gv_width; + grsp->cdim[1] = v->gv_height; + grsp->aspect = (fastf_t)v->gv_s->gv_rect.cdim[X] / v->gv_s->gv_rect.cdim[Y]; + emit view_updated(QG_VIEW_DRAWN); + return true; + } + + if (e->type() == QEvent::MouseMove) { + struct bv_interactive_rect_state *grsp = &v->gv_s->gv_rect; + grsp->draw = 1; + grsp->dim[0] = v->gv_mouse_x - px; + grsp->dim[1] = (v->gv_height - v->gv_mouse_y) - v->gv_s->gv_rect.pos[1]; + grsp->x = (grsp->pos[X] / (fastf_t)grsp->cdim[X] - 0.5) * 2.0; + grsp->y = ((0.5 - (grsp->cdim[Y] - grsp->pos[Y]) / (fastf_t)grsp->cdim[Y]) / grsp->aspect * 2.0); + grsp->width = grsp->dim[X] * 2.0 / (fastf_t)grsp->cdim[X]; + grsp->height = grsp->dim[Y] * 2.0 / (fastf_t)grsp->cdim[X]; + emit view_updated(QG_VIEW_DRAWN); + return true; + } + + if (e->type() == QEvent::MouseButtonRelease) { + // Mouse release - time to use the rectangle to assemble the selected set + int ipx = (int)px; + int ipy = (int)py; + bv_view_objs_rect_select(&selected_set, v, ipx, ipy, v->gv_mouse_x, v->gv_mouse_y); + +#if 0 + // If we want only the closest object (or more precisely, in this mode, + // the object with the closest bounding box) there's more work to do. + // TODO - this is the wrong test for the selection rectangle - should + // be the distance between an aabb and a view plane. Looks like we + // need to add that one to libbg... there's DIST_PNT_PLANE and + // MAT4X3VEC(view_pl, v->gv_view2model, dir) as starting points... + struct bv_scene_obj *s_closest = closest_obj_bbox(&selected_set, v); + bu_ptbl_reset(&selected_set); + bu_ptbl_ins(&selected_set, (long *)s_closest); +#endif + + // reset rectangle + struct bv_interactive_rect_state *grsp = &v->gv_s->gv_rect; + grsp->draw = 0; + grsp->line_width = 0; + grsp->pos[0] = 0; + grsp->pos[1] = 0; + grsp->dim[0] = 0; + grsp->dim[1] = 0; + emit view_updated(QG_VIEW_DRAWN); + return true; + } + + // Shouldn't get here + return false; +} + + +struct select_rec_state { + std::unordered_set active; + int rec_all; + double cdist; + std::string closest; +}; + +static int +_obj_record(struct application *ap, struct partition *p_hp, struct seg *UNUSED(segs)) +{ + struct select_rec_state *rc = (struct select_rec_state *)ap->a_uptr; + for (struct partition *pp = p_hp->pt_forw; pp != p_hp; pp = pp->pt_forw) { + if (rc->rec_all) { + rc->active.insert(std::string(pp->pt_regionp->reg_name)); + } else { + struct hit *hitp = pp->pt_inhit; + if (hitp->hit_dist < rc->cdist) { + rc->closest = std::string(pp->pt_regionp->reg_name); + rc->cdist = hitp->hit_dist; + } + } + } + bu_log("hit\n"); + return 1; +} + +static int +_ovlp_record(struct application *ap, struct partition *pp, struct region *reg1, struct region *reg2, struct partition *UNUSED(ihp)) +{ + struct select_rec_state *rc = (struct select_rec_state *)ap->a_uptr; + if (rc->rec_all) { + rc->active.insert(std::string(reg1->reg_name)); + rc->active.insert(std::string(reg2->reg_name)); + } else { + rc->closest = std::string(reg1->reg_name); + rc->cdist = pp->pt_inhit->hit_dist; + } + bu_log("ovlp\n"); + return 1; +} + +bool +QgSelectRayFilter::eventFilter(QObject *, QEvent *e) +{ + QMouseEvent *m_e = view_sync(e); + if (!m_e) + return false; + + // If we're raytracing, the view itself isn't enough - we have + // to have the dbip as well. + if (!v || !dbip) + return false; + + // Eat everything except the mouse release + if (e->type() != QEvent::MouseButtonRelease) + return true; + + // Left mouse button only + if (m_e->button() != Qt::LeftButton) + return true; + + // Pre-filter what we're going to be shooting using the bounding box tests. + // If we have no intersections, there's no point in doing the raytrace. + int scnt = bv_view_objs_select(&selected_set, v, v->gv_mouse_x, v->gv_mouse_y); + if (!scnt) + return true; + + // librt intersection test. + struct application *ap; + BU_GET(ap, struct application); + RT_APPLICATION_INIT(ap); + ap->a_onehit = 0; + ap->a_hit = _obj_record; + ap->a_miss = NULL; + ap->a_overlap = _ovlp_record; + ap->a_logoverlap = NULL; + + struct rt_i *rtip = rt_new_rti(dbip); + struct resource *resp = NULL; + BU_GET(resp, struct resource); + rt_init_resource(resp, 0, rtip); + ap->a_resource = resp; + ap->a_rt_i = rtip; + const char **objs = (const char **)bu_calloc(BU_PTBL_LEN(&selected_set) + 1, sizeof(char *), "objs"); + for (size_t i = 0; i < BU_PTBL_LEN(&selected_set); i++) { + struct bv_scene_obj *s = (struct bv_scene_obj *)BU_PTBL_GET(&selected_set, i); + objs[i] = bu_vls_cstr(&s->s_name); + } + if (rt_gettrees_and_attrs(rtip, NULL, scnt, objs, 1)) { + bu_free(objs, "objs"); + rt_free_rti(rtip); + BU_PUT(resp, struct resource); + BU_PUT(ap, struct appliation); + return false; + } + size_t ncpus = bu_avail_cpus(); + rt_prep_parallel(rtip, (int)ncpus); + fastf_t vx = -FLT_MAX; + fastf_t vy = -FLT_MAX; + bv_screen_to_view(v, &vx, &vy, v->gv_mouse_x, v->gv_mouse_y); + point_t vpnt, mpnt; + VSET(vpnt, vx, vy, 0); + MAT4X3PNT(mpnt, v->gv_view2model, vpnt); + vect_t dir; + VMOVEN(dir, v->gv_rotation + 8, 3); + VUNITIZE(dir); + VSCALE(dir, dir, v->radius); + VADD2(ap->a_ray.r_pt, mpnt, dir); + VUNITIZE(dir); + VSCALE(ap->a_ray.r_dir, dir, -1); + + struct select_rec_state rc; + + // Decide what we record in the hit function based on whether we want the + // closest or all hits. + if (!first_only) { + rc.rec_all = 1; + } else { + rc.rec_all = 0; + rc.cdist = INFINITY; + } + ap->a_uptr = (void *)&rc; + + (void)rt_shootray(ap); + bu_free(objs, "objs"); + rt_free_rti(rtip); + BU_PUT(resp, struct resource); + BU_PUT(ap, struct appliation); + + // We only have reg_names from the raytrace - translate into scene objects. + bu_ptbl_reset(&selected_set); + struct bu_vls dpath = BU_VLS_INIT_ZERO; + if (first_only) { + bu_vls_sprintf(&dpath, "%s", rc.closest.c_str()); + if (bu_vls_cstr(&dpath)[0] == '/') + bu_vls_nibble(&dpath, 1); + struct bv_scene_obj *so = bv_find_obj(v, bu_vls_cstr(&dpath)); + if (so) + bu_ptbl_ins(&selected_set, (long *)so); + } else { + std::unordered_set::iterator a_it; + for (a_it = rc.active.begin(); a_it != rc.active.end(); a_it++) { + bu_vls_sprintf(&dpath, "%s", a_it->c_str()); + if (bu_vls_cstr(&dpath)[0] == '/') + bu_vls_nibble(&dpath, 1); + struct bv_scene_obj *so = bv_find_obj(v, bu_vls_cstr(&dpath)); + if (so) + bu_ptbl_ins(&selected_set, (long *)so); + } + } + bu_vls_free(&dpath); + + return true; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgToolPalette.cpp b/src/libqtcad/QgToolPalette.cpp new file mode 100644 index 00000000000..86f3437dc24 --- /dev/null +++ b/src/libqtcad/QgToolPalette.cpp @@ -0,0 +1,306 @@ +/* Q G T O O L P A L E T T E . C X X + * BRL-CAD + * + * Copyright (c) 2014-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgToolPalette.cxx + * + * Qt Tool Palette implementation + * + */ + +#include "common.h" + +#include +#include +#include "qtcad/QgToolPalette.h" + +QgToolPaletteButton::QgToolPaletteButton(QWidget *bparent, QIcon *iicon, QgToolPaletteElement *eparent) : QPushButton(bparent) +{ + setIcon(*iicon); + element = eparent; + QObject::connect(this, &QgToolPaletteButton::clicked, this, &QgToolPaletteButton::select_element); +} + + +void +QgToolPaletteButton::select_element() +{ + QTCAD_SLOT("QgToolPaletteButton::select_element", 1); + emit element_selected(element); +} + +void +QgToolPaletteButton::setButtonElement(QIcon *iicon, QgToolPaletteElement *n_element) +{ + setIcon(*iicon); + element = n_element; +} + + +QgToolPaletteElement::QgToolPaletteElement(QIcon *iicon, QWidget *control) +{ + button = new QgToolPaletteButton(this, iicon, this); + button->setCheckable(true); + controls = control; + controls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); +} + +QgToolPaletteElement::~QgToolPaletteElement() +{ + delete button; +} + +#if 0 +bool +QgToolPaletteElement::eventFilter(QObject *o, QEvent *e) +{ + if (!o || !e) + return false; + + printf("palette element filter\n"); + + return controls->eventFilter(o, e); +} +#endif + +void +QgToolPaletteElement::setButton(QgToolPaletteButton *n_button) +{ + button = n_button; +} + +void +QgToolPaletteElement::setControls(QWidget *n_control) +{ + controls = n_control; +} + +void +QgToolPaletteElement::element_view_changed(unsigned long long flags) +{ + QTCAD_SLOT("QgToolPaletteElement::element_view_changed", 1); + emit view_changed(flags); +} + +void +QgToolPaletteElement::do_view_update(unsigned long long flags) +{ + QTCAD_SLOT("QgToolPaletteElement::do_view_update", 1); + // TODO - do any element level updating (button highlighting?) + emit element_view_update(flags); +} + +void +QgToolPaletteElement::do_element_unhide(void *) +{ + QTCAD_SLOT("QgToolPaletteElement::do_element_unhide", 1); + emit element_unhide(); +} + +QgToolPalette::QgToolPalette(QWidget *pparent) : QWidget(pparent) +{ + always_selected = 1; + icon_width = 30; + icon_height = 30; + mlayout = new QVBoxLayout(); + mlayout->setSpacing(0); + mlayout->setContentsMargins(1,1,1,1); + + + button_container = new QWidget(); + button_layout = new QgFlowLayout(); + button_layout->setHorizontalSpacing(0); + button_layout->setVerticalSpacing(0); + button_layout->setContentsMargins(0,0,0,0); + button_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button_container->setMinimumHeight(icon_height); + button_container->setMinimumWidth(icon_width*5+1); + button_container->setLayout(button_layout); + + control_container = new QScrollArea(); + control_container->setWidgetResizable(true); + mlayout->addWidget(button_container); + mlayout->addWidget(control_container); + + selected = NULL; + + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + setLayout(mlayout); + + selected_style = QString("border: 1px solid rgb(255, 255, 0)"); +} + +QgToolPalette::~QgToolPalette() +{ +} + +void +QgToolPalette::button_layout_resize() +{ + QTCAD_SLOT("QgToolPalette::button_layout_resize", 1); + div_t layout_dim = div(button_container->size().width()-1, icon_width); + div_t layout_grid = div((int)elements.count(), (int)layout_dim.quot); + if (layout_grid.rem > 0) { + button_container->setMinimumHeight((layout_grid.quot + 1) * icon_height); + button_container->setMaximumHeight((layout_grid.quot + 1) * icon_height); + } else { + button_container->setMinimumHeight((layout_grid.quot) * icon_height); + button_container->setMaximumHeight((layout_grid.quot) * icon_height); + } +} + +void +QgToolPalette::resizeEvent(QResizeEvent *pevent) +{ + QWidget::resizeEvent(pevent); + button_layout_resize(); +} + +void +QgToolPalette::setIconWidth(int iwidth) +{ + icon_width = iwidth; + foreach(QgToolPaletteElement *el, elements) { + el->button->setMinimumWidth(icon_height); + el->button->setMaximumWidth(icon_height); + } + updateGeometry(); +} + +void +QgToolPalette::setIconHeight(int iheight) +{ + icon_height = iheight; + foreach(QgToolPaletteElement *el, elements) { + el->button->setMinimumHeight(icon_height); + el->button->setMaximumHeight(icon_height); + } + updateGeometry(); +} + + +void +QgToolPalette::setAlwaysSelected(int toggle) +{ + always_selected = toggle; + if (always_selected && selected == NULL) { + palette_displayElement(*(elements.begin())); + } +} + +void +QgToolPalette::do_view_update(unsigned long long flags) +{ + QTCAD_SLOT("QgToolPalette::do_element_unhide", 1); + emit palette_view_update(flags); +} + + +void +QgToolPalette::palette_do_view_changed(unsigned long long flags) +{ + QTCAD_SLOT("QgToolPalette::palette_do_view_changed", 1); + emit view_changed(flags); +} + +void +QgToolPalette::addElement(QgToolPaletteElement *element) +{ + element->button->setMinimumWidth(icon_width); + element->button->setMaximumWidth(icon_width); + element->button->setMinimumHeight(icon_height); + element->button->setMaximumHeight(icon_height); + button_layout->addWidget(element->button); + elements.insert(element); + + QObject::connect(element->button, &QgToolPaletteButton::element_selected, this, &QgToolPalette::palette_displayElement); + + QObject::connect(this, &QgToolPalette::palette_view_update, element, &QgToolPaletteElement::do_view_update); + QObject::connect(element, &QgToolPaletteElement::view_changed, this, &QgToolPalette::palette_do_view_changed); + + + updateGeometry(); + if (!selected && always_selected) { + palette_displayElement(element); + selected->button->setStyleSheet(""); + } +} + +void +QgToolPalette::deleteElement(QgToolPaletteElement *element) +{ + elements.remove(element); + if (selected == element) { + palette_displayElement(*elements.begin()); + } + button_layout->removeWidget(element->button); + updateGeometry(); + delete element; +} + +void +QgToolPalette::palette_displayElement(QgToolPaletteElement *element) +{ + QTCAD_SLOT("QgToolPalette::palette_displayElement", 1); + if (element) { + if (element == selected) { + if (!always_selected) { + if (element->button->isChecked()) element->button->setChecked(false); + element->controls->hide(); + selected = NULL; + } else { + element->button->setStyleSheet(selected_style); + } + } else { + if (!element->button->isChecked()) element->button->setChecked(true); + if (selected && element != selected) { + selected->scroll_pos = control_container->verticalScrollBar()->sliderPosition(); + selected->controls->hide(); + if (selected->button->isChecked()) selected->button->setChecked(false); + } + control_container->takeWidget(); + control_container->setWidget(element->controls); + element->controls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + element->controls->show(); + element->do_element_unhide(NULL); + control_container->verticalScrollBar()->setSliderPosition(element->scroll_pos); + selected = element; + foreach(QgToolPaletteElement *el, elements) { + if (el != selected) { + el->button->setDown(false); + el->button->setStyleSheet(""); + } else { + el->button->setStyleSheet(selected_style); + } + } + } + emit palette_element_selected(element); + } +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + + diff --git a/src/libqtcad/QgTreeSelectionModel.cpp b/src/libqtcad/QgTreeSelectionModel.cpp index d65b1981fdb..0ea8ad0562b 100644 --- a/src/libqtcad/QgTreeSelectionModel.cpp +++ b/src/libqtcad/QgTreeSelectionModel.cpp @@ -27,43 +27,36 @@ #include #include #include +#include #include "qtcad/QgUtil.h" #include "qtcad/QgModel.h" #include "qtcad/QgTreeSelectionModel.h" -#include "qtcad/SignalFlags.h" +#include "qtcad/QgSignalFlags.h" void QgTreeSelectionModel::clear_all() { QgModel *m = treeview->m; - QgItem *snode = m->root(); - std::queue get_children; - if (snode->children.size()) - get_children.push(snode); - - while (!get_children.empty()) { - QgItem *cnode = get_children.front(); - get_children.pop(); - cnode->select_state = 0; - for (size_t j = 0; j < cnode->children.size(); j++) { - QgItem *ccnode = cnode->children[j]; - get_children.push(ccnode); - } - } -} + std::vector sv = m->gedp->dbi_state->get_selected_states(NULL); + BSelectState *ss = sv[0]; + ss->clear(); + ss->characterize(); +} void QgTreeSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags flags) { + QTCAD_SLOT("QgTreeSelectionModel::select QItemSelection", 1); QgModel *m = treeview->m; struct ged *gedp = m->gedp; - struct ged_selection_set *gs = gedp->ged_cset; - if (flags & QItemSelectionModel::Clear) { - if (gs) - ged_selection_set_clear(gs); - } + std::vector ssv = gedp->dbi_state->get_selected_states(NULL); + + if (ssv.size() != 1) + return; + + BSelectState *ss = ssv[0]; #if 0 QModelIndexList dl = selection.indexes(); @@ -78,497 +71,107 @@ QgTreeSelectionModel::select(const QItemSelection &selection, QItemSelectionMode #endif // If we are selecting an already selected node, clear it - if (flags & QItemSelectionModel::Select && snode->select_state) { - snode->select_state = 0; - struct bu_vls tpath = BU_VLS_INIT_ZERO; - QString nstr = snode->toString(); - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - - // This toggle is a local operation - continue; - } - - // If a node is being selected, all of its parents and children - // will be de-selected - if (!(flags & QItemSelectionModel::Deselect)) { - - // Find the parents - QgItem *pnode = snode->parent(); - while (pnode) { - QString nstr = pnode->toString(); - if (nstr == QString()) - break; - std::cout << "Parent: " << nstr.toLocal8Bit().data() << "\n"; - if (pnode->select_state && gs) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } - pnode->select_state = 0; - pnode = pnode->parent(); - } - - std::queue get_children; - if (snode->children.size()) - get_children.push(snode); - - while (!get_children.empty()) { - QgItem *cnode = get_children.front(); - get_children.pop(); - cnode->select_state = 0; - for (size_t j = 0; j < cnode->children.size(); j++) { - QgItem *ccnode = cnode->children[j]; - get_children.push(ccnode); + if (flags & QItemSelectionModel::Select && ss->is_selected(snode->path_hash())) { + if (!(QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier))) { + if (flags & QItemSelectionModel::Clear && ss->selected.size() > 1) { + ss->clear(); + std::vector path_hashes = snode->path_items(); + ss->select_hpath(path_hashes); + } else { + std::vector path_hashes = snode->path_items(); + ss->deselect_hpath(path_hashes); } } - - - // This node is selected - snode->select_state = 1; - - if (gs) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - QString nstr = snode->toString(); - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - std::cout << "ged insert: " << bu_vls_cstr(&tpath) << "\n"; - ged_selection_insert(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } - - } else { + if (flags & QItemSelectionModel::Clear) + ss->clear(); - snode->select_state = 0; - - QString nstr = snode->toString(); - if (gs && nstr != QString()) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - std::cout << "ged remove: " << bu_vls_cstr(&tpath) << "\n"; - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } + std::vector path_hashes = snode->path_items(); + ss->select_hpath(path_hashes); } } + // Done manipulating paths - update metadata + ss->characterize(); + + unsigned long long sflags = QG_VIEW_SELECT; + if (ss->draw_sync()) + sflags |= QG_VIEW_REFRESH; - emit treeview->view_changed(QTCAD_VIEW_SELECT); + emit treeview->view_changed(sflags); emit treeview->m->layoutChanged(); } void QgTreeSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags) { + QTCAD_SLOT("QgTreeSelectionModel::select QModelIndex", 1); QgModel *m = treeview->m; struct ged *gedp = m->gedp; - struct ged_selection_set *gs = gedp->ged_cset; - - QgItem *snode = static_cast(index.internalPointer()); - if (!snode) { - if (gs) - ged_selection_set_clear(gs); - return; - } - - if (!(flags & QItemSelectionModel::Deselect)) { - - // If we are selecting an already selected node, clear it - if (flags & QItemSelectionModel::Select && snode->select_state) { - snode->select_state = 0; - struct bu_vls tpath = BU_VLS_INIT_ZERO; - QString nstr = snode->toString(); - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - - // This toggle is a local operation - emit treeview->view_changed(QTCAD_VIEW_SELECT); - emit treeview->m->layoutChanged(); - return; - } - - // Find the parents - QgItem *pnode = snode->parent(); - while (pnode) { - QString nstr = pnode->toString(); - if (nstr == QString()) - break; - std::cout << "IParent: " << nstr.toLocal8Bit().data() << "\n"; - if (pnode->select_state && gs) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } - pnode->select_state = 0; - pnode = pnode->parent(); - } - - std::queue get_children; - if (snode->children.size()) - get_children.push(snode); - - while (!get_children.empty()) { - QgItem *cnode = get_children.front(); - get_children.pop(); - cnode->select_state = 0; - for (size_t j = 0; j < cnode->children.size(); j++) { - QgItem *ccnode = cnode->children[j]; - get_children.push(ccnode); - } - } - - // This node is selected - snode->select_state = 1; - - if (gs) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - QString nstr = snode->toString(); - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - std::cout << "ged insert: " << bu_vls_cstr(&tpath) << "\n"; - ged_selection_insert(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } - - } else { - snode->select_state = 0; - - QString nstr = snode->toString(); - if (gs && nstr != QString()) { - struct bu_vls tpath = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&tpath, "%s", nstr.toLocal8Bit().data()); - std::cout << "ged remove: " << bu_vls_cstr(&tpath) << "\n"; - ged_selection_remove(gs, bu_vls_cstr(&tpath)); - bu_vls_free(&tpath); - } - } - - emit treeview->view_changed(QTCAD_VIEW_SELECT); - emit treeview->m->layoutChanged(); -} -void -QgTreeSelectionModel::mode_change(int i) -{ - if (i != interaction_mode && treeview) { - interaction_mode = i; - update_selected_node_relationships(treeview->selected()); - } -} + std::vector ssv = gedp->dbi_state->get_selected_states(NULL); -void -QgTreeSelectionModel::ged_selection_sync(QgItem *start, struct ged_selection_set *gs) -{ - if (!gs) + if (ssv.size() != 1) return; - bu_log("ged_selection_sync\n"); - - QgModel *m = treeview->m; - std::queue to_check; - if (start && start != m->root()) { - to_check.push(start); - } else { - clear_all(); - for (size_t i = 0; i < m->root()->children.size(); i++) { - to_check.push(m->root()->children[i]); - } - } - struct bu_vls pstr = BU_VLS_INIT_ZERO; - while (!to_check.empty()) { - QgItem *cnode = to_check.front(); - to_check.pop(); - for (size_t i = 0; i < cnode->children.size(); i++) { - to_check.push(cnode->children[i]); - } - QString qstr = cnode->toString(); - bu_vls_sprintf(&pstr, "%s", qstr.toLocal8Bit().data()); - if (ged_selection_find(gs, bu_vls_cstr(&pstr))) { - cnode->select_state = 1; - } else { - cnode->select_state = 0; - } - } -} - -static void -_fp_path_split(std::vector &objs, const char *str) -{ - std::string s(str); - size_t pos = 0; - if (s.c_str()[0] == '/') - s.erase(0, 1); //Remove leading slash - while ((pos = s.find_first_of("/", 0)) != std::string::npos) { - std::string ss = s.substr(0, pos); - objs.push_back(ss); - s.erase(0, pos + 1); - } - objs.push_back(s); -} -static bool -_path_top_match(std::vector &top, std::vector &candidate) -{ - for (size_t i = 0; i < top.size(); i++) { - if (i == candidate.size()) - return false; - if (top[i] != candidate[i]) - return false; - } - return true; -} + BSelectState *ss = ssv[0]; -/* There are three possible determinations - 0, which is not drawn, 1, which is - * fully drawn, and 2 which is partially drawn */ -static int -_get_draw_state(std::vector> &view_objs, std::vector &candidate) -{ - for (size_t i = 0; i < view_objs.size(); i++) { - // If view_objs is a top path for candidate, it is fully drawn - if (_path_top_match(view_objs[i], candidate)) - return 1; - // If we don't have a match, see if the candidate is a top path of a - // view_obj. If so, candidate is partially drawn - if (_path_top_match(candidate, view_objs[i])) - return 2; - } + if (flags & QItemSelectionModel::Clear) + ss->clear(); - return 0; -} + QgItem *snode = static_cast(index.internalPointer()); + if (!snode) { + ss->clear(); -void -QgTreeSelectionModel::ged_drawn_sync(QgItem *start, struct ged *gedp) -{ - if (!gedp) - return; + // Done manipulating paths - update metadata + ss->characterize(); - bu_log("ged_drawn_sync\n"); + unsigned long long sflags = QG_VIEW_SELECT; + if (ss->draw_sync()) + sflags |= QG_VIEW_REFRESH; - // Query from GED to get the drawn view objects (i.e. the "who" list). - // This will tell us what the current drawn state is. - std::vector> view_objs; - struct bu_ptbl *sg = bv_view_objs(gedp->ged_gvp, BV_DB_OBJS); - if (!sg) + emit treeview->view_changed(sflags); + emit treeview->m->layoutChanged(); return; - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - std::vector cg_p; - _fp_path_split(cg_p, bu_vls_cstr(&cg->s_name)); - view_objs.push_back(cg_p); - } - - QgModel *m = treeview->m; - std::queue to_check; - if (start && start != m->root()) { - to_check.push(start); - } else { - for (size_t i = 0; i < m->root()->children.size(); i++) { - to_check.push(m->root()->children[i]); - } } - // Note that we always have to visit all the QgItem children, regardless of - // parent drawn determinations, to make sure all the flags are consistent - // with the current state. We don't have to do path tests if the parent - // state is decisive, but we do need to track and set the flags. - struct bu_vls pstr = BU_VLS_INIT_ZERO; - while (!to_check.empty()) { - QgItem *cnode = to_check.front(); - to_check.pop(); - QString qstr = cnode->toString(); - bu_vls_sprintf(&pstr, "%s", qstr.toLocal8Bit().data()); - std::vector cg_p; - _fp_path_split(cg_p, bu_vls_cstr(&pstr)); - cnode->draw_state = _get_draw_state(view_objs, cg_p); - if (cnode->draw_state == 0) { - // Not drawn - none of the children are drawn either, zero - // all of them out. - std::queue to_clear; - for (size_t i = 0; i < cnode->children.size(); i++) { - to_clear.push(cnode->children[i]); - } - while (!to_clear.empty()) { - QgItem *nnode = to_clear.front(); - to_clear.pop(); - nnode->draw_state = 0; - for (size_t i = 0; i < nnode->children.size(); i++) { - to_clear.push(nnode->children[i]); - } - } - continue; - } - if (cnode->draw_state == 1) { - // Fully drawn - all of the children are drawn, set - // all of them. - std::queue to_set; - for (size_t i = 0; i < cnode->children.size(); i++) { - to_set.push(cnode->children[i]); - } - while (!to_set.empty()) { - QgItem *nnode = to_set.front(); - to_set.pop(); - nnode->draw_state = 1; - for (size_t i = 0; i < nnode->children.size(); i++) { - to_set.push(nnode->children[i]); - } - } - continue; - } + if (!(flags & QItemSelectionModel::Deselect)) { - // Partially drawn. cnode draw state is set to 2 - we need to look - // more closely at the children - for (size_t i = 0; i < cnode->children.size(); i++) { - to_check.push(cnode->children[i]); + // If we are selecting an already selected node, clear it + if (flags & QItemSelectionModel::Select && ss->is_selected(snode->path_hash())) { + std::vector path_hashes = snode->path_items(); + ss->deselect_hpath(path_hashes); + // Done manipulating paths - update metadata + ss->characterize(); + unsigned long long sflags = QG_VIEW_SELECT; + if (ss->draw_sync()) + sflags |= QG_VIEW_REFRESH; + emit treeview->view_changed(sflags); + emit treeview->m->layoutChanged(); + return; } - } -} - -// These functions tell the related-object highlighting logic what the current -// status is. We need to do this whenever the selected object is changed - -// highlighted items may change anywhere (or everywhere) in the tree view with -// any operation, so we have to check everything. -// -// Note that we're setting flags here, not deciding whether to highlight a -// particular QgItem. That decision will be made later, and is a combination -// of active_flag status and the open status of the QgItem. -// -// TODO - this may be the correct place to also illuminate or de-illuminate the -// drawn solids in response to tree selections, in which case this method name -// should be generalized... -void -QgTreeSelectionModel::update_selected_node_relationships(const QModelIndex &idx) -{ - std::unordered_map::iterator g_it; - - // Clear all highlighting state - QgModel *m = treeview->m; - if (!m || !m->instances) - return; - for (g_it = m->instances->begin(); g_it != m->instances->end(); g_it++) { - g_it->second->active_flag = 0; - } + std::vector path_hashes = snode->path_items(); + ss->select_hpath(path_hashes); - if (!idx.isValid() || interaction_mode == QgViewMode) { - // For the case of a selection change, emit a layout change signal so - // the drawBranches call updates the portions of the row colors not - // handled by the itemDelegate painting. For expand and close - // operations on items this is already handled by Qt, but layout - // updating is not a normal part of the selection process in most tree - // views so for the customized selection drawing we do we need to call - // it manually. - emit m->layoutChanged(); - return; - } + } else { - QgItem *snode = static_cast(idx.internalPointer()); + std::vector path_hashes = snode->path_items(); + ss->deselect_hpath(path_hashes); - if (!snode) { - emit m->layoutChanged(); - return; } - gInstance *sg = snode->instance(); - - std::unordered_set processed; - processed.insert(sg); - - std::queue to_flag; - // If we're in QgInstanceEditMode, we key off of the exact gInstance - // pointer that corresponds to this instance. Since that instance is - // unique, we only need to flag parent instances (and all the parents of - // those parents) so the parent QgItems know to highlight themselves if - // their children are closed. - if (interaction_mode == QgInstanceEditMode) { - - sg->active_flag = 3; - - // For gInstances where the child dp == the parent (i.e. the comb - // directly containing the instance), set to 2 - for (g_it = m->instances->begin(); g_it != m->instances->end(); g_it++) { - gInstance *cd = g_it->second; - if (cd->dp == sg->parent && processed.find(cd) == processed.end()) { - cd->active_flag = 2; - to_flag.push(cd); - processed.insert(cd); - } - } - // For gInstances above the active instance, set to 1 - while (!to_flag.empty()) { - gInstance *curr = to_flag.front(); - to_flag.pop(); - if (!curr->parent) - continue; - for (g_it = m->instances->begin(); g_it != m->instances->end(); g_it++) { - gInstance *cd = g_it->second; - if (cd->dp == curr->parent && processed.find(cd) == processed.end()) { - cd->active_flag = 1; - to_flag.push(cd); - processed.insert(cd); - } - } - } - // For the case of a selection change, emit a layout change signal so - // the drawBranches call updates the portions of the row colors not - // handled by the itemDelegate painting. For expand and close - // operations on items this is already handled by Qt, but layout - // updating is not a normal part of the selectio n process in most - // tree views so for the customized selection drawing we do we need to - // call it manually. - emit m->layoutChanged(); - return; - } + // Done manipulating paths - update metadata + ss->characterize(); - // If we're in QgPrimitiveEditMode, we have slightly different work to do - - // we need to check the gInstances to see if anybody else is using the same - // dp as sg - if so, they are also directly being altered in this mode - // since their underlying primitive may change. We then need to flag all - // the parent instances of all the activated gInstances (and all their - // parents) so the tree will know which combs to highlight to indicate - // there is a relevant object in the subtree. - if (interaction_mode == QgPrimitiveEditMode) { - for (g_it = m->instances->begin(); g_it != m->instances->end(); g_it++) { - gInstance *cg = g_it->second; - if (cg->dp == sg->dp) { - cg->active_flag = 2; - to_flag.push(cg); - processed.insert(cg); - } - } - // Iterate over parents and parents of parents of any gInstance with - // active_flag set until all parents have been assigned an active_flag - // of at least 1 (or two, if they are one of the exact matches from the - // previous step.) - while (!to_flag.empty()) { - gInstance *curr = to_flag.front(); - to_flag.pop(); - if (!curr->parent) - continue; - for (g_it = m->instances->begin(); g_it != m->instances->end(); g_it++) { - gInstance *cd = g_it->second; - if (curr->parent == cd->dp && processed.find(cd) == processed.end()) { - cd->active_flag = 1; - to_flag.push(cd); - processed.insert(cd); - } - } - } - // For the case of a selection change, emit a layout change signal so - // the drawBranches call updates the portions of the row colors not - // handled by the itemDelegate painting. For expand and close - // operations on items this is already handled by Qt, but layout - // updating is not a normal part of the selectio n process in most - // tree views so for the customized selection drawing we do we need to - // call it manually. - emit m->layoutChanged(); - return; - } + unsigned long long sflags = QG_VIEW_SELECT; + if (ss->draw_sync()) + sflags |= QG_VIEW_REFRESH; + emit treeview->view_changed(sflags); + emit treeview->m->layoutChanged(); } - // Local Variables: // tab-width: 8 // mode: C++ diff --git a/src/libqtcad/QgTreeView.cpp b/src/libqtcad/QgTreeView.cpp index e9b4d906e0b..39b98d7d764 100644 --- a/src/libqtcad/QgTreeView.cpp +++ b/src/libqtcad/QgTreeView.cpp @@ -36,7 +36,7 @@ #include "qtcad/QgModel.h" #include "qtcad/QgTreeSelectionModel.h" #include "qtcad/QgTreeView.h" -#include "qtcad/SignalFlags.h" +#include "qtcad/QgSignalFlags.h" void gObjDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -51,7 +51,7 @@ void gObjDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, } aflag = index.data(QgModel::HighlightDisplayRole).toInt(); - if (!cadtreeview->isExpanded(index) && aflag == 1) { + if (aflag == 1) { painter->fillRect(option.rect, QBrush(QColor(220, 200, 30))); goto text_string; } @@ -164,7 +164,7 @@ QgTreeView::QgTreeView(QWidget *pparent, QgModel *treemodel) : QTreeView(pparent header()->setStretchLastSection(true); QObject::connect(this, &QgTreeView::expanded, this, &QgTreeView::tree_column_size); QObject::connect(this, &QgTreeView::collapsed, this, &QgTreeView::tree_column_size); - QObject::connect(this, &QgTreeView::clicked, sm, &QgTreeSelectionModel::update_selected_node_relationships); + //QObject::connect(this, &QgTreeView::clicked, sm, &QgTreeSelectionModel::update_selected_node_relationships); QObject::connect(this, &QgTreeView::customContextMenuRequested, (QgTreeView *)this, &QgTreeView::context_menu); QObject::connect(this, &QgTreeView::doubleClicked, (QgTreeView *)this, &QgTreeView::do_draw_toggle); } @@ -231,11 +231,13 @@ void QgTreeView::mousePressEvent(QMouseEvent *e) void QgTreeView::tree_column_size(const QModelIndex &) { + QTCAD_SLOT("QgTreeView::tree_column_size", 1); header_state(); } void QgTreeView::context_menu(const QPoint &point) { + QTCAD_SLOT("QgTreeView::context_menu", 1); QModelIndex index = indexAt(point); QgItem *cnode = static_cast(index.internalPointer()); @@ -272,6 +274,7 @@ void QgTreeView::context_menu(const QPoint &point) void QgTreeView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { + QTCAD_SLOT("QgTreeView::selectionChanged", 1); if (selected.indexes().size()) { // Stash a valid selection for potential post-model rebuild restoration. QModelIndex nindex = selected.indexes().first(); @@ -293,6 +296,7 @@ QModelIndex QgTreeView::selected() void QgTreeView::do_draw_toggle(const QModelIndex &index) { + QTCAD_SLOT("QgTreeView::do_draw_toggle", 1); QgItem *cnode = static_cast(index.internalPointer()); if (!m->gedp) @@ -302,32 +306,28 @@ QgTreeView::do_draw_toggle(const QModelIndex &index) if (!v) return; - struct db_full_path *clicked_path = cnode->fp(); - - bool do_draw = true; - struct bu_ptbl *sg = bv_view_objs(m->gedp->ged_gvp, BV_DB_OBJS); - for (size_t i = 0; i < BU_PTBL_LEN(sg); i++) { - struct bv_scene_group *cg = (struct bv_scene_group *)BU_PTBL_GET(sg, i); - if (db_full_path_match_top((struct db_full_path *)cg->s_path, clicked_path)) { - do_draw = false; - break; - } - } - db_free_full_path(clicked_path); - BU_PUT(clicked_path, struct db_full_path); + BViewState *sv = m->gedp->dbi_state->get_view_state(v); + if (!sv) + return; - QString cnode_path = cnode->toString(); - if (do_draw) { - m->draw(cnode_path); + std::vector path_hashes = cnode->path_items(); + unsigned long long phash = m->gedp->dbi_state->path_hash(path_hashes, 0); + if (!sv->is_hdrawn(-1, phash)) { + sv->add_hpath(path_hashes); + std::unordered_set views; + views.insert(v); + sv->redraw(NULL, views, 1); } else { - m->erase(cnode_path); + unsigned long long c_hash = path_hashes[path_hashes.size() - 1]; + path_hashes.pop_back(); + sv->erase_hpath(-1, c_hash, path_hashes, true); } - } void QgTreeView::redo_expansions(void *) { + QTCAD_SLOT("QgTreeView::redo_expansions", 1); std::unordered_set::iterator i_it; for (i_it = m->items->begin(); i_it != m->items->end(); i_it++) { QgItem *itm = *i_it; @@ -338,9 +338,12 @@ QgTreeView::redo_expansions(void *) } } + +// TODO - probably no longer needed? void QgTreeView::redo_highlights() { + QTCAD_SLOT("QgTreeView::redo_highlights", 1); // Restore the previous selection, if we have no replacement and its still valid QModelIndex selected_idx = selected(); if (!selected_idx.isValid()) { @@ -353,10 +356,11 @@ QgTreeView::redo_highlights() } } - QgTreeSelectionModel *selm = (QgTreeSelectionModel *)selectionModel(); - selm->update_selected_node_relationships(selected_idx); + //QgTreeSelectionModel *selm = (QgTreeSelectionModel *)selectionModel(); + //selm->update_selected_node_relationships(selected_idx); } +#if 0 void QgTreeView::expand_path(QString path) { int i = 0; @@ -395,38 +399,18 @@ void QgTreeView::expand_link(const QUrl &link) { expand_path(link.path()); } +#endif -void QgTreeView::qgitem_select_sync(QgItem *itm) +void QgTreeView::qgitem_select_sync(QgItem *) { - struct ged *gedp = m->gedp; - struct ged_selection_set *gs = NULL; - if (gedp->ged_selection_sets) { - struct bu_ptbl ssets = BU_PTBL_INIT_ZERO; - size_t scnt = ged_selection_sets_lookup(&ssets, gedp->ged_selection_sets, "default"); - if (scnt == 1) - gs = (struct ged_selection_set *)BU_PTBL_GET(&ssets, 0); - bu_ptbl_free(&ssets); - } - if (!gs) - return; - - QgTreeSelectionModel *selm = (QgTreeSelectionModel *)selectionModel(); - selm->ged_selection_sync(itm, gs); - selm->ged_drawn_sync(itm, gedp); + QTCAD_SLOT("QgTreeView::qgitem_select_sync", 1); + emit m->layoutChanged(); } -void QgTreeView::do_view_update(unsigned long long flags) +void QgTreeView::do_view_update(unsigned long long UNUSED(flags)) { - struct ged *gedp = m->gedp; - QgTreeSelectionModel *selm = (QgTreeSelectionModel *)selectionModel(); - - if (flags & QTCAD_VIEW_SELECT && gedp->ged_cset) - selm->ged_selection_sync(NULL, gedp->ged_cset); - - if (flags & QTCAD_VIEW_DRAWN) - selm->ged_drawn_sync(NULL, gedp); - + QTCAD_SLOT("QgTreeView::do_view_update", 1); // TODO - can the mode logic be triggered from here as well? emit m->layoutChanged(); diff --git a/src/libqtcad/QgView.cpp b/src/libqtcad/QgView.cpp new file mode 100644 index 00000000000..3cecf6e8a44 --- /dev/null +++ b/src/libqtcad/QgView.cpp @@ -0,0 +1,447 @@ +/* Q G V I E W . C P P + * BRL-CAD + * + * Copyright (c) 2021-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgView.cpp + * + * Wrapper widget that handles the various widget types which may + * constitute a Qt based geometry view. + * + */ + +#include "common.h" + +#include "bg/polygon.h" +#include "bv.h" +#include "raytrace.h" // For finalize polygon sketch export functionality (TODO - need to move...) +#include "qtcad/QgView.h" +#include "qtcad/QgSignalFlags.h" + +extern "C" { +#include "bu/malloc.h" +} + + +QgView::QgView(QWidget *parent, int type, struct fb *fbp) + : QWidget(parent) +{ + this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + l = new QBoxLayout(QBoxLayout::LeftToRight, this); + l->setSpacing(0); + l->setContentsMargins(0, 0, 0, 0); + + switch (type) { +#ifdef BRLCAD_OPENGL + case QgView_GL: + canvas_gl = new QgGL(this, fbp); + canvas_gl->setMinimumSize(50,50); + canvas_gl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + l->addWidget(canvas_gl); + QObject::connect(canvas_gl, &QgGL::changed, this, &QgView::do_view_changed); + QObject::connect(canvas_gl, &QgGL::init_done, this, &QgView::do_init_done); + break; +#endif + case QgView_SW: + canvas_sw = new QgSW(this, fbp); + canvas_sw->setMinimumSize(50,50); + canvas_sw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + l->addWidget(canvas_sw); + QObject::connect(canvas_sw, &QgSW::changed, this, &QgView::do_view_changed); + QObject::connect(canvas_sw, &QgSW::init_done, this, &QgView::do_init_done); + break; + default: +#ifdef BRLCAD_OPENGL + canvas_gl = new QgGL(this, fbp); + canvas_gl->setMinimumSize(50,50); + canvas_gl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + l->addWidget(canvas_gl); + QObject::connect(canvas_gl, &QgGL::changed, this, &QgView::do_view_changed); + QObject::connect(canvas_gl, &QgGL::init_done, this, &QgView::do_init_done); +#else + canvas_sw = new QgSW(this, fbp); + canvas_sw->setMinimumSize(50,50); + canvas_sw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + l->addWidget(canvas_sw); + QObject::connect(canvas_sw, &QgSW::changed, this, &QgView::do_view_changed); + QObject::connect(canvas_sw, &QgSW::init_done, this, &QgView::do_init_done); +#endif + return; + } +} + +QgView::~QgView() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) + delete canvas_gl; +#endif + if (canvas_sw) + delete canvas_sw; +} + +bool +QgView::isValid() +{ + if (canvas_sw) + return true; + +#ifdef BRLCAD_OPENGL + if (canvas_gl) + return canvas_gl->isValid(); +#endif + + return false; +} + +int +QgView::view_type() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) + return QgView_GL; +#endif + if (canvas_sw) + return QgView_SW; + + return -1; +} + + +void +QgView::save_image(int UNUSED(quad)) +{ +} + +void +QgView::do_view_changed() +{ + QTCAD_SLOT("QgView::do_view_changed", 1); + emit changed(this); +} + +void +QgView::need_update(unsigned long long) +{ + bv_log(4, "QgView::need_update"); + QTCAD_SLOT("QgView::need_update", 1); +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->need_update(); + return; + } +#endif + if (canvas_sw) { + canvas_sw->need_update(); + return; + } +} + +struct bview * +QgView::view() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) + return canvas_gl->v; +#endif + if (canvas_sw) + return canvas_sw->v; + + return NULL; +} + +struct dm * +QgView::dmp() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) + return canvas_gl->dmp; +#endif + if (canvas_sw) + return canvas_sw->dmp; + + return NULL; +} + +struct fb * +QgView::ifp() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) + return canvas_gl->ifp; +#endif + if (canvas_sw) + return canvas_sw->ifp; + + return NULL; +} + +void +QgView::set_view(struct bview *nv) +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->v = nv; + if (canvas_gl->dmp && canvas_gl->v) { + canvas_gl->v->dmp = canvas_gl->dmp; + struct dm *dmp = (struct dm *)canvas_gl->dmp; + dm_configure_win(dmp, 0); + canvas_gl->v->gv_width = dm_get_width(dmp); + canvas_gl->v->gv_height = dm_get_height(dmp); + } + } +#endif + if (canvas_sw) { + canvas_sw->v = nv; + if (canvas_sw->dmp && canvas_sw->v) { + canvas_sw->v->dmp = canvas_sw->dmp; + struct dm *dmp = (struct dm *)canvas_sw->dmp; + dm_configure_win(dmp, 0); + canvas_gl->v->gv_width = dm_get_width(dmp); + canvas_gl->v->gv_height = dm_get_height(dmp); + } + } +} + +void +QgView::stash_hashes() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->stash_hashes(); + } +#endif + if (canvas_sw) { + canvas_sw->stash_hashes(); + } +} + +bool +QgView::diff_hashes() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + return canvas_gl->diff_hashes(); + } +#endif + if (canvas_sw) { + return canvas_sw->diff_hashes(); + } + + return false; +} + +void +QgView::aet(double a, double e, double t) +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->aet(a, e, t); + } +#endif + if (canvas_sw) { + canvas_sw->aet(a, e, t); + } +} + +void +QgView::set_current(int i) +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->current = i; + } +#endif + if (canvas_sw) { + canvas_sw->current = i; + } +} + +int +QgView::current() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + return canvas_gl->current; + } +#endif + if (canvas_sw) { + return canvas_sw->current; + } + + return 0; +} + +void +QgView::add_event_filter(QObject *o) +{ + curr_event_filter = o; + filters.push_back(o); +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->installEventFilter(o); + return; + } +#endif + if (canvas_sw) { + canvas_sw->installEventFilter(o); + return; + } +} + +void +QgView::clear_event_filter(QObject *o) +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + if (o) { + canvas_gl->removeEventFilter(o); + } else { + for (size_t i = 0; i < filters.size(); i++) { + canvas_gl->removeEventFilter(filters[i]); + } + filters.clear(); + } + } +#endif + if (canvas_sw) { + if (o) { + canvas_sw->removeEventFilter(o); + } else { + for (size_t i = 0; i < filters.size(); i++) { + canvas_sw->removeEventFilter(filters[i]); + } + filters.clear(); + } + } + curr_event_filter = NULL; +} + +void +QgView::set_draw_custom(void (*draw_custom)(struct bview *, void *), void *draw_udata) +{ + +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->draw_custom = draw_custom; + canvas_gl->draw_udata = draw_udata; + return; + } +#endif + if (canvas_sw) { + canvas_sw->draw_custom = draw_custom; + canvas_sw->draw_udata = draw_udata; + return; + } +} + +void +QgView::enableDefaultKeyBindings() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->enableDefaultKeyBindings(); + return; + } +#endif + if (canvas_sw) { + canvas_sw->enableDefaultKeyBindings(); + return; + } +} + +void +QgView::disableDefaultKeyBindings() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->disableDefaultKeyBindings(); + return; + } +#endif + if (canvas_sw) { + canvas_sw->disableDefaultKeyBindings(); + return; + } +} + +void +QgView::enableDefaultMouseBindings() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->enableDefaultMouseBindings(); + return; + } +#endif + if (canvas_sw) { + canvas_sw->enableDefaultMouseBindings(); + return; + } + + +} + +void +QgView::disableDefaultMouseBindings() +{ +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->disableDefaultMouseBindings(); + return; + } +#endif + if (canvas_sw) { + canvas_sw->disableDefaultMouseBindings(); + return; + } +} + + +void +QgView::set_lmouse_move_default(int mm) +{ + QTCAD_SLOT("QgView::set_lmouse_move_default", 1); + +#ifdef BRLCAD_OPENGL + if (canvas_gl) { + canvas_gl->set_lmouse_move_default(mm); + return; + } +#endif + if (canvas_sw) { + canvas_sw->set_lmouse_move_default(mm); + return; + } +} + + +void +QgView::do_init_done() +{ + QTCAD_SLOT("QgView::do_init_done", 1); + emit init_done(); +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QgViewCtrl.cpp b/src/libqtcad/QgViewCtrl.cpp new file mode 100644 index 00000000000..e29616ee555 --- /dev/null +++ b/src/libqtcad/QgViewCtrl.cpp @@ -0,0 +1,222 @@ +/* Q G V I E W C T R L . C P P + * BRL-CAD + * + * Copyright (c) 2022-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file QgViewCtrl.cpp + * + * Qt BRL-CAD View Control button panel implementation + * + */ + +#include "common.h" + +#include "bu/env.h" +#include "qtcad/QgViewCtrl.h" +#include "qtcad/QgSignalFlags.h" + + +QgViewCtrl::QgViewCtrl(QWidget *pparent, struct ged *pgedp) : QToolBar(pparent) +{ + gedp = pgedp; + + this->setStyleSheet("QToolButton{margin:0px;}"); + + sca = addAction(QIcon(QPixmap(":images/view/view_scale.png")), "Scale"); + rot = addAction(QIcon(QPixmap(":images/view/view_rotate.png")), "Rotate"); + tra = addAction(QIcon(QPixmap(":images/view/view_translate.png")), "Translate"); + center = addAction(QIcon(QPixmap(":images/view/view_center.png")), "Center"); + + addSeparator(); + + raytrace = addAction(QIcon(QPixmap(":images/view/raytrace.png")), "Raytrace"); + fb_mode = addAction(QIcon(QPixmap(":images/view/framebuffer_off.png")), "Framebuffer Off/Overlay/Underlay"); + fb_clear = addAction(QIcon(QPixmap(":images/view/framebuffer_clear.png")), "Clear Framebuffer"); + + // Connect buttons to standard actions + connect(sca, &QAction::triggered, this, &QgViewCtrl::sca_mode); + connect(rot, &QAction::triggered, this, &QgViewCtrl::rot_mode); + connect(tra, &QAction::triggered, this, &QgViewCtrl::tra_mode); + connect(center, &QAction::triggered, this, &QgViewCtrl::center_mode); + connect(raytrace, &QAction::triggered, this, &QgViewCtrl::raytrace_cmd); + connect(fb_clear, &QAction::triggered, this, &QgViewCtrl::fbclear_cmd); + connect(fb_mode, &QAction::triggered, this, &QgViewCtrl::fb_mode_cmd); +} + +QgViewCtrl::~QgViewCtrl() +{ +} + +void +QgViewCtrl::sca_mode() +{ + QTCAD_SLOT("QgViewCtrl::sca_mode", 1); + emit lmouse_mode(BV_SCALE); +} + +void +QgViewCtrl::rot_mode() +{ + QTCAD_SLOT("QgViewCtrl::rot_mode", 1); + emit lmouse_mode(BV_ROT); +} + +void +QgViewCtrl::tra_mode() +{ + QTCAD_SLOT("QgViewCtrl::tra_mode", 1); + emit lmouse_mode(BV_TRANS); +} + +void +QgViewCtrl::center_mode() +{ + QTCAD_SLOT("QgViewCtrl::center_mode", 1); + emit lmouse_mode(BV_CENTER); +} + + +void +QgViewCtrl::fbclear_cmd() +{ + QTCAD_SLOT("QgViewCtrl::fbclear_cmd", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + const char *av[2] = {NULL}; + av[0] = "fbclear"; + ged_exec(gedp, 1, (const char **)av); + emit view_changed(QG_VIEW_REFRESH); +} + +void +QgViewCtrl::fb_mode_cmd() +{ + QTCAD_SLOT("QgViewCtrl::fb_mode_cmd", 1); + if (!gedp->ged_gvp) + return; + struct bview *v = gedp->ged_gvp; + switch (v->gv_s->gv_fb_mode) { + case 0: + v->gv_s->gv_fb_mode = 2; + break; + case 2: + v->gv_s->gv_fb_mode = 1; + break; + case 1: + v->gv_s->gv_fb_mode = 0; + break; + default: + bu_log("Error - invalid fb mode: %d\n", v->gv_s->gv_fb_mode); + } + emit view_changed(QG_VIEW_REFRESH); +} + +void +QgViewCtrl::do_view_update(unsigned long long flags) +{ + QTCAD_SLOT("QgViewCtrl::do_view_update", 1); + if (!gedp->ged_gvp || !flags) + return; + struct bview *v = gedp->ged_gvp; + switch (v->gv_s->gv_fb_mode) { + case 0: + fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer_off.png"))); + break; + case 1: + fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer.png"))); + break; + case 2: + fb_mode->setIcon(QIcon(QPixmap(":images/view/framebuffer_underlay.png"))); + break; + default: + bu_log("Error - invalid fb mode: %d\n", v->gv_s->gv_fb_mode); + } +} + +void rt_cmd_start(int pid, void *ctx) +{ + QgViewCtrl *vctrl = (QgViewCtrl *)ctx; + vctrl->raytrace_start(pid); +} + +void rt_cmd_done(int pid, void *ctx) +{ + QgViewCtrl *vctrl = (QgViewCtrl *)ctx; + vctrl->raytrace_done(pid); +} + +void +QgViewCtrl::raytrace_cmd() +{ + QTCAD_SLOT("QgViewCtrl::raytrace_cmd", 1); + bu_setenv("GED_TEST_NEW_CMD_FORMS", "1", 1); + const char *av[4] = {NULL}; + struct bu_vls pid_str = BU_VLS_INIT_ZERO; + + gedp->ged_subprocess_init_callback = &rt_cmd_start; + gedp->ged_subprocess_end_callback = &rt_cmd_done; + gedp->ged_subprocess_clbk_context = (void *)this; + + if (raytrace_running) { + if (pid < 0) + goto cmd_cleanup; + bu_vls_sprintf(&pid_str, "%d", pid); + av[0] = "process"; + av[1] = "pabort"; + av[2] = bu_vls_cstr(&pid_str); + ged_exec(gedp, 3, (const char **)av); + goto cmd_cleanup; + } + + av[0] = "ert"; + ged_exec(gedp, 1, (const char **)av); + emit view_changed(QG_VIEW_REFRESH); + +cmd_cleanup: + gedp->ged_subprocess_init_callback = NULL; + gedp->ged_subprocess_end_callback =NULL; + gedp->ged_subprocess_clbk_context = NULL; + bu_vls_free(&pid_str); +} + +void +QgViewCtrl::raytrace_start(int rpid) +{ + QTCAD_SLOT("QgViewCtrl::raytrace_start", 1); + raytrace->setIcon(QIcon(QPixmap(":images/view/raytrace_abort.png"))); + raytrace_running = true; + pid = rpid; +} + +void +QgViewCtrl::raytrace_done(int) +{ + QTCAD_SLOT("QgViewCtrl::raytrace_done", 1); + raytrace->setIcon(QIcon(QPixmap(":images/view/raytrace.png"))); + raytrace_running = false; + pid = -1; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + + diff --git a/src/libqtcad/QtAppExecDialog.cpp b/src/libqtcad/QtAppExecDialog.cpp deleted file mode 100644 index 9e85939f92f..00000000000 --- a/src/libqtcad/QtAppExecDialog.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* Q T A P P E X E C D I A L O G . C P P - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtAppExecDialog.cpp - * - * Support for running external applications and viewing the output - * stream in a console widget embedded in a dialog window. - * - */ - -#include -#include -#include -#include -#include "qtcad/QtAppExecDialog.h" - -QtAppExecDialog::QtAppExecDialog(QWidget *pparent, QString executable, QStringList args, QString lfile) : QDialog(pparent) -{ - QVBoxLayout *dlayout = new QVBoxLayout; - buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel); - QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QtAppExecDialog::process_abort); - console = new QtConsole(this); - console->prompt(""); - setLayout(dlayout); - dlayout->addWidget(console); - dlayout->addWidget(buttonBox); - logfile = NULL; - if (lfile.length() > 0) { - logfile = new QFile(lfile); - if (!logfile->open(QIODevice::Append | QIODevice::Text)) { - logfile = NULL; - return; - } - QTextStream log_stream(logfile); - log_stream << executable << " " << args.join(" ") << "\n"; - } -} - -void QtAppExecDialog::read_stdout() -{ - QString std_output = proc->readAllStandardOutput(); - console->printString(std_output); - if (logfile) { - QTextStream log_stream(logfile); - log_stream << std_output; - logfile->flush(); - } -} - -void QtAppExecDialog::read_stderr() -{ - QString err_output = proc->readAllStandardError(); - console->printString(err_output); - if (logfile) { - QTextStream log_stream(logfile); - log_stream << err_output; - logfile->flush(); - } -} - -void QtAppExecDialog::process_abort() -{ - proc->kill(); - console->printString("\nAborted!\n"); - if (logfile) { - QTextStream log_stream(logfile); - log_stream << "\nAborted!\n"; - logfile->flush(); - } - process_done(0, QProcess::NormalExit); -} - -void QtAppExecDialog::process_done(int , QProcess::ExitStatus) -{ - if (logfile) logfile->close(); - buttonBox->clear(); - buttonBox->addButton(QDialogButtonBox::Ok); - QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &QtAppExecDialog::accept); - setWindowTitle("Process Finished"); -} - -/* - * Local Variables: - * mode: C++ - * tab-width: 8 - * c-basic-offset: 4 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ - diff --git a/src/libqtcad/QtCADQuad.cpp b/src/libqtcad/QtCADQuad.cpp deleted file mode 100644 index 1554c51eb21..00000000000 --- a/src/libqtcad/QtCADQuad.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* Q T C A D Q U A D . C P P - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtCADQuad.cpp - * - * TODO - initialize non-current views to the standard views (check MGED for - * what the defaults should be.) Also, need to implement an event filter for - * this widget (I think there is an example in qged...) Events should pass - * through to the current selected widget when they are either key based or - * take place with the xy coordinates matching the current widget. However, a - * mouse click over the quad widget but NOT located with xy coordinates over - * the currently selected view should change the selected view (updating - * gedp->ged_gvp, perhaps changing the background or some other visual - * signature of which widget is currently active. - * - * One open question is whether the faceplate settings of the previous - * selection should be copied/transferred to the new current selection (in - * effect, making the faceplate settings independent of the specific view - * selected.) Maybe this should be a widget setting, since there are arguments - * that could be made either way... that we we wouldn't be locked into one - * approach at the app level. - * - */ - -#include "common.h" - -#include - -#include "bu/str.h" -#include "bv.h" -#include "ged/defines.h" -#include "ged/commands.h" -#include "qtcad/QtCADQuad.h" - -static const char *VIEW_NAMES[] = {"Q1", "Q2", "Q3", "Q4"}; - -/** - * @brief Construct a new Qt C A D Quad:: Qt C A D Quad object - * - * @param parent Parent Qt widget - * @param gedpRef Associated GED struct - * @param type Requesting either a GL or SWRAST display mechanism - */ -QtCADQuad::QtCADQuad(QWidget *parent, struct ged *gedpRef, int type) : QWidget(parent) -{ - gedp = gedpRef; - graphicsType = type; - - views[UPPER_RIGHT_QUADRANT] = createView(UPPER_RIGHT_QUADRANT); - bv_set_add_view(&gedp->ged_views, views[UPPER_RIGHT_QUADRANT]->view()); - gedp->ged_gvp = views[UPPER_RIGHT_QUADRANT]->view(); - - // Define the spacers - spacerTop = new QSpacerItem(3, 0, QSizePolicy::Fixed, QSizePolicy::Expanding); - spacerBottom = new QSpacerItem(3, 0, QSizePolicy::Fixed, QSizePolicy::Expanding); - spacerLeft = new QSpacerItem(0, 3, QSizePolicy::Expanding, QSizePolicy::Fixed); - spacerRight = new QSpacerItem(0, 3, QSizePolicy::Expanding, QSizePolicy::Fixed); - spacerCenter = new QSpacerItem(3, 3, QSizePolicy::Fixed, QSizePolicy::Fixed); - - views[UPPER_RIGHT_QUADRANT]->set_current(1); - currentView = views[UPPER_RIGHT_QUADRANT]; - -} - -QtCADQuad::~QtCADQuad() -{ - for (int i = 0; i < 4; i++) { - if (views[i] != nullptr) { - delete views[i]; - views[i] = nullptr; - } - } - - delete spacerTop; - delete spacerBottom; - delete spacerLeft; - delete spacerRight; - delete spacerCenter; -} - -/** - * @brief Creates a view for the viewport. Convenience method of common things that need to be done to the view. - * - * @param index of the view names to use from the constant list of names - * @return QtCADView* - */ -QtCADView * -QtCADQuad::createView(unsigned int index) -{ - QtCADView *view = new QtCADView(this, graphicsType); - bu_vls_sprintf(&view->view()->gv_name, "%s", VIEW_NAMES[index]); - view->set_current(0); - view->installEventFilter(this); - - view->view()->vset = &gedp->ged_views; - view->view()->independent = 0; - - QObject::connect(view, &QtCADView::changed, this, &QtCADQuad::do_view_changed); - QObject::connect(view, &QtCADView::init_done, this, &QtCADQuad::do_init_done); - return view; -} - -/** - * @brief Convenience method to create the layout and set common parameters. - * - * @return QGridLayout* - */ -QGridLayout * -QtCADQuad::createLayout() -{ - QGridLayout *layout = new QGridLayout(this); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - layout->setAlignment(Qt::AlignTop | Qt::AlignLeft); - - this->setLayout(layout); - - if (currentLayout != nullptr) { - delete currentLayout; - } - currentLayout = layout; - - return layout; -} - -/** - * @brief Changes the viewport layout to only have the single view. We destroy the other views if needed and the flag is set - * - */ -void -QtCADQuad::changeToSingleFrame() -{ - QGridLayout *layout = (QGridLayout *)this->layout(); - if (layout == nullptr) { - layout = createLayout(); - } - while (layout->takeAt(0) != NULL); - layout->addWidget(views[UPPER_RIGHT_QUADRANT], 0, 2); - - for (int i = 1; i < 4; i++) { - // Don't want use cpu for views that are not visible - if (views[i] != nullptr) { - views[i]->disconnect(); - bv_set_rm_view(&gedp->ged_views, views[i]->view()); - delete views[i]; - views[i] = nullptr; - } - } - - views[UPPER_RIGHT_QUADRANT]->set_current(1); - currentView = views[UPPER_RIGHT_QUADRANT]; - // This is only used in quad mode - currentView->select(1); - - default_views(); -} - -/** - * @brief Changes the viewport layout to have 4 views the views will be equal size and not resizeable. This will create the extra view if needed. - * - */ -void -QtCADQuad::changeToQuadFrame() -{ - for (int i = UPPER_RIGHT_QUADRANT + 1; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] == nullptr) { - views[i] = createView(i); - } - bv_set_add_view(&gedp->ged_views, views[i]->view()); - } - QGridLayout *layout = (QGridLayout *)this->layout(); - if (layout == nullptr) { - layout = createLayout(); - } - while (layout->takeAt(0) != NULL); - - layout->addWidget(views[UPPER_LEFT_QUADRANT], 0, 0); - layout->addItem(spacerTop, 0, 1); - layout->addWidget(views[UPPER_RIGHT_QUADRANT], 0, 2); - layout->addItem(spacerLeft, 1, 0); - layout->addItem(spacerCenter, 1, 1); - layout->addItem(spacerRight, 1, 2); - layout->addWidget(views[LOWER_LEFT_QUADRANT], 2, 0); - layout->addItem(spacerBottom, 2, 1); - layout->addWidget(views[LOWER_RIGHT_QUADRANT], 2, 2); - - default_views(); - - // Not sure if this is the right way to do this but need to autoset each of the views - const char *av[2]; - av[0] = "autoview"; - av[1] = (char *)0; - for (int i = UPPER_RIGHT_QUADRANT + 1; i < LOWER_RIGHT_QUADRANT + 1; i++) { - gedp->ged_gvp = views[i]->view(); - ged_exec(gedp, 1, (const char **)av); - } - gedp->ged_gvp = views[UPPER_RIGHT_QUADRANT]->view(); - views[UPPER_RIGHT_QUADRANT]->set_current(1); - currentView = views[UPPER_RIGHT_QUADRANT]; - // This is only used in quad mode - currentView->select(1); -} - -void -QtCADQuad::do_view_changed() -{ - emit changed(currentView); -} - -bool -QtCADQuad::isValid() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr && !views[i]->isValid()) - return false; - } - return true; -} - -void -QtCADQuad::fallback() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->fallback(); - - views[i]->set_current(0); - } - } - - // ur is still the default current - views[UPPER_RIGHT_QUADRANT]->set_current(1); - currentView = views[UPPER_RIGHT_QUADRANT]; -} - -bool -QtCADQuad::eventFilter(QObject *t, QEvent *e) -{ - if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress) { - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr && t == views[i]) { - select(i); - break; - } - } - } - return false; -} - -void -QtCADQuad::default_views() -{ - if (views[UPPER_RIGHT_QUADRANT] != nullptr) { - if (views[UPPER_LEFT_QUADRANT] == nullptr) { - views[UPPER_RIGHT_QUADRANT]->aet(270, 90, 0); - } - else { - views[UPPER_RIGHT_QUADRANT]->aet(35, 25, 0); - } - } - if (views[UPPER_LEFT_QUADRANT] != nullptr) { - views[UPPER_LEFT_QUADRANT]->aet(0, 90, 0); - } - if (views[LOWER_LEFT_QUADRANT] != nullptr) { - views[LOWER_LEFT_QUADRANT]->aet(0, 0, 0); - } - if (views[LOWER_RIGHT_QUADRANT] != nullptr) { - views[LOWER_RIGHT_QUADRANT]->aet(90, 0, 0); - } -} - -struct bview * -QtCADQuad::view(int quadrantId) -{ - if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; - - if (views[quadrantId] != nullptr) { - return views[quadrantId]->view(); - } - - return currentView->view(); -} - -QtCADView * -QtCADQuad::get(int quadrantId) -{ - if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; - - if (views[quadrantId] != nullptr) { - return views[quadrantId]; - } - - return currentView; -} - -void -QtCADQuad::select(int quadrantId) -{ - if (quadrantId > LOWER_RIGHT_QUADRANT || quadrantId < UPPER_RIGHT_QUADRANT) quadrantId = UPPER_RIGHT_QUADRANT; - - QtCADView *oc = currentView; - - // Set new selection - if (views[quadrantId] != nullptr) { - currentView = views[quadrantId]; - // Make sure we are in quad mode - if (views[1] != nullptr) { - views[quadrantId]->select(1); - currentView->set_current(1); - } - } - - // Clear any old selections - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (i == quadrantId) - continue; - if (views[i] != nullptr) { - views[i]->set_current(0); - views[i]->select(0); - } - } - - if (oc != currentView) - emit selected(currentView); -} - -void -QtCADQuad::select(const char *quadrant_id) -{ - if (BU_STR_EQUIV(quadrant_id, "ur")) { - select(UPPER_RIGHT_QUADRANT); - return; - } - if (BU_STR_EQUIV(quadrant_id, "ul")) { - select(UPPER_LEFT_QUADRANT); - return; - } - if (BU_STR_EQUIV(quadrant_id, "ll")) { - select(LOWER_LEFT_QUADRANT); - return; - } - if (BU_STR_EQUIV(quadrant_id, "lr")) { - select(LOWER_RIGHT_QUADRANT); - return; - } -} - - -int -QtCADQuad::get_selected() -{ - if (currentView == views[UPPER_RIGHT_QUADRANT]) { - return 0; - } - if (currentView == views[UPPER_LEFT_QUADRANT]) { - return 1; - } - if (currentView == views[LOWER_LEFT_QUADRANT]) { - return 2; - } - if (currentView == views[LOWER_RIGHT_QUADRANT]) { - return 3; - } - - return 0; -} - -void -QtCADQuad::do_view_update(unsigned long long flags) -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->need_update(flags); - } - } -} - -void -QtCADQuad::stash_hashes() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->stash_hashes(); - } - } -} - -bool -QtCADQuad::diff_hashes() -{ - bool ret = false; - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - if (views[i]->diff_hashes()) { - ret = true; - } - } - } - - return ret; -} - -void -QtCADQuad::enableDefaultKeyBindings() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->enableDefaultKeyBindings(); - } - } -} - -void -QtCADQuad::disableDefaultKeyBindings() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->disableDefaultKeyBindings(); - } - } -} - -void -QtCADQuad::enableDefaultMouseBindings() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->enableDefaultMouseBindings(); - } - } -} - -void -QtCADQuad::disableDefaultMouseBindings() -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->disableDefaultMouseBindings(); - } - } -} - -void -QtCADQuad::set_lmouse_move_default(int mm) -{ - for (int i = UPPER_RIGHT_QUADRANT; i < LOWER_RIGHT_QUADRANT + 1; i++) { - if (views[i] != nullptr) { - views[i]->set_lmouse_move_default(mm); - } - } -} - -void -QtCADQuad::do_init_done() -{ - if (!init_done_flag) { - init_done_flag = true; - emit init_done(); - } -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QtCADView.cpp b/src/libqtcad/QtCADView.cpp deleted file mode 100644 index d6ad7230748..00000000000 --- a/src/libqtcad/QtCADView.cpp +++ /dev/null @@ -1,541 +0,0 @@ -/* Q T C A D V I E W . C P P - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtCADView.cpp - * - * Wrapper widget that handles the various widget types which may - * constitute a Qt based geometry view. - * - */ - -#include "common.h" - -#include "qtcad/QtCADView.h" - -extern "C" { -#include "bu/malloc.h" -} - - -QtCADView::QtCADView(QWidget *parent, int type, struct fb *fbp) - : QWidget(parent) -{ - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l = new QBoxLayout(QBoxLayout::LeftToRight, this); - l->setSpacing(0); - l->setContentsMargins(0, 0, 0, 0); - - switch (type) { -#ifdef BRLCAD_OPENGL - case QtCADView_GL: - canvas_gl = new QtGL(this, fbp); - canvas_gl->setMinimumSize(50,50); - canvas_gl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l->addWidget(canvas_gl); - QObject::connect(canvas_gl, &QtGL::changed, this, &QtCADView::do_view_changed); - QObject::connect(canvas_gl, &QtGL::init_done, this, &QtCADView::do_init_done); - break; -#endif - case QtCADView_SW: - canvas_sw = new QtSW(this, fbp); - canvas_sw->setMinimumSize(50,50); - canvas_sw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l->addWidget(canvas_sw); - QObject::connect(canvas_sw, &QtSW::changed, this, &QtCADView::do_view_changed); - QObject::connect(canvas_sw, &QtSW::init_done, this, &QtCADView::do_init_done); - break; - default: -#ifdef BRLCAD_OPENGL - canvas_gl = new QtGL(this, fbp); - canvas_gl->setMinimumSize(50,50); - canvas_gl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l->addWidget(canvas_gl); - QObject::connect(canvas_gl, &QtGL::changed, this, &QtCADView::do_view_changed); - QObject::connect(canvas_gl, &QtGL::init_done, this, &QtCADView::do_init_done); -#else - canvas_sw = new QtSW(this, fbp); - canvas_sw->setMinimumSize(50,50); - canvas_sw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l->addWidget(canvas_sw); - QObject::connect(canvas_sw, &QtSW::changed, this, &QtCADView::do_view_changed); - QObject::connect(canvas_sw, &QtSW::init_done, this, &QtCADView::do_init_done); -#endif - return; - } -} - -QtCADView::~QtCADView() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - delete canvas_gl; -#endif - if (canvas_sw) - delete canvas_sw; -} - -bool -QtCADView::isValid() -{ - if (canvas_sw) - return true; - -#ifdef BRLCAD_OPENGL - if (canvas_gl) - return canvas_gl->isValid(); -#endif - - return false; -} - -void -QtCADView::fallback() -{ - if (canvas_sw) - return; - -#ifdef BRLCAD_OPENGL - if (canvas_gl && !canvas_gl->isValid()) { - bu_log("System OpenGL Canvas didn't work, falling back on Software Rasterizer\n"); - delete canvas_gl; - canvas_gl = NULL; - canvas_sw = new QtSW(this, NULL); - canvas_sw->setMinimumSize(50,50); - canvas_sw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - l->addWidget(canvas_sw); - } -#endif -} - - -int -QtCADView::view_type() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - return QtCADView_GL; -#endif - if (canvas_sw) - return QtCADView_SW; - - return -1; -} - - -void -QtCADView::save_image(int UNUSED(quad)) -{ -} - -void -QtCADView::select(int quad) -{ - if (quad) { - // TODO This spacing needs to be configurable - l->setContentsMargins(5, 5, 5, 5); - } - else { - l->setContentsMargins(0, 0, 0, 0); - } -} - -void -QtCADView::do_view_changed() -{ - emit changed(); -} - -void -QtCADView::need_update(unsigned long long) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->need_update(); - return; - } -#endif - if (canvas_sw) { - canvas_sw->need_update(); - return; - } -} - -struct bview * -QtCADView::view() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - return canvas_gl->v; -#endif - if (canvas_sw) - return canvas_sw->v; - - return NULL; -} - -struct dm * -QtCADView::dmp() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - return canvas_gl->dmp; -#endif - if (canvas_sw) - return canvas_sw->dmp; - - return NULL; -} - -struct fb * -QtCADView::ifp() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - return canvas_gl->ifp; -#endif - if (canvas_sw) - return canvas_sw->ifp; - - return NULL; -} - -double -QtCADView::base2local() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl && canvas_gl->v) - return canvas_gl->v->gv_base2local; -#endif - if (canvas_sw && canvas_sw->v) - return canvas_sw->v->gv_base2local; - - return 1.0; -} - -double -QtCADView::local2base() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl && canvas_gl->v) - return canvas_gl->v->gv_local2base; -#endif - if (canvas_sw && canvas_sw->v) - return canvas_sw->v->gv_local2base; - - return 1.0; -} - -// TODO - for quad view, we're going to need to keep -// local views - scene object vlists will be shared, -// but camera settings will not. -void -QtCADView::set_view(struct bview *nv, int UNUSED(quad)) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->v = nv; - if (canvas_gl->dmp && canvas_gl->v) { - canvas_gl->v->dmp = canvas_gl->dmp; - } - } -#endif - if (canvas_sw) { - canvas_sw->v = nv; - if (canvas_sw->dmp && canvas_sw->v) { - canvas_sw->v->dmp = canvas_sw->dmp; - } - } -} - -void -QtCADView::set_dmp(struct dm *ndmp, int UNUSED(quad)) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - canvas_gl->dmp = ndmp; -#endif - if (canvas_sw) - canvas_sw->dmp = ndmp; -} - -void -QtCADView::set_dm_current(struct dm **ndmp, int UNUSED(quad)) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->dm_current = ndmp; - if (canvas_gl->dmp && canvas_gl->dm_current) { - (*canvas_gl->dm_current) = canvas_gl->dmp; - } - } -#endif - if (canvas_sw) { - canvas_sw->dm_current = ndmp; - if (canvas_sw->dmp && canvas_sw->dm_current) { - (*canvas_sw->dm_current) = canvas_sw->dmp; - } - } -} - -void -QtCADView::set_ifp(struct fb *nfbp, int UNUSED(quad)) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) - canvas_gl->ifp = nfbp; -#endif - if (canvas_sw) - canvas_sw->ifp = nfbp; -} - -void -QtCADView::set_base2local(double nb2l) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl && canvas_gl->v) - canvas_gl->v->gv_base2local = nb2l; -#endif - if (canvas_sw && canvas_sw->v) - canvas_sw->v->gv_base2local = nb2l; -} - -void -QtCADView::set_local2base(double nl2b) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl && canvas_gl->v) - canvas_gl->v->gv_local2base = nl2b; -#endif - if (canvas_sw && canvas_sw->v) - canvas_sw->v->gv_local2base = nl2b; -} - -void -QtCADView::stash_hashes() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->stash_hashes(); - } -#endif - if (canvas_sw) { - canvas_sw->stash_hashes(); - } -} - -bool -QtCADView::diff_hashes() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - return canvas_gl->diff_hashes(); - } -#endif - if (canvas_sw) { - return canvas_sw->diff_hashes(); - } - - return false; -} - -void -QtCADView::aet(double a, double e, double t) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->aet(a, e, t); - } -#endif - if (canvas_sw) { - canvas_sw->aet(a, e, t); - } -} - -void -QtCADView::set_current(int i) -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->current = i; - } -#endif - if (canvas_sw) { - canvas_sw->current = i; - } -} - -int -QtCADView::current() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - return canvas_gl->current; - } -#endif - if (canvas_sw) { - return canvas_sw->current; - } - - return 0; -} - -void -QtCADView::add_event_filter(QObject *o) -{ - curr_event_filter = o; -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->installEventFilter(o); - return; - } -#endif - if (canvas_sw) { - canvas_sw->installEventFilter(o); - return; - } -} - -void -QtCADView::clear_event_filter(QObject *o) -{ - if (!o) - return; -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->removeEventFilter(o); - } -#endif - if (canvas_sw) { - canvas_sw->removeEventFilter(o); - } - curr_event_filter = NULL; -} - -void -QtCADView::set_draw_custom(void (*draw_custom)(struct bview *, double, double, void *), void *draw_udata) -{ - -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->draw_custom = draw_custom; - canvas_gl->draw_udata = draw_udata; - return; - } -#endif - if (canvas_sw) { - canvas_sw->draw_custom = draw_custom; - canvas_sw->draw_udata = draw_udata; - return; - } -} - -void -QtCADView::enableDefaultKeyBindings() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->enableDefaultKeyBindings(); - return; - } -#endif - if (canvas_sw) { - canvas_sw->enableDefaultKeyBindings(); - return; - } -} - -void -QtCADView::disableDefaultKeyBindings() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->disableDefaultKeyBindings(); - return; - } -#endif - if (canvas_sw) { - canvas_sw->disableDefaultKeyBindings(); - return; - } -} - -void -QtCADView::enableDefaultMouseBindings() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->enableDefaultMouseBindings(); - return; - } -#endif - if (canvas_sw) { - canvas_sw->enableDefaultMouseBindings(); - return; - } - - -} - -void -QtCADView::disableDefaultMouseBindings() -{ -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->disableDefaultMouseBindings(); - return; - } -#endif - if (canvas_sw) { - canvas_sw->disableDefaultMouseBindings(); - return; - } -} - - -void -QtCADView::set_lmouse_move_default(int mm) -{ - -#ifdef BRLCAD_OPENGL - if (canvas_gl) { - canvas_gl->set_lmouse_move_default(mm); - return; - } -#endif - if (canvas_sw) { - canvas_sw->set_lmouse_move_default(mm); - return; - } -} - - -void -QtCADView::do_init_done() -{ - emit init_done(); -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QtConsole.cpp b/src/libqtcad/QtConsole.cpp deleted file mode 100644 index 27faed2b155..00000000000 --- a/src/libqtcad/QtConsole.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc. - All rights reserved. - * - * Sandia National Laboratories, New Mexico PO Box 5800 Albuquerque, NM 87185 - * - * Kitware Inc. - * 28 Corporate Drive - * Clifton Park, NY 12065 - * USA - * - * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license - * for use of this work by or on behalf of the U.S. Government. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of Kitware nor the names of any contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - * This widget is based off of ParaView's QtConsole - */ - -#include "common.h" - -#include "qtcad/QtConsole.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bu.h" -#include "ged.h" - -GEDShellCompleter::GEDShellCompleter( - QWidget* parent, struct ged *ged_ptr) -{ - setParent(parent); - gedp = ged_ptr; -} - -void -GEDShellCompleter::updateCompletionModel(const QString& console_txt) -{ - setModel(NULL); - if (console_txt.isEmpty()) - return; - - // If the last char is a space, don't offer any completions - the prior - // contents are presumed to be complete - if (console_txt.at(console_txt.length() - 1) == ' ') - return; - - // We're going to be splitting up and processing this string's components - // with libged C style, so get the data out of QString into a stable form - char *ct = bu_strdup(console_txt.toLocal8Bit().constData()); - - // Break the console text down into an argc/argv array, so we can examine - // the components - int ac = 0; - char **av = NULL; - av = (char **)bu_calloc(strlen(ct) + 1, sizeof(char *), "av array"); - ac = bu_argv_from_string(av, strlen(ct), ct); - if (!ac) { - bu_free(ct, "strcpy"); - bu_free(av, "av"); - return; - } - - // If we only have 1 argument, it needs to be a command of some sort - if (ac == 1) { - char *seed = av[0]; - const char **completions = NULL; - int completion_cnt = ged_cmd_completions(&completions, seed); - QStringList clist = QStringList(); - for (int i = 0; i < completion_cnt; i++) { - clist.append(QString(completions[i])); - } - bu_argv_free(completion_cnt, (char **)completions); - if (!clist.isEmpty()) { - setCompletionMode(QCompleter::PopupCompletion); - setModel(new QStringListModel(clist, this)); - setCaseSensitivity(Qt::CaseSensitive); - setCompletionPrefix(QString(seed)); - if (popup()) - popup()->setCurrentIndex(completionModel()->index(0, 0)); - } - bu_free(ct, "strcpy"); - bu_free(av, "av"); - return; - } - - // If we've got more than one argument, the last element (the one we are - // looking to complete) is some sort of db geometry object/path element. - // TODO - does QComplete allow for mid-string insertions? - - if (!gedp) - return; - - char *seed = av[ac - 1]; - const char **completions = NULL; - struct bu_vls prefix = BU_VLS_INIT_ZERO; - int completion_cnt = ged_geom_completions(&completions, &prefix, gedp->dbip, seed); - ((QtConsole *)(parent()))->split_slash = 0; - if (!BU_STR_EQUAL(bu_vls_cstr(&prefix), seed)) - ((QtConsole *)(parent()))->split_slash = 1; - QStringList clist = QStringList(); - for (int i = 0; i < completion_cnt; i++) { - clist.append(QString(completions[i])); - } - bu_argv_free(completion_cnt, (char **)completions); - if (!clist.isEmpty()) { - setCompletionMode(QCompleter::PopupCompletion); - setModel(new QStringListModel(clist, this)); - setCaseSensitivity(Qt::CaseSensitive); - setCompletionPrefix(QString(bu_vls_cstr(&prefix))); - if (popup()) - popup()->setCurrentIndex(completionModel()->index(0, 0)); - } - bu_vls_free(&prefix); - bu_free(ct, "strcpy"); - bu_free(av, "av"); -} - -///////////////////////////////////////////////////////////////////////// -// QtConsole::pqImplementation - -class QtConsole::pqImplementation : - public QPlainTextEdit -{ - public: - pqImplementation(QtConsole& p) : - QPlainTextEdit(&p), - Parent(p), - InteractivePosition(documentEnd()) - { - this->setTabChangesFocus(false); - this->setAcceptDrops(false); - this->setUndoRedoEnabled(false); - this->setMinimumHeight(200); - this->setMaximumBlockCount(10000); - - QFont f("Courier"); - f.setStyleHint(QFont::TypeWriter); - f.setFixedPitch(true); - this->setFont(f); - - this->CommandHistory.append(""); - this->CommandPosition = 0; - } - - void setFont(const QFont& i_font) - { - QPlainTextEdit::setFont(i_font); - } - - QFont getFont() - { - return this->font(); - } - - // TODO - figure out how to implement this... - bool consolidateHistory(size_t start, size_t end) - { - if (start > end) - return false; - QString nline; - for (size_t i = start; i < end; i++) { - nline.append(CommandHistory.at(i)); - if (i != end - 1) - nline.append(" "); - } - while (CommandHistory.count() > (int)start) { - CommandHistory.pop_back(); - } - CommandHistory.push_back(nline); - CommandHistory.push_back(""); - CommandPosition = CommandHistory.size() - 1; - return true; - } - - std::string historyAt(size_t ind) - { - const char *cmd = CommandHistory.at(ind).toLocal8Bit().data(); - std::string scmd(cmd); - return scmd; - } - - // Try to keep the scrollbar slider from getting too small to be usable - void resizeEvent(QResizeEvent *e) - { - this->setMaximumBlockCount(2*this->height()); - QPlainTextEdit::resizeEvent(e); - } - - void insertFromMimeData(const QMimeData * s) - { - QTextCursor text_cursor = this->textCursor(); - - // Set to true if the cursor overlaps the history area - const bool history_area = - text_cursor.anchor() < this->InteractivePosition - || text_cursor.position() < this->InteractivePosition; - - // Avoid pasting into history - if (history_area) { - return; - } - - QPlainTextEdit::insertFromMimeData(s); - - // The text changed - make sure the command buffer knows - this->updateCommandBuffer(); - } - - void keyPressEvent(QKeyEvent* e) - { - if (this->Completer && this->Completer->popup()->isVisible()) { - // The following keys are forwarded by the completer to the widget - switch (e->key()) { - case Qt::Key_Tab: - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Escape: - case Qt::Key_Backtab: - e->ignore(); - return; // let the completer do default behavior - default: - break; - } - } - - QTextCursor text_cursor = this->textCursor(); - - // Set to true if there's a current selection - const bool selection = text_cursor.anchor() != text_cursor.position(); - // Set to true if the cursor overlaps the history area - const bool history_area = - text_cursor.anchor() < this->InteractivePosition - || text_cursor.position() < this->InteractivePosition; - - // Allow copying anywhere in the console ... - if (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier) { - if (selection) { - this->copy(); - } - - e->accept(); - return; - } - - // Allow cut only if the selection is limited to the interactive area ... - if (e->key() == Qt::Key_X && e->modifiers() == Qt::ControlModifier) { - if (selection && !history_area) { - this->cut(); - } - - e->accept(); - return; - } - - // Allow paste only if the selection is in the interactive area ... - if (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier) { - if (!history_area) { - const QMimeData* const clipboard = QApplication::clipboard()->mimeData(); - const QString text = clipboard->text(); - if (!text.isNull()) { - text_cursor.insertText(text); - this->updateCommandBuffer(); - } - } - - e->accept(); - return; - } - - // Force the cursor back to the interactive area - if (history_area && e->key() != Qt::Key_Control) { - text_cursor.setPosition(this->documentEnd()); - this->setTextCursor(text_cursor); - } - - switch (e->key()) { - case Qt::Key_Up: - e->accept(); - if (this->CommandPosition > 0) { - this->replaceCommandBuffer(this->CommandHistory[--this->CommandPosition]); - } - break; - - case Qt::Key_Down: - e->accept(); - if (this->CommandPosition < this->CommandHistory.size() - 2) { - this->replaceCommandBuffer(this->CommandHistory[++this->CommandPosition]); - } else { - this->CommandPosition = this->CommandHistory.size()-1; - this->replaceCommandBuffer(""); - } - break; - - case Qt::Key_Left: - if (text_cursor.position() > this->InteractivePosition) { - QPlainTextEdit::keyPressEvent(e); - } else { - e->accept(); - } - break; - - - case Qt::Key_Delete: - e->accept(); - QPlainTextEdit::keyPressEvent(e); - this->updateCommandBuffer(); - break; - - case Qt::Key_Backspace: - e->accept(); - if (text_cursor.position() > this->InteractivePosition) { - QPlainTextEdit::keyPressEvent(e); - this->updateCommandBuffer(); - this->updateCompleterIfVisible(); - } - break; - - case Qt::Key_Tab: - e->accept(); - { - int anchor = text_cursor.anchor(); - int position = text_cursor.position(); - text_cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); - text_cursor.setPosition(position, QTextCursor::KeepAnchor); - QString text = text_cursor.selectedText().trimmed(); - text_cursor.setPosition(anchor, QTextCursor::MoveAnchor); - text_cursor.setPosition(position, QTextCursor::KeepAnchor); - if (text == ">>>" || text == "...") { - text_cursor.insertText(" "); - } else { - this->updateCompleter(); - this->selectCompletion(); - } - } - break; - - case Qt::Key_Home: - e->accept(); - text_cursor.setPosition(this->InteractivePosition); - this->setTextCursor(text_cursor); - break; - - case Qt::Key_Return: - case Qt::Key_Enter: - e->accept(); - - text_cursor.setPosition(this->documentEnd()); - this->setTextCursor(text_cursor); - - this->internalExecuteCommand(); - break; - - default: - e->accept(); - QPlainTextEdit::keyPressEvent(e); - this->updateCommandBuffer(); - this->updateCompleterIfVisible(); - break; - } - } - - /// Returns the end of the document - int documentEnd() - { - QTextCursor c(this->document()); - c.movePosition(QTextCursor::End); - return c.position(); - } - - void focusOutEvent(QFocusEvent *e) - { - QPlainTextEdit::focusOutEvent(e); - - // For some reason the QCompleter tries to set the focus policy to - // NoFocus, set let's make sure we set it back to the default WheelFocus. - this->setFocusPolicy(Qt::WheelFocus); - } - - - void updateCompleterIfVisible() - { - if (this->Completer && this->Completer->popup()->isVisible()) { - this->updateCompleter(); - } - } - - /// If there is exactly 1 completion, insert it and hide the completer, - /// else do nothing. - void selectCompletion() - { - if (this->Completer && this->Completer->completionCount() == 1) { - this->Parent.insertCompletion(this->Completer->currentCompletion()); - this->Completer->popup()->hide(); - } - } - - void updateCompleter() - { - if (this->Completer) { - // Get the text between the current cursor position - // and the start of the line - QTextCursor text_cursor = this->textCursor(); - text_cursor.setPosition(this->InteractivePosition, QTextCursor::KeepAnchor); - QString commandText = text_cursor.selectedText(); - - // Call the completer to update the completion model - this->Completer->updateCompletionModel(commandText); - - // Place and show the completer if there are available completions - if (this->Completer->completionCount()) { - // Get a QRect for the cursor at the start of the - // current word and then translate it down 8 pixels. - text_cursor = this->textCursor(); - text_cursor.movePosition(QTextCursor::StartOfWord); - QRect cr = this->cursorRect(text_cursor); - cr.translate(0, 8); - cr.setWidth(this->Completer->popup()->sizeHintForColumn(0) + - this->Completer->popup()->verticalScrollBar()->sizeHint().width()); - this->Completer->complete(cr); - } else { - this->Completer->popup()->hide(); - } - } - } - - /// Update the contents of the command buffer from the contents of the widget - void updateCommandBuffer() - { - this->commandBuffer() = this->toPlainText().mid(this->InteractivePosition); - } - - /// Replace the contents of the command buffer, updating the display - void replaceCommandBuffer(const QString& Text) - { - this->commandBuffer() = Text; - - QTextCursor c(this->document()); - c.setPosition(this->InteractivePosition); - c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); - c.removeSelectedText(); - c.insertText(Text); - } - - /// References the buffer where the current un-executed command is stored - QString& commandBuffer() - { - return this->CommandHistory.back(); - } - - /// Implements command-execution - void internalExecuteCommand() - { - // First update the history cache. It's essential to update the - // this->CommandPosition before calling internalExecuteCommand() since that - // can result in a clearing of the current command (BUG #8765). - QString command = this->commandBuffer(); - if (!command.isEmpty()) { // Don't store empty commands in the history - this->CommandHistory.push_back(""); - this->CommandPosition = this->CommandHistory.size() - 1; - } - QTextCursor c(this->document()); - c.movePosition(QTextCursor::End); - c.insertText("\n"); - - this->InteractivePosition = this->documentEnd(); - this->Parent.internalExecuteCommand(command); - } - - void setCompleter(QtConsoleWidgetCompleter* completer) - { - if (this->Completer) { - this->Completer->setWidget(nullptr); - QObject::disconnect(this->Completer, QOverload::of(&QCompleter::activated), &this->Parent, &QtConsole::insertCompletion); - } - this->Completer = completer; - if (this->Completer) { - this->Completer->setWidget(this); - QObject::connect(this->Completer, QOverload::of(&QCompleter::activated), &this->Parent, &QtConsole::insertCompletion); - } - } - - /// Stores a back-reference to our owner - QtConsole& Parent; - - /// A custom completer - QPointer Completer; - - /** Stores the beginning of the area of interactive input, outside which - changes can't be made to the text edit contents */ - int InteractivePosition; - /// Stores command-history, plus the current command buffer - QStringList CommandHistory; - /// Stores the current position in the command-history - int CommandPosition; -}; - -///////////////////////////////////////////////////////////////////////// -// QtConsole - -QtConsole::QtConsole(QWidget* Parent) : - QWidget(Parent), - Implementation(new pqImplementation(*this)) -{ - QVBoxLayout* const l = new QVBoxLayout(this); -#ifndef USE_QT6 - // TODO - figure out what to do for Qt6 here... - l->setMargin(0); -#endif - l->addWidget(this->Implementation); - QObject::connect(this, &QtConsole::queued_log, this, &QtConsole::printStringBeforePrompt); -} - -//----------------------------------------------------------------------------- -QtConsole::~QtConsole() -{ - delete this->Implementation; -} - -//----------------------------------------------------------------------------- -QFont QtConsole::getFont() -{ - return this->Implementation->getFont(); -} - -//----------------------------------------------------------------------------- -bool QtConsole::consolidateHistory(size_t start, size_t end) -{ - return this->Implementation->consolidateHistory(start, end); -} - -//----------------------------------------------------------------------------- -size_t QtConsole::historyCount() -{ - return this->Implementation->CommandHistory.count(); -} - -//----------------------------------------------------------------------------- -std::string QtConsole::historyAt(size_t ind) -{ - return this->Implementation->historyAt(ind); -} - -//----------------------------------------------------------------------------- -void QtConsole::setFont(const QFont& i_font) -{ - this->Implementation->setFont(i_font); -} - -//----------------------------------------------------------------------------- -QPoint QtConsole::getCursorPosition() -{ - QTextCursor tc = this->Implementation->textCursor(); - - return this->Implementation->cursorRect(tc).topLeft(); -} - -//----------------------------------------------------------------------------- -void QtConsole::listen(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d) -{ - QConsoleListener *l = new QConsoleListener(fd, p, t, c, d); - bu_log("Start listening: %d\n", (int)t); - QObject::connect(l, &QConsoleListener::newLine, this, &QtConsole::printStringBeforePrompt); - QObject::connect(l, &QConsoleListener::is_finished, this, &QtConsole::detach); - listeners[std::make_pair(p, t)] = l; -} -void QtConsole::detach(struct ged_subprocess *p, int t) -{ - std::map, QConsoleListener *>::iterator l_it, si_it, so_it, e_it; - l_it = listeners.find(std::make_pair(p,t)); - - struct ged_subprocess *process = NULL; - ged_io_func_t callback = NULL; - void *gdata = NULL; - - if (l_it != listeners.end()) { - bu_log("Stop listening: %d\n", (int)t); - QConsoleListener *l = l_it->second; - process = l->process; - callback = l->callback; - gdata = l->data; - listeners.erase(l_it); - delete l; - } - - if (process) { - si_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDIN)); - so_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDOUT)); - e_it = listeners.find(std::make_pair(p,(int)BU_PROCESS_STDERR)); - - // We don't want to destroy the process until all the listeners are removed. - // If they all have been, do a final callback call with -1 key to instruct - // the callback to finalize process and memory removal. - if (si_it == listeners.end() && so_it == listeners.end() && e_it == listeners.end() && callback) { - (*callback)(gdata, -1); - // This is also the point at which we know any output from the subprocess - // is at an end. Finalize the before-prompt printing. - log_timestamp = 0; - QString estr(""); - printStringBeforePrompt(estr); - } - } -} - -//----------------------------------------------------------------------------- -void QtConsole::setCompleter(QtConsoleWidgetCompleter* completer) -{ - this->Implementation->setCompleter(completer); -} - -//----------------------------------------------------------------------------- -void QtConsole::insertCompletion(const QString& completion) -{ - QTextCursor tc = this->Implementation->textCursor(); - tc.setPosition(tc.position(), QTextCursor::MoveAnchor); - QString text = tc.selectedText(); - //const char *txt = text.toLocal8Bit().data(); - //bu_log("txt: %s\n", txt); - while (tc.position() > 0 && (!text.length() || (text.at(0) != ' ' && (!split_slash || text.at(0) != '/')))) { - tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor); - text = tc.selectedText(); - //txt = text.toLocal8Bit().data(); - //bu_log("txt: %s\n", txt); - } - if (tc.selectedText() == ".") { - tc.insertText(QString(".") + completion); - } else { - tc.setPosition(tc.position()+1, QTextCursor::MoveAnchor); - tc.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - tc.insertText(completion); - this->Implementation->setTextCursor(tc); - } - this->Implementation->updateCommandBuffer(); -} - - -//----------------------------------------------------------------------------- -void QtConsole::printString(const QString& Text) -{ - QTextCursor text_cursor = this->Implementation->textCursor(); - text_cursor.setPosition(this->Implementation->documentEnd()); - this->Implementation->setTextCursor(text_cursor); - text_cursor.insertText(Text); - - this->Implementation->InteractivePosition = this->Implementation->documentEnd(); - this->Implementation->ensureCursorVisible(); -} - -//----------------------------------------------------------------------------- -// This style of insertion is is too slow to just attempt it every time the -// subprocesses send output (Goliath rtcheck is an example.) Instead, we -// keep track of the last time we updated and if not enough time has passed -// we just queue up the text for later insertion. -// -// This approach also depends on the listener clean-up finalizing the string - -// otherwise there would be a chance of losing some printing due to timing -// issues if the last bits of the output come in right after an insertion. -// -// TODO: It would be better if the input prompt and command were one -// QPlainTextEdit and the output another, so they could operate independently - -// this approach will still introduce brief periods where the input prompt -// disappears and reappears during updating. However, that would -// require restructuring QtConsole's widget design - for now this functions, -// and if this becomes the production solution we can/should revisit it later. -void QtConsole::printStringBeforePrompt(const QString& Text) -{ - logbuf.append(Text); - int64_t ctime = bu_gettime(); - double elapsed = ((double)ctime - (double)log_timestamp)/1000000.0; - if (elapsed > 0.1 && logbuf.length()) { - // Make a local printing copy and clear the buffer - QString llogbuf = logbuf; - logbuf.clear(); - - log_timestamp = bu_gettime(); - - // While we're manipulating the console contents, we don't want - // the user modifying anything. - this->Implementation->setReadOnly(true); - - // Make a copy of the text cursor on which to operate. Note that this - // is not the actual cursor being used for editing and we need to use - // setTextCursor to impact that cursor. For most of this operation we - // don't need to, but it's important for restoring the editing state - // to the user at the end. - QTextCursor tc = this->Implementation->textCursor(); - - // Store the current editing point relative to the prompt (it may not - // be the end of the command, if the user is editing mid-command.) - int curr_pos_offset = tc.position() - (prompt_start + prompt_str.length()); - - // Before appending new content to the log, clear the old prompt and - // command string. We restore them after the new log content is added. - tc.setPosition(prompt_start); - tc.setPosition(this->Implementation->documentEnd(), QTextCursor::KeepAnchor); - tc.removeSelectedText(); - - // Print the accumulated logged output to the command window. - this->Implementation->insertPlainText(llogbuf); - - // Before we re-add the prompt and command buffer, store the new prompt - // starting point for use in the next write cycle. - prompt_start = tc.position(); - - // Restore the prompt and the next command (if any) - this->Implementation->insertPlainText(prompt_str); - this->Implementation->textCursor().insertText(this->Implementation->commandBuffer()); - - // Denote the interactive portion of the new state of the buffer as starting after - // the new prompt. - this->Implementation->InteractivePosition = prompt_start + prompt_str.length(); - - // Make sure the scrolling is set to view the new prompt - this->Implementation->ensureCursorVisible(); - - // The final touch - in case the cursor was not at the end of the command buffer, - // restore it to its prior offset from the prompt. Since we are altering the - // user-interactive editing cursor this time, and not just manipulating the text, - // we must use setTextCursor to apply the change. - tc.setPosition(prompt_start + prompt_str.length() + curr_pos_offset); - this->Implementation->setTextCursor(tc); - - // All done - unlock - this->Implementation->setReadOnly(false); - } - - // If there is anything queued up, we need to make sure we print it soon(ish) - if (logbuf.length()) { - QTimer::singleShot(1000, this, &QtConsole::emit_queued); - } -} - -//----------------------------------------------------------------------------- -void QtConsole::printCommand(const QString& cmd) -{ - this->Implementation->textCursor().insertText(cmd); - this->Implementation->updateCommandBuffer(); -} - -//----------------------------------------------------------------------------- -void QtConsole::prompt(const QString& text) -{ - QTextCursor text_cursor = this->Implementation->textCursor(); - - // if the cursor is currently on a clean line, do nothing, otherwise we move - // the cursor to a new line before showing the prompt. - text_cursor.movePosition(QTextCursor::StartOfLine); - int startpos = text_cursor.position(); - text_cursor.movePosition(QTextCursor::EndOfLine); - int endpos = text_cursor.position(); - if (endpos != startpos) { - this->Implementation->textCursor().insertText("\n"); - } - - prompt_start = text_cursor.position(); - prompt_str = text; - - this->Implementation->textCursor().insertText(text); - this->Implementation->InteractivePosition = this->Implementation->documentEnd(); - this->Implementation->ensureCursorVisible(); -} - -//----------------------------------------------------------------------------- -void QtConsole::clear() -{ - this->Implementation->clear(); - - // For some reason the QCompleter tries to set the focus policy to - // NoFocus, set let's make sure we set it back to the default WheelFocus. - this->Implementation->setFocusPolicy(Qt::WheelFocus); -} - -//----------------------------------------------------------------------------- -void QtConsole::internalExecuteCommand(const QString& Command) -{ - emit this->executeCommand(Command); -} - -//----------------------------------------------------------------------------- - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 diff --git a/src/libqtcad/QtConsoleListener.cpp b/src/libqtcad/QtConsoleListener.cpp deleted file mode 100644 index f8723e940d8..00000000000 --- a/src/libqtcad/QtConsoleListener.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 Juan Gonzalez Burgos - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Originally from https://github.com/juangburgos/QConsoleListener - */ - -#include "common.h" - -#include -#include "qtcad/QtConsoleListener.h" - -#define RT_MAXLINE 10240 - -void noMessageOutput(QtMsgType, const QMessageLogContext&, const QString&) {} - -QConsoleListener::QConsoleListener(int fd, struct ged_subprocess *p, bu_process_io_t t, ged_io_func_t c, void *d) -{ - this->process = p; - this->callback = c; - this->data = d; - this->type = t; - QObject::connect( - this, &QConsoleListener::finishedGetLine, - this, &QConsoleListener::on_finishedGetLine, - Qt::QueuedConnection - ); -#ifdef Q_OS_WIN - HANDLE h = (fd < 0) ? GetStdHandle(STD_INPUT_HANDLE) : (HANDLE)_get_osfhandle(fd); - m_notifier = new QWinEventNotifier(h); -#else - int lfd = (fd < 0) ? fileno(stdin) : fd; - m_notifier = new QSocketNotifier(lfd, QSocketNotifier::Read); -#endif - // NOTE : move to thread to avoid blocking, then sync with - // main thread using a QueuedConnection with finishedGetLine - m_notifier->moveToThread(&m_thread); - QObject::connect(&m_thread , &QThread::finished, m_notifier, &QObject::deleteLater); -#ifdef Q_OS_WIN - QObject::connect(m_notifier, &QWinEventNotifier::activated, m_notifier, -#else - QObject::connect(m_notifier, &QSocketNotifier::activated, m_notifier, -#endif - [this]() { - if (callback) { - size_t s1 = bu_vls_strlen(process->gedp->ged_result_str); - (*callback)(data, (int)type); - size_t s2 = bu_vls_strlen(process->gedp->ged_result_str); - if (s1 != s2) { - struct bu_vls nstr = BU_VLS_INIT_ZERO; - bu_vls_substr(&nstr, process->gedp->ged_result_str, s1, s2 - s1); - QString strLine = QString::fromStdString(std::string(bu_vls_cstr(&nstr))); - bu_vls_free(&nstr); - Q_EMIT this->finishedGetLine(strLine); - } - } - }); - m_thread.start(); -} - -QConsoleListener::~QConsoleListener() -{ - m_notifier->disconnect(); - m_thread.quit(); - m_thread.wait(); -} - -void QConsoleListener::on_finishedGetLine(const QString &strNewLine) -{ - Q_EMIT this->newLine(strNewLine); -} - -void QConsoleListener::on_finished() -{ - Q_EMIT this->is_finished(this->process, (int)this->type); -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/src/libqtcad/QtGL.cpp b/src/libqtcad/QtGL.cpp deleted file mode 100644 index 497cfd56787..00000000000 --- a/src/libqtcad/QtGL.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* Q T G L . C P P - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtGL.cpp - * - * Use a QOpenGLWidget to display libdm drawing content. - * - */ - -#include "common.h" - -#include - -extern "C" { -#include "bu/malloc.h" -} -#include "bindings.h" -#include "qtcad/QtGL.h" - -// FROM MGED -#define XMIN (-2048) -#define XMAX (2047) -#define YMIN (-2048) -#define YMAX (2047) - -// from GED_MIN and GED_MAX -#define QTGL_ZMIN -2048 -#define QTGL_ZMAX 2047 - -QtGL::QtGL(QWidget *parent, struct fb *fbp) - : QOpenGLWidget(parent), ifp(fbp) -{ - // Provide a view specific to this widget - set gedp->ged_gvp to v - // if this is the current view - BU_GET(v, struct bview); - bv_init(v, NULL); - bu_vls_sprintf(&v->gv_name, "qtgl"); - - // We can't initialize dmp successfully until more of the OpenGL - // initialization is complete - dmp = NULL; - - // If we weren't supplied with a framebuffer, allocate one. - // We don't open it until we have the dmp. - if (!ifp) { - ifp = fb_raw("qtgl"); - fb_set_standalone(ifp, 0); - } - - // This is an important Qt setting for interactivity - it allowing key - // bindings to propagate to this widget and trigger actions such as - // resolution scaling, rotation, etc. - setFocusPolicy(Qt::WheelFocus); -} - -QtGL::~QtGL() -{ - if (dmp) - dm_close(dmp); - if (ifp && !fb_get_standalone(ifp)) { - fb_close_existing(ifp); - } - BU_PUT(v, struct bv); -} - - -void QtGL::paintGL() -{ - int w = width(); - int h = height(); - // Zero size == nothing to do - if (!w || !h) - return; - - if (!m_init) { - - if (!dmp) { - - // This is needed so we can work with Qt's OpenGL widget - // using standard OpenGL functions. - initializeOpenGLFunctions(); - - // Do the standard libdm attach to get our rendering backend. - const char *acmd = "attach"; - dmp = dm_open((void *)this, NULL, "qtgl", 1, &acmd); - if (!dmp) - return; - - // If we have a framebuffer, now we can open it - if (ifp) { - struct fb_platform_specific *fbps = fb_get_platform_specific(FB_QTGL_MAGIC); - fbps->data = (void *)dmp; - fb_setup_existing(ifp, dm_get_width(dmp), dm_get_height(dmp), fbps); - fb_put_platform_specific(fbps); - } - - dm_set_pathname(dmp, "QTDM"); - } - - // QTGL_ZMIN and QTGL_ZMAX are historical - need better - // documentation on why those specific values are used. - //fastf_t windowbounds[6] = { XMIN, XMAX, YMIN, YMAX, QTGL_ZMIN, QTGL_ZMAX }; - fastf_t windowbounds[6] = { -1, 1, -1, 1, QTGL_ZMIN, QTGL_ZMAX }; - dm_set_win_bounds(dmp, windowbounds); - - // Associate the view scale with the dmp - dm_set_vp(dmp, &v->gv_scale); - - // Let the view know it now has an associated display manager - v->dmp = dmp; - - // Set the view width and height to match the dm - v->gv_width = dm_get_width(dmp); - v->gv_height = dm_get_height(dmp); - - // If we have a ptbl defining the current dm set and/or an unset - // pointer to indicate the current dm, go ahead and set them. - if (dm_set) - bu_ptbl_ins_unique(dm_set, (long int *)dmp); - if (dm_current && !(*dm_current)) - (*dm_current) = dmp; - - // Ready to go - m_init = true; - emit init_done(); - } - - if (!m_init || !dmp) - return; - - unsigned char *dm_bg1; - unsigned char *dm_bg2; - dm_get_bg(&dm_bg1, &dm_bg2, dmp); - dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); - - // Go ahead and set the flag, but (unlike the rendering thread - // implementation) we need to do the draw routine every time in paintGL, or - // we end up with unrendered frames. - dm_set_dirty(dmp, 0); - dm_draw_objs(v, v->gv_base2local, v->gv_local2base, draw_custom, draw_udata); - dm_draw_end(dmp); -} - -void QtGL::resizeGL(int, int) -{ - if (!dmp) - return; - dm_configure_win(dmp, 0); - v->gv_width = dm_get_width(dmp); - v->gv_height = dm_get_height(dmp); - if (ifp) { - fb_configure_window(ifp, v->gv_width, v->gv_height); - } - if (dmp) - dm_set_dirty(dmp, 1); - emit changed(); -} - -void QtGL::need_update() -{ - if (!dmp) - return; - dm_set_dirty(dmp, 1); - update(); -} - -void QtGL::keyPressEvent(QKeyEvent *k) { - - if (!dmp || !current || !use_default_keybindings) { - QOpenGLWidget::keyPressEvent(k); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADkeyPressEvent(v, x_prev, y_prev, k)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QOpenGLWidget::keyPressEvent(k); -} - -void QtGL::mousePressEvent(QMouseEvent *e) { - - if (!dmp || !current || !use_default_mousebindings) { - QOpenGLWidget::mousePressEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADmousePressEvent(v, x_prev, y_prev, e)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - -#ifdef USE_QT6 - x_press_pos = e->position().x(); - y_press_pos = e->position().y(); -#else - x_press_pos = (double)e->x(); - y_press_pos = (double)e->y(); -#endif - bu_log("X,Y: %g, %g\n", x_press_pos, y_press_pos); - - QOpenGLWidget::mousePressEvent(e); -} - -void QtGL::mouseReleaseEvent(QMouseEvent *e) { - - // To avoid an abrupt jump in scene motion the next time movement is - // started with the mouse, after we release we return to the default state. - x_prev = -INT_MAX; - y_prev = -INT_MAX; - - if (CADmouseReleaseEvent(v, x_press_pos, y_press_pos, x_prev, y_prev, e, lmouse_mode)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QOpenGLWidget::mouseReleaseEvent(e); -} - -void QtGL::mouseMoveEvent(QMouseEvent *e) -{ - if (!dmp || !current || !use_default_mousebindings) { - QOpenGLWidget::mouseMoveEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADmouseMoveEvent(v, x_prev, y_prev, e, lmouse_mode)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - // Current positions are the new previous positions -#ifdef USE_QT6 - x_prev = e->position().x(); - y_prev = e->position().y(); -#else - x_prev = e->x(); - y_prev = e->y(); -#endif - - QOpenGLWidget::mouseMoveEvent(e); -} - -void QtGL::wheelEvent(QWheelEvent *e) { - - if (!dmp || !current || !use_default_mousebindings) { - QOpenGLWidget::wheelEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADwheelEvent(v, e)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QOpenGLWidget::wheelEvent(e); -} - -void QtGL::stash_hashes() -{ - if (!dmp) { - prev_dhash = 0; - } else { - prev_dhash = dm_hash(dmp); - } - prev_vhash = bv_hash(v); -} - -bool QtGL::diff_hashes() -{ - bool ret = false; - unsigned long long c_dhash = 0; - unsigned long long c_vhash = 0; - - if (dmp) - c_dhash = dm_hash(dmp); - c_vhash = bv_hash(v); - - if (dmp && dm_get_dirty(dmp)) - ret = true; - - if (prev_dhash != c_dhash) { - if (dmp) - dm_set_dirty(dmp, 1); - ret = true; - } - if (prev_vhash != c_vhash) { - if (dmp) - dm_set_dirty(dmp, 1); - ret = true; - } - - if (ret) { - need_update(); - emit changed(); - } - - return ret; -} - -void QtGL::save_image() { - QImage image = this->grabFramebuffer(); - image.save("file.png"); -} - -void QtGL::aet(double a, double e, double t) -{ - fastf_t aet[3]; - double aetd[3]; - aetd[0] = a; - aetd[1] = e; - aetd[2] = t; - - /* convert from double to fastf_t */ - VMOVE(aet, aetd); - - VMOVE(v->gv_aet, aet); - - /* TODO - based on the suspect bv_mat_aet... */ - mat_t tmat; - fastf_t twist; - fastf_t c_twist; - fastf_t s_twist; - bn_mat_angles(v->gv_rotation, 270.0 + v->gv_aet[1], 0.0, 270.0 - v->gv_aet[0]); - twist = -v->gv_aet[2] * DEG2RAD; - c_twist = cos(twist); - s_twist = sin(twist); - bn_mat_zrot(tmat, s_twist, c_twist); - bn_mat_mul2(tmat, v->gv_rotation); - - bv_update(v); -} - -void -QtGL::enableDefaultKeyBindings() -{ - use_default_keybindings = true; -} - -void -QtGL::disableDefaultKeyBindings() -{ - use_default_keybindings = false; -} - -void -QtGL::enableDefaultMouseBindings() -{ - use_default_mousebindings = true; -} - -void -QtGL::disableDefaultMouseBindings() -{ - use_default_mousebindings = false; -} - -void -QtGL::set_lmouse_move_default(int mm) -{ - lmouse_mode = mm; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/src/libqtcad/QtSW.cpp b/src/libqtcad/QtSW.cpp deleted file mode 100644 index 74774b54649..00000000000 --- a/src/libqtcad/QtSW.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* Q T S W . C P P - * BRL-CAD - * - * Copyright (c) 2021-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file QtSW.cpp - * - * Qt widget for visualizing libosmesa OpenGL software rasterizer output. - */ - -#define USE_MGL_NAMESPACE 1 - -#include "common.h" - -#include -#include - -extern "C" { -#include "bu/malloc.h" -} -#include "bindings.h" -#include "qtcad/QtSW.h" - -QtSW::QtSW(QWidget *parent, struct fb *fbp) - : QWidget(parent), ifp(fbp) -{ - // Provide a view specific to this widget - set gedp->ged_gvp to v - // if this is the current view - BU_GET(v, struct bview); - bv_init(v, NULL); - bu_vls_sprintf(&v->gv_name, "swrast"); - - // Don't dm_open until we have the view. - dmp = NULL; - - // If we weren't supplied with a framebuffer, allocate one. - // We don't open it until we have the dmp. - if (!ifp) { - ifp = fb_raw("swrast"); - fb_set_standalone(ifp, 0); - } - - // This is an important Qt setting for interactivity - it allowing key - // bindings to propagate to this widget and trigger actions such as - // resolution scaling, rotation, etc. - setFocusPolicy(Qt::WheelFocus); -} - -QtSW::~QtSW() -{ - if (dmp) - dm_close(dmp); - if (ifp && !fb_get_standalone(ifp)) { - fb_close_existing(ifp); - } - BU_PUT(v, struct bv); -} - -void QtSW::need_update() -{ - dm_set_dirty(dmp, 1); - update(); -} - -void QtSW::paintEvent(QPaintEvent *e) -{ - // Go ahead and set the flag, but (unlike the rendering thread - // implementation) we need to do the draw routine every time in paintGL, or - // we end up with unrendered frames. - dm_set_dirty(dmp, 0); - - if (!m_init) { - - if (!dmp) { - // swrast will need to know the window size - v->gv_width = width(); - v->gv_height = height(); - - // Do the standard libdm attach to get our rendering backend. - const char *acmd = "attach"; - dmp = dm_open((void *)v, NULL, "swrast", 1, &acmd); - if (!dmp) - return; - - // Let dmp know what the app level widget is (needed so we can - // connect framebuffer drawing events to the widget redraw logic.) - dm_set_udata(dmp, this); - - // If we have a framebuffer, now we can open it - if (ifp) { - struct fb_platform_specific *fbps = fb_get_platform_specific(FB_QTGL_MAGIC); - fbps->data = (void *)dmp; - fb_setup_existing(ifp, dm_get_width(dmp), dm_get_height(dmp), fbps); - fb_put_platform_specific(fbps); - } - } - - dm_configure_win(dmp, 0); - dm_set_pathname(dmp, "SWDM"); - dm_set_zbuffer(dmp, 1); - - // Using the full GED_MIN/GED_MAX was causing drawing artifacts with moss I - // in shaded mode (I think I was seeing the "Z-fighting" problem: - // https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html ) - // - // Setting to (-1,1) clips geometry too quickly as we start to zoom in. - // -100,100 seems to work, but may need a better long term solution to - // this... maybe basing it on the currently visible object bounds? - fastf_t windowbounds[6] = { -1, 1, -1, 1, -100, 100 }; - dm_set_win_bounds(dmp, windowbounds); - - // Associate the view scale with the dmp - dm_set_vp(dmp, &v->gv_scale); - - // Let the view know it has an associated dm. - v->dmp = dmp; - - // Set the view width and height to match the dm - v->gv_width = dm_get_width(dmp); - v->gv_height = dm_get_height(dmp); - - // If we have a ptbl defining the current dm set and/or an unset - // pointer to indicate the current dm, go ahead and set them. - if (dm_set) - bu_ptbl_ins_unique(dm_set, (long int *)dmp); - if (dm_current && !(*dm_current)) - (*dm_current) = dmp; - - // Ready to go - m_init = true; - - emit init_done(); - } - - if (!m_init || !dmp) - return; - - unsigned char *dm_bg1; - unsigned char *dm_bg2; - dm_get_bg(&dm_bg1, &dm_bg2, dmp); - dm_set_bg(dmp, dm_bg1[0], dm_bg1[1], dm_bg1[2], dm_bg2[0], dm_bg2[1], dm_bg2[2]); - - matp_t mat = v->gv_model2view; - dm_loadmatrix(dmp, mat, 0); - dm_draw_begin(dmp); - dm_draw_objs(v, v->gv_base2local, v->gv_local2base, draw_custom, draw_udata); - dm_draw_end(dmp); - - // Set up a QImage with the rendered output.. - unsigned char *dm_image; - if (dm_get_display_image(dmp, &dm_image, 1, 1)) { - return; - } - QImage image(dm_image, dm_get_width(dmp), dm_get_height(dmp), QImage::Format_RGBA8888); - QImage img32 = image.convertToFormat(QImage::Format_RGB32); - QPainter painter(this); - painter.drawImage(this->rect(), img32); - bu_free(dm_image, "copy of backend image"); - QWidget::paintEvent(e); -} - -void QtSW::resizeEvent(QResizeEvent *e) -{ - QWidget::resizeEvent(e); - if (dmp && v) { - dm_set_width(dmp, width()); - dm_set_height(dmp, height()); - v->gv_width = width(); - v->gv_height = height(); - dm_configure_win(dmp, 0); - if (ifp) { - fb_configure_window(ifp, v->gv_width, v->gv_height); - } - dm_set_dirty(dmp, 1); - emit changed(); - } -} - -void QtSW::keyPressEvent(QKeyEvent *k) { - - if (!dmp || !current || !use_default_keybindings) { - QWidget::keyPressEvent(k); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADkeyPressEvent(v, x_prev, y_prev, k)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QWidget::keyPressEvent(k); -} - -void QtSW::mousePressEvent(QMouseEvent *e) { - - if (!dmp || !current || !use_default_mousebindings) { - QWidget::mousePressEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADmousePressEvent(v, x_prev, y_prev, e)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - -#ifdef USE_QT6 - x_press_pos = e->position().x(); - y_press_pos = e->position().y(); -#else - x_press_pos = (double)e->x(); - y_press_pos = (double)e->y(); -#endif - bu_log("X,Y: %g, %g\n", x_press_pos, y_press_pos); - - QWidget::mousePressEvent(e); -} - -void QtSW::mouseReleaseEvent(QMouseEvent *e) { - - // To avoid an abrupt jump in scene motion the next time movement is - // started with the mouse, after we release we return to the default state. - x_prev = -INT_MAX; - y_prev = -INT_MAX; - - if (CADmouseReleaseEvent(v, x_press_pos, y_press_pos, x_prev, y_prev, e, lmouse_mode)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QWidget::mouseReleaseEvent(e); -} - - -void QtSW::mouseMoveEvent(QMouseEvent *e) -{ - if (!dmp || !current || !use_default_mousebindings) { - QWidget::mouseMoveEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADmouseMoveEvent(v, x_prev, y_prev, e, lmouse_mode)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - // Current positions are the new previous positions -#ifdef USE_QT6 - x_prev = e->position().x(); - y_prev = e->position().y(); -#else - x_prev = e->x(); - y_prev = e->y(); -#endif - - QWidget::mouseMoveEvent(e); -} - -void QtSW::wheelEvent(QWheelEvent *e) { - - if (!dmp || !current || !use_default_mousebindings) { - QWidget::wheelEvent(e); - return; - } - - // Let bv know what the current view width and height are, in - // case the dx/dy mouse translations need that information - v->gv_width = width(); - v->gv_height = height(); - - if (CADwheelEvent(v, e)) { - dm_set_dirty(dmp, 1); - update(); - emit changed(); - } - - QWidget::wheelEvent(e); -} - -void QtSW::stash_hashes() -{ - if (!dmp) { - prev_dhash = 0; - } else { - prev_dhash = dm_hash(dmp); - } - prev_vhash = bv_hash(v); -} - -bool QtSW::diff_hashes() -{ - bool ret = false; - unsigned long long c_dhash = 0; - unsigned long long c_vhash = 0; - - if (dmp) { - c_dhash = dm_hash(dmp); - } - if (v) { - c_vhash = bv_hash(v); - } - - if (dmp && dm_get_dirty(dmp)) - ret = true; - - if (prev_dhash != c_dhash) { - if (dmp) - dm_set_dirty(dmp, 1); - ret = true; - } - if (prev_vhash != c_vhash) { - if (dmp) - dm_set_dirty(dmp, 1); - ret = true; - } - - if (ret) { - need_update(); - emit changed(); - } - - return ret; -} - -void QtSW::save_image() { - // Set up a QImage with the rendered output.. - unsigned char *dm_image; - if (dm_get_display_image(dmp, &dm_image, 1, 1)) { - return; - } - QImage image(dm_image, dm_get_width(dmp), dm_get_height(dmp), QImage::Format_RGBA8888); - QImage img32 = image.convertToFormat(QImage::Format_RGB32); - img32.save("file.png"); -} - -void QtSW::aet(double a, double e, double t) -{ - fastf_t aet[3]; - double aetd[3]; - aetd[0] = a; - aetd[1] = e; - aetd[2] = t; - - /* convert from double to fastf_t */ - VMOVE(aet, aetd); - - VMOVE(v->gv_aet, aet); - - /* TODO - based on the suspect bv_mat_aet... */ - mat_t tmat; - fastf_t twist; - fastf_t c_twist; - fastf_t s_twist; - bn_mat_angles(v->gv_rotation, 270.0 + v->gv_aet[1], 0.0, 270.0 - v->gv_aet[0]); - twist = -v->gv_aet[2] * DEG2RAD; - c_twist = cos(twist); - s_twist = sin(twist); - bn_mat_zrot(tmat, s_twist, c_twist); - bn_mat_mul2(tmat, v->gv_rotation); - - bv_update(v); -} - -void -QtSW::enableDefaultKeyBindings() -{ - use_default_keybindings = true; -} - -void -QtSW::disableDefaultKeyBindings() -{ - use_default_keybindings = false; -} - -void -QtSW::enableDefaultMouseBindings() -{ - use_default_mousebindings = true; -} - -void -QtSW::disableDefaultMouseBindings() -{ - use_default_mousebindings = false; -} - -void -QtSW::set_lmouse_move_default(int mm) -{ - lmouse_mode = mm; -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/src/libqtcad/bindings.cpp b/src/libqtcad/bindings.cpp index 844d3ae5ea0..192a71b598e 100644 --- a/src/libqtcad/bindings.cpp +++ b/src/libqtcad/bindings.cpp @@ -24,6 +24,7 @@ */ #include "common.h" +#include extern "C" { #include "bn/str.h" @@ -31,12 +32,14 @@ extern "C" { #include "bv/util.h" } +#include "qtcad/defines.h" #include "bindings.h" // TODO - look into QShortcut, see if it might be a better way // to manage this int CADkeyPressEvent(struct bview *v, int UNUSED(x_prev), int UNUSED(y_prev), QKeyEvent *k) { + QTCAD_EVENT("keyPress", 1); if (!v) return 0; #if 0 @@ -120,6 +123,7 @@ int CADkeyPressEvent(struct bview *v, int UNUSED(x_prev), int UNUSED(y_prev), QK int CADmousePressEvent(struct bview *v, int UNUSED(x_prev), int UNUSED(y_prev), QMouseEvent *e) { + QTCAD_EVENT("mousePress", 1); if (!v) return 0; @@ -136,13 +140,13 @@ int CADmousePressEvent(struct bview *v, int UNUSED(x_prev), int UNUSED(y_prev), } if (e->buttons().testFlag(Qt::LeftButton)) { - bu_log("Press Left\n"); + //bu_log("Press Left\n"); } if (e->buttons().testFlag(Qt::RightButton)) { - bu_log("Press Right\n"); + //bu_log("Press Right\n"); } if (e->buttons().testFlag(Qt::MiddleButton)) { - bu_log("Press Middle\n"); + //bu_log("Press Middle\n"); } return 0; @@ -150,6 +154,7 @@ int CADmousePressEvent(struct bview *v, int UNUSED(x_prev), int UNUSED(y_prev), int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UNUSED(x_prev), int UNUSED(y_prev), QMouseEvent *e, int mode) { + QTCAD_EVENT("mouseRelease", 1); if (!v) return 0; @@ -169,12 +174,12 @@ int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UN } double cx, cy; -#ifdef USE_QT6 - cx = e->position().x(); - cy = e->position().y(); -#else +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) cx = (double)e->x(); cy = (double)e->y(); +#else + cx = e->position().x(); + cy = e->position().y(); #endif if ((fabs(cx - x_press) > 10) || (fabs(cy - y_press) > 10)) return 0; @@ -184,7 +189,7 @@ int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UN unsigned long long view_flags = BV_IDLE; if (e->button() == Qt::LeftButton) { - bu_log("Release Left\n"); + //bu_log("Release Left\n"); if (mode != BV_CENTER) { view_flags = BV_SCALE; dx = 10; @@ -196,7 +201,7 @@ int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UN } } if (e->button() == Qt::RightButton) { - bu_log("Release Right\n"); + //bu_log("Release Right\n"); if (mode == BV_CENTER) return 0; view_flags = BV_SCALE; @@ -205,7 +210,7 @@ int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UN } if (e->button() == Qt::MiddleButton) { - bu_log("Release Center\n"); + //bu_log("Release Center\n"); view_flags = BV_CENTER; dx = (int)cx; dy = (int)cy; @@ -217,6 +222,7 @@ int CADmouseReleaseEvent(struct bview *v, double x_press, double y_press, int UN int CADmouseMoveEvent(struct bview *v, int x_prev, int y_prev, QMouseEvent *e, int mode) { + QTCAD_EVENT("mouseMove", 2); if (!v) return 0; @@ -234,41 +240,41 @@ int CADmouseMoveEvent(struct bview *v, int x_prev, int y_prev, QMouseEvent *e, i view_flags = BV_SCALE; if (e->buttons().testFlag(Qt::LeftButton)) { - bu_log("Left\n"); + //bu_log("Left\n"); if (e->modifiers().testFlag(Qt::ControlModifier)) { - bu_log("Ctrl+Left\n"); + //bu_log("Ctrl+Left\n"); view_flags = BV_ROT; } if (e->modifiers().testFlag(Qt::ShiftModifier)) { - bu_log("Shift+Left\n"); + //bu_log("Shift+Left\n"); view_flags = BV_TRANS; } if (e->modifiers().testFlag(Qt::ShiftModifier) && e->modifiers().testFlag(Qt::ControlModifier)) { - bu_log("Ctrl+Shift+Left\n"); + //bu_log("Ctrl+Shift+Left\n"); view_flags = BV_SCALE; } } if (e->buttons().testFlag(Qt::MiddleButton)) { - bu_log("Middle\n"); + //bu_log("Middle\n"); } if (e->buttons().testFlag(Qt::RightButton)) { - bu_log("Right\n"); + //bu_log("Right\n"); } if (!e->buttons().testFlag(Qt::LeftButton)) return 0; -#ifdef USE_QT6 - int dx = e->position().x() - x_prev; - int dy = e->position().y() - y_prev; -#else +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) int dx = e->x() - x_prev; int dy = e->y() - y_prev; +#else + int dx = e->position().x() - x_prev; + int dy = e->position().y() - y_prev; #endif if (view_flags == BV_SCALE) { @@ -300,6 +306,7 @@ int CADmouseMoveEvent(struct bview *v, int x_prev, int y_prev, QMouseEvent *e, i int CADwheelEvent(struct bview *v, QWheelEvent *e) { + QTCAD_EVENT("mouseWheel", 1); if (!v) return 0; diff --git a/src/libqtcad/gInstance.cpp b/src/libqtcad/gInstance.cpp deleted file mode 100644 index a1e675c7bbc..00000000000 --- a/src/libqtcad/gInstance.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/* G I N S T A N C E . C P P - * BRL-CAD - * - * Copyright (c) 2014-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file gInstance.cpp - * - * Lowest level expression of BRL-CAD .g instance data. - * - * The gInstance container translates implicit .g object instances into - * explicit data that can be referenced by higher level model constructs. - */ - -#include "common.h" - -#include -#include - -#define XXH_STATIC_LINKING_ONLY -#define XXH_IMPLEMENTATION -#include "xxhash.h" - -#include "bu/env.h" -#include "bu/sort.h" -#include "raytrace.h" -#include "qtcad/gInstance.h" - -unsigned long long -ginstance_hash(struct directory *parent, std::string &dp_name, struct db_i *dbip, db_op_t op, mat_t c_m, int cnt) -{ - XXH64_state_t h_state; - XXH64_hash_t hash_val; - XXH64_reset(&h_state, 0); - - // Make sure the hash is tied to a particular database - XXH64_update(&h_state, &dbip, sizeof(struct db_i *)); - - // For uniqueness - XXH64_update(&h_state, &cnt, sizeof(int)); - - if (parent) - XXH64_update(&h_state, parent->d_namep, strlen(parent->d_namep)); - // We use dp_name instead of the dp because we want the same hash - // whether we have a dp or an invalid comb entry - the hash lookup - // should return both with the same key. - if (dp_name.length()) - XXH64_update(&h_state, dp_name.c_str(), dp_name.length()); - - int int_op = 0; - switch (op) { - case DB_OP_UNION: - int_op = 1; - break; - case DB_OP_SUBTRACT: - int_op = 2; - break; - case DB_OP_INTERSECT: - int_op = 3; - break; - default: - int_op = 0; - break; - } - XXH64_update(&h_state, &int_op, sizeof(int)); - XXH64_update(&h_state, c_m, sizeof(mat_t)); - - hash_val = XXH64_digest(&h_state); - XXH64_reset(&h_state, 0); - - return (unsigned long long)hash_val; -} - - -gInstance::gInstance(struct directory *idp, struct db_i *idbip) -{ - dp = idp; - dbip = idbip; -} - -gInstance::~gInstance() -{ -} - -std::string -gInstance::print() -{ - std::string s; - if (parent) { - s.append(std::string(parent->d_namep)); - s.append(std::string(" ->")); - } - switch (op) { - case DB_OP_UNION: - s.append(std::string(" u ")); - break; - case DB_OP_SUBTRACT: - s.append(std::string(" - ")); - break; - case DB_OP_INTERSECT: - s.append(std::string(" + ")); - break; - default: - bu_log("Warning - unknown op"); - break; - } - if (!bn_mat_is_identity(c_m)) { - s.append(std::string("[M]")); - } - s.append(dp_name); - if (!dp) { - s.append(std::string("[missing]")); - } - - return s; -} - -static void -add_g_instance(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_leaf, int tree_op, void *pdp, void *inst_map, void *vchash, void *val_inst, void *c_map) -{ - std::unordered_map::iterator i_it; - - // Validate - if (comb) RT_CK_COMB(comb); - RT_CK_TREE(comb_leaf); - - // Unpack - std::unordered_map *instances = (std::unordered_map *)inst_map; - std::unordered_map *valid_instances = (std::unordered_map *)val_inst; - std::unordered_map *c_inst_map = (std::unordered_map *)c_map; - struct directory *parent_dp = (struct directory *)pdp; - std::vector *chash = (std::vector *)vchash; - - // Translate the op into the db_op_t type - struct directory *dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_QUIET); - db_op_t op = DB_OP_UNION; - if (tree_op == OP_SUBTRACT) { - op = DB_OP_SUBTRACT; - } - if (tree_op == OP_INTERSECT) { - op = DB_OP_INTERSECT; - } - - // We need to do the lookup to see if we already have this instance stored - // - to do the lookup we need the hash. - mat_t c_m; - MAT_IDN(c_m); - std::string dp_name(comb_leaf->tr_l.tl_name); - - // The c_inst_map exists only for this tree walk, and its purpose is to ensure that all comb - // instances get their correct index - (*c_inst_map)[std::string(comb_leaf->tr_l.tl_name)]++; - int icnt = (*c_inst_map)[std::string(comb_leaf->tr_l.tl_name)] - 1; - - if (comb_leaf->tr_l.tl_mat) { - MAT_COPY(c_m, comb_leaf->tr_l.tl_mat); - } - unsigned long long nhash = ginstance_hash(parent_dp, dp_name, dbip, op, c_m, icnt); - - // See if we already have this gInstance hash or not. If not, - // create and add a new gInstance. - i_it = instances->find(nhash); - if (i_it == instances->end()) { - gInstance *ninst = new gInstance(dp, dbip); - ninst->parent = parent_dp; - ninst->hash = nhash; - ninst->dp_name = std::string(comb_leaf->tr_l.tl_name); - ninst->op = op; - ninst->icnt = icnt; - MAT_COPY(ninst->c_m, c_m); - (*instances)[nhash] = ninst; - if (valid_instances) - (*valid_instances)[nhash] = ninst; - } else { - if (valid_instances) - (*valid_instances)[i_it->first] = i_it->second; - } - - // If we're collecting child hashes of the dp, push the hash onto the - // vector to denote it as a child of the parent. - if (chash) - (*chash).push_back(nhash); -} - -/* db_tree_funcleaf is almost what we need here, but not quite - it doesn't - * pass quite enough information. We need the parent op as well. */ -static void -db_tree_opleaf( - struct db_i *dbip, - struct rt_comb_internal *comb, - union tree *comb_tree, - int op, - void (*leaf_func)(struct db_i *, struct rt_comb_internal *, union tree *, int, - void *, void *, void *, void *, void *), - void *user_ptr1, - void *user_ptr2, - void *user_ptr3, - void *user_ptr4, - void *user_ptr5 - ) -{ - RT_CK_DBI(dbip); - - if (!comb_tree) - return; - - RT_CK_TREE(comb_tree); - - switch (comb_tree->tr_op) { - case OP_DB_LEAF: - leaf_func(dbip, comb, comb_tree, op, user_ptr1, user_ptr2, user_ptr3, user_ptr4, user_ptr5); - break; - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - db_tree_opleaf(dbip, comb, comb_tree->tr_b.tb_left, OP_UNION, leaf_func, user_ptr1, user_ptr2, user_ptr3, user_ptr4, user_ptr5); - db_tree_opleaf(dbip, comb, comb_tree->tr_b.tb_right, comb_tree->tr_op, leaf_func, user_ptr1, user_ptr2, user_ptr3, user_ptr4, user_ptr5); - break; - default: - bu_log("db_tree_opleaf: bad op %d\n", comb_tree->tr_op); - bu_bomb("db_tree_opleaf: bad op\n"); - break; - } -} - -bool -gInstance::has_children() -{ - if (!dp) - return false; - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_COMBINATION) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return false; - if (intern.idb_type != ID_COMBINATION) - return false; - struct rt_comb_internal *comb = (struct rt_comb_internal *)intern.idb_ptr; - if (!comb->tree) - return false; - if (!db_tree_nleaves(comb->tree)) - return false; - return true; - } - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) - return true; - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_REVOLVE) - return true; - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP) - return true; - - return false; -} - -std::vector -gInstance::children(std::unordered_map *instances) -{ - std::vector chash; - if (!dp) - return chash; - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_COMBINATION) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return chash; - if (intern.idb_type != ID_COMBINATION) { - bu_log("NOTICE: %s was marked a combination, but isn't one? Clearing flag\n", dp->d_namep); - dp->d_flags &= ~RT_DIR_COMB; - rt_db_free_internal(&intern); - return chash; - } - - // We do NOT want to entangle the details of the .g comb tree storage - // into the model logic; instead we use the librt tree walkers to - // populate data containers more friendly to the Qt data model. This - // does introduce resource overhead, and someday we may be able figure - // out something more clever to be leaner, but at least in the early - // stages Qt models offer enough complexity without trying to do - // anything cute with the librt comb data containers. Because we are - // only concerned with the immediate comb's children and not the full - // tree, all objects are leaves and we can use db_tree_opleaf - std::unordered_map *cinst_map = new std::unordered_map; - struct rt_comb_internal *comb = (struct rt_comb_internal *)intern.idb_ptr; - db_tree_opleaf(dbip, comb, comb->tree, OP_UNION, add_g_instance, (void *)dp, (void *)instances, (void *)&chash, NULL, cinst_map); - rt_db_free_internal(&intern); - delete cinst_map; - return chash; - } - - std::unordered_map::iterator i_it; - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return chash; - struct rt_extrude_internal *extr = (struct rt_extrude_internal *)intern.idb_ptr; - RT_EXTRUDE_CK_MAGIC(extr); - if (extr->sketch_name) { - std::string sk_name(extr->sketch_name); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, sk_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - chash.push_back(nhash); - } - } - return chash; - } - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_REVOLVE) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return chash; - struct rt_revolve_internal *revolve = (struct rt_revolve_internal *)intern.idb_ptr; - RT_REVOLVE_CK_MAGIC(revolve); - if (bu_vls_strlen(&revolve->sketch_name) > 0) { - std::string sk_name(bu_vls_cstr(&revolve->sketch_name)); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, sk_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - chash.push_back(nhash); - } - } - return chash; - } - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return chash; - struct rt_dsp_internal *dsp = (struct rt_dsp_internal *)intern.idb_ptr; - RT_DSP_CK_MAGIC(dsp); - if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen(&dsp->dsp_name) > 0) { - std::string dsp_name(bu_vls_cstr(&dsp->dsp_name)); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, dsp_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - chash.push_back(nhash); - } - } - return chash; - } - - return chash; -} - -static void -dp_instances(std::unordered_map *valid_instances, std::unordered_map *instances, struct directory *dp, struct db_i *dbip) -{ - mat_t c_m; - std::unordered_map::iterator i_it; - - if (dp->d_flags & RT_DIR_HIDDEN) - return; - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return; - struct rt_extrude_internal *extr = (struct rt_extrude_internal *)intern.idb_ptr; - RT_EXTRUDE_CK_MAGIC(extr); - if (extr->sketch_name) { - std::string sk_name(extr->sketch_name); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, sk_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - if (valid_instances) - (*valid_instances)[i_it->first] = i_it->second; - rt_db_free_internal(&intern); - return; - } - gInstance *ninst = new gInstance(db_lookup(dbip, extr->sketch_name, LOOKUP_QUIET), dbip); - ninst->parent = dp; - ninst->hash = nhash; - ninst->dp_name = std::string(extr->sketch_name); - MAT_IDN(ninst->c_m); - ninst->op = DB_OP_UNION; - (*instances)[nhash] = ninst; - if (valid_instances) - (*valid_instances)[nhash] = ninst; - } - rt_db_free_internal(&intern); - return; - } - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_REVOLVE) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return; - struct rt_revolve_internal *revolve = (struct rt_revolve_internal *)intern.idb_ptr; - RT_REVOLVE_CK_MAGIC(revolve); - if (bu_vls_strlen(&revolve->sketch_name) > 0) { - std::string sk_name(bu_vls_cstr(&revolve->sketch_name)); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, sk_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - if (valid_instances) - (*valid_instances)[i_it->first] = i_it->second; - rt_db_free_internal(&intern); - return; - } - gInstance *ninst = new gInstance(db_lookup(dbip, bu_vls_cstr(&revolve->sketch_name), LOOKUP_QUIET), dbip); - ninst->parent = dp; - ninst->hash = nhash; - ninst->dp_name = std::string(bu_vls_cstr(&revolve->sketch_name)); - MAT_IDN(ninst->c_m); - ninst->op = DB_OP_UNION; - (*instances)[nhash] = ninst; - if (valid_instances) - (*valid_instances)[nhash] = ninst; - } - rt_db_free_internal(&intern); - return; - } - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return; - struct rt_dsp_internal *dsp = (struct rt_dsp_internal *)intern.idb_ptr; - RT_DSP_CK_MAGIC(dsp); - if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen(&dsp->dsp_name) > 0) { - std::string dsp_name(bu_vls_cstr(&dsp->dsp_name)); - MAT_IDN(c_m); - unsigned long long nhash = ginstance_hash(dp, dsp_name, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it != instances->end()) { - if (valid_instances) - (*valid_instances)[i_it->first] = i_it->second; - rt_db_free_internal(&intern); - return; - } - gInstance *ninst = new gInstance(db_lookup(dbip, bu_vls_cstr(&dsp->dsp_name), LOOKUP_QUIET), dbip); - ninst->parent = dp; - ninst->hash = nhash; - ninst->dp_name = std::string(bu_vls_cstr(&dsp->dsp_name)); - MAT_IDN(ninst->c_m); - ninst->op = DB_OP_UNION; - (*instances)[nhash] = ninst; - if (valid_instances) - (*valid_instances)[nhash] = ninst; - } - rt_db_free_internal(&intern); - return; - } - - if (dp->d_minor_type == DB5_MINORTYPE_BRLCAD_COMBINATION) { - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) - return; - if (intern.idb_type != ID_COMBINATION) { - bu_log("NOTICE: %s was marked a combination, but isn't one? Clearing flag\n", dp->d_namep); - dp->d_flags &= ~RT_DIR_COMB; - rt_db_free_internal(&intern); - return; - } - - std::unordered_map *cinst_map = new std::unordered_map; - struct rt_comb_internal *comb = (struct rt_comb_internal *)intern.idb_ptr; - db_tree_opleaf(dbip, comb, comb->tree, OP_UNION, add_g_instance, (void *)dp, (void *)instances, NULL, (void *)valid_instances, cinst_map); - delete cinst_map; - rt_db_free_internal(&intern); - return; - } -} - -void -sync_instances( - std::unordered_map *tops_instances, - std::unordered_map *instances, - struct db_i *dbip, int flatten) -{ - - if (!dbip) { - // If we don't have a dbip, our job is just to clear out everything - for (size_t i = 0; i < instances->size(); i++) { - delete (*instances)[i]; - } - instances->clear(); - tops_instances->clear(); - return; - } - - std::unordered_map::iterator i_it; - std::unordered_map valid_instances; - - // Run through the objects and crack the non-leaf objects to define - // non-tops instances (i.e. all comb instances and some primitive - // types that reference other objects). By definition the instances - // either present or created in this pass are the valid instances. - // - // This routine will collect all instances that are NOT tops instances. - // Because tops instances are not below any other object, they must be - // handled as implicit instances under the "root" .g, which requires a - // slightly different setup as well as identifying the objects in question. - for (int i = 0; i < RT_DBNHASH; i++) { - struct directory *dp; - for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) { - if (dp->d_flags & (RT_DIR_SOLID|RT_DIR_COMB)) - dp_instances(&valid_instances, instances, dp, dbip); - } - } - - // We have to go through the work of figuring this out anyway - just rebuild - // the tops set cleanly each time - tops_instances->clear(); - - // To do a flat, "ls" style tree, all we need to do is switch the above - // db_ls filters to the unfiltered version. Otherwise, we want the TOPS - // list and any cyclic objects (which will be invisible to tops) - struct directory **db_objects = NULL; - int path_cnt = 0; - if (flatten) { - path_cnt = db_ls(dbip, 0, NULL, &db_objects); - } else { - path_cnt = db_ls(dbip, DB_LS_TOPS | DB_LS_CYCLIC , NULL, &db_objects); - } - - if (path_cnt) { - mat_t c_m; - MAT_IDN(c_m); - for (int i = 0; i < path_cnt; i++) { - gInstance *tinst = NULL; - struct directory *curr_dp = db_objects[i]; - std::string dname = std::string(curr_dp->d_namep); - unsigned long long nhash = ginstance_hash(NULL, dname, dbip, DB_OP_UNION, c_m, 0); - i_it = instances->find(nhash); - if (i_it == instances->end()) { - tinst = new gInstance(curr_dp, dbip); - tinst->parent = NULL; - tinst->hash = nhash; - tinst->dp_name = std::string(curr_dp->d_namep); - tinst->op = DB_OP_UNION; - MAT_IDN(tinst->c_m); - (*instances)[nhash] = tinst; - } else { - tinst = i_it->second; - } - (*tops_instances)[nhash] = tinst; - - // tops instances are valid - valid_instances[nhash] = tinst; - } - } - bu_free(db_objects, "tops obj list"); - - // instances now holds both the invalid and the valid instances. To identify - // and remove the invalid ones, we do a set difference. - std::vector removed; - std::vector removed_hashes; - for (i_it = instances->begin(); i_it != instances->end(); i_it++) { - if (valid_instances.find(i_it->first) == valid_instances.end()) { - removed_hashes.push_back(i_it->first); - removed.push_back(i_it->second); - } - } - for (size_t i = 0; i < removed_hashes.size(); i++) { - instances->erase(removed_hashes[i]); - } - for (size_t i = 0; i < removed.size(); i++) { - delete removed[i]; - } -} - -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 - diff --git a/src/libqtcad/tests/CMakeLists.txt b/src/libqtcad/tests/CMakeLists.txt index 52fbc21b052..d85fbe71cf8 100644 --- a/src/libqtcad/tests/CMakeLists.txt +++ b/src/libqtcad/tests/CMakeLists.txt @@ -10,39 +10,45 @@ set(QG_DIRS ) BRLCAD_INCLUDE_DIRS(QG_DIRS) -if (BRLCAD_ENABLE_QT) +set(QGMODEL_SRCS qgmodel.cpp) +set(QGVIEW_SRCS qgview.cpp) +if (TARGET Qt6::Test) add_executable(qgmodel qgmodel.cpp) - if (Qt6Widgets_FOUND) - target_link_libraries(qgmodel libqtcad libged librt libbu Qt6::Widgets) - else() - target_link_libraries(qgmodel libqtcad libged librt libbu Qt5::Widgets) - endif (Qt6Widgets_FOUND) + target_link_libraries(qgmodel libqtcad libged librt libbu Qt6::Widgets Qt6::Test) +endif (TARGET Qt6::Test) +if (TARGET Qt5::Test) + add_executable(qgmodel ${QGMODEL_SRCS}) + target_link_libraries(qgmodel libqtcad libged librt libbu Qt5::Widgets Qt5::Test) +endif (TARGET Qt5::Test) +if (TARGET qgmodel) target_compile_definitions(qgmodel PRIVATE BRLCADBUILD HAVE_CONFIG_H) install(TARGETS qgmodel RUNTIME DESTINATION ${BIN_DIR} LIBRARY DESTINATION ${LIB_DIR} ARCHIVE DESTINATION ${LIB_DIR}) - - add_executable(qgview qgview.cpp) - if (Qt6Widgets_FOUND) - target_link_libraries(qgview libqtcad libged librt libbu Qt6::Widgets) - else() - target_link_libraries(qgview libqtcad libged librt libbu Qt5::Widgets) - endif (Qt6Widgets_FOUND) +endif (TARGET qgmodel) + +if (TARGET Qt6::Widgets) + add_executable(qgview ${QGVIEW_SRCS}) + target_link_libraries(qgview libqtcad libged librt libbu Qt6::Widgets) +endif (TARGET Qt6::Widgets) +if (TARGET Qt5::Widgets) + add_executable(qgview ${QGVIEW_SRCS}) + target_link_libraries(qgview libqtcad libged librt libbu Qt5::Widgets) +endif (TARGET Qt5::Widgets) +if (TARGET qgview) target_compile_definitions(qgview PRIVATE BRLCADBUILD HAVE_CONFIG_H) install(TARGETS qgview RUNTIME DESTINATION ${BIN_DIR} LIBRARY DESTINATION ${LIB_DIR} ARCHIVE DESTINATION ${LIB_DIR}) - -endif (BRLCAD_ENABLE_QT) - +endif (TARGET qgview) CMAKEFILES( CMakeLists.txt - qgmodel.cpp - qgview.cpp + ${QGMODEL_SRCS} + ${QGVIEW_SRCS} ) # Local Variables: diff --git a/src/libqtcad/tests/qgmodel.cpp b/src/libqtcad/tests/qgmodel.cpp index 662649e08cc..0a98cb121d4 100644 --- a/src/libqtcad/tests/qgmodel.cpp +++ b/src/libqtcad/tests/qgmodel.cpp @@ -23,9 +23,13 @@ * */ +#include "common.h" #include #include #include +#ifdef USE_QTTEST +# include +#endif #include "bu/app.h" #include "bu/log.h" @@ -45,8 +49,6 @@ open_children(QgItem *itm, QgModel *s, int depth, int max_depth) for (size_t j = 0; j < itm->children.size(); j++) { QgItem *c = itm->child(j); - if (s->instances->find(c->ihash) == s->instances->end()) - continue; open_children(c, s, depth+1, max_depth); } } @@ -78,12 +80,6 @@ print_children(QgItem *itm, QgModel *s, int depth) if (!itm || !itm->ihash) return; - gInstance *inst; - if (depth == 0) { - inst = (*s->tops_instances)[itm->ihash]; - } else { - inst = (*s->instances)[itm->ihash]; - } for (int i = 0; i < depth; i++) { std::cout << " "; @@ -91,12 +87,14 @@ print_children(QgItem *itm, QgModel *s, int depth) if (depth) std::cout << "* "; - std::cout << inst->dp_name << "\n"; + struct bu_vls path_str = BU_VLS_INIT_ZERO; + std::vector path_hashes = itm->path_items(); + itm->mdl->gedp->dbi_state->print_hash(&path_str, path_hashes[path_hashes.size()-1]); + std::cout << bu_vls_cstr(&path_str) << "\n"; + bu_vls_free(&path_str); for (size_t j = 0; j < itm->children.size(); j++) { QgItem *c = itm->child(j); - if (s->instances->find(c->ihash) == s->instances->end()) - continue; if (!itm->open_itm) { continue; @@ -130,8 +128,10 @@ int main(int argc, char *argv[]) QgModel sm(NULL, argv[0]); QgModel *s = &sm; - bu_log("Hierarchy instance cnt: %zd\n", s->instances->size()); - bu_log("Top instance cnt: %zd\n", s->tops_instances->size()); +#ifdef USE_QTTEST + //QAbstractItemModelTester *tester = new QAbstractItemModelTester((QAbstractItemModel *)s, QAbstractItemModelTester::FailureReportingMode::Fatal); + QAbstractItemModelTester *tester = new QAbstractItemModelTester((QAbstractItemModel *)s, QAbstractItemModelTester::FailureReportingMode::Warning); +#endif // 2. Implement "open" and "close" routines for the items that will exercise // the logic to identify, populate, and clear items based on child info. @@ -189,6 +189,7 @@ int main(int argc, char *argv[]) av[2] = "ellipse.r"; av[3] = NULL; ged_exec(g, ac, (const char **)av); + s->g_update(g->dbip); std::cout << "\nRemoved ellipse.r from all.g:\n"; print_tops(s); @@ -198,6 +199,7 @@ int main(int argc, char *argv[]) av[2] = "ellipse.r"; av[3] = NULL; ged_exec(g, ac, (const char **)av); + s->g_update(g->dbip); std::cout << "\nAdded ellipse.r back to the end of all.g, no call to open:\n"; print_tops(s); @@ -212,6 +214,8 @@ int main(int argc, char *argv[]) av[2] = "tor"; av[3] = NULL; ged_exec(g, ac, (const char **)av); + s->g_update(g->dbip); + std::cout << "\ntops tree after removing tor from tor.r:\n"; print_tops(s); @@ -220,6 +224,7 @@ int main(int argc, char *argv[]) av[2] = "all.g"; av[3] = NULL; ged_exec(g, ac, (const char **)av); + s->g_update(g->dbip); std::cout << "\ntops tree after deleting all.g:\n"; print_tops(s); @@ -239,6 +244,7 @@ int main(int argc, char *argv[]) i++; obj = objs[i]; } + s->g_update(g->dbip); std::cout << "\ntops tree after deleting everything:\n"; print_tops(s); @@ -246,6 +252,9 @@ int main(int argc, char *argv[]) open_tops(s, -1); print_tops(s); +#ifdef USE_QTTEST + delete tester; +#endif // TODO - so the rough progression of steps here is: // @@ -262,7 +271,7 @@ int main(int argc, char *argv[]) // structure to verify. // - return (*s->instances).size(); + return -1; } /* diff --git a/src/libqtcad/tests/qgview.cpp b/src/libqtcad/tests/qgview.cpp index 0ca29bd5ef9..4feaff506d2 100644 --- a/src/libqtcad/tests/qgview.cpp +++ b/src/libqtcad/tests/qgview.cpp @@ -46,8 +46,6 @@ open_children(QgItem *itm, QgModel *s, int depth, int max_depth) itm->open(); for (int j = 0; j < itm->childCount(); j++) { QgItem *c = itm->child(j); - if (s->instances->find(c->ihash) == s->instances->end()) - continue; open_children(c, s, depth+1, max_depth); } } diff --git a/src/librt/CMakeLists.txt b/src/librt/CMakeLists.txt index 9cee582612a..b4b948298a1 100644 --- a/src/librt/CMakeLists.txt +++ b/src/librt/CMakeLists.txt @@ -38,6 +38,7 @@ set(LIBRT_SOURCES binunif/binunif.c binunif/db5_bin.c bool.c + bool_tess.c bundle.c cache.c cache_lz4.c @@ -379,7 +380,7 @@ if(BRLCAD_ENABLE_SPR) endif(BRLCAD_ENABLE_SPR) -BRLCAD_ADDLIB(librt "${LIBRT_SOURCES}" "${OPENCL_LIBS};libbrep;libnmg;libbg;libbv;libbn;libbu;${OPENNURBS_LIBRARIES};${REGEX_LIBRARIES};${WINSOCK_LIB};${RPCRT_LIB};${STDCXX_LIBRARIES}") +BRLCAD_ADDLIB(librt "${LIBRT_SOURCES}" "${OPENCL_LIBS};${librt_deps};${OPENNURBS_LIBRARIES};${REGEX_LIBRARIES};${WINSOCK_LIB};${RPCRT_LIB};${STDCXX_LIBRARIES}") # set(MATERIALX_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/../../../MaterialXSource/lib/MaterialXCore.lib;${CMAKE_CURRENT_SOURCE_DIR}/../../../MaterialXSource/lib/MaterialXFormat.lib;${CMAKE_CURRENT_SOURCE_DIR}/../../../MaterialXSource/lib/MaterialXGenOsl.lib;${CMAKE_CURRENT_SOURCE_DIR}/../../../MaterialXSource/lib/MaterialXGenShader.lib) # BRLCAD_ADDLIB(librt "${LIBRT_SOURCES}" "${MATERIALX_LIBS};${OPENCL_LIBS};libbrep;libnmg;libbg;libbv;libbn;libbu;${OPENNURBS_LIBRARIES};${REGEX_LIBRARIES};${WINSOCK_LIB};${RPCRT_LIB};${STDCXX_LIBRARIES}") diff --git a/src/librt/attr.cpp b/src/librt/attr.cpp index 0bf351f971b..69ed989fdd7 100644 --- a/src/librt/attr.cpp +++ b/src/librt/attr.cpp @@ -21,13 +21,14 @@ * * Parsing logic for the ASCII v5 attr command. * - * Many of the attr subcommands are intended for interactive use, and as such - * would be a better conceptual fit for the LIBGED layer, but the BRL-CAD v5 - * ASCII .g serialization makes use of attr sub-commands to define its format. - * Consequently, the "attr" command is not only an interactive tool but also an - * integral part of the definition of one of the BRL-CAD geometry file formats - * - hence the inclusion of the logic defining this command in a lower level - * library. + * many of the attr subcommands are intended for interactive use, and + * as such would be a better conceptual fit for the LIBGED layer, but + * the BRL-CAD v5 ASCII .g serialization makes use of attr + * sub-commands to define its format. Consequently, the "attr" + * command is not only an interactive tool but also an integral part + * of the definition of one of the BRL-CAD geometry file formats - + * hence the inclusion of the logic defining this command in a lower + * level library. */ #include "common.h" @@ -50,6 +51,7 @@ #include "rt/search.h" #include "rt/wdb.h" + typedef enum { ATTR_APPEND, ATTR_COPY, @@ -171,6 +173,7 @@ attr_cmd(const char* arg) return ATTR_UNKNOWN; } + struct avsncmp { bool operator () (const std::pair &p_left, const std::pair &p_right) const { @@ -195,6 +198,7 @@ struct avsncmp { } }; + static int attr_list(struct bu_vls *msg, struct db_i *dbip, size_t path_cnt, struct directory **paths, int argc, const char **argv) { @@ -218,9 +222,11 @@ attr_list(struct bu_vls *msg, struct db_i *dbip, size_t path_cnt, struct directo } size_t j = 0; for (j = 0, avpp = lavs.avp; j < lavs.count; j++, avpp++) { - /* If we have a key-only filter, filter printing based on matching - * to that filter. If we also have a value filter, print the value as well according to value - * matches. */ + /* If we have a key-only filter, filter printing based on + * matching to that filter. If we also have a value + * filter, print the value as well according to value + * matches. + */ if (!argc) { uniq_avp.insert(std::make_pair(std::string(avpp->name), std::string(""))); continue; @@ -260,6 +266,7 @@ attr_list(struct bu_vls *msg, struct db_i *dbip, size_t path_cnt, struct directo return BRLCAD_OK; } + static void attr_print(struct bu_vls *msg, struct bu_attribute_value_set *avs, int argc, const char **argv) { @@ -270,7 +277,7 @@ attr_print(struct bu_vls *msg, struct bu_attribute_value_set *avs, int argc, con struct bu_attribute_value_pair *avpp; size_t i, j; /* If we don't have a specified set, do everything */ - /* find the max_attr_name_len */ + /* find the max_attr_name_len */ if (argc == 0 || !argv) { for (j = 0, avpp = avs->avp; j < avs->count; j++, avpp++) { size_t len = strlen(avpp->name); @@ -412,10 +419,12 @@ rt_cmd_attr(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) goto rt_attr_core_memfree; } if (argc == 3) { - /* just list the already sorted attribute-value pairs */ + /* just list already sorted attribute-value pairs */ attr_print(msg, &avs, 0, NULL); } else { - /* argv[3] is the sort type: 'case', 'nocase', 'value', 'value-nocase' */ + /* argv[3] is the sort type: 'case', 'nocase', + * 'value', 'value-nocase' + */ if (BU_STR_EQUIV(argv[3], NOCASE)) { bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp_nocase, NULL); } else if (BU_STR_EQUIV(argv[3], VALUE)) { @@ -423,7 +432,9 @@ rt_cmd_attr(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) } else if (BU_STR_EQUIV(argv[3], VALUE_NOCASE)) { bu_sort(&avs.avp[0], avs.count, sizeof(struct bu_attribute_value_pair), attr_cmp_value_nocase, NULL); } else if (BU_STR_EQUIV(argv[3], CASE)) { - ; /* don't need to do anything since this is the existing (default) sort */ + ; /* don't need to do anything since this is the + * existing (default) sort + */ } /* just list the already sorted attribute-value pairs */ attr_print(msg, &avs, 0, NULL); @@ -787,6 +798,7 @@ rt_cmd_attr(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) return ret; } + // Local Variables: // tab-width: 8 // mode: C++ diff --git a/src/librt/attributes.c b/src/librt/attributes.c index 44d86ee6405..8c2c34151e1 100644 --- a/src/librt/attributes.c +++ b/src/librt/attributes.c @@ -58,7 +58,8 @@ db5_import_attributes(struct bu_attribute_value_set *avs, const struct bu_extern } #if defined(USE_BINARY_ATTRIBUTES) /* Do we have binary attributes? If so, they are after the last - * ASCII attribute. */ + * ASCII attribute. + */ if (ep > (cp+1)) { /* Count binary attrs. */ /* format is: NULL */ @@ -70,9 +71,9 @@ db5_import_attributes(struct bu_attribute_value_set *avs, const struct bu_extern /* The next value is an unsigned integer of variable width * (a_width: DB5HDR_WIDTHCODE_x) so how do we get its * width? We now have a new member of struct bu_external: - * 'unsigned char widcode'. Note that the integer - * is in network order and must be properly decoded for - * the local architecture. + * 'unsigned char widcode'. Note that the integer is in + * network order and must be properly decoded for the + * local architecture. */ cp += db5_decode_length(&abinlen, (const unsigned char*)cp, ap->widcode); /* account for the abinlen bytes */ @@ -118,7 +119,9 @@ db5_import_attributes(struct bu_attribute_value_set *avs, const struct bu_extern /* Count binary attrs. */ /* format is: NULL */ size_t abinlen; - cp += 2; /* We are now at the first byte of the first binary attribute... */ + cp += 2; /* We are now at the first byte of the first binary + * attribute... + */ while (cp != ep) { const char *name = cp; /* name */ cp += strlen(cp)+1; /* name */ @@ -331,7 +334,9 @@ db5_update_attributes(struct directory *dp, struct bu_attribute_value_set *avsp, } } - // set the material_id field using the material given by the material_name field + /* set the material_id field using the material given by the + * material_name field + */ const char *material_name = bu_avs_get(avsp, "material_name"); if (material_name != NULL && !BU_STR_EQUAL(material_name, "(null)") && !BU_STR_EQUAL(material_name, "del")) { struct directory *material_dp = db_lookup(dbip, material_name, LOOKUP_QUIET); @@ -372,7 +377,7 @@ db5_update_attributes(struct directory *dp, struct bu_attribute_value_set *avsp, bu_free_external(&attr); bu_free_external(&ext2); - bu_free_external(&ext); /* 'raw' is now invalid */ + bu_free_external(&ext); /* 'raw' is now invalid */ bu_avs_free(&old_avs); bu_avs_free(avsp); @@ -414,7 +419,7 @@ int db5_update_ident(struct db_i *dbip, const char *title, double local2mm) bu_log("db5_update_ident() WARNING: %s object is missing, creating new one.\nYou may have lost important global state when you deleted this object.\n", DB5_GLOBAL_OBJECT_NAME); - /* OK, make one. It will be empty to start with, updated below. */ + /* OK, make one. Will be empty to start, updated below. */ db5_export_object3(&global, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT, DB5_GLOBAL_OBJECT_NAME, DB5HDR_HFLAGS_HIDDEN_OBJECT, NULL, NULL, @@ -441,8 +446,7 @@ int db5_update_ident(struct db_i *dbip, const char *title, double local2mm) bu_vls_free(&units); bu_avs_free(&avs); - /* protect from losing memory and from freeing what we are - about to dup */ + /* protect from losing memory & freeing what we're about to dup */ if (dbip->dbi_title) { old_title = dbip->dbi_title; } diff --git a/src/librt/bbox.c b/src/librt/bbox.c index 19d9db56e0c..abdc1010285 100644 --- a/src/librt/bbox.c +++ b/src/librt/bbox.c @@ -312,8 +312,9 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas /* Discard right rpp */ break; - /* This case is especially for handling rt_db_internal formats which generally contain a "unloaded" - * tree with tp->tr_op = OP_DB_LEAF + /* This case is especially for handling rt_db_internal + * formats which generally contain a "unloaded" tree with + * tp->tr_op = OP_DB_LEAF */ case OP_DB_LEAF: { @@ -331,8 +332,9 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas stp = rt_find_solid(rtip, tp->tr_l.tl_name); if (stp == NULL) { - /* It was a comb! get an internal format and repeat the whole thing that got us here - * in the 1st place + /* It was a comb! get an internal format and + * repeat the whole thing that got us here in the + * 1st place */ struct rt_db_internal intern; struct directory *dp; @@ -344,11 +346,14 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas return -1; } - /* Why does recursion work with the internal format ? - * The internal format does have the boolean op for a comb in the tr_a.tu_op field - * in the root node, even though it has no prims at the leaves. - * So recursive calls to load the prim further down the tree, will return the correct bb - * as we are going through the proper switch case in each step down the tree + /* Why does recursion work with the internal + * format ? The internal format does have the + * boolean op for a comb in the tr_a.tu_op field + * in the root node, even though it has no prims + * at the leaves. So recursive calls to load the + * prim further down the tree, will return the + * correct bb as we are going through the proper + * switch case in each step down the tree */ if (!rt_db_lookup_internal(rtip->rti_dbip, tp->tr_l.tl_name, &dp, &intern, LOOKUP_NOISY, &rt_uniresource)) { @@ -357,11 +362,15 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas return -1; } - /* The passed rt_db_internal should be a comb, prepare a rt_comb_internal */ + /* The passed rt_db_internal should be a comb, + * prepare a rt_comb_internal + */ if (intern.idb_minor_type == ID_COMBINATION) { combp = (struct rt_comb_internal *)intern.idb_ptr; } else { - /* if it's not a comb, then something else is cooking */ + /* if it's not a comb, then something else is + * cooking. + */ bu_log("rt_traverse_tree: WARNING : rt_db_lookup_internal(%s) got the internal form of a primitive when it should not, the bounds may not be correct", tp->tr_l.tl_name); return -1; } @@ -401,15 +410,16 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas return 0; } + int rt_bound_instance(point_t *bmin, point_t *bmax, - struct directory *dp, - struct db_i *dbip, - const struct bg_tess_tol *ttol, - const struct bn_tol *tol, - mat_t *s_mat, - struct resource *res - ) + struct directory *dp, + struct db_i *dbip, + const struct bg_tess_tol *ttol, + const struct bn_tol *tol, + mat_t *s_mat, + struct resource *res + ) { if (UNLIKELY(!bmin || !bmax || !dp || !dbip || !res)) return -1; @@ -429,10 +439,11 @@ rt_bound_instance(point_t *bmin, point_t *bmax, bbret = ip->idb_meth->ft_bbox(ip, bmin, bmax, tol); if (bbret < 0 && ip->idb_meth->ft_plot) { - /* As a fallback for primitives that don't have a bbox function, - * (there are still some as of 2021) use the old bounding method of - * calculating the default (non-adaptive) plot for the primitive - * and using the extent of the plotted segments as the bounds. + /* As a fallback for primitives that don't have a bbox + * function, (there are still some as of 2021) use the old + * bounding method of calculating the default (non-adaptive) + * plot for the primitive and using the extent of the plotted + * segments as the bounds. */ struct bu_list vhead; BU_LIST_INIT(&(vhead)); @@ -449,6 +460,7 @@ rt_bound_instance(point_t *bmin, point_t *bmax, return bbret; } + int rt_bound_internal(struct db_i *dbip, struct directory *dp, point_t rpp_min, point_t rpp_max) @@ -468,7 +480,9 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp, return -1; } - /* Call rt_gettree() to get the bounds for primitives, else soltab ptr is null */ + /* Call rt_gettree() to get the bounds for primitives, else soltab + * ptr is null + */ if (rt_gettree(rtip, dp->d_namep) < 0) { bu_log("rt_bound_internal: rt_gettree('%s') failed\n", dp->d_namep); rt_free_rti(rtip); @@ -482,11 +496,15 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp, return -1; } - /* If passed rt_db_internal is a combination(a group or a region) then further calls needed */ + /* If passed rt_db_internal is a combination(a group or a region) + * then further calls needed. + */ if (intern.idb_minor_type == ID_COMBINATION) { combp = (struct rt_comb_internal *)intern.idb_ptr; } else { - /* A primitive was passed, construct a struct rt_comb_internal with a single leaf node */ + /* A primitive was passed, construct a struct rt_comb_internal + * with a single leaf node. + */ BU_ALLOC(combp, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(combp); combp->region_flag = 0; @@ -512,7 +530,9 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp, VMOVE(rpp_min, tree_min); VMOVE(rpp_max, tree_max); - /* Check if the model bounds look correct e.g. if they are all 0, then it's not correct */ + /* Check if the model bounds look correct e.g. if they are all 0, + * then it's not correct. + */ if ((NEAR_ZERO(rpp_min[0], SMALL_FASTF) || rpp_min[0] <= -INFINITY || rpp_min[0] >= INFINITY) && (NEAR_ZERO(rpp_min[1], SMALL_FASTF) || rpp_min[1] <= -INFINITY || rpp_min[1] >= INFINITY) && (NEAR_ZERO(rpp_min[2], SMALL_FASTF) || rpp_min[2] <= -INFINITY || rpp_min[2] >= INFINITY) && diff --git a/src/librt/binunif/db5_bin.c b/src/librt/binunif/db5_bin.c index 29212c6259b..9ac61b45341 100644 --- a/src/librt/binunif/db5_bin.c +++ b/src/librt/binunif/db5_bin.c @@ -207,6 +207,8 @@ rt_binunif_export5(struct bu_external *ep, RT_CK_DB_INTERNAL(ip); bip = (struct rt_binunif_internal *)ip->idb_ptr; RT_CK_BINUNIF(bip); + if (bip->count <= 0) /* nothing to convert */ + return 0; BU_EXTERNAL_INIT(ep); diff --git a/src/librt/bool.c b/src/librt/bool.c index 659cb614b97..380f500c6ad 100644 --- a/src/librt/bool.c +++ b/src/librt/bool.c @@ -102,8 +102,9 @@ bool_weave0seg(struct seg *segp, struct partition *PartHdp, struct application * * Cases: seg at start of pt, in middle of pt, at end of pt, or * past end of pt but before start of next pt. * - * XXX For the first 3 cases, we might want to make a new 0-len pt, - * XXX especially as the NMG ray-tracer starts reporting wire hits. + * XXX For the first 3 cases, we might want to make a new 0-len + * pt, XXX especially as the NMG ray-tracer starts reporting wire + * hits. */ for (pp=PartHdp->pt_forw; pp != PartHdp; pp=pp->pt_forw) { if (NEAR_EQUAL(segp->seg_in.hit_dist, pp->pt_inhit->hit_dist, tol_dist) || @@ -286,8 +287,8 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s */ if (RT_G_DEBUG&RT_DEBUG_PARTITION) { bu_log("seg starts beyond last partition end. (%g, %g) Appending new partition\n", - PartHdp->pt_back->pt_inhit->hit_dist, - PartHdp->pt_back->pt_outhit->hit_dist); + PartHdp->pt_back->pt_inhit->hit_dist, + PartHdp->pt_back->pt_outhit->hit_dist); } GET_PT_INIT(rtip, pp, res); bu_ptbl_ins_unique(&pp->pt_seglist, (long *)segp); @@ -298,11 +299,11 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s APPEND_PT(pp, PartHdp->pt_back); } else { /* Loop through current partition list weaving the current - * input segment into the list. The following three variables - * keep track of the current starting point of the input - * segment. The starting point of the segment moves to higher - * hit_dist values (as it is woven in) until it is entirely - * consumed. + * input segment into the list. The following three + * variables keep track of the current starting point of + * the input segment. The starting point of the segment + * moves to higher hit_dist values (as it is woven in) + * until it is entirely consumed. */ lastseg = segp; lasthit = &segp->seg_in; @@ -312,9 +313,9 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s if (RT_G_DEBUG&RT_DEBUG_PARTITION) { bu_log("At start of loop:\n"); bu_log(" remaining input segment: (%.12e - %.12e)\n", - lasthit->hit_dist, segp->seg_out.hit_dist); + lasthit->hit_dist, segp->seg_out.hit_dist); bu_log(" current partition: (%.12e - %.12e)\n", - pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist); + pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist); rt_pr_partitions(rtip, PartHdp, "At start of loop"); } @@ -328,8 +329,8 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s */ if (RT_G_DEBUG&RT_DEBUG_PARTITION) { bu_log("seg start beyond partition end, skipping. (%g, %g)\n", - pp->pt_inhit->hit_dist, - pp->pt_outhit->hit_dist); + pp->pt_inhit->hit_dist, + pp->pt_outhit->hit_dist); } continue; } @@ -382,31 +383,32 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s if (RT_G_DEBUG&RT_DEBUG_PARTITION) { bu_log("seg starts within p. Split p at seg start, advance. (diff = %g)\n", diff); bu_log("newpp starts at %.12e, pp starts at %.12e\n", - newpp->pt_inhit->hit_dist, - pp->pt_inhit->hit_dist); + newpp->pt_inhit->hit_dist, + pp->pt_inhit->hit_dist); bu_log("newpp = %p, pp = %p\n", (void *)newpp, (void *)pp); } } else if (diff > -(tol_dist)) { /* - * Make a subtle but important distinction here. Even - * though the two distances are "equal" within - * tolerance, they are not exactly the same. If the - * new segment is slightly closer to the ray origin, - * then use its IN point. + * Make a subtle but important distinction here. + * Even though the two distances are "equal" + * within tolerance, they are not exactly the + * same. If the new segment is slightly closer to + * the ray origin, then use its IN point. * - * This is an attempt to reduce the deflected normals - * sometimes seen along the edges of e.g. a cylinder - * unioned with an ARB8, where the ray hits the top of - * the cylinder and the *side* face of the ARB8 rather - * than the top face of the ARB8. + * This is an attempt to reduce the deflected + * normals sometimes seen along the edges of + * e.g. a cylinder unioned with an ARB8, where the + * ray hits the top of the cylinder and the *side* + * face of the ARB8 rather than the top face of + * the ARB8. */ diff = segp->seg_in.hit_dist - pp->pt_inhit->hit_dist; if (!pp->pt_back || - pp->pt_back == PartHdp || - pp->pt_back->pt_outhit->hit_dist <= - segp->seg_in.hit_dist) { + pp->pt_back == PartHdp || + pp->pt_back->pt_outhit->hit_dist <= + segp->seg_in.hit_dist) { if (NEAR_ZERO(diff, tol_dist) && - diff < 0) { + diff < 0) { if (RT_G_DEBUG&RT_DEBUG_PARTITION) bu_log("changing partition start point to segment start point\n"); pp->pt_inseg = segp; pp->pt_inhit = &segp->seg_in; @@ -543,8 +545,8 @@ rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, s if (RT_G_DEBUG&RT_DEBUG_PARTITION) { bu_log("start together, seg shorter than partition\n"); bu_log("newpp starts at %.12e, pp starts at %.12e\n", - newpp->pt_inhit->hit_dist, - pp->pt_inhit->hit_dist); + newpp->pt_inhit->hit_dist, + pp->pt_inhit->hit_dist); bu_log("newpp = %p, pp = %p\n", (void *)newpp, (void *)pp); } break; @@ -587,9 +589,7 @@ rt_defoverlap(register struct application *ap, register struct partition *pp, st RT_CK_REGION(reg1); RT_CK_REGION(reg2); - /* - * Apply heuristics as to which region should claim partition. - */ + /* Apply heuristics as to which region should claim partition. */ if (reg1->reg_aircode != 0) { /* reg1 was air, replace with reg2 */ return 2; @@ -805,7 +805,7 @@ bool_plate_vol_overlap(struct region **fr1, struct region **fr2, struct partitio return; } - /* need to test sensitivity before changing to distance tolerance. */ + /* test sensitivity before changing to distance tolerance. */ if (!NEAR_EQUAL(prev->pt_outhit->hit_dist, pp->pt_inhit->hit_dist, 0.001)) { /* There is a gap between previous partition and this one. So * both plate and vol start at same place, d=0, plate wins. @@ -869,8 +869,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ if (regp->reg_is_fastgen != REGION_NON_FASTGEN) n_fastgen++; } - /* - * Resolve all FASTGEN overlaps before considering BRL-CAD + /* Resolve all FASTGEN overlaps before considering BRL-CAD * overlaps, because FASTGEN overlaps have strict rules. */ if (n_fastgen >= 2) { @@ -885,8 +884,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ } } - /* - * First, resolve volume_mode/volume_mode overlaps because + /* First, resolve volume_mode/volume_mode overlaps because * they are a simple choice. The searches run from high to * low in the ptbl array. */ @@ -939,8 +937,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ RT_CK_REGION(lastregion); if (BU_PTBL_LEN(regiontable) > 1 && ap->a_rt_i->rti_save_overlaps != 0) { - /* - * Snapshot current state of overlap list, so that downstream + /* Snapshot current state of overlap list, so that downstream * application code can resolve any FASTGEN plate/plate * overlaps. The snapshot is not taken at the top of the * routine because nobody is interested in FASTGEN vol/plate @@ -976,8 +973,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ /* both are same air, keep last */ code = 1; - /* - * If a FASTGEN region overlaps a non-FASTGEN region, the + /* If a FASTGEN region overlaps a non-FASTGEN region, the * non-FASTGEN ("traditional BRL-CAD") region wins. No * mixed-mode geometry like this will be built by the * fastgen-to-BRL-CAD converters, only by human editors. @@ -987,10 +983,9 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ } else if (lastregion->reg_is_fastgen != regp->reg_is_fastgen && regp->reg_is_fastgen) { code = 1; /* keep lastregion */ - /* - * To support ray bundles, find partition with the lower - * contributing ray number (closer to center of bundle), and - * retain that one. + /* To support ray bundles, find partition with the lower + * contributing ray number (closer to center of bundle), + * and retain that one. */ } else { int r1 = bool_max_raynum(lastregion->reg_treetop, pp); @@ -1008,9 +1003,9 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ code = 2; /* keep regp */ } } else { - /* - * Hand overlap to old-style application-specific + /* Hand overlap to old-style application-specific * overlap handler, or default. + * * 0 = destroy partition, * 1 = keep part, claiming region=lastregion * 2 = keep part, claiming region=regp @@ -1033,7 +1028,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ /* Keep partition, claiming region = lastregion */ if (RT_G_DEBUG&RT_DEBUG_PARTITION) bu_log("rt_default_multioverlap: overlap policy=1, code=%d, p retained in region=%s\n", - code, lastregion->reg_name); + code, lastregion->reg_name); BU_PTBL_SET(regiontable, i, (long*)0); break; case 2: @@ -1042,7 +1037,7 @@ rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ lastregion = regp; if (RT_G_DEBUG&RT_DEBUG_PARTITION) bu_log("rt_default_multioverlap: overlap policy!=(0, 1) code=%d, p retained in region=%s\n", - code, lastregion->reg_name); + code, lastregion->reg_name); break; } } @@ -1085,7 +1080,7 @@ rt_default_logoverlap(struct application *ap, const struct partition *pp, const bu_vls_extend(&str, 80*8); bu_vls_putc(&str, '\n'); - /* List all the regions which evaluated to BOOL_TRUE in this partition */ + /* List all regions that evaluate to BOOL_TRUE in this partition */ for (i=0; i < BU_PTBL_LEN(regiontable); i++) { struct region *regp = (struct region *)BU_PTBL_GET(regiontable, i); @@ -1520,7 +1515,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta if (!ZERO(diff)) { if (NEAR_ZERO(diff, ap->a_rt_i->rti_tol.dist)) { if (RT_G_DEBUG&RT_DEBUG_PARTITION) bu_log("rt_boolfinal: fusing 2 partitions %p %p\n", - (void *)pp, (void *)pp->pt_forw); + (void *)pp, (void *)pp->pt_forw); pp->pt_forw->pt_inhit->hit_dist = pp->pt_outhit->hit_dist; } else if (diff > 0) { bu_log("rt_boolfinal: sorting defect %e > %e! x%d y%d lvl%d, diff = %g\n", @@ -1538,8 +1533,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta } } - /* - * If partition is behind ray start point, discard it. + /* If partition is behind ray start point, discard it. * * Partition may start before current box starts, because it's * still waiting for all its solids to be shot. @@ -1556,8 +1550,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta continue; } - /* - * If partition begins beyond current box end, the state of + /* If partition begins beyond current box end, the state of * the partition is not fully known yet, and new partitions * might be added in front of this one, so stop now. */ @@ -1570,8 +1563,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta goto out; } - /* - * If partition ends somewhere beyond the end of the current + /* If partition ends somewhere beyond the end of the current * box, the condition of the outhit information is not fully * known yet. The partition might be broken or shortened by * subsequent segments, not discovered until entering future @@ -1599,8 +1591,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta /* Start with a clean slate when evaluating this partition */ bu_ptbl_reset(regiontable); - /* - * For each segment's solid that lies in this partition, add + /* For each segment's solid that lies in this partition, add * the list of regions that refer to that solid into the * "regiontable" array. */ @@ -1631,8 +1622,7 @@ rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t sta if (indefinite_outpt) { if (RT_G_DEBUG&RT_DEBUG_PARTITION) bu_log("indefinite out point, checking partition eligibility for early evaluation.\n"); - /* - * More hits still needed. HITS_TODO > 0. If every solid + /* More hits still needed. HITS_TODO > 0. If every solid * in every region participating in this partition has * been intersected, then it is OK to evaluate it now. */ @@ -1965,13 +1955,16 @@ rt_rebuild_overlaps(struct partition *PartHdp, struct application *ap, int rebui pp_reg->reg_is_fastgen != REGION_FASTGEN_PLATE) continue; - /* if the original partition is available, just use it */ + /* if the original partition is available, just + * use it. + */ if (!pp->pt_regionp || pp->pt_regionp == pp_reg) { pp->pt_regionp = pp_reg; bu_ptbl_ins(&open_parts, (long *)pp); } else { - /* create a new partition, link it to the end of the current pp, - * and add it to the open list */ + /* create a new partition, link it to the end + * of the current pp, and add it to the open + * list */ RT_DUP_PT(ap->a_rt_i, new_pp, pp, ap->a_resource) new_pp->pt_regionp = pp_reg; new_pp->pt_overlap_reg = (struct region **)NULL; diff --git a/src/librt/bool_tess.c b/src/librt/bool_tess.c new file mode 100644 index 00000000000..05ea95939b3 --- /dev/null +++ b/src/librt/bool_tess.c @@ -0,0 +1,305 @@ +/* B O O L _ T E S S . C + * BRL-CAD + * + * Copyright (c) 2005-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup librt */ +/** @{ */ +/** @file bool_tess.c + * + * Tree walking routines for tessellation/facetization of CSG trees. + * + * Originally these routines were specific to NMG, but they have + * been made generic here with callbacks. + * + * The leaf tessellation routine, however, does still use NMG - that is + * because for CSG primitives, in particular, NMG is how they are converted + * from implicit to explicit form. For the purposes of these routines, + * that should be considered an implementation detail. + */ +/** @} */ + +#include "common.h" +#include "string.h" +#include "nmg.h" +#include "raytrace.h" + +/** + * Called from db_walk_tree() each time a tree leaf is encountered. + * The primitive solid, in external format, is provided in 'ep', and + * the type of that solid (e.g. ID_ELL) is in 'id'. The full tree + * state including the accumulated transformation matrix and the + * current tolerancing is in 'tsp', and the full path from root to + * leaf is in 'pathp'. + * + * Import the solid, tessellate it into an NMG, stash a pointer to the + * tessellation in a new tree structure (union), and return a pointer + * to that. + * + * Usually given as an argument to, and called from db_walk_tree(). + * + * This routine must be prepared to run in parallel. + */ +union tree * +rt_booltree_leaf_tess(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *UNUSED(client_data)) +{ + struct model *m; + struct nmgregion *r1 = (struct nmgregion *)NULL; + union tree *curtree; + struct directory *dp; + + if (!tsp || !pathp || !ip) + return TREE_NULL; + + RT_CK_DB_INTERNAL(ip); + RT_CK_FULL_PATH(pathp); + dp = DB_FULL_PATH_CUR_DIR(pathp); + RT_CK_DIR(dp); + + if (!ip->idb_meth || !ip->idb_meth->ft_tessellate) { + bu_log("ERROR(%s): tessellation support not available\n", dp->d_namep); + return TREE_NULL; + } + + if (tsp->ts_m) + NMG_CK_MODEL(*tsp->ts_m); + BN_CK_TOL(tsp->ts_tol); + BG_CK_TESS_TOL(tsp->ts_ttol); + RT_CK_RESOURCE(tsp->ts_resp); + + m = nmg_mm(); + + if (ip->idb_meth->ft_tessellate(&r1, m, ip, tsp->ts_ttol, tsp->ts_tol) < 0) { + bu_log("ERROR(%s): tessellation failure\n", dp->d_namep); + return TREE_NULL; + } + + NMG_CK_REGION(r1); + if (nmg_debug & NMG_DEBUG_VERIFY) { + nmg_vshell(&r1->s_hd, r1); + } + + BU_GET(curtree, union tree); + RT_TREE_INIT(curtree); + curtree->tr_op = OP_TESS; + curtree->tr_d.td_name = bu_strdup(dp->d_namep); + curtree->tr_d.td_r = r1; + curtree->tr_d.td_d = NULL; + + if (RT_G_DEBUG&RT_DEBUG_TREEWALK) + bu_log("booltree_leaf_tess(%s) OK\n", dp->d_namep); + + return curtree; +} + +/** + * Given a tree of leaf nodes tessellated earlier by + * rt_booltree_leaf_tess(), use recursion to do a depth-first + * traversal of the tree, evaluating each pair of boolean operations + * and reducing that result to a single result. + * + * Returns an OP_TESS union tree node, which will contain the + * resulting region and its name, as a dynamic string. The caller is + * responsible for releasing the string, and the node, by calling + * db_free_tree() on the node. + * + * Returns TREE_NULL if there is no geometry to return. + */ +union tree * +rt_booltree_evaluate( + register union tree *tp, + struct bu_list *vlfree, + const struct bn_tol *tol, + struct resource *resp, + int (*do_bool)(union tree *, union tree *, union tree *, int op, struct bu_list *, const struct bn_tol *, void *), + int verbose, + void *data + ) +{ + if (!do_bool) { + tp->tr_op = OP_NOP; + return TREE_NULL; + } + + union tree *tl = NULL; + union tree *tr = NULL; + const char *op_str = NULL; + size_t rem = 0; + char *name = NULL; + + RT_CK_TREE(tp); + if (tol) + BN_CK_TOL(tol); + RT_CK_RESOURCE(resp); + + switch (tp->tr_op) { + case OP_NOP: + return TREE_NULL; + case OP_TESS: + /* Hit a tree leaf */ + if (tp->tr_d.td_r && nmg_debug & NMG_DEBUG_VERIFY) { + nmg_vshell(&tp->tr_d.td_r->s_hd, tp->tr_d.td_r); + } + return tp; + case OP_UNION: + op_str = " u "; + break; + case OP_INTERSECT: + op_str = " + "; + break; + case OP_SUBTRACT: + op_str = " - "; + break; + default: + bu_bomb("rt_booltree_evaluate(): bad op\n"); + } + + /* Handle a boolean operation node. First get its leaves. */ + tl = rt_booltree_evaluate(tp->tr_b.tb_left, vlfree, tol, resp, do_bool, verbose, data); + tr = rt_booltree_evaluate(tp->tr_b.tb_right, vlfree, tol, resp, do_bool, verbose, data); + + if (tl) { + RT_CK_TREE(tl); + if (tl != tp->tr_b.tb_left) { + bu_bomb("rt_booltree_evaluate(): tl != tp->tr_b.tb_left\n"); + } + } + if (tr) { + RT_CK_TREE(tr); + if (tr != tp->tr_b.tb_right) { + bu_bomb("rt_booltree_evaluate(): tr != tp->tr_b.tb_right\n"); + } + } + + if (!tl && !tr) { + /* left-r == null && right-r == null */ + RT_CK_TREE(tp); + db_free_tree(tp->tr_b.tb_left, resp); + db_free_tree(tp->tr_b.tb_right, resp); + tp->tr_op = OP_NOP; + return TREE_NULL; + } + + if (tl && !tr) { + /* left-r != null && right-r == null */ + RT_CK_TREE(tp); + db_free_tree(tp->tr_b.tb_right, resp); + if (tp->tr_op == OP_INTERSECT) { + /* OP_INTERSECT '+' */ + RT_CK_TREE(tp); + db_free_tree(tl, resp); + tp->tr_op = OP_NOP; + return TREE_NULL; + } else { + /* copy everything from tl to tp no matter which union type + * could probably have done a mem-copy + */ + tp->tr_op = tl->tr_op; + tp->tr_b.tb_regionp = tl->tr_b.tb_regionp; + tp->tr_b.tb_left = tl->tr_b.tb_left; + tp->tr_b.tb_right = tl->tr_b.tb_right; + + /* null data from tl so only to free this node */ + tl->tr_b.tb_regionp = (struct region *)NULL; + tl->tr_b.tb_left = TREE_NULL; + tl->tr_b.tb_right = TREE_NULL; + + db_free_tree(tl, resp); + return tp; + } + } + + if (!tl && tr) { + /* left-r == null && right-r != null */ + RT_CK_TREE(tp); + db_free_tree(tp->tr_b.tb_left, resp); + if (tp->tr_op == OP_UNION) { + /* OP_UNION 'u' */ + /* copy everything from tr to tp no matter which union type + * could probably have done a mem-copy + */ + tp->tr_op = tr->tr_op; + tp->tr_b.tb_regionp = tr->tr_b.tb_regionp; + tp->tr_b.tb_left = tr->tr_b.tb_left; + tp->tr_b.tb_right = tr->tr_b.tb_right; + + /* null data from tr so only to free this node */ + tr->tr_b.tb_regionp = (struct region *)NULL; + tr->tr_b.tb_left = TREE_NULL; + tr->tr_b.tb_right = TREE_NULL; + + db_free_tree(tr, resp); + return tp; + + } else if ((tp->tr_op == OP_SUBTRACT) || (tp->tr_op == OP_INTERSECT)) { + /* for sub and intersect, if left-hand-side is null, result is null */ + RT_CK_TREE(tp); + db_free_tree(tr, resp); + tp->tr_op = OP_NOP; + return TREE_NULL; + + } else { + bu_bomb("rt_booltree_evaluate(): error, unknown operation\n"); + } + } + + if (tl->tr_op != OP_TESS) { + bu_bomb("rt_booltree_evaluate(): bad left tree\n"); + } + if (tr->tr_op != OP_TESS) { + bu_bomb("rt_booltree_evaluate(): bad right tree\n"); + } + + if (verbose) { + bu_log(" {%s}%s{%s}\n", tl->tr_d.td_name, op_str, tr->tr_d.td_name); + } + + // Execute the specified method that actually evaluates the mesh geometries + int b = do_bool(tp, tl, tr, tp->tr_op, vlfree, tol, data); + + if (b) { + /* result was null */ + tp->tr_op = OP_NOP; + return TREE_NULL; + } + + /* build string of result name */ + rem = strlen(tl->tr_d.td_name) + 3 + strlen(tr->tr_d.td_name) + 2 + 1; + name = (char *)bu_calloc(rem, sizeof(char), "rt_booltree_evaluate name"); + snprintf(name, rem, "(%s%s%s)", tl->tr_d.td_name, op_str, tr->tr_d.td_name); + tp->tr_d.td_name = name; + + /* clean up child tree nodes */ + tl->tr_d.td_r = NULL; + tr->tr_d.td_r = NULL; + tl->tr_d.td_d = NULL; + tr->tr_d.td_d = NULL; + db_free_tree(tl, resp); + db_free_tree(tr, resp); + + return tp; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/librt/bundle.c b/src/librt/bundle.c index 09f75c9c293..37aa3d9a0f9 100644 --- a/src/librt/bundle.c +++ b/src/librt/bundle.c @@ -219,8 +219,7 @@ rt_shootray_bundle(struct application *ap, struct xray *rays, int nrays) ss.rstep[Z] = 0; } - /* - * If ray does not enter the model RPP, skip on. + /* If ray does not enter the model RPP, skip on. * If ray ends exactly at the model RPP, trace it. */ if (!rt_in_rpp(&ap->a_ray, ss.inv_dir, rtip->mdl_min, rtip->mdl_max) || @@ -234,8 +233,7 @@ rt_shootray_bundle(struct application *ap, struct xray *rays, int nrays) goto out; } - /* - * The interesting part of the ray starts at distance 0. If the + /* The interesting part of the ray starts at distance 0. If the * ray enters the model at a negative distance, (i.e., the ray * starts within the model RPP), we only look at little bit behind * (BACKING_DIST) to see if we are just coming out of something, @@ -570,6 +568,7 @@ bundle_miss(register struct application *ap) return 0; } + #ifdef SHOOTRAYS_IN_PARALLEL static void shootrays_in_parallel(int UNUSED(cpu), void *data) diff --git a/src/librt/cache.c b/src/librt/cache.c index 66794491dcc..bb4f014e035 100644 --- a/src/librt/cache.c +++ b/src/librt/cache.c @@ -626,14 +626,14 @@ cache_try_store(struct rt_cache *cache, const char *name, const struct rt_db_int } db5_export_object3(&db_external, 0, name, 0, &attributes_external, - &data_external, DB5_MAJORTYPE_BINARY_MIME, 0, - DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED); + &data_external, DB5_MAJORTYPE_BINARY_MIME, 0, + DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED); focache = fopen(tmppath, "wb"); if (!focache) { - CACHE_DEBUG("++++++ [%lu.%lu] Failed to put cache temp %s\n", bu_process_id(), bu_parallel_id(), tmpname); - return 0; /* can't stash */ - } + CACHE_DEBUG("++++++ [%lu.%lu] Failed to put cache temp %s\n", bu_process_id(), bu_parallel_id(), tmpname); + return 0; /* can't stash */ + } if (fwrite((void *)db_external.ext_buf, 1, db_external.ext_nbytes, focache) != db_external.ext_nbytes) { fclose(focache); @@ -677,7 +677,7 @@ cache_try_store(struct rt_cache *cache, const char *name, const struct rt_db_int if (tmp_file_size != final_file_size) { CACHE_DEBUG("++++++ [%lu.%lu] BUT the file size of %s (%d) doesn't match that of %s (%d)!!! Giving up.\n", bu_process_id(), bu_parallel_id(), path, final_file_size, tmpname, tmp_file_size); if (!cache->debug) { - bu_file_delete(tmppath); + bu_file_delete(tmppath); } else { CACHE_DEBUG("++++++ [%lu.%lu] Note: temporary file %s has been left intact for debugging examination.\n", bu_process_id(), bu_parallel_id(), path, tmpname); } @@ -691,9 +691,9 @@ cache_try_store(struct rt_cache *cache, const char *name, const struct rt_db_int CACHE_DEBUG("++++++ [%lu.%lu] Successfully read %s\n", bu_process_id(), bu_parallel_id(), name); return 1; } else { - CACHE_DEBUG("++++++ [%lu.%lu] BUT we can't read %s !!! Giving up.\n", bu_process_id(), bu_parallel_id(), name); - return 0; - } + CACHE_DEBUG("++++++ [%lu.%lu] BUT we can't read %s !!! Giving up.\n", bu_process_id(), bu_parallel_id(), name); + return 0; + } } /* atomically flip it into place */ diff --git a/src/librt/cmd.c b/src/librt/cmd.c index 1f79a5b25b1..547daa5d359 100644 --- a/src/librt/cmd.c +++ b/src/librt/cmd.c @@ -97,13 +97,11 @@ rt_read_cmd(register FILE *fp) #define MAXWORDS 4096 /* Max # of args per command */ +/* FUTURE: rtip for globbing */ int rt_do_cmd(struct rt_i *rtip, const char *ilp, register const struct command_tab *tp) -/* FUTURE: for globbing */ - - { - register int nwords; /* number of words seen */ + register int nwords; /* number of words seen */ char *cmd_args[MAXWORDS+1]; /* array of ptrs to args */ char *lp; int retval; @@ -131,8 +129,10 @@ rt_do_cmd(struct rt_i *rtip, const char *ilp, register const struct command_tab for (; tp->ct_cmd != (char *)0; tp++) { if (cmd_args[0][0] != tp->ct_cmd[0] || - /* the length of "n" is not significant, just needs to be big enough */ - bu_strncmp(cmd_args[0], tp->ct_cmd, MAXWORDS) != 0) + /* length of "n" is not significant, just needs to be big + * enough + */ + bu_strncmp(cmd_args[0], tp->ct_cmd, MAXWORDS) != 0) continue; if ((nwords >= tp->ct_min) && ((tp->ct_max < 0) || (nwords <= tp->ct_max))) @@ -151,6 +151,7 @@ rt_do_cmd(struct rt_i *rtip, const char *ilp, register const struct command_tab return -1; /* ERROR */ } + /* Note - see attr.cpp for the rt_cmd_attr implementation */ /** @@ -197,6 +198,7 @@ _rt_color_putrec(struct bu_vls *msg, struct db_i *dbip, struct mater *mp) } } + /** * Used to release database resources occupied by a material record. */ @@ -223,6 +225,7 @@ _rt_color_zaprec(struct bu_vls *msg, struct db_i *dbip, struct mater *mp) mp->mt_daddr = MATER_NO_ADDR; } + int rt_cmd_color(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) { @@ -245,8 +248,9 @@ rt_cmd_color(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) } /* The -e option is not supported by this portion of the command - * implementation - see LIBGED's color command for how to handle the -e - * (edcolor) option at a higher level. */ + * implementation - see LIBGED's color command for how to handle + * the -e (edcolor) option at a higher level. + */ if (argc == 2) { if (argv[1][0] == '-' && argv[1][1] == 'e' && argv[1][2] == '\0') { if (msg) @@ -317,6 +321,7 @@ rt_cmd_color(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) return BRLCAD_OK; } + int rt_cmd_put(struct bu_vls *msg, struct rt_wdb *wdbp, int argc, const char **argv) { @@ -344,58 +349,61 @@ rt_cmd_put(struct bu_vls *msg, struct rt_wdb *wdbp, int argc, const char **argv) return BRLCAD_ERROR; } - int i; - char type[16] = {0}; - for (i = 0; argv[2][i] != 0 && i < 15; i++) { - type[i] = isupper((int)argv[2][i]) ? tolower((int)argv[2][i]) : argv[2][i]; - } - type[i] = 0; - - const struct rt_functab *ftp = rt_get_functab_by_label(type); - if (ftp == NULL) { - if (msg) - bu_vls_printf(msg, "rt_cmd_put: %s is an unknown object type.", type); - return BRLCAD_ERROR; - } - - RT_CK_FUNCTAB(ftp); - - struct rt_db_internal intern; - RT_DB_INTERNAL_INIT(&intern); - - if (ftp->ft_make) { - ftp->ft_make(ftp, &intern); - } else { - rt_generic_make(ftp, &intern); - } - - /* The LIBBU struct parsing commands require a non-NULL logstr to work (??) - - * if the caller hasn't provided us a logging buffer, make a temporary one */ - struct bu_vls *amsg; - struct bu_vls tmpmsg = BU_VLS_INIT_ZERO; - amsg = (msg) ? msg : &tmpmsg; - - if (!ftp->ft_adjust || ftp->ft_adjust(amsg, &intern, argc-3, argv+3) & BRLCAD_ERROR) { - if (msg) - bu_vls_printf(msg, "rt_cmd_put: error calling ft_adjust"); - bu_vls_free(&tmpmsg); - rt_db_free_internal(&intern); - return BRLCAD_ERROR; - } - bu_vls_free(&tmpmsg); - - if (wdb_put_internal(wdbp, argv[1], &intern, 1.0) < 0) { - if (msg) - bu_vls_printf(msg, "rt_cmd_put: wdb_put_internal(%s)", argv[1]); - rt_db_free_internal(&intern); - return BRLCAD_ERROR; - } - - rt_db_free_internal(&intern); - - return BRLCAD_OK; + int i; + char type[16] = {0}; + for (i = 0; argv[2][i] != 0 && i < 15; i++) { + type[i] = isupper((int)argv[2][i]) ? tolower((int)argv[2][i]) : argv[2][i]; + } + type[i] = 0; + + const struct rt_functab *ftp = rt_get_functab_by_label(type); + if (ftp == NULL) { + if (msg) + bu_vls_printf(msg, "rt_cmd_put: %s is an unknown object type.", type); + return BRLCAD_ERROR; + } + + RT_CK_FUNCTAB(ftp); + + struct rt_db_internal intern; + RT_DB_INTERNAL_INIT(&intern); + + if (ftp->ft_make) { + ftp->ft_make(ftp, &intern); + } else { + rt_generic_make(ftp, &intern); + } + + /* The LIBBU struct parsing commands require a non-NULL logstr to + * work (??) - if the caller hasn't provided us a logging buffer, + * make a temporary one + */ + struct bu_vls *amsg; + struct bu_vls tmpmsg = BU_VLS_INIT_ZERO; + amsg = (msg) ? msg : &tmpmsg; + + if (!ftp->ft_adjust || ftp->ft_adjust(amsg, &intern, argc-3, argv+3) & BRLCAD_ERROR) { + if (msg) + bu_vls_printf(msg, "rt_cmd_put: error calling ft_adjust"); + bu_vls_free(&tmpmsg); + rt_db_free_internal(&intern); + return BRLCAD_ERROR; + } + bu_vls_free(&tmpmsg); + + if (wdb_put_internal(wdbp, argv[1], &intern, 1.0) < 0) { + if (msg) + bu_vls_printf(msg, "rt_cmd_put: wdb_put_internal(%s)", argv[1]); + rt_db_free_internal(&intern); + return BRLCAD_ERROR; + } + + rt_db_free_internal(&intern); + + return BRLCAD_OK; } + int rt_cmd_title(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) { @@ -415,7 +423,9 @@ rt_cmd_title(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) return BRLCAD_OK; } - /* If doing anything other than reporting, we need to be able to write */ + /* If doing anything other than reporting, we need to be able to + * write. + */ if (dbip->dbi_read_only) { if (msg) bu_vls_printf(msg, "rt_cmd_title: database is read-only\n"); @@ -436,6 +446,7 @@ rt_cmd_title(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) return BRLCAD_OK; } + int rt_cmd_units(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) { @@ -478,7 +489,7 @@ rt_cmd_units(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) bu_vls_printf(msg, "%s", str); else bu_vls_printf(msg, "You are editing in '%s'. 1 %s = %g mm \n", - str, str, dbip->dbi_local2base); + str, str, dbip->dbi_local2base); } return BRLCAD_OK; @@ -496,8 +507,8 @@ rt_cmd_units(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) if ((loc2mm = bu_mm_value(argv[1])) <= 0) { if (msg) bu_vls_printf(msg, - "%s: unrecognized unit\nvalid units: \n", - argv[1]); + "%s: unrecognized unit\nvalid units: \n", + argv[1]); return BRLCAD_ERROR; } @@ -513,7 +524,7 @@ rt_cmd_units(struct bu_vls *msg, struct db_i *dbip, int argc, const char **argv) if (!str) str = "Unknown_unit"; if (msg) bu_vls_printf(msg, "You are now editing in '%s'. 1 %s = %g mm \n", - str, str, dbip->dbi_local2base); + str, str, dbip->dbi_local2base); return BRLCAD_OK; } diff --git a/src/librt/constraint.c b/src/librt/constraint.c index f9bdb7dba07..f1cc2333f61 100644 --- a/src/librt/constraint.c +++ b/src/librt/constraint.c @@ -39,7 +39,7 @@ #include "raytrace.h" -static const struct bu_structparse rt_constraint_parse[] = { +const struct bu_structparse rt_constraint_parse[] = { {"%d", 1, "ID", bu_offsetof(struct rt_constraint_internal, id), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, {"%d", 1, "N", bu_offsetof(struct rt_constraint_internal, type), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, {"%V", 1, "Ex", bu_offsetof(struct rt_constraint_internal, expression), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL}, @@ -61,12 +61,51 @@ rt_constraint_ifree(struct rt_db_internal *ip) if (constraint) { constraint->magic = 0; /* sanity */ - bu_vls_free(&constraint->expression); + if (BU_VLS_IS_INITIALIZED(&constraint->expression)) + bu_vls_free(&constraint->expression); bu_free((void *)constraint, "constraint ifree"); } ip->idb_ptr = ((void *)0); /* sanity */ } +/** + * Import a constraint from the database format to the internal format. + */ +int +rt_constraint_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *UNUSED(mat), const struct db_i *dbip) +{ + struct rt_constraint_internal* cip; + struct bu_vls str = BU_VLS_INIT_ZERO; + + if (dbip) RT_CK_DBI(dbip); + BU_CK_EXTERNAL(ep); + + RT_CK_DB_INTERNAL(ip); + ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; + ip->idb_type = ID_CONSTRAINT; + ip->idb_meth = &OBJ[ID_CONSTRAINT]; + BU_ALLOC(ip->idb_ptr, struct rt_constraint_internal); + + cip = (struct rt_constraint_internal *)ip->idb_ptr; + cip->magic = RT_CONSTRAINT_MAGIC; + BU_VLS_INIT(&cip->expression); + cip->id = 0; + cip->type = 0; + + bu_vls_strncpy(&str, (const char *)ep->ext_buf, ep->ext_nbytes); + + if (bu_struct_parse(&str, rt_constraint_parse, (char *)cip, NULL) < 0) { + bu_vls_free(&str); + bu_free((char *)cip, "rt_constraint_import5: cip"); + ip->idb_type = ID_NULL; + ip->idb_ptr = (void *)NULL; + return -2; + } + bu_vls_free(&str); + + return 0; +} + int rt_constraint_export5(struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *UNUSED(dbip)) @@ -84,6 +123,8 @@ rt_constraint_export5(struct bu_external *ep, const struct rt_db_internal *ip, d bu_vls_struct_print(&str, rt_constraint_parse, (char *)cip); ep->ext_nbytes = bu_vls_strlen(&str); + if (ep->ext_nbytes == 0) + return -1; ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "constrnt external"); bu_strlcpy((char *)ep->ext_buf, bu_vls_addr(&str), ep->ext_nbytes); @@ -92,6 +133,50 @@ rt_constraint_export5(struct bu_external *ep, const struct rt_db_internal *ip, d return 0; /* OK */ } +/** + * Make human-readable formatted presentation of this solid. + * First line describes type of solid. + * Additional lines are indented one tab, and give parameter values. + */ +int +rt_constraint_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double UNUSED(mm2local)) +{ + struct rt_constraint_internal *cip = (struct rt_constraint_internal *)ip->idb_ptr; + + if (cip->magic != RT_CONSTRAINT_MAGIC) bu_bomb("rt_constraint_describe() bad magic"); + bu_vls_strcat(str, "constraint (CONSTRNT)\n"); + + if (!verbose) + return 0; + + bu_vls_printf(str, "\tid=%d\n\ttype=%d\n\texpression=%s\n", + cip->id, + cip->type, + bu_vls_addr(&cip->expression)); + + return 0; +} + +void +rt_constraint_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_constraint_internal* ip; + + intern->idb_type = ID_CONSTRAINT; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_constraint_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_CONSTRAINT_MAGIC; + ip->id = 1; + ip->type = 0; + BU_VLS_INIT(&ip->expression); +} + /** @} */ /* diff --git a/src/librt/db5_attr.c b/src/librt/db5_attr.c index 05ede3c5ee5..3404ff2b07a 100644 --- a/src/librt/db5_attr.c +++ b/src/librt/db5_attr.c @@ -37,133 +37,144 @@ #include "rt/db5.h" #include "raytrace.h" -/* this is the master source of standard and registered attribute information */ +/* this is the master source of standard and registered attribute + * information + */ const struct db5_attr_ctype db5_attr_std[] = { { ATTR_REGION, 0, ATTR_STANDARD, - "region", - "boolean", - "Yes, R, 1, 0", /* example */ - "", /* aliases, if any */ - "Region Flag", /* property, if any */ - /* long_description, if any: */ - "The Region Flag identifies a particular geometric combination as being a solid material; in other words, any geometry below this combination in the tree can overlap without the overlap being regarded as a non-physical description, since it is the combination of all descriptions in the region object that defines the physical volume in space." + "region", + "boolean", + "Yes, R, 1, 0", /* example */ + "", /* aliases, if any */ + "Region Flag", /* property, if any */ + /* long_description, if any: */ + "The Region Flag identifies a particular geometric combination as being a solid material; in other words, any geometry below this combination in the tree can overlap without the overlap being regarded as a non-physical description, since it is the combination of all descriptions in the region object that defines the physical volume in space." }, { ATTR_REGION_ID, 0, ATTR_STANDARD, - "region_id", - "an integer", - "0, -1, and positive integers", /* examples */ - "id", /* aliases, if any */ - "Region Identifier Number", /* property, if any */ - /* long_description, if any: */ - "The Region Identifier Number identifies a particular region with a unique number. This allows multiple region objects to be regarded as being the same type of region, without requiring that they be included in the same combination object." + "region_id", + "an integer", + "0, -1, and positive integers", /* examples */ + "id", /* aliases, if any */ + "Region Identifier Number", /* property, if any */ + /* long_description, if any: */ + "The Region Identifier Number identifies a particular region with a unique number. This allows multiple region objects to be regarded as being the same type of region, without requiring that they be included in the same combination object." }, { ATTR_MATERIAL_ID, 0, ATTR_STANDARD, - "material_id", - "zero or positive integer (user-defined)", - "", /* examples */ - "giftmater,mat", /* aliases, if any */ - "Material Identifier Number", /* property, if any */ - /* long_description, if any: */ - "The Material ID Number corresponds to an entry in a DENSITIES table, usually contained in a text file. This table associates numbers with material names and density information used by analytical programs such as 'rtweight'." + "material_id", + "zero or positive integer (user-defined)", + "", /* examples */ + "giftmater, mat", /* aliases, if any */ + "Material Identifier Number", /* property, if any */ + /* long_description, if any: */ + "The Material ID Number corresponds to an entry in a DENSITIES table, usually contained in a text file. This table associates numbers with material names and density information used by analytical programs such as 'rtweight'." }, - { ATTR_MATERIAL_NAME, 0, ATTR_STANDARD, - "material_name", - "empty or content-filled string (user-defined)", - "", /* examples */ - "material", /* aliases, if any */ - "Material Name", /* property, if any */ - /* long_description, if any: */ - "The Material Name corresponds to an entry in a DENSITIES table or material objects, usually contained in a text file that are imported through the material command. This table associates numbers with material names and density information used by analytical programs such as 'rtweight'." + { ATTR_MATERIAL_NAME, 0, ATTR_STANDARD, + "material_name", + "empty or content-filled string (user-defined)", + "", /* examples */ + "material", /* aliases, if any */ + "Material Name", /* property, if any */ + /* long_description, if any: */ + "The Material Name corresponds to an entry in a DENSITIES table or material objects, usually contained in a text file that are imported through the material command. This table associates numbers with material names and density information used by analytical programs such as 'rtweight'." }, { ATTR_AIR, 0, ATTR_STANDARD, - "aircode", - "an integer (application defined)", - "'0', '1', or '-2'", /* examples */ - "air", /* aliases, if any */ - "Air Code", /* property, if any */ - /* long_description, if any: */ - "Any non-zero Air Code alerts the raytracer that the region in question is modeling air which is handled by specialized rules in LIBRT." + "aircode", + "an integer (application defined)", + "'0', '1', or '-2'", /* examples */ + "air", /* aliases, if any */ + "Air Code", /* property, if any */ + /* long_description, if any: */ + "Any non-zero Air Code alerts the raytracer that the region in question is modeling air which is handled by specialized rules in LIBRT." }, { ATTR_LOS, 0, ATTR_STANDARD, - "los", - "an integer in the inclusive range: 0 to 100", - "'24' or '100'", /* examples */ - "", /* aliases, if any */ - "Line of Sight Thickness Equivalence", /* property, if any */ - /* long_description, if any: */ - "" + "los", + "an integer in the inclusive range: 0 to 100", + "'24' or '100'", /* examples */ + "", /* aliases, if any */ + "Line of Sight Thickness Equivalence", /* property, if any */ + /* long_description, if any: */ + "" }, { ATTR_COLOR, 0, ATTR_STANDARD, - "color", - "a 3-tuple of RGB values", - "\"0 255 255\"", /* examples */ - "rgb", /* aliases, if any */ - "Color", /* property, if any */ - "" /* long_description, if any */ + "color", + "a 3-tuple of RGB values", + "\"0 255 255\"", /* examples */ + "rgb", /* aliases, if any */ + "Color", /* property, if any */ + "" /* long_description, if any */ }, { ATTR_SHADER, 0, ATTR_STANDARD, - "shader", - "a string of shader characteristics in a standard format", - "", /* examples */ - "oshader", /* aliases, if any */ - "Shader Name", /* property, if any */ - /* long_description, if any: */ - "LIBRT can use a variety of shaders when rendering. This attribute holds a text string which corresponds to the name and other details of the shader to be used." + "shader", + "a string of shader characteristics in a standard format", + "", /* examples */ + "oshader", /* aliases, if any */ + "Shader Name", /* property, if any */ + /* long_description, if any: */ + "LIBRT can use a variety of shaders when rendering. This attribute holds a text string which corresponds to the name and other details of the shader to be used." }, { ATTR_INHERIT, 0, ATTR_STANDARD, - "inherit", - "boolean", - "Yes, 1, 0", /* examples */ - "", /* aliases, if any */ - "Inherit Properties", /* property, if any */ - /* long_description, if any: */ - "The Inherit Properties value, if true, indicates all child objects inherit the attributes of this parent object." + "inherit", + "boolean", + "Yes, 1, 0", /* examples */ + "", /* aliases, if any */ + "Inherit Properties", /* property, if any */ + /* long_description, if any: */ + "The Inherit Properties value, if true, indicates all child objects inherit the attributes of this parent object." }, { ATTR_TIMESTAMP, 1, ATTR_STANDARD, /* first binary attribute */ - "mtime", + "mtime", - "a binary time stamp for an object's last mod time (the time is displayed in human-readable form with the 'attr' command)", + "a binary time stamp for an object's last mod time (the time is displayed in human-readable form with the 'attr' command)", - "", /* examples */ - "timestamp,time_stamp,modtime,mod_time,mtime", /* aliases, if any */ - "Time Stamp", /* property, if any */ - /* long_description, if any: */ - "" + "", /* examples */ + "timestamp, time_stamp, modtime, mod_time, mtime", /* aliases, if any */ + "Time Stamp", /* property, if any */ + /* long_description, if any: */ + "" }, { ATTR_NULL, 0, ATTR_UNKNOWN_ORIGIN, "", "", "", "", "", "" } }; + const char * db5_standard_attribute(int idx) { - if (idx >= ATTR_NULL) return NULL; + if (idx >= ATTR_NULL) + return NULL; return db5_attr_std[idx].name; } + int db5_is_standard_attribute(const char *attr_want) { int i = 0; const char *attr_have = NULL; - if (!attr_want) return 0; + if (!attr_want) + return 0; for (i = 0; (attr_have = db5_standard_attribute(i)) != NULL; i++) { - if (BU_STR_EQUIV(attr_want, attr_have)) return 1; + if (BU_STR_EQUIV(attr_want, attr_have)) { + return 1; + } } return 0; } +#define COMMA ',' + int db5_standardize_attribute(const char *attr) { int curr_attr = 0; struct bu_vls alias; const char *curr_pos, *next_pos; - if (!attr) return ATTR_NULL; + if (!attr) + return ATTR_NULL; bu_vls_init(&alias); while (db5_attr_std[curr_attr].attr_type != ATTR_NULL) { if (BU_STR_EQUIV(attr, db5_attr_std[curr_attr].name)) { @@ -172,7 +183,7 @@ db5_standardize_attribute(const char *attr) } curr_pos = db5_attr_std[curr_attr].aliases; while (curr_pos && strlen(curr_pos) > 0) { - next_pos = strchr(curr_pos+1, ','); + next_pos = strchr(curr_pos+1, COMMA); if (next_pos) { bu_vls_strncpy(&alias, curr_pos, next_pos - curr_pos); if (BU_STR_EQUIV(attr, bu_vls_addr(&alias))) { @@ -283,12 +294,16 @@ db5_standardize_avs(struct bu_attribute_value_set *avs) (void)attr_add(&newavs, attr_type, stdattr, avpp->value); } else if (attr_type != ATTR_NULL && BU_STR_EQUAL(added, avpp->value)) { - /* case 2: name is "standardizable", but we already added the same value */ + /* case 2: name is "standardizable", but we already added + * the same value + */ /* ignore/skip it (because it's the same value) */ } else if (attr_type != ATTR_NULL && !BU_STR_EQUAL(added, avpp->value)) { - /* case 3: name is "standardizable", but we already added something else */ + /* case 3: name is "standardizable", but we already added + * something else + */ /* preserve the conflict, keep the old value too */ (void)attr_add(&newavs, attr_type, avpp->name, avpp->value); @@ -314,7 +329,7 @@ db5_sync_attr_to_comb(struct rt_comb_internal *comb, const struct bu_attribute_v int ret; size_t i; long int attr_num_val; - char *attr_char_val; + char *attr_char_val; /*double attr_float_val;*/ char *endptr = NULL; int color[3] = {-1, -1, -1}; @@ -367,15 +382,15 @@ db5_sync_attr_to_comb(struct rt_comb_internal *comb, const struct bu_attribute_v comb->GIFTmater = 0; } - /* material_name */ + /* material_name */ bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_MATERIAL_NAME))); bu_vls_trimspace(&newval); if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) { - endptr = bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval)); + endptr = bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval)); if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) { - attr_char_val = bu_vls_strdup(&newval); - bu_vls_strcpy(&comb->material, attr_char_val); - // set the material_id using this material_name + attr_char_val = bu_vls_strdup(&newval); + bu_vls_strcpy(&comb->material, attr_char_val); + // set the material_id using this material_name } else { bu_log("WARNING: [%s] has invalid material_name value [%s]\nmaterial_name remains at %s\n", name, bu_vls_addr(&newval), bu_vls_strdup(&comb->material)); } @@ -405,8 +420,9 @@ db5_sync_attr_to_comb(struct rt_comb_internal *comb, const struct bu_attribute_v if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) { - /* Currently, struct rt_comb_internal lists los as a long. Probably should allow - * floating point, but as it's DEPRECATED anyway I suppose we can wait for that? */ + /* Currently, struct rt_comb_internal lists los as a long. + * Probably should allow floating point, but as it's + * DEPRECATED anyway I suppose we can wait for that? */ /* attr_float_val = strtod(bu_vls_addr(&newval), &endptr); */ attr_num_val = strtol(bu_vls_addr(&newval), &endptr, 0); if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) { @@ -501,7 +517,7 @@ db5_sync_comb_to_attr(struct bu_attribute_value_set *avs, const struct rt_comb_i bu_avs_remove(avs, db5_standard_attribute(ATTR_MATERIAL_ID)); } - /* Material Name */ + /* Material Name */ if (bu_vls_strlen(&comb->material) != 0) { bu_vls_sprintf(&newval, "%s", bu_vls_strdup(&comb->material)); (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_MATERIAL_NAME), &newval); diff --git a/src/librt/db_tree.cpp b/src/librt/db_tree.cpp index 4978eac2b53..83a3a905a2c 100644 --- a/src/librt/db_tree.cpp +++ b/src/librt/db_tree.cpp @@ -504,7 +504,7 @@ db_tree_del_lhs(union tree *tp, struct resource *resp) case OP_NOP: case OP_SOLID: case OP_REGION: - case OP_NMG_TESS: + case OP_TESS: case OP_DB_LEAF: /* lhs is indeed a leaf node */ db_free_tree(tp->tr_b.tb_left, resp); @@ -551,7 +551,7 @@ db_tree_del_rhs(union tree *tp, struct resource *resp) case OP_NOP: case OP_SOLID: case OP_REGION: - case OP_NMG_TESS: + case OP_TESS: case OP_DB_LEAF: /* rhs is indeed a leaf node */ db_free_tree(tp->tr_b.tb_right, resp); @@ -1276,7 +1276,7 @@ db_dup_subtree(const union tree *tp, struct resource *resp) new_tp->tr_b.tb_right = db_dup_subtree(tp->tr_b.tb_right, resp); return new_tp; - case OP_NMG_TESS: { + case OP_TESS: { /* FIXME: fake "copy" .. lie!!! */ new_tp->tr_d.td_r = tp->tr_d.td_r; new_tp->tr_d.td_name = bu_strdup(tp->tr_d.td_name); @@ -1371,7 +1371,7 @@ db_free_tree(union tree *tp, struct resource *resp) tp->tr_c.tc_ctsp = (struct combined_tree_state *)0; break; - case OP_NMG_TESS: + case OP_TESS: { struct nmgregion *r = tp->tr_d.td_r; if (tp->tr_d.td_name) { diff --git a/src/librt/mater.c b/src/librt/mater.c index ff699a2d6de..bddb8bba6d3 100644 --- a/src/librt/mater.c +++ b/src/librt/mater.c @@ -48,7 +48,7 @@ static struct mater *material_head = MATER_NULL; void rt_pr_mater(register const struct mater *mp) { - bu_log("%5d..%d\t", mp->mt_low, mp->mt_high); + bu_log("%5ld..%ld\t", mp->mt_low, mp->mt_high); bu_log("%d, %d, %d\t", mp->mt_r, mp->mt_g, mp->mt_b); } @@ -224,7 +224,7 @@ rt_vls_color_map(struct bu_vls *str) for (mp = material_head; mp != MATER_NULL; mp = mp->mt_forw) { bu_vls_printf(str, - "{%d %d %d %d %d} ", + "{%ld %ld %d %d %d} ", mp->mt_low, mp->mt_high, mp->mt_r, diff --git a/src/librt/material/material.c b/src/librt/material/material.c index d756b53f405..b13a07c7100 100644 --- a/src/librt/material/material.c +++ b/src/librt/material/material.c @@ -281,6 +281,100 @@ int rt_material_export5(struct bu_external *ep, const struct rt_db_internal *ip, return 0; /* OK */ } +void +rt_material_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_material_internal* ip; + + intern->idb_type = ID_MATERIAL; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_material_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_MATERIAL_MAGIC; + BU_VLS_INIT(&ip->name); + BU_VLS_INIT(&ip->parent); + BU_VLS_INIT(&ip->source); + BU_AVS_INIT(&ip->physicalProperties); + BU_AVS_INIT(&ip->mechanicalProperties); + BU_AVS_INIT(&ip->opticalProperties); + BU_AVS_INIT(&ip->thermalProperties); +} + +int +rt_material_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, const char **argv) +{ + struct rt_material_internal *material = (struct rt_material_internal *)intern->idb_ptr; + + while (argv && argc >= 2) { + const char* prop = *argv++; + argc--; + + if (BU_STR_EQUAL(prop, "name")) { + BU_VLS_INIT(&material->name); + bu_vls_strcpy(&material->name, *argv++); + argc--; + } else if (BU_STR_EQUAL(prop, "parent")) { + BU_VLS_INIT(&material->parent); + bu_vls_strcpy(&material->parent, *argv++); + argc--; + } else if (BU_STR_EQUAL(prop, "source")) { + BU_VLS_INIT(&material->source); + bu_vls_strcpy(&material->source, *argv++); + argc--; + } else if (BU_STR_EQUAL(prop, "physical")) { + if (argc < 2) { + bu_vls_printf(logstr, "Error: (%s) requres sub_property / value pair", prop); + return BRLCAD_ERROR; + } + const char* attr = *argv++; + const char* val = *argv++; + bu_avs_remove(&material->physicalProperties, attr); + bu_avs_add(&material->physicalProperties, attr, val); + argc -= 2; + } else if (BU_STR_EQUAL(prop, "mechanical")) { + if (argc < 2) { + bu_vls_printf(logstr, "Error: (%s) requres sub_property / value pair", prop); + return BRLCAD_ERROR; + } + const char* attr = *argv++; + const char* val = *argv++; + bu_avs_remove(&material->mechanicalProperties, attr); + bu_avs_add(&material->mechanicalProperties, attr, val); + argc -= 2; + } else if (BU_STR_EQUAL(prop, "optical")) { + if (argc < 2) { + bu_vls_printf(logstr, "Error: (%s) requres sub_property / value pair", prop); + return BRLCAD_ERROR; + } + const char* attr = *argv++; + const char* val = *argv++; + bu_avs_remove(&material->opticalProperties, attr); + bu_avs_add(&material->opticalProperties, attr, val); + argc -= 2; + } else if (BU_STR_EQUAL(prop, "thermal")) { + if (argc < 2) { + bu_vls_printf(logstr, "Error: (%s) requres sub_property / value pair", prop); + return BRLCAD_ERROR; + } + const char* attr = *argv++; + const char* val = *argv++; + bu_avs_remove(&material->thermalProperties, attr); + bu_avs_add(&material->thermalProperties, attr, val); + argc -= 2; + } else { + bu_vls_printf(logstr, "an error occurred finding the material property group: (%s)", prop); + return BRLCAD_ERROR; + } + } + + return BRLCAD_OK; +} + /** * Make human-readable formatted presentation of this object. First diff --git a/src/librt/primitives/arb8/arb8.c b/src/librt/primitives/arb8/arb8.c index 79a2c2f1136..e374322aead 100644 --- a/src/librt/primitives/arb8/arb8.c +++ b/src/librt/primitives/arb8/arb8.c @@ -255,6 +255,7 @@ rt_arb_get_cgtype( for (j = i + 1; j < 8; j++) { /* check if points are "equal" */ if (VNEAR_EQUAL(arb->pt[i], arb->pt[j], tol->dist)) { + if (si >= 10) break; /* too many equal points - can't write past array size */ svec[++si] = j; unique = 0; } diff --git a/src/librt/primitives/arbn/arbn.c b/src/librt/primitives/arbn/arbn.c index 9fbcffe213e..d65c980fa86 100644 --- a/src/librt/primitives/arbn/arbn.c +++ b/src/librt/primitives/arbn/arbn.c @@ -1304,6 +1304,25 @@ rt_arbn_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, c return BRLCAD_OK; } +void +rt_arbn_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_arbn_internal *aip; + + intern->idb_type = ID_ARBN; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(aip, struct rt_arbn_internal); + intern->idb_ptr = (void *)aip; + + aip->magic = RT_ARBN_INTERNAL_MAGIC; + aip->neqn = 1; + aip->eqn = (plane_t *)bu_calloc(aip->neqn, sizeof(plane_t), "arbn plane"); +} + int rt_arbn_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/brep/brep.cpp b/src/librt/primitives/brep/brep.cpp index eca5179f19e..50df0c2a1f9 100644 --- a/src/librt/primitives/brep/brep.cpp +++ b/src/librt/primitives/brep/brep.cpp @@ -81,6 +81,7 @@ extern "C" { int rt_brep_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip); void rt_brep_ifree(struct rt_db_internal *ip); int rt_brep_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local); + void rt_brep_make(const struct rt_functab *ftp, struct rt_db_internal *intern); int rt_brep_params(struct pc_pc_set *, const struct rt_db_internal *ip); RT_EXPORT extern int rt_brep_boolean(struct rt_db_internal *out, const struct rt_db_internal *ip1, const struct rt_db_internal *ip2, db_op_t operation); struct rt_selection_set *rt_brep_find_selections(const struct rt_db_internal *ip, const struct rt_selection_query *query); @@ -2397,9 +2398,8 @@ rt_brep_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, c bu_vls_printf(logstr, "%s", ON_String(wonstr).Array()); ON_ModelGeometryComponent *mo = ON_ModelGeometryComponent::Cast(model.ImageFromIndex(0).ExclusiveModelComponent()); bi->brep = ON_Brep::New(*ON_Brep::Cast(mo->Geometry(nullptr))); - return 0; } - return -1; + return BRLCAD_OK; } @@ -2532,6 +2532,24 @@ rt_brep_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbos return 0; } +void +rt_brep_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_brep_internal* ip; + + intern->idb_type = ID_BREP; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_brep_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_BREP_INTERNAL_MAGIC; + ip->brep = (ON_Brep *)brep_create(); +} + int rt_brep_params(struct pc_pc_set *, const struct rt_db_internal *) @@ -3001,17 +3019,17 @@ rt_brep_prep_serialize(struct soltab *stp, const struct rt_db_internal *ip, stru } } -int rt_brep_plot_poly(struct bu_list *vhead, const struct db_full_path *pathp, struct rt_db_internal *ip, +int rt_brep_plot_poly(struct bu_list *vhead, const struct directory *dp, struct rt_db_internal *ip, const struct bg_tess_tol *ttol, const struct bn_tol *tol, const struct bview *UNUSED(info)) { TRACE1("rt_brep_plot"); - if (!vhead || !pathp || pathp->fp_len <= 0 || !ip || !ttol || !tol) + if (!vhead || dp == RT_DIR_NULL || !ip || !ttol || !tol) return -1; struct rt_brep_internal* bi; - const char *solid_name = DB_FULL_PATH_CUR_DIR(pathp)->d_namep; + const char *solid_name = dp->d_namep; ON_wString wstr; ON_TextLog tl(wstr); diff --git a/src/librt/primitives/bspline/bspline.cpp b/src/librt/primitives/bspline/bspline.cpp index 91f85a8725f..856a121afe9 100644 --- a/src/librt/primitives/bspline/bspline.cpp +++ b/src/librt/primitives/bspline/bspline.cpp @@ -1078,7 +1078,9 @@ rt_nurb_import5(struct rt_db_internal *ip, const struct bu_external *ep, const f sip->nsrf = ntohl(*(uint32_t *)cp); cp += SIZEOF_NETWORK_LONG; - sip->srfs = (struct face_g_snurb **) bu_calloc(sip->nsrf, sizeof(struct face_g_snurb *), "nurb srfs[]"); + + if (sip->nsrf > 0) + sip->srfs = (struct face_g_snurb **) bu_calloc(sip->nsrf, sizeof(struct face_g_snurb *), "nurb srfs[]"); for (s = 0; s < sip->nsrf; s++) { struct face_g_snurb *srf; diff --git a/src/librt/primitives/ehy/ehy.c b/src/librt/primitives/ehy/ehy.c index 6e9694238ba..51cf9a1d531 100644 --- a/src/librt/primitives/ehy/ehy.c +++ b/src/librt/primitives/ehy/ehy.c @@ -1946,6 +1946,29 @@ rt_ehy_ifree(struct rt_db_internal *ip) ip->idb_ptr = ((void *)0); /* sanity */ } +void +rt_ehy_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_ehy_internal* ehy_ip; + + intern->idb_type = ID_EHY; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ehy_ip, struct rt_ehy_internal); + intern->idb_ptr = (void *)ehy_ip; + + ehy_ip->ehy_magic = RT_EHY_INTERNAL_MAGIC; + VSETALL(ehy_ip->ehy_V, 0); + VSET(ehy_ip->ehy_H, 0.0, 0.0, 1.0); + VSET(ehy_ip->ehy_Au, 0.0, 1.0, 0.0); + ehy_ip->ehy_r1 = 1.0; + ehy_ip->ehy_r2 = 1.0; + ehy_ip->ehy_c = 1.0; +} + int rt_ehy_params(struct pc_pc_set *ps, const struct rt_db_internal *ip) diff --git a/src/librt/primitives/epa/epa.c b/src/librt/primitives/epa/epa.c index 26423b3208f..2c07b4d18a2 100644 --- a/src/librt/primitives/epa/epa.c +++ b/src/librt/primitives/epa/epa.c @@ -1916,6 +1916,28 @@ rt_epa_ifree(struct rt_db_internal *ip) ip->idb_ptr = ((void *)0); /* sanity */ } +void +rt_epa_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_epa_internal* epa_ip; + + intern->idb_type = ID_EPA; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(epa_ip, struct rt_epa_internal); + intern->idb_ptr = (void *)epa_ip; + + epa_ip->epa_magic = RT_EPA_INTERNAL_MAGIC; + VSETALL(epa_ip->epa_V, 0); + VSET(epa_ip->epa_H, 0.0, 0.0, 1.0); + VSET(epa_ip->epa_Au, 0.0, 1.0, 0.0); + epa_ip->epa_r1 = 1.0; + epa_ip->epa_r2 = 1.0; +} + int rt_epa_params(struct pc_pc_set *ps, const struct rt_db_internal *ip) diff --git a/src/librt/primitives/eto/eto.c b/src/librt/primitives/eto/eto.c index bd6ee4cb12b..9f40e278a76 100644 --- a/src/librt/primitives/eto/eto.c +++ b/src/librt/primitives/eto/eto.c @@ -1587,6 +1587,28 @@ rt_eto_ifree(struct rt_db_internal *ip) ip->idb_ptr = ((void *)0); /* sanity */ } +void +rt_eto_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_eto_internal* eto_ip; + + intern->idb_type = ID_ETO; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(eto_ip, struct rt_eto_internal); + intern->idb_ptr = (void *)eto_ip; + + eto_ip->eto_magic = RT_ETO_INTERNAL_MAGIC; + VSETALL(eto_ip->eto_V, 0); + VSET(eto_ip->eto_N, 0.0, 0.0, 1.0); + VSET(eto_ip->eto_C, 1.0, 0.0, 0.0); + eto_ip->eto_r = 1.0; + eto_ip->eto_rd = 1.0; +} + int rt_eto_params(struct pc_pc_set *ps, const struct rt_db_internal *ip) diff --git a/src/librt/primitives/extrude/extrude.c b/src/librt/primitives/extrude/extrude.c index 3b3a4b47911..7d09c75ef8e 100644 --- a/src/librt/primitives/extrude/extrude.c +++ b/src/librt/primitives/extrude/extrude.c @@ -2841,6 +2841,24 @@ rt_extrude_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc return BRLCAD_OK; } +void +rt_extrude_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_extrude_internal* ip; + + intern->idb_type = ID_EXTRUDE; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_extrude_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_EXTRUDE_INTERNAL_MAGIC; + ip->sketch_name = bu_strdup(""); +} + int rt_extrude_params(struct pc_pc_set *ps, const struct rt_db_internal *ip) diff --git a/src/librt/primitives/joint/joint.c b/src/librt/primitives/joint/joint.c index 9ed790d3013..049bf295343 100644 --- a/src/librt/primitives/joint/joint.c +++ b/src/librt/primitives/joint/joint.c @@ -479,6 +479,28 @@ rt_joint_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, return -1; } +void +rt_joint_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_joint_internal* ip; + + intern->idb_type = ID_JOINT; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_joint_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_JOINT_INTERNAL_MAGIC; + struct bu_vls empty = BU_VLS_INIT_ZERO; + ip->reference_path_1 = empty; + ip->reference_path_2 = empty; + VSET(ip->vector1, 0.0, 1.0, 0.0); + VSET(ip->vector2, 0.0, 1.0, 0.0); +} + int rt_joint_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/metaball/metaball.c b/src/librt/primitives/metaball/metaball.c index e76eb0710f1..58879565e8a 100644 --- a/src/librt/primitives/metaball/metaball.c +++ b/src/librt/primitives/metaball/metaball.c @@ -861,6 +861,24 @@ rt_metaball_add_point(struct rt_metaball_internal *mb, const point_t *loc, const return 0; } +void +rt_metaball_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_metaball_internal* ip; + + intern->idb_type = ID_METABALL; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_metaball_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_METABALL_INTERNAL_MAGIC; + BU_LIST_INIT(&ip->metaball_ctrl_head); +} + int rt_metaball_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/nmg/nmg.c b/src/librt/primitives/nmg/nmg.c index 6c97a5ec75a..ef74a82ae32 100644 --- a/src/librt/primitives/nmg/nmg.c +++ b/src/librt/primitives/nmg/nmg.c @@ -39,6 +39,7 @@ #include "bg/polygon.h" #include "nmg.h" #include "rt/db4.h" +#include "rt/conv.h" #include "raytrace.h" #include "../../librt_private.h" @@ -2256,77 +2257,6 @@ nmg_stash_model_to_file(const char *filename, const struct model *m, const char filename); } - -/* moved from nmg_bool.c - not sure where it should ultimately end up... */ - - -/** - * Called from db_walk_tree() each time a tree leaf is encountered. - * The primitive solid, in external format, is provided in 'ep', and - * the type of that solid (e.g. ID_ELL) is in 'id'. The full tree - * state including the accumulated transformation matrix and the - * current tolerancing is in 'tsp', and the full path from root to - * leaf is in 'pathp'. - * - * Import the solid, tessellate it into an NMG, stash a pointer to the - * tessellation in a new tree structure (union), and return a pointer - * to that. - * - * Usually given as an argument to, and called from db_walk_tree(). - * - * This routine must be prepared to run in parallel. - */ -union tree * -nmg_booltree_leaf_tess(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *UNUSED(client_data)) -{ - struct model *m; - struct nmgregion *r1 = (struct nmgregion *)NULL; - union tree *curtree; - struct directory *dp; - - if (!tsp || !pathp || !ip) - return TREE_NULL; - - RT_CK_DB_INTERNAL(ip); - RT_CK_FULL_PATH(pathp); - dp = DB_FULL_PATH_CUR_DIR(pathp); - RT_CK_DIR(dp); - - if (!ip->idb_meth || !ip->idb_meth->ft_tessellate) { - bu_log("ERROR(%s): tessellation support not available\n", dp->d_namep); - return TREE_NULL; - } - - NMG_CK_MODEL(*tsp->ts_m); - BN_CK_TOL(tsp->ts_tol); - BG_CK_TESS_TOL(tsp->ts_ttol); - RT_CK_RESOURCE(tsp->ts_resp); - - m = nmg_mm(); - - if (ip->idb_meth->ft_tessellate(&r1, m, ip, tsp->ts_ttol, tsp->ts_tol) < 0) { - bu_log("ERROR(%s): tessellation failure\n", dp->d_namep); - return TREE_NULL; - } - - NMG_CK_REGION(r1); - if (nmg_debug & NMG_DEBUG_VERIFY) { - nmg_vshell(&r1->s_hd, r1); - } - - BU_GET(curtree, union tree); - RT_TREE_INIT(curtree); - curtree->tr_op = OP_NMG_TESS; - curtree->tr_d.td_name = bu_strdup(dp->d_namep); - curtree->tr_d.td_r = r1; - - if (RT_G_DEBUG&RT_DEBUG_TREEWALK) - bu_log("nmg_booltree_leaf_tess(%s) OK\n", dp->d_namep); - - return curtree; -} - - /** * Called from db_walk_tree() each time a tree leaf is encountered. * The primitive solid, in external format, is provided in 'ep', and @@ -2373,7 +2303,7 @@ nmg_booltree_leaf_tnurb(struct db_tree_state *tsp, const struct db_full_path *pa BU_GET(curtree, union tree); RT_TREE_INIT(curtree); - curtree->tr_op = OP_NMG_TESS; + curtree->tr_op = OP_TESS; curtree->tr_d.td_name = bu_strdup(dp->d_namep); curtree->tr_d.td_r = r1; @@ -2383,232 +2313,82 @@ nmg_booltree_leaf_tnurb(struct db_tree_state *tsp, const struct db_full_path *pa return curtree; } - /* quell the output of nmg_booltree_evaluate() to bu_log. */ int nmg_bool_eval_silent=0; /** - * Given a tree of leaf nodes tessellated earlier by - * nmg_booltree_leaf_tess(), use recursion to do a depth-first - * traversal of the tree, evaluating each pair of boolean operations - * and reducing that result to a single nmgregion. - * - * Usually called from a do_region_end() handler from db_walk_tree(). - * For an example of several, see mged/dodraw.c. - * - * Returns an OP_NMG_TESS union tree node, which will contain the - * resulting region and its name, as a dynamic string. The caller is - * responsible for releasing the string, and the node, by calling - * db_free_tree() on the node. - * * It is *essential* that the caller call nmg_model_fuse() before - * calling this subroutine. - * - * Returns NULL if there is no geometry to return. + * using this subroutine. * * Typical calls will be of this form: * (void)nmg_model_fuse(m, tol); - * curtree = nmg_booltree_evaluate(curtree, tol); + * curtree = rt_booltree_evaluate(curtree, vlfree, tol, resp, &rt_nmg_do_bool, 0, NULL); */ -union tree * -nmg_booltree_evaluate(register union tree *tp, struct bu_list *vlfree, const struct bn_tol *tol, struct resource *resp) -{ - union tree *tl; - union tree *tr; - struct nmgregion *reg; - int op = NMG_BOOL_ADD; /* default value */ - const char *op_str = " u "; /* default value */ - size_t rem; - char *name; - - RT_CK_TREE(tp); - BN_CK_TOL(tol); - RT_CK_RESOURCE(resp); - - switch (tp->tr_op) { - case OP_NOP: - return TREE_NULL; - case OP_NMG_TESS: - /* Hit a tree leaf */ - if (nmg_debug & NMG_DEBUG_VERIFY) { - nmg_vshell(&tp->tr_d.td_r->s_hd, tp->tr_d.td_r); - } - return tp; - case OP_UNION: - op = NMG_BOOL_ADD; - op_str = " u "; - break; - case OP_INTERSECT: - op = NMG_BOOL_ISECT; - op_str = " + "; - break; - case OP_SUBTRACT: - op = NMG_BOOL_SUB; - op_str = " - "; - break; - default: - bu_bomb("nmg_booltree_evaluate(): bad op\n"); - } - - /* Handle a boolean operation node. First get its leaves. */ - tl = nmg_booltree_evaluate(tp->tr_b.tb_left, vlfree, tol, resp); - tr = nmg_booltree_evaluate(tp->tr_b.tb_right, vlfree, tol, resp); - - if (tl) { - RT_CK_TREE(tl); - if (tl != tp->tr_b.tb_left) { - bu_bomb("nmg_booltree_evaluate(): tl != tp->tr_b.tb_left\n"); - } - } - if (tr) { - RT_CK_TREE(tr); - if (tr != tp->tr_b.tb_right) { - bu_bomb("nmg_booltree_evaluate(): tr != tp->tr_b.tb_right\n"); - } - } - - if (!tl && !tr) { - /* left-r == null && right-r == null */ - RT_CK_TREE(tp); - db_free_tree(tp->tr_b.tb_left, resp); - db_free_tree(tp->tr_b.tb_right, resp); - tp->tr_op = OP_NOP; - return TREE_NULL; - } - - if (tl && !tr) { - /* left-r != null && right-r == null */ - RT_CK_TREE(tp); - db_free_tree(tp->tr_b.tb_right, resp); - if (op == NMG_BOOL_ISECT) { - /* OP_INTERSECT '+' */ - RT_CK_TREE(tp); - db_free_tree(tl, resp); - tp->tr_op = OP_NOP; - return TREE_NULL; - } else { - /* copy everything from tl to tp no matter which union type - * could probably have done a mem-copy - */ - tp->tr_op = tl->tr_op; - tp->tr_b.tb_regionp = tl->tr_b.tb_regionp; - tp->tr_b.tb_left = tl->tr_b.tb_left; - tp->tr_b.tb_right = tl->tr_b.tb_right; - - /* null data from tl so only to free this node */ - tl->tr_b.tb_regionp = (struct region *)NULL; - tl->tr_b.tb_left = TREE_NULL; - tl->tr_b.tb_right = TREE_NULL; - - db_free_tree(tl, resp); - return tp; - } - } - - if (!tl && tr) { - /* left-r == null && right-r != null */ - RT_CK_TREE(tp); - db_free_tree(tp->tr_b.tb_left, resp); - if (op == NMG_BOOL_ADD) { - /* OP_UNION 'u' */ - /* copy everything from tr to tp no matter which union type - * could probably have done a mem-copy - */ - tp->tr_op = tr->tr_op; - tp->tr_b.tb_regionp = tr->tr_b.tb_regionp; - tp->tr_b.tb_left = tr->tr_b.tb_left; - tp->tr_b.tb_right = tr->tr_b.tb_right; - - /* null data from tr so only to free this node */ - tr->tr_b.tb_regionp = (struct region *)NULL; - tr->tr_b.tb_left = TREE_NULL; - tr->tr_b.tb_right = TREE_NULL; - - db_free_tree(tr, resp); - return tp; - - } else if ((op == NMG_BOOL_SUB) || (op == NMG_BOOL_ISECT)) { - /* for sub and intersect, if left-hand-side is null, result is null */ - RT_CK_TREE(tp); - db_free_tree(tr, resp); - tp->tr_op = OP_NOP; - return TREE_NULL; - - } else { - bu_bomb("nmg_booltree_evaluate(): error, unknown operation\n"); - } - } - - if (tl->tr_op != OP_NMG_TESS) { - bu_bomb("nmg_booltree_evaluate(): bad left tree\n"); - } - if (tr->tr_op != OP_NMG_TESS) { - bu_bomb("nmg_booltree_evaluate(): bad right tree\n"); - } - - if (!nmg_bool_eval_silent) { - bu_log(" {%s}%s{%s}\n", tl->tr_d.td_name, op_str, tr->tr_d.td_name); +int +rt_nmg_do_bool( + union tree *tp, union tree *tl, union tree *tr, + int op, struct bu_list *vlfree, const struct bn_tol *tol, void *UNUSED(data)) +{ + int nmg_op = NMG_BOOL_ADD; + switch (op) { + case OP_UNION: + nmg_op = NMG_BOOL_ADD; + break; + case OP_INTERSECT: + nmg_op = NMG_BOOL_ISECT; + break; + case OP_SUBTRACT: + nmg_op = NMG_BOOL_SUB; + break; + default: + nmg_op = NMG_BOOL_ADD; } NMG_CK_REGION(tr->tr_d.td_r); NMG_CK_REGION(tl->tr_d.td_r); - if (nmg_ck_closed_region(tr->tr_d.td_r, tol)) { - bu_bomb("nmg_booltree_evaluate(): ERROR, non-closed shell (r)\n"); - } - if (nmg_ck_closed_region(tl->tr_d.td_r, tol)) { - bu_bomb("nmg_booltree_evaluate(): ERROR, non-closed shell (l)\n"); - } + if (nmg_ck_closed_region(tr->tr_d.td_r, tol)) + bu_bomb("rt_nmg_do_bool(): ERROR, non-closed shell (r)\n"); + + if (tl->tr_d.td_r && nmg_ck_closed_region(tl->tr_d.td_r, tol)) + bu_bomb("rt_nmg_do_bool(): ERROR, non-closed shell (l)\n"); nmg_r_radial_check(tr->tr_d.td_r, vlfree, tol); nmg_r_radial_check(tl->tr_d.td_r, vlfree, tol); if (nmg_debug & NMG_DEBUG_BOOL) { - bu_log("Before model fuse\nShell A:\n"); - nmg_pr_s_briefly(BU_LIST_FIRST(shell, &tl->tr_d.td_r->s_hd), ""); - bu_log("Shell B:\n"); - nmg_pr_s_briefly(BU_LIST_FIRST(shell, &tr->tr_d.td_r->s_hd), ""); + bu_log("Before model fuse\nShell A:\n"); + nmg_pr_s_briefly(BU_LIST_FIRST(shell, &tl->tr_d.td_r->s_hd), ""); + bu_log("Shell B:\n"); + nmg_pr_s_briefly(BU_LIST_FIRST(shell, &tr->tr_d.td_r->s_hd), ""); } /* move operands into the same model */ - if (tr->tr_d.td_r->m_p != tl->tr_d.td_r->m_p) { - nmg_merge_models(tl->tr_d.td_r->m_p, tr->tr_d.td_r->m_p); - } + if (tr->tr_d.td_r->m_p != tl->tr_d.td_r->m_p) + nmg_merge_models(tl->tr_d.td_r->m_p, tr->tr_d.td_r->m_p); /* input r1 and r2 are destroyed, output is new region */ - reg = nmg_do_bool(tl->tr_d.td_r, tr->tr_d.td_r, op, vlfree, tol); - - /* build string of result name */ - rem = strlen(tl->tr_d.td_name) + 3 + strlen(tr->tr_d.td_name) + 2 + 1; - name = (char *)bu_calloc(rem, sizeof(char), "nmg_booltree_evaluate name"); - snprintf(name, rem, "(%s%s%s)", tl->tr_d.td_name, op_str, tr->tr_d.td_name); - - /* clean up child tree nodes */ - tl->tr_d.td_r = (struct nmgregion *)NULL; - tr->tr_d.td_r = (struct nmgregion *)NULL; - db_free_tree(tl, resp); - db_free_tree(tr, resp); - - + struct nmgregion *reg = nmg_do_bool(tl->tr_d.td_r, tr->tr_d.td_r, nmg_op, vlfree, tol); if (reg) { - /* convert argument binary node into a result node */ - NMG_CK_REGION(reg); - nmg_r_radial_check(reg, vlfree, tol); - tp->tr_op = OP_NMG_TESS; - tp->tr_d.td_r = reg; - tp->tr_d.td_name = name; - - if (nmg_debug & NMG_DEBUG_VERIFY) { - nmg_vshell(®->s_hd, reg); - } - return tp; - - } else { - /* resulting region was null */ - tp->tr_op = OP_NOP; - return TREE_NULL; + /* convert argument binary node into a result node */ + NMG_CK_REGION(reg); + nmg_r_radial_check(reg, vlfree, tol); + tp->tr_op = OP_TESS; + tp->tr_d.td_r = reg; + if (nmg_debug & NMG_DEBUG_VERIFY) { + nmg_vshell(®->s_hd, reg); + } + return 0; } + /* resulting region was null */ + return -1; +} + +union tree * +nmg_booltree_evaluate(register union tree *tp, struct bu_list *vlfree, const struct bn_tol *tol, struct resource *resp) +{ + return rt_booltree_evaluate(tp, vlfree, tol, resp, &rt_nmg_do_bool, nmg_bool_eval_silent, NULL); } #if 0 @@ -2655,7 +2435,7 @@ nmg_find_leaves(register union tree *tp, struct bu_ptbl *regions) switch (tp->tr_op) { case OP_NOP: return; - case OP_NMG_TESS: + case OP_TESS: /* Hit a tree leaf */ bu_ptbl_ins_unique(regions, (long *)tp->tr_d.td_r); return; @@ -2692,6 +2472,8 @@ nmg_perturb_tree(union tree *tp) } #endif + + /** * This is the main application interface to the NMG Boolean * Evaluator. @@ -2722,27 +2504,11 @@ nmg_boolean(union tree *tp, struct model *m, struct bu_list *vlfree, const struc (void *)tp, (void *)m); } - /* The nmg_model_fuse function was removed from this point in the - * boolean process since not all geometry that is to be processed is - * always within the single 'm' nmg model structure passed into this - * function. In some cases the geometry resides in multiple nmg model - * structures within the 'tp' tree that is passed into this function. - * Running nmg_model_fuse is still required but is done later, i.e. - * within the nmg_booltree_evaluate function just before the nmg_do_bool - * function is called which is when the geometry, in which the boolean - * to be performed, is always in a single nmg model structure. - */ - -#if 0 - /* TODO - this doesn't seem to help any... */ - nmg_perturb_tree(tp); -#endif - /* * Evaluate the nodes of the boolean tree one at a time, until * only a single region remains. */ - result = nmg_booltree_evaluate(tp, vlfree, tol, resp); + result = rt_booltree_evaluate(tp, vlfree, tol, resp, &rt_nmg_do_bool, nmg_bool_eval_silent, NULL); if (result == TREE_NULL) { bu_log("nmg_boolean(): result of nmg_booltree_evaluate() is NULL\n"); @@ -2757,8 +2523,8 @@ nmg_boolean(union tree *tp, struct model *m, struct bu_list *vlfree, const struc RT_CK_TREE(result); - if (tp->tr_op != OP_NMG_TESS) { - bu_log("nmg_boolean(): result of nmg_booltree_evaluate() op != OP_NMG_TESS\n"); + if (tp->tr_op != OP_TESS) { + bu_log("nmg_boolean(): result of nmg_booltree_evaluate() op != OP_TESS\n"); rt_pr_tree(tp, 0); ret = 1; goto out; diff --git a/src/librt/primitives/pipe/pipe.c b/src/librt/primitives/pipe/pipe.c index 6f699e4904f..651d4166144 100644 --- a/src/librt/primitives/pipe/pipe.c +++ b/src/librt/primitives/pipe/pipe.c @@ -4594,6 +4594,36 @@ rt_pipe_adjust( return (rt_pipe_ck(&pip->pipe_segs_head) == 0) ? BRLCAD_OK : BRLCAD_ERROR; } +void +rt_pipe_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_pipe_internal* pipe_ip; + struct wdb_pipe_pnt* pipe_pp; + + intern->idb_type = ID_PIPE; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(pipe_ip, struct rt_pipe_internal); + intern->idb_ptr = (void *)pipe_ip; + + pipe_ip->pipe_magic = RT_PIPE_INTERNAL_MAGIC; + + BU_LIST_INIT(&pipe_ip->pipe_segs_head); + for (int i = 0; i < 2; i++) { + BU_ALLOC(pipe_pp, struct wdb_pipe_pnt); + pipe_pp->l.magic = WDB_PIPESEG_MAGIC; + VSETALL(pipe_pp->pp_coord, i); + + pipe_pp->pp_od = 1; + pipe_pp->pp_id = 0.1 * pipe_pp->pp_od; + pipe_pp->pp_bendradius = pipe_pp->pp_od; + BU_LIST_INSERT(&pipe_ip->pipe_segs_head, &pipe_pp->l); + } +} + int rt_pipe_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/rhc/rhc.c b/src/librt/primitives/rhc/rhc.c index d6c7275ff55..de283822eb0 100644 --- a/src/librt/primitives/rhc/rhc.c +++ b/src/librt/primitives/rhc/rhc.c @@ -1751,6 +1751,28 @@ rt_rhc_ifree(struct rt_db_internal *ip) ip->idb_ptr = ((void *)0); /* sanity */ } +void +rt_rhc_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_rhc_internal* rhc_ip; + + intern->idb_type = ID_RHC; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(rhc_ip, struct rt_rhc_internal); + intern->idb_ptr = (void *)rhc_ip; + + rhc_ip->rhc_magic = RT_RHC_INTERNAL_MAGIC; + VSETALL(rhc_ip->rhc_V, 0); + VSET(rhc_ip->rhc_H, 0.0, 0.0, 1.0); + VSET(rhc_ip->rhc_B, 0.0, 1.0, 0.0); + rhc_ip->rhc_r = 1.0; + rhc_ip->rhc_c = 1.0; +} + int rt_rhc_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/rpc/rpc.c b/src/librt/primitives/rpc/rpc.c index f4207b61ad6..70218944c9d 100644 --- a/src/librt/primitives/rpc/rpc.c +++ b/src/librt/primitives/rpc/rpc.c @@ -1608,6 +1608,28 @@ rt_rpc_ifree(struct rt_db_internal *ip) ip->idb_ptr = ((void *)0); /* sanity */ } +void +rt_rpc_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_rpc_internal* rpc_ip; + + intern->idb_type = ID_RPC; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(rpc_ip, struct rt_rpc_internal); + intern->idb_ptr = (void *)rpc_ip; + + rpc_ip->rpc_magic = RT_RPC_INTERNAL_MAGIC; + VSETALL(rpc_ip->rpc_V, 0); + VSET(rpc_ip->rpc_H, 0.0, 0.0, 1.0); + VSET(rpc_ip->rpc_B, 0.0, 1.0, 0.0); + rpc_ip->rpc_r = 1.0; + +} + int rt_rpc_params(struct pc_pc_set *UNUSED(ps), const struct rt_db_internal *ip) diff --git a/src/librt/primitives/script/script.c b/src/librt/primitives/script/script.c index 79c75cc1a3c..4603fad45fc 100644 --- a/src/librt/primitives/script/script.c +++ b/src/librt/primitives/script/script.c @@ -349,6 +349,24 @@ rt_script_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const return BRLCAD_OK; } +void +rt_script_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_script_internal* ip; + + intern->idb_type = ID_SCRIPT; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_script_internal); + intern->idb_ptr = (void *)ip; + + ip->script_magic = RT_SCRIPT_INTERNAL_MAGIC; + BU_VLS_INIT(&ip->s_type); +} + int rt_script_adjust(struct bu_vls *UNUSED(logstr), struct rt_db_internal *intern, int UNUSED(argc), const char **UNUSED(argv)) diff --git a/src/librt/primitives/sketch/polygons.c b/src/librt/primitives/sketch/polygons.c index 4b2e9dfd46a..4365f89c435 100644 --- a/src/librt/primitives/sketch/polygons.c +++ b/src/librt/primitives/sketch/polygons.c @@ -60,33 +60,12 @@ struct contour_node { struct bu_list head; }; -/** - * FIXME: this routine is suspect and needs investigating. if run - * during view initialization, the shaders regression test fails. - */ -void -_sketch_mat_aet(struct bview *gvp) -{ - mat_t tmat; - fastf_t twist; - fastf_t c_twist; - fastf_t s_twist; - - bn_mat_angles(gvp->gv_rotation, - 270.0 + gvp->gv_aet[1], - 0.0, - 270.0 - gvp->gv_aet[0]); - - twist = -gvp->gv_aet[2] * DEG2RAD; - c_twist = cos(twist); - s_twist = sin(twist); - bn_mat_zrot(tmat, s_twist, c_twist); - bn_mat_mul2(tmat, gvp->gv_rotation); -} - struct bv_scene_obj * -db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *dp, struct bview *sv) +db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *dp, struct bview *sv, int flags) { + if (!sv) + return NULL; + // Begin import size_t ncontours = 0; struct bu_list HeadSegmentNodes; @@ -216,18 +195,24 @@ db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *d ++j; } + /* Unlike interactive sketch creation, the plane of an imported sketch comes from the + * sketch parameters. */ + vect_t pn; + VCROSS(pn, sketch_ip->u_vec, sketch_ip->v_vec); + bg_plane_pt_nrml(&p->vp, sketch_ip->V, pn); + /* Clean up */ bu_free((void *)all_segment_nodes, "all_segment_nodes"); /* Create the scene object here so we can read a default color */ - struct bv_scene_obj *s = bv_create_polygon_obj(sv, p); + struct bv_scene_obj *s = bv_create_polygon_obj(sv, flags, p); if (!s) { bg_polygon_free(&p->polygon); BU_PUT(p, struct bv_polygon); return NULL; } - bu_vls_init(&s->s_uuid); - bu_vls_printf(&s->s_uuid, "%s", sname); + bu_vls_init(&s->s_name); + bu_vls_printf(&s->s_name, "%s", sname); // check attributes for visual properties int have_view = 1; @@ -284,7 +269,7 @@ db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *d if (have_view) { val = bu_avs_get(&lavs, "VIEWSCALE"); if (val) { - bu_opt_fastf_t(NULL, 1, (const char **)&val, (void *)&p->v.gv_scale); + bu_opt_fastf_t(NULL, 1, (const char **)&val, (void *)&sv->gv_scale); } else { have_view = 0; } @@ -302,7 +287,7 @@ db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *d bu_opt_fastf_t(NULL, 1, (const char **)&av[1], (void *)&quat[1]); bu_opt_fastf_t(NULL, 1, (const char **)&av[2], (void *)&quat[2]); bu_opt_fastf_t(NULL, 1, (const char **)&av[3], (void *)&quat[3]); - quat_quat2mat(p->v.gv_rotation, quat); + quat_quat2mat(sv->gv_rotation, quat); } bu_free(lp, "val cpy"); } else { @@ -322,7 +307,7 @@ db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *d bu_opt_fastf_t(NULL, 1, (const char **)&av[1], (void *)&quat[1]); bu_opt_fastf_t(NULL, 1, (const char **)&av[2], (void *)&quat[2]); bu_opt_fastf_t(NULL, 1, (const char **)&av[3], (void *)&quat[3]); - quat_quat2mat(p->v.gv_center, quat); + quat_quat2mat(sv->gv_center, quat); } bu_free(lp, "val cpy"); } else { @@ -332,38 +317,11 @@ db_sketch_to_scene_obj(const char *sname, struct db_i *dbip, struct directory *d } bu_avs_free(&lavs); - /* If we didn't have a saved version, construct an appropriate bv from the - * sketch's 3D info so we can snap to it. autoview, then dir. TODO - this - * needs improvement... */ + /* TODO - if we didn't have a saved version, construct an appropriate plane from the + * sketch's 3D info so we can snap to it. */ if (!have_view) { - struct bview *v = &p->v; - bv_init(v, NULL); - vect_t center = VINIT_ZERO; - vect_t min, max; - VSETALL(min, -dmax); - VSETALL(max, dmax); - vect_t radial; - VADD2SCALE(center, max, min, 0.5); - VSUB2(radial, max, center); - if (VNEAR_ZERO(radial, SQRT_SMALL_FASTF)) - VSETALL(radial, 1.0); - MAT_IDN(v->gv_center); - MAT_DELTAS_VEC_NEG(v->gv_center, center); - v->gv_scale = radial[X]; - V_MAX(v->gv_scale, radial[Y]); - V_MAX(v->gv_scale, radial[Z]); - v->gv_size = 2.0 * v->gv_scale; - v->gv_isize = 1.0 / v->gv_size; - bv_update(v); - - vect_t snorm; - VCROSS(snorm, sketch_ip->u_vec, sketch_ip->v_vec); - AZEL_FROM_V3DIR(p->v.gv_aet[0], p->v.gv_aet[1], snorm); - _sketch_mat_aet(&p->v); } - bv_update(&p->v); - /* Have new polygon, now update view object vlist */ bv_polygon_vlist(s); @@ -384,13 +342,13 @@ db_scene_obj_to_sketch(struct db_i *dbip, const char *sname, struct bv_scene_obj return NULL; } + if (!s->s_v) + return NULL; + size_t num_verts = 0; struct rt_db_internal internal; struct rt_sketch_internal *sketch_ip; struct line_seg *lsg; - vect_t view; - point_t vorigin; - mat_t invRot; struct bv_polygon *p = (struct bv_polygon *)s->s_i_data; for (size_t j = 0; j < p->polygon.num_contours; ++j) @@ -414,36 +372,23 @@ db_scene_obj_to_sketch(struct db_i *dbip, const char *sname, struct bv_scene_obj sketch_ip->curve.reverse = (int *)bu_calloc(sketch_ip->curve.count, sizeof(int), "sketch_ip->curve.reverse"); sketch_ip->curve.segment = (void **)bu_calloc(sketch_ip->curve.count, sizeof(void *), "sketch_ip->curve.segment"); - bn_mat_inv(invRot, p->v.gv_rotation); - VSET(view, 1.0, 0.0, 0.0); - MAT4X3PNT(sketch_ip->u_vec, invRot, view); - VSET(view, 0.0, 1.0, 0.0); - MAT4X3PNT(sketch_ip->v_vec, invRot, view); + bg_plane_pt_at(&sketch_ip->u_vec, p->vp, 0, 1); + bg_plane_pt_at(&sketch_ip->v_vec, p->vp, 1, 0); /* should already be unit vectors */ VUNITIZE(sketch_ip->u_vec); VUNITIZE(sketch_ip->v_vec); - /* Project the origin onto the front of the viewing cube */ - MAT4X3PNT(vorigin, p->v.gv_model2view, p->v.gv_center); - vorigin[Z] = p->v.gv_data_vZ; - - /* Convert back to model coordinates for storage */ - MAT4X3PNT(sketch_ip->V, p->v.gv_view2model, vorigin); + /* Plane origin is sketch origin */ + bg_plane_pt_at(&sketch_ip->V, p->vp, 0, 0); int n = 0; for (size_t j = 0; j < p->polygon.num_contours; ++j) { size_t cstart = n; size_t k = 0; for (k = 0; k < p->polygon.contour[j].num_points; ++k) { - point_t vpt; - vect_t vdiff; - - MAT4X3PNT(vpt, p->v.gv_model2view, p->polygon.contour[j].point[k]); - VSUB2(vdiff, vpt, vorigin); - VSCALE(vdiff, vdiff, p->v.gv_scale); - V2MOVE(sketch_ip->verts[n], vdiff); + bg_plane_closest_pt(&sketch_ip->verts[n][1], &sketch_ip->verts[n][0], p->vp, p->polygon.contour[j].point[k]); if (k) { BU_ALLOC(lsg, struct line_seg); @@ -514,14 +459,14 @@ db_scene_obj_to_sketch(struct db_i *dbip, const char *sname, struct bv_scene_obj } bu_avs_add(&lavs, "POLYGON_TYPE", bu_vls_cstr(&val)); // Save view - bu_vls_sprintf(&val, "%.15e", p->v.gv_scale); + bu_vls_sprintf(&val, "%.15e", s->s_v->gv_scale); bu_avs_add(&lavs, "VIEWSCALE", bu_vls_cstr(&val)); quat_t rquat; - quat_mat2quat(rquat, p->v.gv_rotation); + quat_mat2quat(rquat, s->s_v->gv_rotation); bu_vls_sprintf(&val, "%.15e %.15e %.15e %.15e", V4ARGS(rquat)); bu_avs_add(&lavs, "ROTATION", bu_vls_cstr(&val)); quat_t cquat; - quat_mat2quat(cquat, p->v.gv_center); + quat_mat2quat(cquat, s->s_v->gv_center); bu_vls_sprintf(&val, "%.15e %.15e %.15e %.15e", V4ARGS(cquat)); bu_avs_add(&lavs, "CENTER", bu_vls_cstr(&val)); } diff --git a/src/librt/primitives/submodel/submodel.c b/src/librt/primitives/submodel/submodel.c index ed4a65c6bd8..434207dcfa6 100644 --- a/src/librt/primitives/submodel/submodel.c +++ b/src/librt/primitives/submodel/submodel.c @@ -912,6 +912,8 @@ rt_submodel_export5(struct bu_external *ep, const struct rt_db_internal *ip, dou BU_CK_EXTERNAL(ep); bu_vls_struct_print(&str, rt_submodel_parse, (char *)sip); + if (ep->ext_nbytes <= 0) + return 0; ep->ext_nbytes = bu_vls_strlen(&str); ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "submodel external"); @@ -946,6 +948,26 @@ rt_submodel_describe(struct bu_vls *str, const struct rt_db_internal *ip, int ve return 0; } +void +rt_submodel_make(const struct rt_functab *ftp, struct rt_db_internal *intern) +{ + struct rt_submodel_internal* ip; + struct bu_vls empty = BU_VLS_INIT_ZERO; + + intern->idb_type = ID_SUBMODEL; + intern->idb_major_type = DB5_MAJORTYPE_BRLCAD; + + BU_ASSERT(&OBJ[intern->idb_type] == ftp); + intern->idb_meth = ftp; + + BU_ALLOC(ip, struct rt_submodel_internal); + intern->idb_ptr = (void *)ip; + + ip->magic = RT_SUBMODEL_INTERNAL_MAGIC; + ip->file = empty; + ip->treetop = empty; +} + /** * Free the storage associated with the rt_db_internal version of this solid. diff --git a/src/librt/primitives/table.cpp b/src/librt/primitives/table.cpp index 45ee7e3ef61..9a0a8ae67ab 100644 --- a/src/librt/primitives/table.cpp +++ b/src/librt/primitives/table.cpp @@ -854,7 +854,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_arbn_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_arbn_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_arbn_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_arbn_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_arbn_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_arbn_volume), @@ -901,7 +901,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_pipe_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_pipe_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_pipe_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_pipe_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_pipe_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_pipe_volume), @@ -995,7 +995,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_rpc_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_rpc_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_rpc_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_rpc_volume), @@ -1042,7 +1042,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_rhc_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_rhc_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_rhc_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_rhc_volume), @@ -1089,7 +1089,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_epa_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_epa_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_epa_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_epa_volume), @@ -1136,7 +1136,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_ehy_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_ehy_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_ehy_bbox), NULL, /* volume */ @@ -1183,7 +1183,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_eto_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_eto_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_eto_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_eto_volume), @@ -1277,7 +1277,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_joint_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_joint_params), NULL, /* bbox */ NULL, /* volume */ @@ -1509,7 +1509,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_extrude_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_extrude_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_extrude_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_extrude_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_extrude_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_extrude_bbox), RTFUNCTAB_FUNC_VOLUME_CAST(rt_extrude_volume), @@ -1556,7 +1556,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_submodel_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_submodel_params), NULL, /* bbox */ NULL, /* volume */ @@ -1715,7 +1715,7 @@ const struct rt_functab OBJ[] = { /* 32 available placeholder to not offset latter table indices * (was ID_BINEXPM) */ - RT_FUNCTAB_MAGIC, "ID_UNUSED1", "unused1", + RT_FUNCTAB_MAGIC, "ID_UNUSED1", "UNUSED1", 0, /* ft_use_rpp */ NULL, /* prep */ NULL, /* shot */ @@ -1811,7 +1811,7 @@ const struct rt_functab OBJ[] = { /* 34 available placeholder to not offset latter table indices * (was ID_BINMIME) */ - RT_FUNCTAB_MAGIC, "ID_UNUSED2", "unused2", + RT_FUNCTAB_MAGIC, "ID_UNUSED2", "UNUSED2", 0, /* ft_use_rpp */ NULL, /* prep */ NULL, /* shot */ @@ -1936,7 +1936,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_metaball_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_metaball_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_metaball_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_metaball_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_metaball_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_metaball_bbox), NULL, /* volume */ @@ -1983,7 +1983,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_brep_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_brep_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_generic_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_brep_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_brep_params), RTFUNCTAB_FUNC_BBOX_CAST(rt_brep_bbox), NULL, /* volume */ @@ -2064,20 +2064,20 @@ const struct rt_functab OBJ[] = { NULL, /* tess */ NULL, /* tnurb */ NULL, /* brep */ - NULL, /* import5 */ + RTFUNCTAB_FUNC_IMPORT5_CAST(rt_constraint_import5), RTFUNCTAB_FUNC_EXPORT5_CAST(rt_constraint_export5), NULL, /* import4 */ NULL, /* export4 */ RTFUNCTAB_FUNC_IFREE_CAST(rt_constraint_ifree), - NULL, /* describe */ + RTFUNCTAB_FUNC_DESCRIBE_CAST(rt_constraint_describe), NULL, /* xform */ - NULL, /* parse */ - 0, /* sizeof(internal) */ - 0, /* magic */ - NULL, /* get */ - NULL, /* adjust */ + rt_constraint_parse, + sizeof(struct rt_constraint_internal), + RT_CONSTRAINT_MAGIC, + RTFUNCTAB_FUNC_GET_CAST(rt_generic_get), + RTFUNCTAB_FUNC_ADJUST_CAST(rt_generic_adjust), NULL, /* form */ - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_constraint_make), NULL, /* params */ NULL, /* bbox */ NULL, /* volume */ @@ -2361,7 +2361,7 @@ const struct rt_functab OBJ[] = { RTFUNCTAB_FUNC_GET_CAST(rt_script_get), RTFUNCTAB_FUNC_ADJUST_CAST(rt_script_adjust), RTFUNCTAB_FUNC_FORM_CAST(rt_script_form), - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_script_make), RTFUNCTAB_FUNC_PARAMS_CAST(rt_script_params), NULL, /* bbox */ NULL, /* volume */ @@ -2404,11 +2404,11 @@ const struct rt_functab OBJ[] = { NULL, /* xform */ NULL, /* parse */ 0, /* sizeof(internal) */ - 0, /* magic */ + RT_MATERIAL_MAGIC, NULL, /* get */ - NULL, /* adjust */ + RTFUNCTAB_FUNC_ADJUST_CAST(rt_material_adjust), NULL, /* form */ - NULL, /* make */ + RTFUNCTAB_FUNC_MAKE_CAST(rt_material_make), NULL, /* params */ NULL, /* bbox */ NULL, /* volume */ diff --git a/src/librt/tests/CMakeLists.txt b/src/librt/tests/CMakeLists.txt index c3bf4eb49b5..c4a266b1bd4 100644 --- a/src/librt/tests/CMakeLists.txt +++ b/src/librt/tests/CMakeLists.txt @@ -65,16 +65,20 @@ BRLCAD_ADD_TEST(NAME rt_cache_parallel_multiple_different_objects_hierarchy_1 C # lod testing BRLCAD_ADDEXEC(rt_lod lod.c "librt;libbg" TEST) +# bv_polygon <-> sketch testing +BRLCAD_ADDEXEC(rt_bv_poly_sketch bv_poly_sketch.c "librt;libbv" TEST) + set(distcheck_files CMakeLists.txt arb_intersect.g + binary_attribute.c brep_boolean_tests.g cyclic_tests.g + extreme_ssi_test.g matrix_tests.g nurbs_surfaces.g - extreme_ssi_test.g - binary_attribute.c rt_datum.c + sketch.g ) CMAKEFILES(${distcheck_files}) diff --git a/src/librt/tests/bv_poly_sketch.c b/src/librt/tests/bv_poly_sketch.c new file mode 100644 index 00000000000..e6b3c0bfd6b --- /dev/null +++ b/src/librt/tests/bv_poly_sketch.c @@ -0,0 +1,111 @@ +/* B V _ P O L Y _ S K E T C H . C + * BRL-CAD + * + * Copyright (c) 2013-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "common.h" + +#include "vmath.h" +#include "bu/app.h" +#include "bv.h" +#include "raytrace.h" +#include "rt/primitives/sketch.h" +#include "rt/db_diff.h" + +int +main(int argc, char *argv[]) +{ + struct db_i *dbip; + struct directory *dp; + + bu_setprogname(argv[0]); + + if (argc != 2) { + bu_exit(EXIT_FAILURE, "Usage: %s file.g", argv[0]); + } + + // First, open the database and make sure we have poly.s + + dbip = db_open(argv[1], DB_OPEN_READONLY); + if (dbip == DBI_NULL) { + bu_exit(EXIT_FAILURE, "ERROR: Unable to read from %s\n", argv[1]); + } + + if (db_dirbuild(dbip) < 0) { + bu_exit(EXIT_FAILURE, "ERROR: Unable to read from %s\n", argv[1]); + } + + db_update_nref(dbip, &rt_uniresource); + + dp = db_lookup(dbip, "poly.s", LOOKUP_QUIET); + if (dp == RT_DIR_NULL) + bu_exit(EXIT_FAILURE, "ERROR: Unable to look up object poly.s\n"); + + // Create the view + struct bview *v; + BU_GET(v, struct bview); + bv_init(v, NULL); + + struct bv_scene_obj *pobj = db_sketch_to_scene_obj("poly", dbip, dp, v, 0); + + if (!pobj) + bu_exit(EXIT_FAILURE, "Failed to create scene object from poly.s\n"); + + char ofile[MAXPATHLEN]; + bu_dir(ofile, MAXPATHLEN, BU_DIR_CURR, "poly_sketch_out.g", NULL); + struct rt_wdb *wfp = wdb_fopen_v(ofile, 5); + if (!wfp) + bu_exit(EXIT_FAILURE, "Failed to create output database %s\n", ofile); + + struct directory *odp = db_scene_obj_to_sketch(wfp->dbip, "poly.s", pobj); + if (odp == RT_DIR_NULL) + bu_exit(EXIT_FAILURE, "Failed to write scene obj polygon to output database %s\n", ofile); + + const struct bn_tol tol = BN_TOL_INIT_TOL; + int dret = db_diff_dp(dbip, wfp->dbip, dp, odp, &tol, DB_COMPARE_PARAM, NULL); + if (dret) { + struct rt_db_internal ointern, nintern; + int old_id = rt_db_get_internal(&ointern, dp, dbip, NULL, &rt_uniresource); + int new_id = rt_db_get_internal(&nintern, odp, wfp->dbip, NULL, &rt_uniresource); + struct bu_vls msg = BU_VLS_INIT_ZERO; + if (OBJ[old_id].ft_describe) + OBJ[old_id].ft_describe(&msg, &ointern, 100, dbip->dbi_base2local); + bu_log("Original sketch info: %s\n", bu_vls_cstr(&msg)); + bu_vls_trunc(&msg, 0); + if (OBJ[new_id].ft_describe) + OBJ[new_id].ft_describe(&msg, &nintern, 100, wfp->dbip->dbi_base2local); + bu_log("Exported sketch info: %s\n", bu_vls_cstr(&msg)); + bu_vls_free(&msg); + bu_exit(EXIT_FAILURE, "Difference between imported sketch and written sketch\n"); + } + + db_close(dbip); + db_close(wfp->dbip); + + return 0; +} + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/librt/tests/cache.cpp b/src/librt/tests/cache.cpp index 8ab6fc4d4f5..76f082be8fa 100644 --- a/src/librt/tests/cache.cpp +++ b/src/librt/tests/cache.cpp @@ -221,7 +221,7 @@ create_test_g_file(long int test_num, const char *gfile) bu_exit(1, "Test %ld: Stale .g file %s exists\n", test_num, gfile); } - dbip = db_create(gfile, 5); + dbip = db_create(gfile, BRLCAD_DB_FORMAT_LATEST); if (dbip == DBI_NULL) { bu_exit(1, "Test %ld: unable to create test file %s\n", test_num, gfile); diff --git a/src/librt/tests/lod.c b/src/librt/tests/lod.c index 79438c3987c..2511611f56f 100644 --- a/src/librt/tests/lod.c +++ b/src/librt/tests/lod.c @@ -25,7 +25,7 @@ #include "bu/time.h" #include "bu/units.h" #include "bg.h" -#include "bg/lod.h" +#include "bv/lod.h" #include "raytrace.h" int @@ -73,13 +73,13 @@ main(int argc, char *argv[]) if (!bot->num_faces) bu_exit(1, "ERROR: %s - no faces found\n", argv[2]); - struct bg_mesh_lod_context *c = bg_mesh_lod_context_create(argv[1]); + struct bv_mesh_lod_context *c = bv_mesh_lod_context_create(argv[1]); - unsigned long long key = bg_mesh_lod_cache(c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); + unsigned long long key = bv_mesh_lod_cache(c, (const point_t *)bot->vertices, bot->num_vertices, NULL, bot->faces, bot->num_faces, 0, 0.66); if (!key) bu_exit(1, "ERROR: %s - lod creation failed\n", argv[2]); - struct bv_mesh_lod *mlod = bg_mesh_lod_create(c, key); + struct bv_mesh_lod *mlod = bv_mesh_lod_create(c, key); if (!mlod) bu_exit(1, "ERROR: %s - lod creation failed\n", argv[2]); @@ -96,7 +96,7 @@ main(int argc, char *argv[]) start = bu_gettime(); for (int i = 0; i < 16; i++) { - bg_mesh_lod_level(s, i, 0); + bv_mesh_lod_level(s, i, 0); } elapsed = bu_gettime() - start; @@ -104,8 +104,8 @@ main(int argc, char *argv[]) bu_log("lod level setting: %f sec\n", seconds); BU_PUT(s, struct bv_scene_obj); - bg_mesh_lod_destroy(mlod); - bg_mesh_lod_context_destroy(c); + bv_mesh_lod_destroy(mlod); + bv_mesh_lod_context_destroy(c); return 0; } diff --git a/src/librt/tests/sketch.g b/src/librt/tests/sketch.g new file mode 100644 index 00000000000..fea2a83ea6f Binary files /dev/null and b/src/librt/tests/sketch.g differ diff --git a/src/libtclcad/CMakeLists.txt b/src/libtclcad/CMakeLists.txt index e59c23b9d98..b98cd48c4eb 100644 --- a/src/libtclcad/CMakeLists.txt +++ b/src/libtclcad/CMakeLists.txt @@ -58,17 +58,7 @@ if (BRLCAD_ENABLE_TCL) BRLCAD_LIB_INCLUDE_DIRS(tclcad TCLCAD_INCLUDE_DIRS TCLCAD_LOCAL_INCLUDE_DIRS) - set(TCLCAD_LIBS - libged - libdm - libnmg - libbg - libbv - libbn - libbu - ${TCL_LIBRARY} - ${TCLCAD_XLIBS} - ) + set(TCLCAD_LIBS ${libtclcad_deps} ${TCL_LIBRARY} ${TCLCAD_XLIBS}) if (TK_LIBRARY) set(TCLCAD_LIBS ${TCLCAD_LIBS} ${TK_LIBRARY}) endif (TK_LIBRARY) diff --git a/src/libtclcad/command_io.cpp b/src/libtclcad/command_io.cpp index 77762a332ce..9132563ae55 100644 --- a/src/libtclcad/command_io.cpp +++ b/src/libtclcad/command_io.cpp @@ -31,17 +31,14 @@ #include extern "C" { - #include "tcl.h" - #include "bu/malloc.h" -#include "tclcad.h" +} +#include "tclcad.h" /* Private headers */ #include "./tclcad_private.h" -} - struct tclcad_process_channels { Tcl_Channel cstdin; Tcl_Channel cstdout; diff --git a/src/libtclcad/commands.c b/src/libtclcad/commands.c index 41beccdb535..c072a98e834 100644 --- a/src/libtclcad/commands.c +++ b/src/libtclcad/commands.c @@ -2814,7 +2814,7 @@ to_data_vZ(struct ged *gedp, /* Get the data vZ */ if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%lf", gdvp->gv_data_vZ); + bu_vls_printf(gedp->ged_result_str, "%lf", gdvp->gv_tcl.gv_data_vZ); return BRLCAD_OK; } @@ -2824,7 +2824,7 @@ to_data_vZ(struct ged *gedp, return BRLCAD_ERROR; } - gdvp->gv_data_vZ = vZ; + gdvp->gv_tcl.gv_data_vZ = vZ; return BRLCAD_OK; } @@ -3333,11 +3333,7 @@ to_fit_png_image(struct ged *gedp, int UNUSED(maxargs)) { icv_image_t *img; - size_t i_w, i_n; size_t o_w_requested, o_n_requested; - size_t o_w_used, o_n_used; - size_t x_offset, y_offset; - fastf_t ar_w; fastf_t sf; /* initialize result */ @@ -3363,62 +3359,12 @@ to_fit_png_image(struct ged *gedp, return BRLCAD_ERROR; } - i_w = img->width; - i_n = img->height; - ar_w = o_w_requested / (fastf_t)i_w; - - o_w_used = (size_t)(i_w * ar_w * sf); - o_n_used = (size_t)(i_n * ar_w * sf); - - if (icv_resize(img, ICV_RESIZE_BINTERP, o_w_used, o_n_used, 1) < 0) { - bu_vls_printf(gedp->ged_result_str, "%s: icv_resize failed", argv[0]); + int ret = icv_fit(img, gedp->ged_result_str, o_w_requested, o_n_requested, sf); + if (ret == BRLCAD_ERROR) { icv_destroy(img); - return BRLCAD_ERROR; - } - - if (NEAR_EQUAL(sf, 1.0, BN_TOL_DIST)) { - fastf_t ar_n = o_n_requested / (fastf_t)i_n; - - if (ar_w > ar_n && !NEAR_EQUAL(ar_w, ar_n, BN_TOL_DIST)) { - /* need to crop final image height so that we keep the center of the image */ - size_t x_orig = 0; - size_t y_orig = (o_n_used - o_n_requested) * 0.5; - - if (icv_rect(img, x_orig, y_orig, o_w_requested, o_n_requested) < 0) { - bu_vls_printf(gedp->ged_result_str, "%s: icv_rect failed", argv[0]); - icv_destroy(img); - return BRLCAD_ERROR; - } - - x_offset = 0; - y_offset = 0; - } else { - /* user needs to offset final image in the window */ - x_offset = 0; - y_offset = (size_t)((o_n_requested - o_n_used) * 0.5); - } - } else { - if (sf > 1.0) { - size_t x_orig = (o_w_used - o_w_requested) * 0.5; - size_t y_orig = (o_n_used - o_n_requested) * 0.5; - - if (icv_rect(img, x_orig, y_orig, o_w_requested, o_n_requested) < 0) { - bu_vls_printf(gedp->ged_result_str, "%s: icv_rect failed", argv[0]); - icv_destroy(img); - return BRLCAD_ERROR; - } - - x_offset = 0; - y_offset = 0; - } else { - /* user needs to offset final image in the window */ - x_offset = (size_t)((o_w_requested - o_w_used) * 0.5); - y_offset = (size_t)((o_n_requested - o_n_used) * 0.5); - } + return ret; } - bu_vls_printf(gedp->ged_result_str, "%zu %zu %zu %zu", img->width, img->height, x_offset, y_offset); - /* icv_write should return < 0 for errors but doesn't */ if (icv_write(img, argv[5], BU_MIME_IMAGE_PNG) == 0) { icv_destroy(img); @@ -4582,6 +4528,7 @@ to_new_view(struct ged *gedp, bv_init(new_gdvp, ¤t_top->to_gedp->ged_views); new_gdvp->callbacks = callbacks; bv_set_add_view(¤t_top->to_gedp->ged_views, new_gdvp); + bu_ptbl_ins(&gedp->ged_free_views, (long *)new_gdvp); new_gdvp->gv_s->point_scale = 1.0; new_gdvp->gv_s->curve_scale = 1.0; @@ -4618,6 +4565,11 @@ to_new_view(struct ged *gedp, NULL); } + // If we don't already have a default ged_gvp, set the one we just + // created as the new default + if (!gedp->ged_gvp) + gedp->ged_gvp = new_gdvp; + bu_vls_printf(gedp->ged_result_str, "%s", bu_vls_cstr(&new_gdvp->gv_name)); return BRLCAD_OK; } @@ -5831,6 +5783,7 @@ to_snap_view(struct ged *gedp, int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &fvx, &fvy); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { diff --git a/src/libtclcad/mouse.c b/src/libtclcad/mouse.c index eb4a800607f..f3cac3be3a5 100644 --- a/src/libtclcad/mouse.c +++ b/src/libtclcad/mouse.c @@ -22,7 +22,6 @@ #include "bu/path.h" #include "bv.h" -#include "bg/lseg.h" #include "tclcad.h" /* Private headers */ @@ -115,6 +114,7 @@ to_mouse_append_pnt_common(struct ged *gedp, gedp->ged_gvp = gdvp; int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &view[X], &view[Y]); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -2178,6 +2178,7 @@ to_mouse_poly_circ_func(Tcl_Interp *interp, int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &fx, &fy); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -2192,7 +2193,7 @@ to_mouse_poly_circ_func(Tcl_Interp *interp, fastf_t curr_fx, curr_fy; register int nsegs, n; - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); VSUB2(vdiff, v_pt, gdpsp->gdps_prev_point); r = MAGNITUDE(vdiff); @@ -2215,7 +2216,7 @@ to_mouse_poly_circ_func(Tcl_Interp *interp, curr_fx = cos(ang*DEG2RAD) * r + gdpsp->gdps_prev_point[X]; curr_fy = sin(ang*DEG2RAD) * r + gdpsp->gdps_prev_point[Y]; - VSET(v_pt, curr_fx, curr_fy, gdvp->gv_data_vZ); + VSET(v_pt, curr_fx, curr_fy, gdvp->gv_tcl.gv_data_vZ); MAT4X3PNT(m_pt, gdvp->gv_view2model, v_pt); bu_vls_printf(&plist, " {%lf %lf %lf}", V3ARGS(m_pt)); } @@ -2348,7 +2349,7 @@ to_mouse_poly_cont_func(Tcl_Interp *interp, gdvp->gv_width = dm_get_width((struct dm *)gdvp->dmp); gdvp->gv_height = dm_get_height((struct dm *)gdvp->dmp); bv_screen_to_view(gdvp, &fx, &fy, x, y); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); MAT4X3PNT(m_pt, gdvp->gv_view2model, v_pt); gedp->ged_gvp = gdvp; @@ -2495,6 +2496,7 @@ to_mouse_poly_ell_func(Tcl_Interp *interp, int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &fx, &fy); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -2520,8 +2522,8 @@ to_mouse_poly_ell_func(Tcl_Interp *interp, * note that sin(alpha) is cos(90-alpha). */ - VSET(A, a, 0, gdvp->gv_data_vZ); - VSET(B, 0, b, gdvp->gv_data_vZ); + VSET(A, a, 0, gdvp->gv_tcl.gv_data_vZ); + VSET(B, 0, b, gdvp->gv_tcl.gv_data_vZ); /* use a variable number of segments based on the size of the * circle being created so small circles have few segments and @@ -2679,6 +2681,7 @@ to_mouse_poly_rect_func(Tcl_Interp *interp, int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &fx, &fy); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -2708,14 +2711,14 @@ to_mouse_poly_rect_func(Tcl_Interp *interp, MAT4X3PNT(m_pt, gdvp->gv_view2model, gdpsp->gdps_prev_point); bu_vls_printf(&plist, "{0 {%lf %lf %lf} ", V3ARGS(m_pt)); - VSET(v_pt, gdpsp->gdps_prev_point[X], fy, gdvp->gv_data_vZ); + VSET(v_pt, gdpsp->gdps_prev_point[X], fy, gdvp->gv_tcl.gv_data_vZ); MAT4X3PNT(m_pt, gdvp->gv_view2model, v_pt); bu_vls_printf(&plist, "{%lf %lf %lf} ", V3ARGS(m_pt)); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); MAT4X3PNT(m_pt, gdvp->gv_view2model, v_pt); bu_vls_printf(&plist, "{%lf %lf %lf} ", V3ARGS(m_pt)); - VSET(v_pt, fx, gdpsp->gdps_prev_point[Y], gdvp->gv_data_vZ); + VSET(v_pt, fx, gdpsp->gdps_prev_point[Y], gdvp->gv_tcl.gv_data_vZ); MAT4X3PNT(m_pt, gdvp->gv_view2model, v_pt); bu_vls_printf(&plist, "{%lf %lf %lf} }", V3ARGS(m_pt)); diff --git a/src/libtclcad/polygons.c b/src/libtclcad/polygons.c index 68f8fcdb14c..645302bb673 100644 --- a/src/libtclcad/polygons.c +++ b/src/libtclcad/polygons.c @@ -164,7 +164,7 @@ to_data_polygons_func(Tcl_Interp *interp, gdpsp = &gdvp->gv_tcl.gv_data_polygons; gdpsp->gdps_scale = gdvp->gv_scale; - gdpsp->gdps_data_vZ = gdvp->gv_data_vZ; + gdpsp->gdps_data_vZ = gdvp->gv_tcl.gv_data_vZ; VMOVE(gdpsp->gdps_origin, gdvp->gv_center); MAT_COPY(gdpsp->gdps_rotation, gdvp->gv_rotation); MAT_COPY(gdpsp->gdps_model2view, gdvp->gv_model2view); @@ -587,12 +587,14 @@ to_data_polygons_func(Tcl_Interp *interp, else if (bu_sscanf(argv[4], "%d", &op) != 1 || op > bg_Xor) goto bad; + plane_t pl; + bv_view_plane(&pl, gdvp); + gpp = bg_clip_polygon((bg_clip_t)op, &gdpsp->gdps_polygons.polygon[i], &gdpsp->gdps_polygons.polygon[j], CLIPPER_MAX, - gdpsp->gdps_model2view, - gdpsp->gdps_view2model); + &pl); /* Free the target polygon */ bg_polygon_free(&gdpsp->gdps_polygons.polygon[i]); @@ -716,8 +718,11 @@ to_data_polygons_func(Tcl_Interp *interp, i >= gdpsp->gdps_polygons.num_polygons) goto bad; + plane_t pl; + bv_view_plane(&pl, gdvp); + area = bg_find_polygon_area(&gdpsp->gdps_polygons.polygon[i], CLIPPER_MAX, - gdpsp->gdps_model2view, gdpsp->gdps_scale); + &pl, gdpsp->gdps_scale); bu_vls_printf(gedp->ged_result_str, "%lf", area); return BRLCAD_OK; @@ -1163,9 +1168,10 @@ to_poly_circ_mode_func(Tcl_Interp *interp, gdvp->gv_width = dm_get_width((struct dm *)gdvp->dmp); gdvp->gv_height = dm_get_height((struct dm *)gdvp->dmp); bv_screen_to_view(gdvp, &fx, &fy, x, y); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &v_pt[X], &v_pt[Y]); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -1237,9 +1243,10 @@ to_poly_cont_build_func(Tcl_Interp *interp, gdvp->gv_width = dm_get_width((struct dm *)gdvp->dmp); gdvp->gv_height = dm_get_height((struct dm *)gdvp->dmp); bv_screen_to_view(gdvp, &fx, &fy, x, y); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &v_pt[X], &v_pt[Y]); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -1598,9 +1605,10 @@ to_poly_ell_mode_func(Tcl_Interp *interp, gdvp->gv_width = dm_get_width((struct dm *)gdvp->dmp); gdvp->gv_height = dm_get_height((struct dm *)gdvp->dmp); bv_screen_to_view(gdvp, &fx, &fy, x, y); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &v_pt[X], &v_pt[Y]); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { @@ -1769,9 +1777,10 @@ to_poly_rect_mode_func(Tcl_Interp *interp, gdvp->gv_width = dm_get_width((struct dm *)gdvp->dmp); gdvp->gv_height = dm_get_height((struct dm *)gdvp->dmp); bv_screen_to_view(gdvp, &fx, &fy, x, y); - VSET(v_pt, fx, fy, gdvp->gv_data_vZ); + VSET(v_pt, fx, fy, gdvp->gv_tcl.gv_data_vZ); int snapped = 0; if (gedp->ged_gvp->gv_s->gv_snap_lines) { + gedp->ged_gvp->gv_s->gv_snap_flags = BV_SNAP_TCL; snapped = bv_snap_lines_2d(gedp->ged_gvp, &v_pt[X], &v_pt[Y]); } if (!snapped && gedp->ged_gvp->gv_s->gv_grid.snap) { diff --git a/src/libtclcad/view/faceplate.c b/src/libtclcad/view/faceplate.c index c8ae6c83a31..f63cf52bef9 100644 --- a/src/libtclcad/view/faceplate.c +++ b/src/libtclcad/view/faceplate.c @@ -145,16 +145,16 @@ to_faceplate(struct ged *gedp, if (BU_STR_EQUAL(argv[2], "view_params")) { if (BU_STR_EQUAL(argv[3], "draw")) { if (argc == 4) { - bu_vls_printf(gedp->ged_result_str, "%d", gdvp->gv_s->gv_view_params.gos_draw); + bu_vls_printf(gedp->ged_result_str, "%d", gdvp->gv_s->gv_view_params.draw); return BRLCAD_OK; } else if (argc == 5) { if (bu_sscanf(argv[4], "%d", &i) != 1) goto bad; if (i) - gdvp->gv_s->gv_view_params.gos_draw = 1; + gdvp->gv_s->gv_view_params.draw = 1; else - gdvp->gv_s->gv_view_params.gos_draw = 0; + gdvp->gv_s->gv_view_params.draw = 0; to_refresh_view(gdvp); return BRLCAD_OK; @@ -163,7 +163,7 @@ to_faceplate(struct ged *gedp, if (BU_STR_EQUAL(argv[3], "color")) { if (argc == 4) { - bu_vls_printf(gedp->ged_result_str, "%d %d %d", V3ARGS(gdvp->gv_s->gv_view_params.gos_text_color)); + bu_vls_printf(gedp->ged_result_str, "%d %d %d", V3ARGS(gdvp->gv_s->gv_view_params.color)); return BRLCAD_OK; } else if (argc == 7) { int r, g, b; @@ -173,7 +173,7 @@ to_faceplate(struct ged *gedp, bu_sscanf(argv[6], "%d", &b) != 1) goto bad; - VSET(gdvp->gv_s->gv_view_params.gos_text_color, r, g, b); + VSET(gdvp->gv_s->gv_view_params.color, r, g, b); to_refresh_view(gdvp); return BRLCAD_OK; } diff --git a/src/libtclcad/view/refresh.c b/src/libtclcad/view/refresh.c index 3925b9988fe..ce7f57d920a 100644 --- a/src/libtclcad/view/refresh.c +++ b/src/libtclcad/view/refresh.c @@ -44,7 +44,17 @@ go_refresh_draw(struct ged *gedp, struct bview *gdvp, int restore_zbuffer) if (gdvp->gv_s->gv_rect.draw) { go_draw(gdvp); - dm_draw_viewobjs(wdbp, gdvp, &tgd->go_dmv, gedp->dbip->dbi_base2local, gedp->dbip->dbi_local2base); + // TODO - I wouldn't expect these values to differ from the dbi + // versions, but to preserve the old behavior where the factors + // were passed explicitly we stash and restore. Need to figure + // out whether this is ever needed (shouldn't be?) + double l2b = gdvp->gv_local2base; + double b2l = gdvp->gv_base2local; + gdvp->gv_local2base = gedp->dbip->dbi_local2base; + gdvp->gv_base2local = gedp->dbip->dbi_base2local; + dm_draw_viewobjs(wdbp, gdvp, &tgd->go_dmv); + gdvp->gv_local2base = l2b; + gdvp->gv_base2local = b2l; /* disable write to depth buffer */ (void)dm_set_depth_mask((struct dm *)gdvp->dmp, 0); @@ -118,7 +128,18 @@ go_refresh_draw(struct ged *gedp, struct bview *gdvp, int restore_zbuffer) go_draw(gdvp); } - dm_draw_viewobjs(wdbp, gdvp, &tgd->go_dmv, gedp->dbip->dbi_base2local, gedp->dbip->dbi_local2base); + // TODO - I wouldn't expect these values to differ from the dbi versions, + // but to preserve the old behavior where the factors were passed + // explicitly we stash and restore. Need to figure out whether this is + // ever needed (shouldn't be?) + double l2b = gdvp->gv_local2base; + double b2l = gdvp->gv_base2local; + gdvp->gv_local2base = gedp->dbip->dbi_local2base; + gdvp->gv_base2local = gedp->dbip->dbi_base2local; + dm_draw_viewobjs(wdbp, gdvp, &tgd->go_dmv); + dm_draw_viewobjs(wdbp, gdvp, &tgd->go_dmv); + gdvp->gv_local2base = l2b; + gdvp->gv_base2local = b2l; } void diff --git a/src/libtermio/CMakeLists.txt b/src/libtermio/CMakeLists.txt deleted file mode 100644 index 9e5655d0d39..00000000000 --- a/src/libtermio/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -set(TERMIO_SRCS - termio.c - termcap.c - tgoto.c - tputs.c - ) - -if (NOT WIN32) - # Include directories needed by libtermio users - set(TERMIO_INCLUDE_DIRS - ${BRLCAD_BINARY_DIR}/include - ${BRLCAD_SOURCE_DIR}/include - ) - BRLCAD_LIB_INCLUDE_DIRS(termio TERMIO_INCLUDE_DIRS "") - - add_definitions(-DCM_N -DCM_GT -DCM_B -DCM_D - -DB_TERMCAP=\"${CMAKE_INSTALL_PREFIX}/${DATA_DIR}/termio/termcap\" - ) - - BRLCAD_ADDDATA(termcap termio) - - BRLCAD_ADDLIB(libtermio "${TERMIO_SRCS}" "libbu") - set_target_properties(libtermio PROPERTIES VERSION 20.0.1 SOVERSION 20) -endif(NOT WIN32) - -CMAKEFILES( - ${TERMIO_SRCS} - CMakeLists.txt - termcap.h - termcap - ) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/src/libtermio/libtermio.h b/src/libtermio/libtermio.h new file mode 100644 index 00000000000..58c315420ee --- /dev/null +++ b/src/libtermio/libtermio.h @@ -0,0 +1,265 @@ +/* L I B T E R M I O . H + * BRL-CAD + * + * Copyright (c) 2004-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup libtermio + * + * @brief + * Header-only libtermio implementation + */ +/** @{ */ +/** @file libtermio.h */ + +#ifndef LIBTERMIO_H +#define LIBTERMIO_H + +#include "common.h" + +void clr_Echo(int fd); +void reset_Tty(int fd); +void save_Tty(int fd); +void set_Cbreak(int fd); +void set_Raw(int fd); + +#if defined(LIBTERMIO_IMPLEMENTATION) + +#ifdef HAVE_SYS_FILE_H +# include +#endif + +#ifdef HAVE_SYS_IOCTL_COMPAT_H +# if defined(__FreeBSD__) && !defined(COMPAT_43TTY) /* TODO: figure out a better way, mebbe 43bsd tty semantics isn't right anymore? */ +# define COMPAT_43TTY 1 +# endif +# include +# if !defined(OCRNL) +# define OCRNL 0000010 +# endif + +#endif + +#include "bio.h" + +/* + * This file will work IFF one of these three flags is set: + * HAVE_CONIO_H use Windows console IO + * HAVE_TERMIOS_H use POXIX termios and tcsetattr() call with XOPEN flags + * SYSV use SysV Rel3 termio and TCSETA ioctl + * BSD use Version 7 / BSD sgttyb and TIOCSETP ioctl + */ + +#include +#if defined(HAVE_MEMORY_H) +# include +#endif + +#if defined(HAVE_TERMIOS_H) +# undef SYSV +# undef BSD +# include + +static struct termios save_tio[FOPEN_MAX] = {0}; +static struct termios curr_tio[FOPEN_MAX] = {0}; + +#else /* !defined(HAVE_TERMIOS_H) */ + +# ifdef SYSV +# undef BSD +# include +# include +static struct termio save_tio[FOPEN_MAX] = {0}; +static struct termio curr_tio[FOPEN_MAX] = {0}; +# endif /* SYSV */ + +# ifdef BSD +# undef SYSV +# include + +static struct sgttyb save_tio[FOPEN_MAX] = {0}; +static struct sgttyb curr_tio[FOPEN_MAX] = {0}; +# endif /* BSD */ + +#endif /* HAVE_TERMIOS_H */ + +#if defined(HAVE_CONIO_H) +# include +/* array of unused function pointers, but created for consistency */ +static int (*save_tio[FOPEN_MAX])(void) = {0}; +static int (*curr_tio[FOPEN_MAX])(void) = {0}; +#endif + + +static void +copy_Tio( +#if defined(BSD) + struct sgttyb *to, struct sgttyb *from +#elif defined(SYSV) + struct termio *to, struct termio *from +#elif defined(HAVE_TERMIOS_H) + struct termios *to, struct termios*from +#elif defined(HAVE_CONIO_H) + int (**to)(), int (**from)() +#endif + ) +{ + if (to && from) + (void)memcpy((char *) to, (char *) from, sizeof(*from)); + return; +} + + +/* + Clear echo mode, 'fd'. +*/ +void +clr_Echo(int fd) +{ +#ifdef BSD + curr_tio[fd].sg_flags &= ~ECHO; /* Echo mode OFF. */ + (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); +#endif +#ifdef SYSV + curr_tio[fd].c_lflag &= ~ECHO; /* Echo mode OFF. */ + (void) ioctl(fd, TCSETA, &curr_tio[fd]); +#endif +#ifdef HAVE_TERMIOS_H + curr_tio[fd].c_lflag &= ~ECHO; /* Echo mode OFF. */ + (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); +#endif +#ifdef HAVE_CONIO_H + /* nothing to do */ +#endif + return; +} + +/* + Set the terminal back to the mode that the user had last time + save_Tty() was called for 'fd'. +*/ +void +reset_Tty(int fd) +{ +#ifdef BSD + (void) ioctl(fd, TIOCSETP, &save_tio[fd]); /* Write setting. */ +#endif +#ifdef SYSV + (void) ioctl(fd, TCSETA, &save_tio[fd]); /* Write setting. */ +#endif +#ifdef HAVE_TERMIOS_H + (void)tcsetattr(fd, TCSAFLUSH, &save_tio[fd]); +#endif +#ifdef HAVE_CONIO_H + curr_tio[fd] = save_tio[fd]; + #endif + return; +} + +/* + Get and save terminal parameters, 'fd'. +*/ +void +save_Tty(int fd) +{ +#ifdef BSD + (void) ioctl(fd, TIOCGETP, &save_tio[fd]); +#endif +#ifdef SYSV + (void) ioctl(fd, TCGETA, &save_tio[fd]); +#endif +#ifdef HAVE_TERMIOS_H + (void)tcgetattr(fd, &save_tio[fd]); +#endif +#ifdef HAVE_CONIO_H + /* nothing to do, 'cept copy */ +#endif + copy_Tio(&curr_tio[fd], &save_tio[fd]); + return; +} + +/* + Set CBREAK mode, 'fd'. +*/ +void +set_Cbreak(int fd) +{ +#ifdef BSD + curr_tio[fd].sg_flags |= CBREAK; /* CBREAK mode ON. */ + (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); +#endif +#ifdef SYSV + curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ + curr_tio[fd].c_cc[VMIN] = 1; + curr_tio[fd].c_cc[VTIME] = 0; + (void) ioctl(fd, TCSETA, &curr_tio[fd]); +#endif +#ifdef HAVE_TERMIOS_H + curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ + curr_tio[fd].c_cc[VMIN] = 1; + curr_tio[fd].c_cc[VTIME] = 0; + (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); +#endif +#ifdef HAVE_CONIO_H + /* concept doesn't exist */ +#endif + return; +} + +/* + Set raw mode, 'fd'. +*/ +void +set_Raw(int fd) +{ +#ifdef BSD + curr_tio[fd].sg_flags |= RAW; /* Raw mode ON. */ + (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); +#endif +#ifdef SYSV + curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ + curr_tio[fd].c_lflag &= ~ISIG; /* Signals OFF. */ + curr_tio[fd].c_cc[VMIN] = 1; + curr_tio[fd].c_cc[VTIME] = 0; + (void) ioctl(fd, TCSETA, &curr_tio[fd]); +#endif +#ifdef HAVE_TERMIOS_H + curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ + curr_tio[fd].c_lflag &= ~ISIG; /* Signals OFF. */ + curr_tio[fd].c_cc[VMIN] = 1; + curr_tio[fd].c_cc[VTIME] = 0; + (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); +#endif +#ifdef HAVE_CONIO_H + /* nothing to do, raw is default */ +#endif + return; +} + +#endif /* LIBTERMIO_IMPLEMENTATION */ + +#endif /* LIBTERMIO_H */ + +/** @} */ +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/libtermio/termcap b/src/libtermio/termcap deleted file mode 100644 index 9e250084660..00000000000 --- a/src/libtermio/termcap +++ /dev/null @@ -1,13119 +0,0 @@ -# $NetBSD: termcap.src,v 1.99 2007/02/16 21:33:12 wiz Exp $ -# -######## TERMINAL TYPE DESCRIPTIONS SOURCE FILE -# -# Version 9.13.25 -# termcap syntax -# -# Eric S. Raymond (current maintainer) -# John Kunze, Berkeley -# Craig Leres, Berkeley -# -# Please e-mail changes to terminfo@ccil.org. The old termcap@berkeley.edu -# address is no longer valid. -# -# PURPOSE OF THIS FILE: -# -# This file describes the capabilities of various character-cell terminals, -# as needed by software such as screen-oriented editors. -# -# Other terminfo and termcap files exist, supported by various OS vendors -# or as relics of various older versions of UNIX. This one is the longest -# and most comprehensive one in existence. It subsumes not only the entirety -# of the historical 4.4BSD, GNU, System V and SCO termcap files and the BRL -# termcap file, but also large numbers of vendor-maintained termcap and -# terminfo entries more complete and carefully tested than those in historical -# termcap/terminfo versions. -# -# Pointers to related resources (including the ncurses distribution) may -# be found at . -# -# INTERNATIONALIZATION: -# -# This file uses only the US-ASCII as the G0/GL character set. -# -# This file assumes a US-ASCII character set. If you need to fix this, start -# by global-replacing \E(B and \E)B with the appropriate ISO 6429 enablers -# for your character set. \E(A and \E)A enables the British character set -# with the pound sign at position 2/3. -# -# In order to allow 8bit encodings (right half of ISO8859 character sets, -# EUC encondings, etc.), we do not use G1 (and SO/SI) for alternate -# character set but use G0 instead, and \E)0 should be avoided in -# and initialization strings. -# -# FILE FORMAT: -# -# The version you are looking at may be in any of three formats: master -# (terminfo with OT capabilities), stock terminfo, or termcap. You can tell -# which by the format given in the header above. -# -# The master format is accepted and generated by the terminfo tools in the -# ncurses suite; it differs from stock (System V-compatible) terminfo only -# in that it admits a group of capabilities (prefixed `OT') equivalent to -# various obsolete termcap capabilities. You can, thus, convert from master -# to stock terminfo simply by filtering with `sed "/OT[^,]*,/s///"'; but if -# you have ncurses `tic -I' is nicer (among other things, it automatically -# outputs entries in a canonical form). -# -# The termcap version is generated automatically from the master version -# using tic -C. This filtering leaves in the OT capabilities under their -# original termcap names. All translated entries fit within the 1023-byte -# string-table limit of archaic termcap libraries except where explicitly -# noted below. Note that the termcap translation assumes that your termcap -# library can handle multiple tc capabilities in an entry. 4.4BSD has this -# capability. Older versions of GNU termcap, through 1.3, do not. -# -# For details on these formats, see terminfo(5) in the ncurses distribution, -# and termcap(5) in the 4.4BSD Unix Programmer's Manual. Be aware that 4.4BSD -# curses has been declared obsolete by the caretakers of the 4.4BSD sources -# as of June 1995; they are encouraging everyone to migrate to ncurses. -# -# Note: unlike some other distributed terminfo files (Novell Unix & SCO's), -# no entry in this file has embedded comments. This is so source translation -# to termcap only has to carry over leading comments. Also, no name field -# contains embedded whitespace (such whitespace confuses rdist). -# -# Further note: older versions of this file were often installed with an editor -# script (reorder) that moved the most common terminal types to the front of -# the file. This should no longer be necessary, as the file is now ordered -# roughly by type frequency with ANSI/VT100 and other common types up front. -# -# Some information has been merged in from terminfo files distributed by -# USL and SCO (see COPYRIGHTS AND OTHER DELUSIONS below). Much information -# comes from vendors who maintain official terminfos for their hardware -# (notably DEC and Wyse). -# -# A detailed change history is included at the end of this file. -# -# FILE ORGANIZATION: -# -# Comments in this file begin with # - they cannot appear in the middle -# of a terminfo/termcap entry. Individual capabilities are commented out by -# placing a period between the colon and the capability name. -# -# The file is divided up into major sections (headed by lines beginning with -# the string "########") and minor sections (beginning with "####"); do -# -# grep "^####" | more -# -# to see a listing of section headings. The intent of the divisions is -# (a) to make it easier to find things, and (b) to order the database so -# that important and frequently-encountered terminal types are near the -# front (so that you'll get reasonable search efficiency even if you don't -# use reorder). Minor sections usually correspond to manufacturers or -# standard terminal classes. Parenthesized words following manufacturer -# names are type prefixes or product line names used by that manufacturers. -# -# HOW TO READ THE ENTRIES: -# -# The first name in an entry is the canonical name for the model or -# type, last entry is a verbose description. Others are mnemonic synonyms for -# the terminal. -# -# Terminal names look like - -# The part to the left of the dash, if a dash is present, describes the -# particular hardware of the terminal. The part to the right may be used -# for flags indicating special ROMs, extra memory, particular terminal modes, -# or user preferences. -# -# All names should be in lower case, for consistency in typing. -# -# The following are conventionally used suffixes: -# -2p Has two pages of memory. Likewise 4p, 8p, etc. -# -am Enable auto-margin. -# -m Monochrome. Suppress color support -# -mc Magic-cookie. Some terminals (notably older Wyses) can -# only support one attribute without magic-cookie lossage. -# Their base entry is usually paired with another that -# uses magic cookies to support multiple attributes. -# -na No arrow keys - termcap ignores arrow keys which are -# actually there on the terminal, so the user can use -# the arrow keys locally. -# -nam No auto-margin - suppress :am: capability -# -nl No labels - suppress soft labels -# -ns No status line - suppress status line -# -rv Terminal in reverse video mode (black on white) -# -s Enable status line. -# -vb Use visible bell (:vb:) rather than :bl:. -# -w Wide - in 132 column mode. -# If a name has multiple suffixes and one is a line height, that one should -# go first. Thus `aaa-30-s-rv' is recommended over `aaa-s-rv'. -# -# Entries with embedded plus signs are designed to be included through use/tc -# capabilities, not used as standalone entries. -# -# To avoid search clashes, some older all-numeric names for terminals have -# been removed (i.e., "33" for the Model 33 Teletype, "2621" for the HP2621). -# All primary names of terminals now have alphanumeric prefixes. -# -# Comments marked "esr" are mostly results of applying the termcap-compiler -# code packaged with ncurses and contemplating the resulting error messages. -# In many cases, these indicated obvious fixes to syntax garbled by the -# composers. In a few cases, I was able to deduce corrected forms for garbled -# capabilities by looking at context. All the information in the original -# entries is preserved in the comments. -# -# In the comments, terminfo capability names are bracketed with <> (angle -# brackets). Termcap capability names are bracketed with :: (colons). -# -# INTERPRETATION OF USER CAPABILITIES -# -# The System V Release 4 and XPG4 terminfo format defines ten string -# capabilities for use by applications, .... In this file, we use -# certain of these capabilities to describe functions which are not covered -# by terminfo. The mapping is as follows: -# -# u9 terminal enquire string (equiv. to ANSI/ECMA-48 DA) -# u8 terminal answerback description -# u7 cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6) -# u6 cursor position report (equiv. to ANSI/ECMA-48 CPR) -# -# The terminal enquire string should elicit an answerback response -# from the terminal. Common values for will be ^E (on older ASCII -# terminals) or \E[c (on newer VT100/ANSI/ECMA-48-compatible terminals). -# -# The cursor position request () string should elicit a cursor position -# report. A typical value (for VT100 terminals) is \E[6n. -# -# The terminal answerback description (u8) must consist of an expected -# answerback string. The string may contain the following scanf(3)-like -# escapes: -# -# %c Accept any character -# %[...] Accept any number of characters in the given set -# -# The cursor position report () string must contain two scanf(3)-style -# %d format elements. The first of these must correspond to the Y coordinate -# and the second to the %d. If the string contains the sequence %i, it is -# taken as an instruction to decrement each value after reading it (this is -# the inverse sense from the cup string). The typical CPR value is -# \E[%i%d;%dR (on VT100/ANSI/ECMA-48-compatible terminals). -# -# These capabilities are used by tac(1m), the terminfo action checker soon -# to be distributed with ncurses. -# -# TABSET FILES -# -# All the entries in this file have been edited to assume that the tabset -# files directory is /usr/share/tabset, in conformance with the File Hierarchy -# Standard for Linux and free BSD systems. Some vendors (notably Sun) use -# /usr/lib/tabset or (more recently) /usr/share/lib/tabset. -# -# No curses package we know of uses these files. If their location is an -# issue, you will have to hand-patch the file locations before compiling -# this file. -# -# REQUEST FOR CONTACT INFORMATION AND HISTORICAL MATERIAL: -# -# As the ANSI/ECMA-48 standard and variants take firmer hold, and as -# character-cell terminals are increasingly replaced by X displays, much of -# this file is becoming a historical document (this is part of the reason for -# the new organization, which puts ANSI types, xterm, free-Unix consoles, -# and vt100 up front in confidence that this will catch 95% of new hardware). -# -# For the terminal types still alive, I'd like to have manufacturer's -# contact data (Internet address and/or snail-mail + phone). -# -# I'm also interested in enriching the comments so that the latter portions of -# the file do in fact become a potted history of VDT technology as seen by -# UNIX hackers. Ideally, I'd like the headers for each manufacturer to -# include its live/dead/out-of-the-business status, and for as many -# terminal types as possible to be tagged with information like years -# of heaviest use, popularity, and interesting features. -# -# I'm especially interested in identifying the obscure entries listed under -# `Miscellaneous obsolete terminals, manufacturers unknown' before the tribal -# wisdom about them gets lost. If you know a lot about obscure old terminals, -# please go to the terminfo resource page, grab the UFO file (ufo.ti), and -# eyeball it for things you can identify and describe. -# -# If you have been around long enough to contribute, please read the file -# with this in mind and send me your annotations. -# -# COPYRIGHTS AND OTHER DELUSIONS -# -# The BSD ancestor of this file had a standard Regents of the University of -# California copyright with dates from 1980 to 1993. -# -# Some information has been merged in from a terminfo file SCO distributes. -# It has an obnoxious boilerplate copyright which I'm ignoring because they -# took so much of the content from the ancestral BSD versions of this file -# and didn't attribute it, thereby violating the BSD Regents' copyright. -# -# Not that anyone should care. However many valid functions copyrights may -# serve, putting one on a termcap/terminfo file with hundreds of anonymous -# contributors makes about as much sense as copyrighting a wall-full of -# graffiti -- it's legally dubious, ethically bogus, and patently ridiculous. -# -# This file deliberately has no copyright. It belongs to no one and everyone. -# If you claim you own it, you will merely succeed in looking like a fool. -# Use it as you like. Use it at your own risk. Copy and redistribute freely. -# There are no guarantees anywhere. Svaha! -# - -######## STANDARD AND SPECIAL TYPES -# -# This section describes terminal classes and maker brands that are still -# quite common. -# - -#### Specials -# -# Special "terminals". These are used to label tty lines when you don't -# know what kind of terminal is on it. The characteristics of an unknown -# terminal are the lowest common denominator - they look about like a ti 700. -# - -dumb|80-column dumb tty:\ - :am:\ - :co#80:\ - :bl=^G:cr=^M:do=^J:sf=^J: -unknown|unknown terminal type:\ - :gn:tc=dumb: -lpr|printer|line printer:\ - :bs:hc:os:\ - :co#132:li#66:\ - :bl=^G:cr=^M:do=^J:ff=^L:le=^H:sf=^J: -glasstty|classic glass tty interpreting ASCII control characters:\ - :am:\ - :co#80:\ - :bl=^G:cl=^L:cr=^M:do=^J:kb=^H:kd=^J:kl=^H:le=^H:nw=^M^J:\ - :ta=^I: - -#### ANSI.SYS/ISO 6429/ECMA-48 Capabilities -# -# See the end-of-file comment for more on these. -# - -# The IBM PC alternate character set. Plug this into any Intel console entry. -# We use \E[11m for rmacs rather than \E[12m so the string can use the -# ROM graphics for control characters such as the diamond, up- and down-arrow. -# This works with the System V, Linux, and BSDI consoles. It's a safe bet this -# will work with any Intel console, they all seem to have inherited \E[11m -# from the ANSI.SYS de-facto standard. -klone+acs|alternate character set for ansi.sys displays:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030\054\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:as=\E[11m: - -# Highlight controls corresponding to the ANSI.SYS standard. Most -# console drivers for Intel boxes obey these. Makes the same assumption -# about \E[11m as klone+acs. True ANSI/ECMA-48 would have :se=\E[27m:, -# :ue=\E[24m:, but this isn't a documented feature of ANSI.SYS. -klone+sgr|attribute control for ansi.sys displays:\ - :S2=\E[11m:S3=\E[10m:mb=\E[5m:md=\E[1m:me=\E[0;10m:\ - :mk=\E[8m:mr=\E[7m:\ - :se=\E[m:so=\E[7m:ue=\E[m:us=\E[4m:\ - :tc=klone+acs: - -# Highlight controls corresponding to the ANSI.SYS standard. *All* -# console drivers for Intel boxes obey these. Does not assume \E[11m will -# work; uses \E[12m instead, which is pretty bulletproof but loses you the ACS -# diamond and arrow characters under curses. -klone+sgr-dumb|attribute control for ansi.sys displays (no ESC [ 11 m):\ - :as=\E[12m:mb=\E[5m:md=\E[1m:me=\E[0;10m:mk=\E[8m:\ - :mr=\E[7m:\ - :se=\E[m:so=\E[7m:ue=\E[m:us=\E[4m:\ - :tc=klone+acs: - -# KOI8 (RFC1489) alternate character set -# From: Qing Long , 24 Feb 1996. -klone+koi8acs|alternate character set for ansi.sys displays with KOI8 charset:\ - :ac=l\202m\204k\203j\205u\207t\206v\210w\211q\200x\201n\212o\213s\214p\216r\217`\004a\237f\234g\232~\225.\037-\036+\020\054\021h\222I\2200\215y\230z\231{\267}L|\274:\ - :ae=\E[10m:as=\E[11m: - -# ANSI.SYS color control. The setb/setf caps depend on the coincidence -# between SVr4/XPG4's color numbers and ANSI.SYS attributes. Here are longer -# but equivalent strings that don't rely on that coincidence: -# setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, -# setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, -# The DOS 5 manual asserts that these sequences meet the ISO 6429 standard. -# They match a subset of ECMA-48. -klone+color|color control for ansi.sys and ISO6429-compatible displays:\ - :Co#8:NC#3:pa#64:Sb=\E[4%dm:Sf=\E[3%dm:op=\E[37;40m: - -# This is better than klone+color, it doesn't assume white-on-black as the -# default color pair, but many `ANSI' terminals don't grok the cap. -ecma+color|color control for ECMA-48-compatible terminals:\ - :Co#8:NC#3:pa#64:\ - :AB=\E[4%dm:AF=\E[3%dm:op=\E[39;49m: - -# Attribute control for ECMA-48-compatible terminals -ecma+sgr|attribute capabilities for true ECMA-48 terminals:\ - :se=\E[27m:ue=\E[24m:\ - :tc=klone+sgr: - -# For comparison, here are all the capabilities implied by the Intel -# Binary Compatibility Standard (level 2) that fit within terminfo. -# For more detail on this rather pathetic standard, see the comments -# near the end of this file. -ibcs2|Intel Binary Compatibility Standard prescriptions:\ - :AL=\E[%dL:DC=\E[%dP:DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:\ - :RA=\E[?7l:RI=\E[%dC:S1=\E=%dg:SA=\E[?7h:SF=\E[%dS:\ - :SR=\E[%dT:UP=\E[%dA:bt=\E[Z:ch=\E[%i%dG:cl=\Ec:\ - :cm=\E[%i%d;%dH:ct=\E[g:cv=\E[%i%dd:ec=\E[%dX:ei=:im=:\ - :rc=\E7:sc=\E7:st=\EH: - -#### ANSI/ECMA-48 terminals and terminal emulators -# -# See near the end of this file for details on ANSI conformance. -# Don't mess with these entries! Lots of other entries depend on them! -# -# This section lists entries in a least-capable to most-capable order. -# if you're in doubt about what `ANSI' matches yours, try them in that -# order and back off from the first that breaks. - -ansi-mini|any ansi terminal with pessimistic assumptions:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:do=\E[B:ho=\E[H:\ - :le=\E[D:nd=\E[C:ta=^I:up=\E[A: - -# ANSI X3.64 from emory!mlhhh (Hugh Hansard) via BRL -# -# The following is an entry for the full ANSI 3.64 (1977). It lacks -# padding, but most terminals using the standard are "fast" enough -# not to require any -- even at 9600 bps. If you encounter problems, -# try including the padding specifications. -# -# Note: the "as" and "ae" specifications are not implemented here, for -# the available termcap documentation does not make clear WHICH alternate -# character set to specify. ANSI 3.64 seems to make allowances for several. -# Please make the appropriate adjustments to fit your needs -- that is -# if you will be using alternate character sets. -# -# There are very few terminals running the full ANSI 3.64 standard, -# so I could only test this entry on one verified terminal (Visual 102). -# I would appreciate the results on other terminals sent to me. -# -# Please report comments, changes, and problems to: -# -# U.S. MAIL: Hugh Hansard -# Box: 22830 -# Emory University -# Atlanta, GA. 30322. -# -# USENET {akgua,msdc,sb1,sb6,gatech}!emory!mlhhh. -# -ansi77|ansi 3.64 standard 1977 version:\ - :am:bs:mi:\ - :co#80:it#8:li#24:\ - :al=5*\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[;H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=5*\E[M:\ - :do=\E[B:ei=\E[4l:ho=\E[H:im=\E[4h:k1=\EOP:k2=\EOR:k4=\EOS:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :nd=\E[C:nw=^M\ED:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: - -# Procomm and some other ANSI emulations don't recognize all of the ANSI- -# standard capabilities. This entry deletes :UP:, :RI:, :DO:, :LE:, and -# / capabilities, forcing curses to use repetitions of :up:, -# :nd:, :do: and :le:. Also deleted :IC: and :ic:, as QModem up to -# 5.03 doesn't recognize these. Finally, we delete :rp: and :sr:, which seem -# to confuse many emulators. On the other hand, we can count on these programs -# doing :ae:/:as:/:sa:. Older versions of this entry featured -# , but now seems to be more common under -# ANSI.SYS influence. -# From: Eric S. Raymond Oct 30 1995 -pcansi-m|pcansi-mono|ibm-pc terminal programs claiming to be ansi (mono mode):\ - :am:bs:mi:ms:\ - :co#80:it#8:li#24:\ - :al=\E[L:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:ct=\E[2g:dc=\E[P:dl=\E[M:do=\E[B:\ - :ho=\E[H:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=\E[D:nd=\E[C:sf=^J:st=\EH:ta=^I:up=\E[A:\ - :tc=klone+sgr-dumb: -pcansi-25-m|pcansi25m|ibm-pc terminal programs with 25 lines (mono mode):\ - :li#25:tc=pcansi-m: -pcansi-33-m|pcansi33m|ibm-pc terminal programs with 33 lines (mono mode):\ - :li#33:tc=pcansi-m: -pcansi-43-m|ansi43m|ibm-pc terminal programs with 43 lines (mono mode):\ - :li#43:tc=pcansi-m: -# The color versions. All PC emulators do color... -pcansi|cygwin|ibm-pc terminal programs claiming to be ansi:\ - :am:bs:mi:ms:\ - :Co#8:NC#3:co#80:it#8:li#24:pa#64:\ - :Sb=\E[4%dm:Sf=\E[3%dm:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030,\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:al=\E[L:as=\E[12m:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:ct=\E[2g:dc=\E[P:\ - :dl=\E[M:do=\E[B:ho=\E[H:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:md=\E[1m:me=\E[0;10m:\ - :mk=\E[8m:mr=\E[7m:nd=\E[C:nw=^M^J:op=\E[37;40m:se=\E[m:\ - :sf=^J:so=\E[7m:st=\EH:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -pcansi-25|pcansi25|ibm-pc terminal programs with 25 lines:\ - :li#25:tc=pcansi: -pcansi-33|pcansi33|ibm-pc terminal programs with 33 lines:\ - :li#33:tc=pcansi: -pcansi-43|pcansi43|ibm-pc terminal programs with 43 lines:\ - :li#43:tc=pcansi: - -# ansi-m -- full ANSI X3.64 with ANSI.SYS-compatible attributes, no color. -# If you want pound signs rather than dollars, replace `B' with `A' -# in the , , , and capabilities. -# From: Eric S. Raymond Nov 6 1995 -ansi-m|ansi-mono|ANSI X3.64-1979 terminal with ANSI.SYS compatible attributes:\ - :5i:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\ - :cb=\E[1K:ch=\E[%i%dG:ct=\E[2g:cv=\E[%i%dd:ec=\E[%dX:ei=:\ - :im=:kB=\E[Z:kI=\E[L:kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:\ - :nw=\r\E[S:pf=\E[4i:po=\E[5i:\ - :s0=\E(B:s1=\E)B:s2=\E*B:s3=\E+B:ta=\E[I:\ - :tc=pcansi-m: - -# ansi -- this terminfo expresses the largest subset of X3.64 that will fit in -# standard terminfo. Assumes ANSI.SYS-compatible attributes and color. -# From: Eric S. Raymond Nov 6 1995 -ansi|ansi/pc-term compatible with color:\ - :5i:am:bs:mi:ms:\ - :Co#8:NC#3:co#80:it#8:li#24:pa#64:\ - :AB=\E[4%dm:AF=\E[3%dm:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ - :DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:S2=\E[11m:\ - :S3=\E[10m:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030,\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:bt=\E[Z:cb=\E[1K:\ - :cd=\E[J:ce=\E[K:ch=\E[%i%dG:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:ct=\E[2g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:do=\E[B:\ - :ec=\E[%dX:ei=:ho=\E[H:im=:kB=\E[Z:kI=\E[L:kb=^H:kd=\E[B:\ - :kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:md=\E[1m:\ - :me=\E[0;10m:mk=\E[8m:mr=\E[7m:nd=\E[C:nw=\r\E[S:\ - :op=\E[39;49m:pf=\E[4i:po=\E[5i:s0=\E(B:s1=\E)B:s2=\E*B:\ - :s3=\E+B:se=\E[m:sf=^J:so=\E[7m:st=\EH:ta=\E[I:\ - :u6=\E[%i%d;%dR:u7=\E[6n:u9=\E[c:ue=\E[m:up=\E[A:us=\E[4m: - -# -# ANSI.SYS entries -# -# This completely describes the sequences specified in the DOS 2.1 ANSI.SYS -# documentation (except for the keyboard key reassignment feature, which -# doesn't fit the model well). The klone+acs sequences were valid -# though undocumented. The capability is untested but should work for -# keys F1-F10 (%p1 values outside this range will yield unpredictable results). -# From: Eric S. Raymond Nov 7 1995 -ansi.sys-old|ANSI.SYS under PC-DOS 2.1:\ - :am:bs:mi:ms:xo:\ - :Co#8:NC#3:co#80:li#25:pa#64:\ - :RA=\E[?7l:S2=\E[11m:S3=\E[10m:SA=\E[?7h:Sb=\E[4%dm:\ - :Sf=\E[3%dm:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030,\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:as=\E[11m:bl=^G:ce=\E[k:cl=\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:do=\E[B:ho=\E[H:is=\E[m\E[?7h:kb=^H:\ - :kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[0;10m:mk=\E[8m:mr=\E[7m:nd=\E[C:nw=^M^J:\ - :op=\E[37;40m:pk=\E[0;%+\:;"%s":rc=\E[u:sc=\E[s:se=\E[m:\ - :sf=^J:so=\E[7m:ta=^I:u6=\E[%i%d;%dR:u7=\E[6n:ue=\E[m:\ - :up=\E[A:us=\E[4m: -ansi.sys|ANSI.SYS 3.1 and later versions:\ - :ce=\E[K:tc=ansi.sys-old: - -# -# Define IBM PC keypad keys for vi as per MS-Kermit while using ANSI.SYS. -# This should only be used when the terminal emulator cannot redefine the keys. -# Since redefining keys with ansi.sys also affects PC-DOS programs, the key -# definitions must be restored. If the terminal emulator is quit while in vi -# or others using :ks:/:ke:, the keypad will not be defined as per PC-DOS. -# The PgUp and PgDn are prefixed with ESC so that tn3270 can be used on Unix -# (^U and ^D are already defined for tn3270). The ESC is safe for vi but it -# does "beep". ESC ESC i is used for Ins to avoid tn3270 ESC i for coltab. -# Note that :kl: is always BS, because PC-dos can tolerate this change. -# Caution: vi is limited to 256 string bytes, longer crashes or weirds out vi. -# Consequently the End keypad key could not be set (it is relatively safe and -# actually useful because it sends ^@ O, which beeps and opens a line above). -ansi.sysk|ansisysk|PC-DOS 3.1 ANSI.SYS with keypad redefined for vi:\ - :is=U2 PC-DOS 3.1 ANSI.SYS with keypad redefined for vi 9-29-86\n\E[;75;8p:\ - :ke=\E[;71;0;71p\E[;72;0;72p\E[;73;0;73p\E[;77;0;77p\E[;80;0;80p\E[;81;0;81p\E[;82;0;82p\E[;83;0;83p:\ - :ks=\E[;71;30p\E[;72;11p\E[;73;27;21p\E[;77;12p\E[;80;10p\E[;81;27;4p\E[;82;27;27;105p\E[;83;127p:\ - :tc=ansi.sys: -# -# Adds ins/del line/character, hence vi reverse scrolls/inserts/deletes nicer. -nansi.sys|nansisys|PC-DOS Public Domain NANSI.SYS:\ - :al=\E[1L:dc=\E[1P:dl=\E[1M:ei=:ic=\E[1@:im=:\ - :is=U3 PC-DOS Public Domain NANSI.SYS 9-23-86\n:tc=ansi.sys: -# -# See ansi.sysk and nansi.sys above. -nansi.sysk|nansisysk|PC-DOS Public Domain NANSI.SYS with keypad redefined for vi:\ - :al=\E[1L:dc=\E[1P:dl=\E[1M:ei=:ic=\E[1@:im=:\ - :is=U4 PC-DOS Public Domain NANSI.SYS with keypad redefined for vi 9-29-86\n\E[;75;8p:tc=ansi.sysk: - -#### ANSI console types -# - -# This entry is good for the 1.2.13 version of the Linux console driver. -# -# Note: there are numerous broken linux entries out there, which didn't screw -# up BSD termcap but hose ncurses's smarter cursor-movement optimization. -# One common pathology is an incorrect tab length of 4. -# -# *************************************************************************** -# * * -# * WARNING: * -# * Linuxes come with a default keyboard mapping kcbt=^I. This entry, in * -# * response to user requests, assumes kcbt=\E[Z, the ANSI/ECMA reverse-tab * -# * character. Here are the keymap replacement lines that will set this up: * -# * * -# keycode 15 = Tab Tab -# alt keycode 15 = Meta_Tab -# shift keycode 15 = F26 -# string F26 ="\033[Z" -# * * -# * This has to use a key slot which is unfortunate (any unused one will * -# # do, F26 is the higher-numbered one). The change ought to be built * -# * into the kernel tables. * -# * * -# *************************************************************************** -# -# The 1.3.x kernels add color-change capabilities; if yours doesn't have this -# and it matters, turn off . The %02x escape used to implement this is -# not back-portable to SV curses and not supported in ncurses versions before -# 1.9.9. All linux kernels since 1.2.13 (at least) set the screen size -# themselves; this entry assumes that capability. -# -# From: Eric S. Raymond 20 Jun 1997 -linux|linux console:\ - :am:eo:mi:ms:ut:xn:xo:\ - :Co#8:NC#3:it#8:pa#64:\ - :&7=^Z:@7=\E[4~:AB=\E[4%dm:AF=\E[3%dm:AL=\E[%dL:DC=\E[%dP:\ - :DL=\E[%dM:F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:\ - :F5=\E[28~:F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:\ - :FA=\E[34~:IC=\E[%d@:K2=\E[G:S2=\E[11m:S3=\E[10m:\ - :ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:cb=\E[1K:cd=\E[J:\ - :ce=\E[K:ch=\E[%i%dG:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ - :do=^J:ec=\E[%dX:ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:\ - :k1=\E[[A:k2=\E[[B:k3=\E[[C:k4=\E[[D:k5=\E[[E:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kB=\E[Z:kD=\E[3~:\ - :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=\177:kd=\E[B:kh=\E[1~:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[0;10m:mh=\E[2m:mk=\E[8m:mr=\E[7m:nd=\E[C:nw=^M^J:\ - :op=\E[39;49m:r1=\Ec:rc=\E8:sc=\E7:se=\E[27m:sf=^J:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:u6=\E[%i%d;%dR:u7=\E[6n:\ - :u8=\E[?6c:u9=\E[c:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=200\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l: -linux-m|Linux console no color:\ - :Co@:pa@:\ - :AB@:AF@:Sb@:Sf@:tc=linux: -linux-c-nc|linux console 1.3.x hack for ncurses only:\ - :cc:\ - :oc=\E]R:tc=linux: -# From: Dennis Henriksen , 9 July 1996 -linux-c|linux console 1.3.6+ with private palette for each virtual console:\ - :cc:\ - :Co#8:pa#64:\ - :oc=\E]R:\ - :tc=linux: - -# See the note on ICH/ICH1 VERSUS RMIR/SMIR near the end of file -linux-nic|linux with ich/ich1 suppressed for non-curses programs:\ - :IC@:ei=:ic@:im=:\ - :tc=linux: - -# This assumes you have used setfont(8) to load one of the Linux koi8-r fonts. -linux-koi8|linux with koi8 alternate character set:\ - :ac=l\202m\204k\203j\205u\207t\206v\210w\211q\200x\201n\212o\213s\214p\216r\217`\004a\237f\234g\232~\225.\037-\036+\020\054\021h\222I\2200\215y\230z\231{\267}L|\274:\ - :ae=\E[10m:as=\E[11m:\ - :tc=linux: - -# SCO console and SOS-Syscons console for 386bsd -# (scoansi: had unknown capabilities -# :Gc=N:Gd=K:Gh=M:Gl=L:Gu=J:Gv=\072:\ -# :GC=E:GD=B:GH=D:GL=\64:GU=A:GV=\63:GR=C: -# :G1=?:G2=Z:G3=@:G4=Y:G5=;:G6=I:G7=H:G8=<:\ -# :CW=\E[M:NU=\E[N:RF=\E[O:RC=\E[P:\ -# :WL=\E[S:WR=\E[T:CL=\E[U:CR=\E[V:\ -# I renamed GS/GE/HM/EN/PU/PD/RT and added klone+sgr-dumb, based -# on the :as:=\E[12m -- esr) -scoansi|SCO Extended ANSI standard crt:\ - :am:bs:eo:xo:\ - :co#80:it#8:li#25:\ - :@7=\E[F:al=\E[L:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :ic=\E[@:im=:k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:\ - :k6=\E[R:k7=\E[S:k8=\E[T:k9=\E[U:k;=\E[V:kN=\E[G:kP=\E[I:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:\ - :mb=\E[5m:md=\E[1m:nd=\E[C:sf=\E[S:sr=\E[T:ta=^I:up=\E[A:\ - :tc=klone+sgr-dumb: - -# This actually describes the generic SVr4 display driver for Intel boxes. -# The :mh=\E[2m: isn't documented and therefore may not be reliable. -# From: Eric Raymond Mon Nov 27 19:00:53 EST 1995 -att6386|at386|386at|AT&T WGS 6386 console:\ - :am:bw:eo:xo:\ - :co#80:it#8:li#25:\ - :@7=\E[Y:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\EOZ:\ - :F2=\EOA:IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:\ - :SR=\E[%dT:UP=\E[%dA:\ - :ac=``a1fxgqh0jYk?lZm@nEooppqDrrsstCu4vAwBx3yyzz{{||}}~~:\ - :ae=\E[10m:al=\E[1L:as=\E[12m:bl=^G:bt=\E[Z:cd=\E[J:\ - :ce=\E[K:ch=\E[%i%dG:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:\ - :ct=\E[2g:cv=\E[%i%dd:dc=\E[P:dl=\E[1M:do=\E[B:ec=\E[%dX:\ - :ei=:ho=\E[H:ic=\E[1@:im=:is=\E[0;10;39m:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:k5=\EOT:k6=\EOU:k7=\EOV:k8=\EOW:k9=\EOX:\ - :k;=\EOY:kB=^]:kD=\E[P:kI=\E[@:kM=\E0:kN=\E[U:kP=\E[V:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:\ - :md=\E[1m:me=\E[0;10m:mh=\E[2m:mk=\E[9m:mr=\E[7m:nd=\E[C:\ - :nw=\r\E[S:rc=\E8:\ - :sc=\E7:se=\E[m:sf=\E[S:so=\E[7m:sr=\E[T:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m:ve=\E[=1C:vi=\E[=C:\ - :tc=klone+color: -# (pc6300plus: removed ":KM=/usr/lib/ua/kmap.s5:"; renamed BO/EE/CI/CV -- esr) -pc6300plus|AT&T 6300 plus:\ - :am:bs:xo:\ - :co#80:li#24:\ - :al=\E[1L:bl=^G:cd=\E[0J:ce=\E[0K:cl=\E[2J\E[H:\ - :cm=\E[%i%2;%2H:cr=^M:ct=\E[3g:dc=\E[1P:dl=\E[1M:do=\E[B:\ - :ei=:ho=\E[H:ic=\E[1@:im=:k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:\ - :k5=\EOg:k6=\EOh:k7=\EOi:k8=\EOj:k9=\EOk:k;=\EOu:kb=^H:\ - :kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[m:mh=\E[2m:mk=\E[9m:mr=\E[7m:nd=\E[C:nw=^M^J:\ - :se=\E[m:sf=^J:so=\E[7m:st=\EH:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E[=1C:vi=\E[=C: - -# : -# Entry for the DNARD OpenFirmware console, close to ANSI but not quite. -# -# (still unfinished, but good enough so far.) -ofcons:\ - :bs:bw:co#80:li#30:\ - :ku=\233A:kd=\233B:kr=\233C:kl=\233D:kb=^H:kD=\233P:\ - :k1=\2330P:k2=\2330Q:k3=\2330W:k4=\2330x:k5=\2330t:k6=\2330u:\ - :k7=\2330q:k8=\2330r:k9=\2330p:k;=\2330M:\ - :kN=\233/:kP=\233?:\ - :mb=\2337;2m:se=\2330m:ue=\2330m:\ - :md=\2331m:me=\2330m:mh=\2332m:mk=\2338m:mr=\2337m:\ - :UP=\233%dA:DO=\233%dB:RI=\233%dC:LE=\233%dD:\ - :DC=\233%dP:IC=\233%d@:dc=\233P:ic=\233@:\ - :DL=\233%dM:dl=\233M:AL=\233%dL:al=\233L:\ - :le=\233D:nd=\233C:do=\233B:up=\233A:\ - :cl=^L:cr=^M:ta=^I:bl=^G:vb=^G:\ - :cm=\233%i%d;%dH:cd=\233J:ce=\233K: - -# -# Terminfo entry for the AT&T Unix PC 7300 -# from escape(7) in Unix PC 7300 Manual. -# Somewhat similar to a vt100-am (but different enough -# to redo this from scratch.) -# -# /*************************************************************** -# * -# * FONT LOADING PROGRAM FOR THE UNIX PC -# * -# * This routine loads a font defined in the file ALTFONT -# * into font memory slot #1. Once the font has been loaded, -# * it can be used as an alternative character set. -# * -# * The call to ioctl with the argument WIOCLFONT is the key -# * to this routine. For more information, see window(7) in -# * the PC 7300 documentation. -# ***************************************************************/ -# #include /* needed for strcpy call */ -# #include /* needed for ioctl call */ -# #define FNSIZE 60 /* font name size */ -# #define ALTFONT "/usr/lib/wfont/special.8.ft" /* font file */ -# /* -# * The file /usr/lib/wfont/special.8.ft comes with the -# * standard PC software. It defines a graphics character set -# * similar to that of the Teletype 5425 terminal. To view -# * this or other fonts in /usr/lib/wfont, use the command -# * cfont . For further information on fonts see -# * cfont(1) in the PC 7300 documentation. -# */ -# -# struct altfdata /* structure for alt font data */ -# { -# short altf_slot; /* memory slot number */ -# char altf_name[FNSIZE]; /* font name (file name) */ -# }; -# ldfont() -# { -# int wd; /* window in which altfont will be */ -# struct altfdata altf; -# altf.altf_slot=1; -# strcpy(altf.altf_name,ALTFONT); -# for (wd =1; wd < 12; wd++) { -# ioctl(wd, WIOCLFONT,&altf); -# } -# } -# -# (att7300: added :vi:/:ve:/:ic:/ from the BSDI entry, -# they're confirmed by the man page for the System V display---esr) -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att7300|unixpc|pc7300|3b1|s4|AT&T UNIX PC Model 7300:\ - :am:xn:xo:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:\ - :UP=\E[%dA:ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:bt=\E^I:\ - :cd=\E[0J:ce=\E[0K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:i1=^O:ic=\E[@:im=:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E5:k6=\E6:k7=\E7:\ - :k8=\E8:kD=\Edc:kI=\Eim:kN=\Epg:kP=\EPG:kb=^H:kd=\E[B:\ - :kh=\Ehm:kl=\E[D:kr=\E[C:ku=\E[A:md=\E[7m:me=\E[0;10m:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:nw=\EE:se=\E[m:sf=^J:so=\E[7m:\ - :sr=\EM:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[=1C:vi=\E[=C: - -# From: Stefan Stapelberg , 24 Feb 1997 -# (iris-ansi: added rmam/smam based on init string -- esr) -iris-ansi|iris-ansi-net|IRIS emulating 40 line ANSI terminal (almost VT100):\ - :am:\ - :co#80:it#8:li#40:\ - :!2=\E[218q:#2=\E[143q:#4=\E[158q:%9=\E[209q:%f=\E[210q:\ - :%i=\E[167q:&7=\E[217q:*4=\E[P:*7=\E[147q:@7=\E[146q:\ - :@8=^M:AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:F1=\EOR:F2=\EOS:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :al=\E[L:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:dl=\E[M:do=^J:ho=\E[H:\ - :is=\E[?1l\E>\E[?7h\E[100g\E[0m\E7\E[r\E8:k1=\E[001q:\ - :k2=\E[002q:k3=\E[003q:k4=\E[004q:k5=\E[005q:k6=\E[006q:\ - :k7=\E[007q:k8=\E[008q:k9=\EOP:k;=\EOQ:kB=\E[Z:kD=\177:\ - :kI=\E[139q:kM=\E[146q:kN=\E[154q:kP=\E[150q:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:md=\E[1m:\ - :me=\E[m:mr=\E[7m:nd=\E[C:nw=\EE:pk=\EP101;%d.y%s\E\\:\ - :rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[1;7m:sr=\EM:st=\EH:\ - :ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[9/y\E[12/y\E[=6l:\ - :vs=\E[10/y\E[=1h\E[=2l\E[=6h: -iris-ansi-ap|IRIS ANSI in application-keypad mode:\ - :@8=\EOM:F1=\E[011q:F2=\E[012q:is=\E[?1l\E=\E[?7h:\ - :k9=\E[009q:k;=\E[010q:ke=\E>:ks=\E=:\ - :tc=iris-ansi: - -# The following is a version of the ibm-pc entry distributed with PC/IX, -# (Interactive Systems' System 3 for the Big Blue), modified by Richard -# McIntosh at UCB/CSM. The :pt: and :uc: have been removed from the original, -# (the former is untrue, and the latter failed under UCB/man); standout and -# underline modes have been added. Note: this entry describes the "native" -# capabilities of the PC monochrome display, without ANY emulation; most -# communications packages (but NOT PC/IX connect) do some kind of emulation. -pcix|PC/IX console:\ - :am:bw:eo:\ - :co#80:li#24:\ - :cd=\E[J:ce=\E[K:cl=\Ec:cm=\E[%i%2;%2H:do=\E[B:ho=\E[H:\ - :le=^H:me=\E[m:nd=\E[C:se=\E[m:so=\E[7m:ue=\E[m:up=\E[A:\ - :us=\E[4m: - -# (ibmpcx: this entry used to be known as ibmx. -# It formerly included the following extension capabilities: -# :GC=b:GL=v:GR=t:RT=^J:\ -# :GH=\E[196g:GV=\E[179g:\ -# :GU=\E[193g:GD=\E[194g:\ -# :G1=\E[191g:G2=\E[218g:G3=\E[192g:G4=\E[217g:\ -# :CW=\E[E:NU=\E[F:RF=\E[G:RC=\E[H:\ -# :WL=\E[K:WR=\E[L:CL=\E[M:CR=\E[N:\ -# I renamed GS/GE/WL/WR/CL/CR/PU/PD/HM/EN; also, removed a duplicate -# ":kh=\E[Y:". Added IBM-PC forms characters and highlights, they match -# what was there before. -- esr) -ibmpcx|xenix|ibmx|IBM PC xenix console display:\ - :am:bs:ms:\ - :co#80:li#25:\ - :@7=\E[d:S2=\E[11m:S3=\E[10m:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030,\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:cd=\E[J:ce=\E[K:cl=^L:\ - :cm=\E[%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :ic=\E[@:im=:k1=\E[K:k2=\E[L:k3=\E[M:k4=\E[N:kN=\E[e:\ - :kP=\E[Z:kb=^H:kd=\E[B:kh=\E[Y:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:mb=\E[5m:md=\E[1m:me=\E[0;10m:mk=\E[8m:mr=\E[7m:\ - :nd=\E[C:nw=^M^J:se=\E[m:sf=^J:so=\E[7m:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: - - -# QNX 4.0 Console -# Michael's original version of this entry had , :ti=\Ei:, -# :te=\Eh\ER:; this was so terminfo applications could write the lower -# right corner without triggering a scroll. The ncurses terminfo library can -# handle this case with the :ic: capability, and prefers :am: for better -# optimization. Bug: The capability resets attributes. -# From: Michael Hunter 30 Jul 1996 -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -qnx|qnx4|qnx console:\ - :km:mi:ms:xt:\ - :co#80:it#4:li#25:\ - :al=\EE:bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:\ - :dc=\Ef:dl=\EF:do=^J:ei=:ho=\EH:ic=\Ee:im=:k1=\377\201:\ - :k2=\377\202:k3=\377\203:k4=\377\204:k5=\377\205:\ - :k6=\377\206:k7=\377\207:k8=\377\210:k9=\377\211:\ - :kD=\377\254:kI=\377\253:kN=\377\252:kP=\377\242:\ - :kd=\377\251:kh=\377\240:kl=\377\244:kr=\377\246:\ - :ku=\377\241:le=^H:mb=\E{:md=\E<:me=\E}\E]\E>\E):mr=\E(:\ - :nd=\EC:rp=\Eg%r%+ %.:se=\E):sf=^J:so=\E(:sr=\EI:ta=^I:\ - :te=\Eh\ER:ti=\Ei:ue=\E]:up=\EA:us=\E[:ve=\Ey1:vi=\Ey0:\ - :vs=\Ey2: - -#### NetBSD consoles -# -# pcvt termcap database entries (corresponding to release 3.31) -# Author's last edit-date: [Fri Sep 15 20:29:10 1995] -# -# (For the terminfo master file, I translated these into terminfo syntax. -# Then I dropped all the pseudo-HP entries. we don't want and can't use -# the :Xs: flag. Then I split :is: into a size-independent :i1: and a -# size-dependent :is:. Finally, I added / -- esr) - -# NOTE: because the 386BSD "vi"/"elvis" seems to have a bug if -# both :ic: and :im: are specified (an original VT220 -# shows the same buggy behaviour!), :ic: has been taken -# out of this entry. for reference, it should be . -pcvtXX|pcvt vt200 emulator (DEC VT220):\ - :am:km:mi:ms:xn:\ - :it#8:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:SF=\E[%dS:\ - :SR=\E[%dT:UP=\E[%dA:\ - :ac=llmmkkjjuuttvvwwqqxxnnoosspprr``aaffgg~~..--++\054\054hhII00yyzz:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :ct=\E[3g:dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ho=\E[H:\ - :i1=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:im=\E[4h:\ - :k1=\E[17~:k2=\E[18~:k3=\E[19~:k4=\E[20~:k5=\E[21~:\ - :k6=\E[23~:k7=\E[24~:k8=\E[25~:kD=\E[3~:kH=\E[4~:kI=\E[2~:\ - :kN=\E[6~:kP=\E[5~:kb=\177:kd=\EOB:ke=\E[?1l\E>:kh=\E[1~:\ - :kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=\EE:\ - :r1=\Ec\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :rf=/usr/share/tabset/vt100:sc=\E7:se=\E[27m:sf=\ED:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[24m:up=\E[A:us=\E[4m:\ - :ve=\E[?25h:vi=\E[?25l: - -# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor) -# termcap entries for pure VT220-Emulation and 25, 28, 35, 40, 43 and -# 50 lines entries; 80 columns -pcvt25|dec vt220 emulation with 25 lines:\ - :co#80:li#25:\ - :is=\E[1;25r\E[25;1H:tc=pcvtXX: -pcvt28|dec vt220 emulation with 28 lines:\ - :co#80:li#28:\ - :is=\E[1;28r\E[28;1H:tc=pcvtXX: -pcvt35|dec vt220 emulation with 35 lines:\ - :co#80:li#35:\ - :is=\E[1;35r\E[35;1H:tc=pcvtXX: -pcvt40|dec vt220 emulation with 40 lines:\ - :co#80:li#40:\ - :is=\E[1;40r\E[40;1H:tc=pcvtXX: -pcvt43|dec vt220 emulation with 43 lines:\ - :co#80:li#43:\ - :is=\E[1;43r\E[43;1H:tc=pcvtXX: -pcvt50|dec vt220 emulation with 50 lines:\ - :co#80:li#50:\ - :is=\E[1;50r\E[50;1H:tc=pcvtXX: - -# NetBSD/FreeBSD vt220 terminal emulator console (pc keyboard & monitor) -# termcap entries for pure VT220-Emulation and 25, 28, 35, 40, 43 and -# 50 lines entries; 132 columns -pcvt25w|dec vt220 emulation with 25 lines and 132 cols:\ - :co#132:li#25:\ - :is=\E[1;25r\E[25;1H:tc=pcvtXX: -pcvt28w|dec vt220 emulation with 28 lines and 132 cols:\ - :co#132:li#28:\ - :is=\E[1;28r\E[28;1H:tc=pcvtXX: -pcvt35w|dec vt220 emulation with 35 lines and 132 cols:\ - :co#132:li#35:\ - :is=\E[1;35r\E[35;1H:tc=pcvtXX: -pcvt40w|dec vt220 emulation with 40 lines and 132 cols:\ - :co#132:li#40:\ - :is=\E[1;40r\E[40;1H:tc=pcvtXX: -pcvt43w|dec vt220 emulation with 43 lines and 132 cols:\ - :co#132:li#43:\ - :is=\E[1;43r\E[43;1H:tc=pcvtXX: -pcvt50w|dec vt220 emulation with 50 lines and 132 cols:\ - :co#132:li#50:\ - :is=\E[1;50r\E[50;1H:tc=pcvtXX: - -# NetBSD/x68k console vt200 emulator. This port runs on a 68K machine -# manufactured by Sharp for the Japenese market. -# From Minoura Makoto , 12 May 1996 -x68k|x68k-ite|NetBSD/x68k ITE:\ - :co#96:li#32:\ - :%1=\E[28~:kC=\E[9~:tc=vt220: - -# NetBSD "wscons" emulator in vt220 mode -wsvt25|NetBSD wscons in 25 line DEC VT220 mode:\ - :Co#8:pa#64:it#8:ut:co#80:li#25:vb@:xn@:if@:NC#2:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:k;=\E[21~:\ - :AB=\E[4%dm:AF=\E[3%dm:op=\E[m:is=\E[!p:ti=\E)0:te=\E)B:\ - :ac=``aaffggjjkkllmmnnqqttuuvvwwxxyyzz{{}}~~:\ - :@7=\E[8~:kh=\E[7~:kH=\E[8~:rs=\Ec:tc=vt220-8: - -wsvt25m|NetBSD wscons in 25 line DEC VT220 mode with Meta:\ - :km:tc=wsvt25: - -# NetBSD 'window version 2' -# This is the window-v2 binding that NetBSD's window(1) exports into -# the TERMCAP environment variable. -# Note that older versions of window have a bug where turning off -# underscore or standout also turns off the other, but does not reset -# the internal state. -WW|window-v2|window program version 2: \ - :am:bs:da:db:ms:pt:cr=^M:nl=^J:bl=^G:ta=^I: \ - :cm=\EY%+ %+ :le=^H:nd=\EC:up=\EA:do=\EB:ho=\EH: \ - :cd=\EJ:ce=\EK:cl=\EE:me=\Er^?:co#80:li#24:se=\ErA:so=\EsA: \ - :mr=\EsA:ue=\ErD:us=\EsD:ae=\ErH:as=\EsH:al=\EL:dl=\EM: \ - :im=\E@:ei=\EO:ic=:mi:dc=\EN: \ - :kb=^H:ku=^[OA:kd=^[OB:kl=^[OD:kr=^[OC:kh=^[OH: - -#### FreeBSD console entries -# -# From: Andrey Chernov 29 Mar 1996 -# Andrey Chernov maintains the FreeBSD termcap distributions. -# -# Note: Users of FreeBSD 2.1.0 and older versions must either upgrade -# or comment out the :cb: capability in the console entry. -# -# Alexander Lukyanov reports: -# I have seen FreeBSD-2.1.5R... The old el1 bug changed, but it is still there. -# Now el1 clears not only to the line beginning, but also a large chunk -# of previous line. But there is another bug - ech does not work at all. -# (Accordingly, :ec:=\E[%p1%dX and =\E[1K have been removed.) -# - - -# for syscons -# common entry without semigraphics -# Bug: The capability resets attributes. -cons25w|ansiw|ansi80x25-raw|freebsd console (25-line raw mode):\ - :NP:am:bw:eo:ms:ut:\ - :Co#8:co#80:it#8:li#25:pa#64:\ - :@7=\E[F:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[W:\ - :F2=\E[X:IC=\E[%d@:K2=\E[E:LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:\ - :SR=\E[%dT:Sb=\E[4%dm:Sf=\E[3%dm:UP=\E[%dA:al=\E[L:bl=^G:\ - :bt=\E[Z:cd=\E[J:ce=\E[K:ch=\E[%i%d`:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cv=\E[%i%dd:dc=\E[P:dl=\E[M:do=\E[B:\ - :ei=:ho=\E[H:ic=\E[@:im=:k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:\ - :k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:k9=\E[U:k;=\E[V:kB=\E[Z:\ - :kD=\177:kI=\E[L:kN=\E[G:kP=\E[I:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mh=\E[30;1m:mr=\E[7m:nd=\E[C:nw=\E[E:op=\E[x:\ - :r1=\E[x\E[m\Ec:se=\E[m:sf=\E[S:so=\E[7m:sr=\E[T:ta=^I:\ - :up=\E[A: -cons25|ansis|ansi80x25|freebsd console (25-line ansi mode):\ - :ac=l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\305`\004a\260f\370g\361~\371.\031-\030h\261I^U0\333y\363z\362:\ - :tc=cons25w: -cons25-m|ansis-mono|ansi80x25-mono|freebsd console (25-line mono ansi mode):\ - :Co@:pa@:\ - :Sb@:Sf@:md@:mh@:op@:ue=\E[m:us=\E[4m:tc=cons25: -cons30|ansi80x30|freebsd console (30-line ansi mode):\ - :li#30:tc=cons25: -cons30-m|ansi80x30-mono|freebsd console (30-line mono ansi mode):\ - :li#30:tc=cons25-m: -cons43|ansi80x43|freebsd console (43-line ansi mode):\ - :li#43:tc=cons25: -cons43-m|ansi80x43-mono|freebsd console (43-line mono ansi mode):\ - :li#43:tc=cons25-m: -cons50|ansil|ansi80x50|freebsd console (50-line ansi mode):\ - :li#50:tc=cons25: -cons50-m|ansil-mono|ansi80x50-mono|freebsd console (50-line mono ansi mode):\ - :li#50:tc=cons25-m: -cons60|ansi80x60|freebsd console (60-line ansi mode):\ - :li#60:tc=cons25: -cons60-m|ansi80x60-mono|freebsd console (60-line mono ansi mode):\ - :li#60:tc=cons25-m: -cons25r|pc3r|ibmpc3r|cons25-koi8-r|freebsd console w/koi8-r cyrillic:\ - :ac=q\200x\201m\204v\211j\205t\206n\212u\207l\202w\210k\203y\230z\231f\234~\225a\220h\221`\004.\031-\030I^U0\215:\ - :tc=cons25w: -cons25r-m|pc3r-m|ibmpc3r-mono|cons25-koi8r-m|freebsd console w/koi8-r cyrillic (mono):\ - :Co@:pa@:\ - :Sb@:Sf@:op@:ue=\E[m:us=\E[4m:tc=cons25r: -cons50r|cons50-koi8r|freebsd console w/koi8-r cyrillic (50 lines):\ - :li#50:tc=cons25r: -cons50r-m|cons50-koi8r-m|freebsd console w/koi8-r cyrillic (50-line mono):\ - :li#50:tc=cons25r-m: -cons60r|cons60-koi8r|freebsd console w/koi8-r cyrillic (60 lines):\ - :li#60:tc=cons25r: -cons60r-m|cons60-koi8r-m|freebsd console w/koi8-r cyrillic (60-line mono):\ - :li#60:tc=cons25r-m: -# ISO 8859-1 FreeBSD console -cons25l1|cons25-iso8859|freebsd console w/iso 8859-1 chars:\ - :ac=l\215m\216k\214j\213u\226t\225v\227w\230q\222x\231n\217o\220s\224p\221r\223`\201a\202f\207g\210~\237.\031-\030+\253\054\273I\247y\232z\233:\ - :tc=cons25w: -cons25l1-m|cons25-iso-m|freebsd console w/iso 8859-1 chars (mono):\ - :Co@:pa@:\ - :Sb@:Sf@:md@:mh@:op@:ue=\E[m:us=\E[4m:tc=cons25l1: -cons50l1|cons50-iso8859|freebsd console w/iso 8859-1 chars (50 lines):\ - :li#50:tc=cons25l1: -cons50l1-m|cons50-iso-m|freebsd console w/iso 8859-1 chars (50-line mono):\ - :li#50:tc=cons25l1-m: -cons60l1|cons60-iso|freebsd console w/iso 8859-1 chars (60 lines):\ - :li#60:tc=cons25l1: -cons60l1-m|cons60-iso-m|freebsd console w/iso 8859-1 chars (60-line mono):\ - :li#60:tc=cons25l1-m: - -#### 386BSD and BSD/OS Consoles -# - -# This was the original 386BSD console entry (I think). -# Some places it's named oldpc3|oldibmpc3. -# From: Alex R.N. Wetmore -origpc3|origibmpc3|IBM PC 386BSD Console:\ - :am:bs:bw:eo:xo:\ - :co#80:li#25:\ - :ac=l\332q\304k\277x\263j\331m\300w\302u\264v\301t\303n\305:\ - :cd=\E[J:ce=\E[K:cl=\Ec:cm=\E[%i%2;%2H:do=\E[B:ho=\E[H:\ - :kd=\E[B:kh=\E[Y:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:md=\E[7m:\ - :me=\E[m\E[1;0x\E[2;7x:nd=\E[C:se=\E[1;0x\E[2;7x:\ - :sf=\E[S:so=\E[1;7x\E[2;0x:sr=\E[T:ue=\E[1;0x\E[2;7x:\ - :up=\E[A:us=\E[1;7x\E[2;0x: - -# description of BSD/386 console emulator in version 1.0 (supplied by BSDI) -oldpc3|oldibmpc3|old IBM PC BSD/386 Console:\ - :bs:km:\ - :li#25:\ - :al=\E[L:bl=^G:cr=^M:dl=\E[M:do=^J:kH=\E[F:kI=\E[L:kN=\E[G:\ - :kP=\E[I:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :md=\E[=15F:me=\E[=R:mh=\E[=8F:nw=^M^J:sf=^J:ta=^I: - -# Description of BSD/OS console emulator in version 1.1, 2.0, 2.1 -# Note, the emulator supports many of the additional console features -# listed in the iBCS2 (e.g. character-set selection) though not all -# are described here. This entry really ought to be upgraded. -# Also note, the console will also work with fewer lines after doing -# "stty rows NN", e.g. to use 24 lines. -# (Color support from Kevin Rosenberg , 2 May 1996) -# Bug: The capability resets attributes. -bsdos|BSD/OS console:\ - :am:bs:bw:eo:km:xo:\ - :Co#8:co#80:it#8:li#25:pa#64:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:\ - :Sb=\E[4%dm:Sf=\E[3%dm:UP=\E[%dA:al=\E[L:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\Ec:cm=\E[%i%d;%dH:cr=^M:dl=\E[M:do=^J:ho=\E[H:\ - :kH=\E[F:kI=\E[L:kN=\E[G:kP=\E[I:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[0m:\ - :mh=\E[=8F:mr=\E[7m:nd=\E[C:nw=^M^J:op=\E[x:rc=\E8:sc=\E7:\ - :se=\E[0m:sf=^J:so=\E[7m:ta=^I:up=\E[A: -bsdos-bold|IBM PC BSD/386 Console with bold instead of underline:\ - :ue=\E[0m:us=\E[1m:\ - :tc=bsdos: - -# If you are BSDI, you want the following entries, for the moment. -# In release 2.0 they will probably phase out the pc3 and ibmpc3 names -pc3|IBM PC BSD/386 Console:\ - :mh@:tc=bsdos: -ibmpc3|pc3-bold|IBM PC BSD/386 Console with bold instead of underline:\ - :us=\E[1m:\ - :tc=bsdos-bold: - -#### DEC VT100 and compatibles -# -# DEC terminals from the vt100 forward (and the vt52, way obsolete but still -# the basis of some emulations) are collected here. Older DEC terminals and -# micro consoles can be found in the `obsolete' section. More details on -# the relationship between the VT100 and ANSI X3.64/ISO 6429/ECMA-48 may be -# found near the end of this file. -# -# Except where noted, these entries are DEC's official terminfos. -# Contact Bill Hedberg of Terminal Support -# Engineering for more information. Updated terminfos and termcaps -# are kept available at ftp://gatekeeper.dec.com/pub/DEC/termcaps. -# -# In October 1995 DEC sold its terminals business, including the VT and Dorio -# line and trademark, to SunRiver Data Systems. SunRiver has since changed -# its name to Boundless Technologies; see http://www.boundless.com. -# - -# (The , :ae:, and :as: capabilities aren't in DEC's official -# entry -- esr) -vt52|dec vt52:\ - :bs:\ - :co#80:it#8:li#24:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\EG:as=\EF:bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :\ - :cr=^M:do=\EB:ho=\EH:kb=^H:kd=\EB:kl=\ED:kr=\EC:ku=\EA:\ - :le=\ED:nd=\EC:nw=^M^J:sf=^J:sr=\EI:ta=^I:up=\EA: - -# NOTE: Any VT100 emulation, whether in hardware or software, almost -# certainly includes what DEC called the `Level 1 editing extension' codes; -# only the very oldest VT100s lacked these and there probably aren't any of -# those left alive. To capture these, use one of the VT102 entries. -# -# Note that the :xn: glitch in vt100 is not quite the same as on the Concept, -# since the cursor is left in a different position while in the -# weird state (concept at beginning of next line, vt100 at end -# of this line) so all versions of vi before 3.7 don't handle -# :xn: right on vt100. The correct way to handle :xn: is when -# you output the char in column 80, immediately output CR LF -# and then assume you are in column 1 of the next line. If :xn: -# is on, am should be on too. -# -# I assume you have smooth scroll off or are at a slow enough baud -# rate that it doesn't matter (1200? or less). Also this assumes -# that you set auto-nl to "on", if you set it off use vt100-nam -# below. -# -# The padding requirements listed here are guesses. It is strongly -# recommended that xon/xoff be enabled, as this is assumed here. -# -# The vt100 uses and rather than :is:/:ct:/:st: because the -# tab settings are in non-volatile memory and don't need to be -# reset upon login. Also setting the number of columns glitches -# the screen annoyingly. You can type "reset" to get them set. -# -# Here's a diagram of the VT100 keypad keys with their bindings. -# The top line is the name of the key (some DEC keyboards have the keys -# labelled somewhat differently, like GOLD instead of PF1, but this is -# the most "official" name). The second line is the escape sequence it -# generates in Application Keypad mode (where "$" means the ESC -# character). The third line contains two items, first the mapping of -# the key in terminfo, and then in termcap. -# _______________________________________ -# | PF1 | PF2 | PF3 | PF4 | -# | $OP | $OQ | $OR | $OS | -# |_kf1__k1_|_kf2__k2_|_kf3__k3_|_kf4__k4_| -# | 7 8 9 - | -# | $Ow | $Ox | $Oy | $Om | -# |_kf9__k9_|_kf10_k;_|_kf0__k0_|_________| -# | 4 | 5 | 6 | , | -# | $Ot | $Ou | $Ov | $Ol | -# |_kf5__k5_|_kf6__k6_|_kf7__k7_|_kf8__k8_| -# | 1 | 2 | 3 | | -# | $Oq | $Or | $Os | enter | -# |_ka1__K1_|_kb2__K2_|_ka3__K3_| $OM | -# | 0 | . | | -# | $Op | $On | | -# |___kc1_______K4____|_kc3__K5_|_kent_@8_| -# -# And here, for those of you with orphaned VT100s lacking documentation, is -# a description of the soft switches invoked when you do `Set Up'. -# -# Scroll 0-Jump Shifted 3 0-# -# | 1-Smooth | 1-British pound sign -# | Autorepeat 0-Off | Wrap Around 0-Off -# | | 1-On | | 1-On -# | | Screen 0-Dark Bkg | | New Line 0-Off -# | | | 1-Light Bkg | | | 1-On -# | | | Cursor 0-Underline | | | Interlace 0-Off -# | | | | 1-Block | | | | 1-On -# | | | | | | | | -# 1 1 0 1 1 1 1 1 0 1 0 0 0 0 1 0 <--Standard Settings -# | | | | | | | | -# | | | Auto XON/XOFF 0-Off | | | Power 0-60 Hz -# | | | 1-On | | | 1-50 Hz -# | | Ansi/VT52 0-VT52 | | Bits Per Char. 0-7 Bits -# | | 1-ANSI | | 1-8 Bits -# | Keyclick 0-Off | Parity 0-Off -# | 1-On | 1-On -# Margin Bell 0-Off Parity Sense 0-Odd -# 1-On 1-Even -# -# The following SET-UP modes are assumed for normal operation: -# ANSI_MODE AUTO_XON/XOFF_ON NEWLINE_OFF 80_COLUMNS -# WRAP_AROUND_ON JUMP_SCROLL_OFF -# Other SET-UP modes may be set for operator convenience or communication -# requirements; I recommend -# AUTOREPEAT_ON BLOCK_CURSOR MARGIN_BELL_OFF SHIFTED_3_# -# Unless you have a graphics add-on such as Digital Engineering's VT640 -# (and even then, whenever it can be arranged!) you should set -# INTERLACE_OFF -# -# (I added / based on the init string, also :bs: -- esr) -vt100|vt100-am|dec vt100 (w/advanced video):\ - :am:bs:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :@8=\EOM:DO=\E[%dB:K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:do=^J:\ - :eA=\E(B:ho=\E[H:k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:mr=\E[7m:\ - :nd=\E[C:r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: -vt100nam|vt100-nam|vt100 no automargins:\ - :am@:xn@:tc=vt100-am: - -# Ordinary vt100 in 132 column ("wide") mode. -vt100-w|vt100-w-am|dec vt100 132 cols (w/advanced video):\ - :co#132:li#24:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?8h:tc=vt100-am: -vt100-w-nam|vt100-nam-w|dec vt100 132 cols (w/advanced video no automargin):\ - :co#132:li#14:vt@:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?8h:tc=vt100-nam: - -# vt100 with no advanced video. -vt100-nav|vt100 without advanced video option:\ - :sg#1:\ - :mb@:md@:me@:mr@:sa@:se=\E[m:so=\E[7m:ue@:us@:tc=vt100: -vt100-nav-w|vt100-w-nav|dec vt100 132 cols 14 lines (no advanced video option):\ - :co#132:li#14:tc=vt100-nav: - -# vt100 with one of the 24 lines used as a status line. -# We put the status line on the top. -vt100-s|vt100-s-top|vt100-top-s|vt100 for use with top sysline:\ - :es:hs:\ - :li#23:\ - :cl=\E[2;1H\E[J:cm=\E[%i%+^A;%dH:cs=\E[%i%i%d;%dr:\ - :ds=\E7\E[1;24r\E8:fs=\E8:ho=\E[2;1H:is=\E7\E[2;24r\E8:\ - :ts=\E7\E[1;%dH\E[1K:\ - :tc=vt100-am: - -# Status line at bottom. -# Clearing the screen will clobber status line. -vt100-s-bot|vt100-bot-s|vt100 for use with bottom sysline:\ - :es:hs:\ - :li#23:\ - :ds=\E7\E[1;24r\E8:fs=\E8:is=\E[1;23r\E[23;1H:\ - :ts=\E7\E[24;%dH\E[1K:\ - :tc=vt100-am: - -# Most of the `vt100' emulators out there actually emulate a vt102 -# This entry (or vt102-nsgr) is probably the right thing to use for -# these. -vt102|dec vt102:\ - :mi:\ - :al=\E[L:dc=\E[P:dl=\E[M:ei=\E[4l:im=\E[4h:tc=vt100: -vt102-w|dec vt102 in wide mode:\ - :co#132:\ - :r3=\E[?3h:tc=vt102: - -# Many brain-dead PC comm programs that pretend to be `vt100-compatible' -# fail to interpret the ^O and ^N escapes properly. Symptom: the :me: -# string in the canonical vt100 entry above leaves the screen littered -# with little snowflake or star characters (IBM PC ROM character \017 = ^O) -# after highlight turnoffs. This entry should fix that, and even leave -# ACS support working, at the cost of making multiple-highlight changes -# slightly more expensive. -# From: Eric S. Raymond July 22 1995 -vt102-nsgr|vt102 no sgr (use if you see snowflakes after highlight changes):\ - :me=\E[m:sa@:\ - :tc=vt102: - -# VT125 Graphics CRT. Clear screen also erases graphics -vt125|vt125 graphics terminal:\ - :cl=\E[H\E[2J\EPpS(E)\E\:tc=vt100: - -# This isn't a DEC entry, it came from University of Wisconsin. -# (vt131: I added / based on the init string, also :bs: -- esr) -vt131|dec vt131:\ - :am:bs:xn:\ - :co#80:it#8:li#24:vt#3:\ - :RA=\E[?7h:SA=\E[?7h:bl=^G:cd=50\E[J:ce=3\E[K:\ - :cl=50\E[;H\E[2J:cm=5\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :do=^J:ho=\E[H:is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=2\E[5m:md=2\E[1m:\ - :me=2\E[m:mr=2\E[7m:nd=2\E[C:nw=^M^J:\ - :r1=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:sc=\E7:\ - :se=2\E[m:so=2\E[7m:sr=5\EM:ta=^I:ue=2\E[m:up=2\E[A:\ - :us=2\E[4m: - -# vt132 - like vt100 but slower and has ins/del line and such. -# I'm told that :im:/:ei: are backwards in the terminal from the -# manual and from the ANSI standard, this describes the actual -# terminal. I've never actually used a vt132 myself, so this -# is untested. -# -vt132|DEC vt132:\ - :xn:\ - :al=\E[L:dc=\E[P:dl=\E[M:ei=\E[4h:im=\E[4l:ip=:sf=\n:tc=vt100: - -# vt220: -# This vt220 description maps F5--F9 to the second block of function keys -# at the top of the keyboard. The "DO" key is used as F10 to avoid conflict -# with the key marked (ESC) on the vt220. See vt220d for an alternate mapping. -# PF1--PF4 are used as F1--F4. -# -vt220|vt200|DEC VT220 in vt100 emulation mode:\ - :am:bs:mi:pt:xn:xo:\ - :co#80:li#24:vt#3:\ - :@7=\E[4~:RA=\E[?7l:SA=\E[?7h:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ho=\E[H:\ - :if=/usr/share/tabset/vt100:im=\E[4h:\ - :is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :k5=\E[17~:k6=\E[18~:k7=\E[19~:k8=\E[20~:k9=\E[21~:\ - :k;=\E[29~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:\ - :kd=\E[B:kh=\E[1~:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nl=^J:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :rf=/usr/share/tabset/vt100:\ - :sc=\E7:se=\E[27m:sf=20\ED:so=\E[7m:sr=14\EM:ta=^I:\ - :ue=\E[24m:up=\E[A:us=\E[4m:ve=\E[?25h:vi=\E[?25l: -vt220-w|vt200-w|DEC vt220 in wide mode:\ - :co#132:\ - :r3=\E[?3h:tc=vt220: - -# -# vt220d: -# This vt220 description regards F6--F10 as the second block of function keys -# at the top of the keyboard. This mapping follows the description given -# in the VT220 Programmer Reference Manual and agrees with the labeling -# on some terminals that emulate the vt220. There is no support for an F5. -# See vt220 for an alternate mapping. -# -vt220d|DEC VT220 in vt100 mode with DEC function key labeling:\ - :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ - :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:k5@:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\ - :tc=vt220: - -vt220-nam|v200-nam|VT220 in vt100 mode with no auto margins:\ - :am@:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7l\E[?8h:tc=vt220: - -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -vt220-8|dec vt220 8 bit terminal:\ - :am:bs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ec=\E[%dX:\ - :ei=\E[4l:ho=\E[H:if=/usr/share/tabset/vt100:im=\E[4h:\ - :is=\E[?7h\E[>\E[?1h\E F\E[?4l:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kI=\E[2~:\ - :kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :nw=\EE:rc=\E8:sc=\E7:se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:\ - :st=\EH:ta=^I:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ - :ve=\E[?25h:vi=\E[?25l: - -# This was DEC's vt320. Use the purpose-built one below instead -#vt320|DEC VT320 in vt100 emulation mode, -# use=vt220, - -# vt220 termcap written Tue Oct 25 20:41:10 1988 by Alex Latzko -# (not an official DEC entry!) -# The problem with real vt220 terminals is they don't send escapes when in -# in vt220 mode. This can be gotten around two ways. 1> don't send -# escapes or 2> put the vt220 into vt100 mode and use all the nifty -# features of vt100 advanced video which it then has. -# -# This entry takes the view of putting a vt220 into vt100 mode so -# you can use the escape key in emacs and everything else which needs it. -# -# You probably don't want to use this on a VMS machine since VMS will think -# it has a vt220 and will get fouled up coming out of emacs -# -# From: Alexander Latzko , 30 Dec 1996 -vt200-js|vt220-js|dec vt200 series with jump scroll:\ - :am:\ - :co#80:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:dm=:do=^J:ed=:\ - :ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E[61"p\E[H\E[?3l\E[?4l\E[?1l\E[?5l\E[?6l\E[?7h\E[?8h\E[?25h\E>\E[m:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:\ - :ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:\ - :nw=^M\ED:r1=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :rf=/usr/lib/tabset/vt100:se=5\E[27m:sf=\ED:so=5\E[7m:\ - :sr=\EM:ta=^I:ue=\E[24m:up=\E[A:us=\E[4m: - -# -# Use v320n for SCO's LYRIX. Otherwise, use Adam Thompson's vt320-nam. -# -vt320nam|v320n|DEC VT320 in vt100 emul. mode with NO AUTO WRAP mode:\ - :am@:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7l\E[?8h:tc=vt220: - -# These entries are not DEC's official ones, they were purpose-built for the -# VT320. Here are the designer's notes: -# is end on a PC kbd. Actually 'select' on a VT. Mapped to -# 'Erase to End of Field'... since nothing seems to use 'end' anyways... -# khome is Home on a PC kbd. Actually 'FIND' on a VT. -# Things that use usually use tab anyways... and things that don't use -# tab usually use instead... -# kprv is same as tab - Backtab is useless... -# I left out :sa: because of its RIDICULOUS complexity, -# and the resulting fact that it causes the termcap translation of the entry -# to SMASH the 1k-barrier... -# From: Adam Thompson Sept 10 1995 -# (vt320: uncommented :fs: --esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -vt320|vt300|dec vt320 7 bit terminal:\ - :am:es:hs:mi:ms:xn:\ - :co#80:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ec=\E[%dX:\ - :ei=\E[4l:fs=\E[0$}:ho=\E[H:im=\E[4h:\ - :is=\E>\E[?3l\E[?4l\E[5?l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=\177:kd=\EOB:ke=\E[?1l\E>:kh=\E[1~:kl=\EOD:kr=\EOC:\ - :ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:rc=\E8:sc=\E7:se=\E[m:sf=\ED:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:ts=\E[1$}\E[H\E[K:ue=\E[m:\ - :up=\E[A:us=\E[4m:ve=\E[?25h:vi=\E[?25l: -vt320-nam|vt300-nam|dec vt320 7 bit terminal with no am to make SAS happy:\ - :am@:\ - :is=\E>\E[?3l\E[?4l\E[5?l\E[?7l\E[?8h\E[1;24r\E[24;1H:\ - :r2=\E>\E[?3l\E[?4l\E[5?l\E[?7l\E[?8h\E[1;24r\E[24;1H:\ - :tc=vt320: -# We have to init 132-col mode, not 80-col mode. -vt320-w|vt300-w|dec vt320 wide 7 bit terminal:\ - :co#132:ws#132:\ - :is=\E>\E[?3h\E[?4l\E[5?l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :r2=\E>\E[?3h\E[?4l\E[5?l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :tc=vt320: -vt320-w-nam|vt300-w-nam|dec vt320 wide 7 bit terminal with no am:\ - :am@:\ - :is=\E>\E[?3h\E[?4l\E[5?l\E[?7l\E[?8h\E[1;24r\E[24;1H:\ - :r2=\E>\E[?3h\E[?4l\E[5?l\E[?7l\E[?8h\E[1;24r\E[24;1H:\ - :tc=vt320-w: - -# VT330 and VT340 -- These are ReGIS and SIXEL graphics terminals -# which are pretty much a superset of the VT320. They have the -# host writable status line, yet another different DRCS matrix size, -# and such, but they add the DEC Technical character set, Multiple text -# pages, selectable length pages, and the like. The difference between -# the vt330 and vt340 is that the latter has only 2 planes and a monochrome -# monitor, the former has 4 planes and a color monitor. These terminals -# support VT131 and ANSI block mode, but as with much of these things, -# termcap/terminfo doesn't deal with these features. -# -# Note that this entry is are set up in what was the standard way for GNU -# Emacs v18 terminal modes to deal with the cursor keys in that the arrow -# keys were switched into application mode at the same time the numeric pad -# is switched into application mode. This changes the definitions of the -# arrow keys. Emacs v19 is smarter and mines its keys directly out of -# your termcap or terminfo entry, -# -# From: Daniel Glasser , 13 Oct 1993 -# (vt340: string capability "sb=\E[M" corrected to "sr"; -# also, added / based on the init string -- esr) -vt340|dec-vt340|vt330|dec-vt330|dec vt340 graphics terminal with 24 line page:\ - :am:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=^O:al=\E[L:as=^N:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ds=\E[2$~\r\E[1$}\E[K\E[$}:ei=\E[4l:\ - :fs=\E[$}:ho=\E[H:im=\E[4h:\ - :is=\E<\E F\E>\E[?1h\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l1=pf1:l2=pf2:l3=pf3:l4=pf4:\ - :le=^H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=^M\ED:\ - :r1=\E[?3l:rc=\E8:rf=/usr/share/tabset/vt300:sc=\E7:\ - :se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E[2$~\E[1$}\E[1;%dH:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=200\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: - -# DEC doesn't supply a vt400 description, so we add Daniel Glasser's -# (originally written with vt420 as its primary name, and usable for it). -# -# VT400/420 -- This terminal is a superset of the vt320. It adds the multiple -# text pages and long text pages with selectable length of the vt340, along -# with left and right margins, rectangular area text copy, fill, and erase -# operations, selected region character attribute change operations, -# page memory and rectangle checksums, insert/delete column, reception -# macros, and other features too numerous to remember right now. TERMCAP -# can only take advantage of a few of these added features. -# -# Note that this entry is are set up in what was the standard way for GNU -# Emacs v18 terminal modes to deal with the cursor keys in that the arrow -# keys were switched into application mode at the same time the numeric pad -# is switched into application mode. This changes the definitions of the -# arrow keys. Emacs v19 is smarter and mines its keys directly out of -# your termcap entry, -# -# From: Daniel Glasser , 13 Oct 1993 -# (vt400: string capability ":sb=\E[M:" corrected to ":sr=\E[M:"; -# also, added / based on the init string -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -vt400|vt400-24|dec-vt400|dec vt400 24x80 column autowrap:\ - :am:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:\ - :cd=10\E[J:ce=4\E[K:cl=10\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ds=\E[2$~\r\E[1$}\E[K\E[$}:ei=\E[4l:fs=\E[$}:ho=\E[H:\ - :ic=\E[@:im=\E[4h:\ - :is=\E<\E F\E>\E[?1h\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[m:mr=\E[7m:nd=\E[C:nw=^M\ED:rc=\E8:sc=\E7:se=\E[27m:\ - :sf=\ED:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E[2$~\E[1$}\E[1;%dH:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=200\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: - -# (vt420: I removed :k0:, it collided with . I also restored -# a missing :sc: -- esr) -vt420|DEC VT420:\ - :am:mi:xn:xo:\ - :co#80:li#24:vt#3:\ - :*6=\E[4~:@0=\E[1~:RA=\E[?7l:\ - :S5=\E[?0;0r\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :SA=\E[?7h:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ho=\E[H:\ - :i2=\E[?67h\E[64;1"p:if=/usr/share/tabset/vt300:\ - :im=\E[4h:is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\E[17~:k6=\E[18~:k7=\E[19~:k8=\E[20~:\ - :k9=\E[21~:k;=\E[29~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:ke=\E>:kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :r3=\E[?67h\E[64;1"p:rc=\E8:rf=/usr/share/tabset/vt300:\ - :sc=\E7:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: - -# -# DECUDK -# if (key < 16) then value = key; -# else if (key < 21) then value = key + 1; -# else if (key < 25) then value = key + 2; -# else if (key < 27) then value = key + 3; -# else if (key < 30) then value = key + 4; -# else value = key + 5; -# -vt420pc|DEC VT420 w/PC keyboard:\ - :@7=\E[4~:F1=\E[23~:F2=\E[24~:F3=\E[11;2~:F4=\E[12;2~:\ - :F5=\E[13;2~:F6=\E[14;2~:F7=\E[15;2~:F8=\E[17;2~:\ - :F9=\E[18;2~:FA=\E[19;2~:FB=\E[20;2~:FC=\E[21;2~:\ - :FD=\E[23;2~:FE=\E[24;2~:FF=\E[23~:FG=\E[24~:FH=\E[25~:\ - :FI=\E[26~:FJ=\E[28~:FK=\E[29~:FL=\E[31~:FM=\E[32~:\ - :FN=\E[33~:FO=\E[34~:FP=\E[35~:FQ=\E[36~:FR=\E[23;2~:\ - :FS=\E[24;2~:FT=\E[25;2~:FU=\E[26;2~:FV=\E[28;2~:\ - :FW=\E[29;2~:FX=\E[31;2~:FY=\E[32;2~:FZ=\E[33;2~:\ - :Fa=\E[34;2~:Fb=\E[35;2~:Fc=\E[36;2~:\ - :S6=USR_TERM\072vt420pcdos\072:k1=\E[11~:k2=\E[12~:\ - :k3=\E[13~:k4=\E[14~:k5=\E[15~:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:k;=\E[21~:kD=\177:kh=\E[H:\ - :tc=vt420: - -vt420pcdos|DEC VT420 w/PC for DOS Merge:\ - :li#25:\ - :S4=\E[?1;2r\E[34h:\ - :S5=\E[?0;0r\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:S6@:\ - :me=\E[m:sa@:\ - :tc=vt420pc: - -vt420f|DEC VT420 with VT kbd; VT400 mode; F1-F5 used as Fkeys:\ - :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ - :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\ - :kD=\177:kh=\E[H:l1=\EOP:l2=\EOQ:l3=\EOR:l4=\EOS:\ - :tc=vt420: - -vt510|DEC VT510:\ - :tc=vt420: -vt510pc|DEC VT510 w/PC keyboard:\ - :tc=vt420pc: -vt510pcdos|DEC VT510 w/PC for DOS Merge:\ - :tc=vt420pcdos: - -# VT520/VT525 -# -# The VT520 is a monochrome text terminal capable of managing up to -# four independent sessions in the terminal. It has multiple ANSI -# emulations (VT520, VT420, VT320, VT220, VT100, VT PCTerm, SCO Console) -# and ASCII emulations (WY160/60, PCTerm, 50/50+, 150/120, TVI 950, -# 925 910+, ADDS A2). This terminfo data is for the ANSI emulations only. -# -# Terminal Set-Up is entered by pressing [F3], [Caps Lock]/[F3] or -# [Alt]/[Print Screen] depending upon which keyboard and which -# terminal mode is being used. If Set-Up has been disabled or -# assigned to an unknown key, Set-Up may be entered by pressing -# [F3] as the first key after power up, regardless of keyboard type. -# (vt520: I added / based on the init string, also :sc: -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -vt520|DEC VT520:\ - :am:mi:xn:xo:\ - :co#80:li#24:vt#3:\ - :*6=\E[4~:@0=\E[1~:RA=\E[?7l:\ - :S5=\E[?0;0r\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :SA=\E[?7h:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ho=\E[H:\ - :i2=\E[?67h\E[64;1"p:if=/usr/share/tabset/vt300:\ - :im=\E[4h:is=\E[1;24r\E[24;1H:k0=\E[29~:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:k5=\E[17~:k6=\E[18~:k7=\E[19~:k8=\E[20~:\ - :k9=\E[21~:k;=\E[29~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:r3=\E[?67h\E[64;1"p:\ - :rc=\E8:rf=/usr/share/tabset/vt300:sc=\E7:se=\E[m:sf=\ED:\ - :so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: - -# (vt525: I added / based on the init string; -# removed :se:=\E[m, :ue:=\E[m, added :sc: -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -vt525|DEC VT525:\ - :am:mi:xn:xo:\ - :co#80:li#24:vt#3:\ - :*6=\E[4~:@0=\E[1~:RA=\E[?7l:\ - :S5=\E[?0;0r\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :SA=\E[?7h:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ho=\E[H:\ - :i2=\E[?67h\E[64;1"p:if=/usr/share/tabset/vt300:\ - :im=\E[4h:is=\E[1;24r\E[24;1H:k0=\E[29~:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:k5=\E[17~:k6=\E[18~:k7=\E[19~:k8=\E[20~:\ - :k9=\E[21~:k;=\E[29~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:r3=\E[?67h\E[64;1"p:\ - :rc=\E8:rf=/usr/share/tabset/vt300:sc=\E7:se=\E[m:sf=\ED:\ - :so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: - -#### VT100 emulations -# - -# John Hawkinson tells us that the EWAN telnet for Windows -# (the best Windows telnet as of September 1995) presents the name `dec-vt100' -# to telnetd. Michael Deutschmann informs us -# that this works best with a stock vt100 entry. -dec-vt100|EWAN telnet's vt100 emulation:\ - :tc=vt100: - -# From: Adrian Garside <94ajg2@eng.cam.ac.uk>, 19 Nov 1996 -dec-vt220|DOS tnvt200 terminal emulator:\ - :am@:tc=vt220: - -# Zstem340 is an (IMHO) excellent VT emulator for PC's. I recommend it to -# anyone who needs PC VT340 emulation. (or anything below that level, for -# that matter -- DEC's ALL-in-1 seems happy with it, as does INFOPLUS's -# RDBM systems, it includes ReGIS and SiXel support! I'm impressed... -# I can send the address if requested. -# (z340: changed garbled \E[5?l to \E[?5l, DEC smooth scroll off -- esr) -# From: Adam Thompson Sept 10 1995 -z340|zstem vt340 terminal emulator 132col 42line:\ - :li#42:\ - :is=\E>\E[?3h\E[?4l\E[?5l\E[?7h\E[?8h\E[1;42r\E[42;1H:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?7h\E[?8h\E[1;42r\E[42;1H:\ - :tc=vt320-w: -z340-nam|zstem vt340 terminal emulator 132col 42line:\ - :am@:\ - :is=\E>\E[?3h\E[?4l\E[?5l\E[?7l\E[?8h\E[1;42r\E[42;1H:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?7l\E[?8h\E[1;42r\E[42;1H:\ - :tc=z340: - -#### X terminal emulators -# -# You can add the following line to your .Xdefaults to change the terminal type -# set by the xterms you start up to my-xterm: -# -# *termName: my-xterm -# -# System administrators can change the default entry for xterm instances -# by adding a similar line to /usr/X11/lib/X11/app-defaults/XTerm. In either -# case, xterm will detect and reject an invalid terminal type, falling back -# to the default of xterm. -# - -# X10/6.6 11/7/86, minus alternate screen, plus (csr) -# (xterm: ":MT:" changed to ":km:"; added / based on init string; -# removed (hs, eslok, tsl=\E[?E\E[?%i%dT, fsl=\E[?F, dsl=\E[?E) -# as these seem not to work -- esr) -x10term|vs100-x10|xterm terminal emulator (X10 window system):\ - :am:bs:km:mi:ms:xn:xo:\ - :co#80:it#8:li#65:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:RA=\E[?7l:SA=\E[?7h:\ - :al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:ho=\E[H:\ - :im=\E[4h:is=\E\E[m\E[?7h\E[?1;4l:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:\ - :rs=\E[r\E<\E[m\E[H\E[2J\E[?7h\E[?1;3;4;6l:se=\E[m:\ - :sf=^J:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -# Compatible with the R5 xterm -# (from the XFree86 3.2 distribution, removed) -xterm-r5|xterm R5 version:\ - :am:bs:km:ms:xn:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[23~:\ - :F2=\E[24~:IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ei=:ho=\E[H:ic=\E[@:im=:k0=\EOq:k1=\E[11~:\ - :k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kA=\E[30~:\ - :kD=\E[3~:kE=\E[8~:kI=\E[2~:kL=\E[31~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\E[7~:kl=\EOD:kr=\EOC:\ - :ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m:me=\E[m:mr=\E[7m:\ - :nd=\E[C:r1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H:\ - :rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:up=\E[A: -# Compatible with the R6 xterm -# (from XFree86 3.2 distribution, and :it: added, removed) -xterm-r6|xterm-old|xterm X11R6 version:\ - :am:bs:km:mi:ms:xn:\ - :co#80:it#8:li#24:\ - :*6=\E[4~:@0=\E[1~:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ - :DO=\E[%dB:F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:\ - :F5=\E[28~:F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:\ - :FA=\E[34~:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:eA=\E(B:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:k;=\E[21~:kD=\E[3~:kI=\E[2~:kN=\E[6~:\ - :kP=\E[5~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:\ - :ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m:me=\E[m:ml=\El:\ - :mr=\E[7m:mu=\Em:nd=\E[C:\ - :r2=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:\ - :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:ue=\E[m:up=\E[A:\ - :us=\E[4m: -# This is the base xterm entry for the xterm supplied with XFree86 3.2 & up. -# The name has been changed and some aliases have been removed. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -xterm-xf86-v32|xterm terminal emulator (XFree86 3.2 Window System):\ - :am:bs:km:mi:ms:xn:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOy:K3=\EOu:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ec=\E[%dX:\ - :ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:\ - :is=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kD=\177:kI=\E[2~:\ - :kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\EOH:\ - :kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m:\ - :me=\E[m\017:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:\ - :sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:te=\E[2J\E[?47l\E8:\ - :ti=\E7\E[?47h:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: -# This is the stock xterm entry supplied with XFree86 3.3, which uses VT100 -# codes for F1-F4 except while in VT220 mode. -xterm-xf86-v33|xterm terminal emulator (XFree86 3.3 Window System):\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :tc=xterm-xf86-v32: -# This version was released in XFree86 3.3.3 (November 1998). -# Besides providing printer support, it exploits a new feature that allows -# xterm to use terminfo-based descriptions with the titeInhibit resource. -xterm-xf86-v333|xterm terminal emulator (XFree86 3.3.3 Window System):\ - :5i:\ - :*6@:@0@:@7=\E[4~:ei=:ic@:im=:is=\E[\041p\E[?3;4l\E[4l\E>:\ - :kD=\E[3~:kh=\E[1~:mb=\E[5m:mk=\E[8m:pf=\E[4i:po=\E[5i:\ - :ps=\E[i:r1=\Ec:r2=\E[\041p\E[?3;4l\E[4l\E>:\ - :te=\E[?1047l\E[?1048l:ti=\E[?1048h\E[?1047h:\ - :tc=xterm-xf86-v33: -# This beta version will probably be released in XFree86 4.0. -xterm-xf86-v40|xterm terminal emulator (XFree86 4.0 Window System):\ - :@7=\EOF:K1=\EOH:K2=\EOE:K3=\E[5~:K4=\EOF:K5=\E[6~:kD=\177:\ - :kh=\EOH:te=\E[?1049l:ti=\E[?1049h:\ - :tc=xterm-xf86-v333: -# This is one of the variants from XFree86 3.3 (T.Dickey) -xterm-16color|xterm with 16 colors like aixterm:\ - :Co#16:NC#32:pa#256:ut:\ - :AB=\E[4%dm:AF=\E[3%dm:op=\E[m:\ - :tc=xterm-xf86-v33: - -# This is xterm for ncurses. It mainly adds mappings for more high-half -# characters. Note that these will only work for fixed-width fonts. -xterm-nc|vs100-nc|xterms-nc|xterm terminal emulator (X Window System):\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++\054\054II00:\ - :u6=\E[%i%d;%dR:u7=\E[6n:u8=\E[?1;2c:u9=\E[c:\ - :tc=xterm-r6: - -# This is our standard xterm entry. It is based on the xterm-xf86-v33 entry -# with some changes in order to try to be compatible with as many xterm -# implementations as possible. -#xterm|vs100|xterm terminal emulator (X Window System):\ -# :ut:Co#8:pa#64:AB=\E[4%dm:AF=\E[3%dm:op=\E[m:\ -# :@1=\EOE:@7=\EOF:@8=\EOM:k;=\E[21~:\ -# :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ -# :ic@:kD=\E[3~:me=\E[m:se=\E[m:ue=\E[m:vb@:\ -# :tc=xterm-xf86-v33: -xterm|vs100|xterm terminal emulator (X Window System):\ - :am:bs:km:mi:ms:ut:xn:\ - :co#80:it#8:li#24:\ - :Co#8:pa#64:AB=\E[4%dm:AF=\E[3%dm:op=\E[m:\ - :@1=\EOE:@7=\EOF:@8=\EOM:k;=\E[21~:F1=\E[23~:F2=\E[24~:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOy:K3=\EOu:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :eA=\E(B\E)0:ec=\E[%dX:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E[m\E7\E[r\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kB=\E[Z:kD=\E[3~:kI=\E[2~:\ - :kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\EOH:\ - :kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m:\ - :me=\E[m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[m:\ - :sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:te=\E[2J\E[?47l\E8:\ - :ti=\E7\E[?47h:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: - -# Xterm with the visual bell capability. -xterm-vb|xterm terminal emulator with visual bell:\ - :vb=\E[?5h\E[?5l:tc=xterm: - -# These entries allow access to the X titlebar and icon name as a status line. -# Note that twm (and possibly window managers descended from it such as tvtwm, -# ctwm, and vtwm) track windows by icon-name; thus, you don't want to mess -# with it. -xterm+sl|access X title line and icon name:\ - :hs:\ - :ws#40:\ - :ds=\E]0;\007:fs=^G:ts=\E]0;:\ - :tc=xterm: -xterm+sl-twm|access X title line (pacify twm-descended window managers):\ - :hs:\ - :ws#40:\ - :ds=\E]2;\007:fs=^G:ts=\E]2;:\ - :tc=xterm: - -# -# The following xterm variants don't depend on your base version -# -xterm-bold|xterm terminal emulator (X11R6 Window System) standout w/bold:\ - :so=\E[1m:\ - :tc=xterm: -# (kterm: this had extension capabilities ":KJ:TY=ascii:" -- esr) -kterm|kterm kanji terminal emulator (X window system):\ - :es:hs:ds=\E[?H:fs=\E[?F:ts=\E[?E\E[?%i%dT:\ - :ac@:ae=\E(B:as=\E(0:\ - :tc=xterm: -# See the note on ICH/ICH1 VERSUS RMIR/SMIR near the end of file -xterm-nic|xterm with ich/ich1 suppressed for non-curses programs:\ - :IC@:ei=:ic@:im=:\ - :tc=xterm: -# From: Mark Sheppard , 4 May 1996 -xterm1|xterm terminal emulator ignoring the alternate screen buffer:\ - :te@:ti@:\ - :tc=xterm: - -# This describes the capabilities of color_xterm, an xterm variant from -# before ECMA-64 color support was folded into the main-line xterm release. -# This entry is straight from color_xterm's maintainer. -# From: Jacob Mandelson , 09 Nov 1996 -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -color_xterm|cx|cx100|color_xterm color terminal emulator for X:\ - :am:km:mi:ms:xn:\ - :co#80:it#8:li#65:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:ho=\E[H:\ - :i1=\E[r\E[m\E[?7h\E[?4;6l\E[4l:im=\E[4h:k1=\E[11~:\ - :k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\EOB:kh=\E[7~:kl=\EOD:kr=\EOC:ku=\EOA:le=^H:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:\ - :sf=^J:so=\E[7m:sr=\EM:ta=^I:te=\E>\E[?41;1r:\ - :ti=\E[?1;41s\E[?1;41h\E=:ue=\E[24m:up=\E[A:us=\E[4m: - -# The 'nxterm' distributed with Redhat Linux 5.2 is a slight rehack of -# xterm-sb_right-ansi-3d, which implements ANSI colors, but does not support -# SGR 39 or 49. SGR 0 does reset colors (along with everything else). This -# description is "compatible" with color_xterm, rxvt and XFree86 xterm, except -# that each of those implements the home, end, delete keys differently. -# -# Redhat Linux 6.x distributes XFree86 xterm as "nxterm", which uses bce -# colors; note that this is not compatible with the 5.2 version. -# csw (2002-05-15): make xterm-color primary instead of nxterm, to -# match XFree86's xterm.terminfo usage and prevent circular links -xterm-color|nxterm|generic color xterm:\ - :am:bs:km:mi:ms:xn:\ - :NC@:\ - :Co#8:NC#3:pa#64:Sb=\E[4%dm:Sf=\E[3%dm:op=\E[m:\ - :tc=xterm-r6: - -# From rxvt-2.7.10/doc/etc/rxvt.termcap (2005-07-03) -rxvt|rxvt terminal emulator (X Window System):\ - :am:eo:km:ms:ut:xn:xo:\ - :co#80:it#8:li#24:Co#8:pa#64:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :AB=\E[4%dm:AF=\E[3%dm:AL=\E[%dL:\ - :DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:\ - :ae=^O:al=\E[L:as=^N:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :eA=\E(B\E)0:ho=\E[H:i1=\E[?47l\E=\E[?1l:ic=\E[@:\ - :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ - :k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:\ - :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ - :kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=\E>:\ - :kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:op=\E[m:rc=\E8:sc=\E7:\ - :se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :te=\E[?47l\E8:ti=\E7\E[?47h:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h:\ - :@7=\E[8~:kh=\E[7~: -# When compiled with LINUX_KEYS the last line becomes -# :@7=\E[4~:kh=\E[1~: - -# From rxvt-unicode-7.9/doc/etc/rxvt-unicode.termcap (2006-08-07) -# Reconstructed via infocmp from file: /etc/terminfo/r/rxvt-unicode -# (untranslatable capabilities removed to fit entry within 1023 bytes) -rxvt-unicode|rxvt-unicode terminal (X Window System):\ - :am:bw:eo:hs:km:mi:ms:xn:xo:\ - :co#80:it#8:li#24:lm#0:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ae=\E(B:al=\E[L:\ - :as=\E(0:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ds=\E]2;\007:ec=\E[%dX:ei=\E[4l:fs=^G:\ - :ho=\E[H:i1=\E[?47l\E=\E[?1l:ic=\E[@:im=\E[4h:\ - :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kD=\E[3~:\ - :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=\177:kd=\EOB:ke=\E[?1l\E>:\ - :kh=\E[7~:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m\017:mr=\E[7m:nd=\E[C:rc=\E8:\ - :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :te=\E[r\E[?1049l:ti=\E[?1049h:ts=\E]2;:ue=\E[24m:\ - :up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:\ - :vs=\E[?25h: - -# From: David J. MacKenzie 20 Apr 1995 -# Here's a termcap entry I've been using for xterm_color, which comes -# with BSD/OS 2.0, and the X11R6 contrib tape too I think. Besides the -# color stuff, I also have a status line defined as the window manager -# title bar. [I have translated it to terminfo -- ESR] -xterm-pcolor|xterm with color used for highlights and status line:\ - :am:bs:hs:km:mi:ms:xn:\ - :co#80:it#8:li#24:ws#40:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOy:K3=\EOu:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ds=\E]0;\007:ec=\E[%dX:ei=\E[4l:fs=^G:ho=\E[H:im=\E[4h:\ - :is=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\EOH:kl=\EOD:kr=\EOC:\ - :ks=\E[?1h\E=:ku=\EOA:le=^H:md=\E[1m\E[43m:me=\E[m:\ - :mr=\E[7m\E[34m:nd=\E[C:nw=^M^J:rc=\E8:sc=\E7:se=\E[m:\ - :sf=^J:so=\E[7m\E[31m:sr=\EM:st=\EH:ta=^I:\ - :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:ts=\E]0;:ue=\E[m:\ - :up=\E[A:us=\E[4m\E[42m:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: - -# HP ships this, except for the pb#9600 which was merged in from BSD termcap. -# (hpterm: added empty , we have no idea what ACS chars look like --esr) -xhpterm|X-hpterm|xpterm|hpterm|hp X11 terminal emulator:\ - :am:da:db:mi:xs:\ - :Nl#8:co#80:lh#2:li#24:lm#0:lw#8:pb#9600:sg#0:\ - :LF=\E&j@:LO=\E&jB:ac=:ae=^O:al=\EL:as=^N:bl=^G:bt=\Ei:\ - :cd=\EJ:ce=\EK:ch=\E&a%dC:cl=\E&a0y0C\EJ:cm=\E&a%dy%dC:\ - :cr=^M:ct=\E3:cv=\E&a%dY:dc=\EP:dl=\EM:do=\EB:ei=\ER:im=\EQ:\ - :k1=\Ep:k2=\Eq:k3=\Er:k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:\ - :kA=\EL:kC=\EJ:kD=\EP:kE=\EK:kF=\ES:kH=\EF:kI=\EQ:kL=\EM:\ - :kM=\ER:kN=\EU:kP=\EV:kR=\ET:kS=\EJ:kT=\E1:ka=\E3:kb=^H:\ - :kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:ks=\E&s1A:kt=\E2:\ - :ku=\EA:le=^H:md=\E&dB:me=\E&d@:mh=\E&dH:ml=\El:mr=\E&dB:\ - :mu=\Em:nd=\EC:\ - :se=\E&d@:sf=^J:so=\E&dJ:sr=\ET:st=\E1:ta=^I:ue=\E&d@:\ - :up=\EA:us=\E&dD: - -# This entry describes an xterm with Sun-style function keys enabled -# via the X resource setting "xterm*sunFunctionKeys:true" -# To understand / note that L1,L2 and F11,F12 are the same. -# The ... keys are L3-L10. We don't set -# because we want it to be seen as . -# The ... keys are R1-R15. We treat some of these in accordance -# with their Sun keyboard labels instead. -# From: Simon J. Gerraty 10 Jan 1996 -xterm-sun|xterm with sunFunctionKeys true:\ - :%1=\E[196z:&8=\E[195z:@0=\E[200z:@5=\E[197z:@7=\E[220z:\ - :F1=\E[192z:F2=\E[193z:F3=\E[194z:F4=\E[195z:F5=\E[196z:\ - :F7=\E[198z:F8=\E[199z:F9=\E[200z:FA=\E[201z:FL=\E[208z:\ - :FM=\E[209z:FN=\E[210z:FO=\E[211z:FP=\E[212z:FQ=\E[213z:\ - :FS=\E[215z:FU=\E[217z:FW=\E[219z:FY=\E[221z:K2=\E[218z:\ - :k1=\E[224z:k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:\ - :k6=\E[229z:k7=\E[230z:k8=\E[231z:k9=\E[232z:k;=\E[233z:\ - :kI=\E[2z:kN=\E[222z:kP=\E[216z:kh=\E[214z:\ - :tc=xterm: -xterms-sun|small (80x24) xterm with sunFunctionKeys true:\ - :co#80:li#24:tc=xterm-sun: - -# This is for the extensible terminal emulator on the X11R6 contrib tape. -emu|emu native mode:\ - :mi:ms:xo:\ - :Co#15:co#80:it#8:li#24:pa#64:vt#200:\ - :*6=\Esel:@0=\Efind:@8=^M:AL=\EQ%d;:DC=\EI%d;:DL=\ER%d;:\ - :DO=\Ep%d;:F1=\EF11:F2=\EF12:F3=\EF13:F4=\EF14:F5=\EF15:\ - :F6=\EF16:F7=\EF17:F8=\EF18:F9=\EF19:FA=\EF20:LE=\Eq-%d;:\ - :RI=\Eq%d;:Sb=\Es%i%d;:Sf=\Er%i%d;:UP=\Ep-%d;:\ - :ac=a\202f\260g261j\213k\214l\215m\216n\217o\220q\222s\224t\225u\226v\227w\230x\231~\244:\ - :ae=\200:al=\EQ1;:as=\200:bl=^G:cb=\EL:cd=\EN:ce=\EK:\ - :cl=\EP\EE0;0;:cm=\EE%d;%d;:cr=^M:cs=\Ek%d;%d;:ct=\Ej:\ - :dc=\EI1;:dl=\ER1;:do=\EB:eA=\200:ec=\Ej%d;:ei=\EX:\ - :ho=\EE0;0;:im=\EY:is=\ES\Er0;\Es0;:k0=\EF00:k1=\EF01:\ - :k2=\EF02:k3=\EF03:k4=\EF04:k5=\EF05:k6=\EF06:k7=\EF07:\ - :k8=\EF08:k9=\EF09:k;=\EF10:kD=\177:kI=\Eins:kN=\Enext:\ - :kP=\Eprior:kb=^H:kd=\EB:kl=\EC:kr=\ED:ku=\EA:le=^H:\ - :mb=\ES\EW:md=\ES\EU:me=\ES:mr=\ES\ET:nd=\ED:\ - :oc=\Es0;\Er0;:r2=\ES\Es0;\Er0;:se=\ES:sf=\EG:so=\ES\ET:\ - :sr=\EF:st=\Eh:ta=^I:ue=\ES:up=\EA:us=\ES\EV:ve=\Ea:vi=\EZ:\ - :vs=\Ea: - -######## MGR -# -# MGR is a Bell Labs window system lighter-weight than X. -# These entries describe MGR's xterm-equivalent. -# They are courtesy of Vincent Broman 14 Jan 1997 -# - -mgr|Bellcore MGR (non X) window system terminal emulation:\ - :am:km:\ - :AL=\E%da:DC=\E%dE:DL=\E%dd:IC=\E%dA:RA=\E5S:SA=\E5s:\ - :al=\Ea:bl=^G:cd=\EC:ce=\Ec:cl=^L:cm=\E%r%d;%dM:cr=^M:\ - :cs=\E%d;%dt:dc=\EE:dl=\Ed:do=\Ef:ei=:hd=\E1;2f:hu=\E1;2u:\ - :ic=\EA:im=:kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :md=\E2n:me=\E0n:mr=\E1n:nd=\Er:nw=^M^J:se=\E0n:sf=^J:\ - :so=\E1n:ta=^I:ue=\E0n:up=\Eu:us=\E4n:ve=\Eh:vi=\E9h:\ - :vs=\E0h: -mgr-sun|Mgr window with Sun keyboard:\ - :%1=\E[207z:%6=\E[198z:&8=\E[195z:@0=\E[200z:@5=\E197z:\ - :@7=\E[220z:@8=\E[250z:F1=\E[234z:F2=\E[235z:K1=\E[214z:\ - :K2=\E[218z:K3=\E[216z:K4=\E[220z:K5=\E[222z:k1=\E[224z:\ - :k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:k6=\E[229z:\ - :k7=\E[230z:k8=\E[231z:k9=\E[232z:k;=\E[233z:kN=\E[222z:\ - :kP=\E[216z:kh=\E[214z:\ - :tc=mgr: -mgr-linux|Mgr window with Linux keyboard:\ - :@7=\E[4~:F1=\E[23~:F2=\E[24~:K1=\E[H:K2=\E[G:K3=\E[5~:\ - :K4=\E[Y:K5=\E[6~:k0=\E[[J:k1=\E[[A:k2=\E[[B:k3=\E[[C:\ - :k4=\E[[D:k5=\E[[E:k6=\E[17~:k7=\E[18~:k8=\E[19~:\ - :k9=\E[20~:k;=\E[21~:kD=\E[3~:kN=\E[6~:kP=\E[5~:kh=\E[1~:tc=mgr: - -# Eterm: the enlightenment terminal emulator -Eterm|Eterm Terminal Emulator (X11 Window System):\ - :am:bs:bw:eo:km:mi:ms:xn:xo:\ - :co#80:it#8:li#24:lm#0:pa#64:Co#8:AF=\E[3%dm:AB=\E[4%dm:op=\E[39m\E[49m:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\E[7~:K2=\EOu:K3=\E[5~:K4=\E[8~:K5=\E[6~:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=\E[B:\ - :ec=\E[%dX:ei=\E[4l:ho=\E[H:i1=\E[?47l\E>\E[?1l:ic=\E[@:\ - :im=\E[4h:is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kD=\E[3~:\ - :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=:kh=\E[7~:\ - :kl=\E[D:kr=\E[C:ks=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[m\017:mr=\E[7m:nd=\E[C:rc=\E8:\ - :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:ue=\E[24m:up=\E[A:\ - :us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:\ - :ac=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~: - -######## UNIX VIRTUAL TERMINALS, VIRTUAL CONSOLES, AND TELNET CLIENTS -# - -# Columbus UNIX virtual terminal. This terminal also appears in -# UNIX 4.0 and successors as line discipline 1 (?), but is -# undocumented and does not really work quite right. -cbunix|cb unix virtual terminal:\ - :am:bs:da:db:\ - :co#80:li#24:lm#0:\ - :al=\EP:bl=^G:cd=\EL:ce=\EK:cl=\EL:cm=\EG%r%.%.:cr=^M:\ - :dc=\EM:dl=\EN:do=^J:ei=:ic=\EO:im=:kd=\EB:kh=\EE:kl=\ED:\ - :kr=\EC:ku=\EA:le=^H:nd=\EC:se=\Eb^D:sf=^J:so=\Ea^D:\ - :ue=\Eb^A:up=\EA:us=\Ea^A: -# (vremote: removed obsolete ":nl@:" -- esr) -vremote|virtual remote terminal:\ - :am@:\ - :co#79:tc=cbunix: -pty|4bsd pseudo teletype:\ - :cm=\EG%+ %+ :se=\Eb$:so=\Ea$:ue=\Eb\041:us=\Ea\041:tc=cbunix: - -# The codes supported by the term.el terminal emulation in GNU Emacs 19.30 -eterm|gnu emacs term.el terminal emulation:\ - :am:mi:xn:\ - :co#80:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:cb=\E[1K:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:ho=\E[H:\ - :im=\E[4h:le=^H:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:se=\E[m:\ - :sf=^J:so=\E[7m:ta=^I:te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:\ - :ue=\E[m:up=\E[A:us=\E[4m: - -# Entries for use by the FSF's `screen' program. The screen and -# screen-w entries came with version 3.7.1. The screen2 and screen3 entries -# come from University of Wisconsin and may be older. -# (screen: added :ve: on ANSI model -- esr) - -screen|VT 100/ANSI X3.64 virtual terminal:\ - :am:km:mi:ms:xn:\ - :Co#8:co#80:it#8:li#24:pa#64:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[23~:\ - :F2=\E[24~:IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++\054\054hhII00:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:eA=\E(B:ei=\E[4l:\ - :ho=\E[H:im=\E[4h:is=\E(B:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ - :k;=\E[21~:kD=\E[3~:kH=\E[4~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\E[1~:kl=\EOD:kr=\EOC:\ - :ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:r2=\Ec:rc=\E8:sc=\E7:se=\E[23m:\ - :sf=^J:so=\E[3m:sr=\EM:st=\EH:ta=^I:ue=\E[24m:up=\EM:\ - :us=\E[4m:vb=\Eg:ve=\E[?25h:vi=\E[?25l:vs=\E[34l:\ - :tc=ecma+color: - -screen-w|VT 100/ANSI X3.64 virtual terminal with 132 cols:\ - :co#132:tc=screen: - -screen2|VT 100/ANSI X3.64 virtual terminal:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bt=\E[Z:cd=\E[J:\ - :ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:ic=:im=\E[4h:k0=\E~:\ - :k1=\ES:k2=\ET:k3=\EU:k4=\EV:k5=\EW:k6=\EP:k7=\EQ:k8=\ER:\ - :k9=\E0I:kb=^H:kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:\ - :me=\E[m:nd=\E[C:nw=^M^J:r1=\Ec:rc=\E8:sc=\E7:se=\E[23m:\ - :sf=^J:so=\E[3m:sr=\EM:st=\EH:ta=^I:ue=\E[24m:up=\E[A:\ - :us=\E[4m: -# (screen3: removed unknown ":xv:LP:G0:" -- esr) -screen3|VT 100/ANSI X3.64 virtual terminal:\ - :km:mi:ms:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:\ - :ho=\E[H:im=\E[4h:is=:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :kb=^H:kd=\EOB:ke=\E>:kl=\EOD:kr=\EOC:ks=\E=:ku=\EOA:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=\EE:r1=\Ec:\ - :rc=\E8:sc=\E7:se=\E[23m:sf=^J:so=\E[3m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[24m:up=\EM:us=\E[4m: - -#### Pilot Pro Palm-Top -# -# From: Jason Downs , 15 Jun 1997 (Top Gun Telnet's author) -pilot|tgtelnet|Top Gun Telnet on the Palm Pilot Professional:\ - :am:xn:\ - :co#39:li#16:\ - :bl=^G:cl=\Ec:cm=\Em%+ %+ :cr=^M:do=^J:ho=\Em :kN=^L:kP=^K:\ - :kb=^H:kd=^J:kl=^H:le=^H:nw=\Em~ :se=\EB:sf=^J:so=\Eb:ta=^I: - -######## WORKSTATION CONSOLES -# - -#### Sun consoles -# - -# :is1: resets scrolling region in case a previous user had used "tset vt100" -oldsun|Sun Microsystems Workstation console:\ - :am:bs:km:mi:ms:\ - :co#80:it#8:li#34:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:al=\E[L:bl=^G:\ - :cd=\E[J:ce=\E[K:cl=^L:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:\ - :dl=\E[M:do=\E[B:ei=:i1=\E[1r:ic=\E[@:im=:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:me=\E[m:nd=\E[C:se=\E[m:sf=^J:so=\E[7m:ta=^I:up=\E[A: -# From: Alexander Lukyanov , 14 Nov 1995 -# :li: capability later corrected by J.T. Conklin -sun-il|Sun Microsystems console with working insert-line:\ - :am:km:ms:\ - :co#80:li#34:\ - :%7=\E[194z:&5=\E[193z:&8=\E[195z:@7=\E[220z:AL=\E[%dL:\ - :DC=\E[%dP:DL=\E[%dM:F1=\E[234z:F2=\E[235z:IC=\E[%d@:\ - :K2=\E[218z:al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=^L:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=^J:ei=:ic=\E[@:im=:\ - :k1=\E[224z:k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:\ - :k6=\E[229z:k7=\E[230z:k8=\E[231z:k9=\E[232z:k;=\E[233z:\ - :kD=\177:kN=\E[222z:kP=\E[216z:kb=^H:kd=\E[B:kh=\E[214z:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:md=\E[1m:me=\E[m:mr=\E[7m:\ - :nd=\E[C:r2=\E[s:\ - :se=\E[m:sf=^J:so=\E[7m:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -# On some versions of CGSIX framebuffer firmware, :al:/:AL: flake out on -# the last line. Unfortunately, without them the terminal has no way to scroll. -sun-cgsix|Sun cgsix framebuffer console:\ - :AL@:al@:tc=sun-il: -# Backwards compatibility: `sun-cgsix' used to be called `sun-ss5' -sun-ss5:\ - :tc=sun-cgsix: -# If you are using an SS5, change the sun definition to use sun-ss5. -sun|sun1|sun2|Sun Microsystems Inc. workstation console:\ - :tc=sun-il: - -# From: Tue Sep 24 13:14:44 1985 -sun-s|Sun Microsystems Workstation window with status line:\ - :hs:\ - :ds=\E]l\E\:fs=\E\:ts=\E]l:tc=sun: -sun-e-s|sun-s-e|Sun Microsystems Workstation with status hacked for emacs:\ - :hs:\ - :ds=\E]l\E\:fs=\E\:ts=\E]l:tc=sun-e: -sun-48|Sun 48-line window:\ - :co#80:li#48:tc=sun: -sun-34|Sun 34-line window:\ - :co#80:li#34:tc=sun: -sun-24|Sun 24-line window:\ - :co#80:li#24:tc=sun: -sun-17|Sun 17-line window:\ - :co#80:li#17:tc=sun: -sun-12|Sun 12-line window:\ - :co#80:li#12:tc=sun: -sun-1|Sun 1-line window for sysline:\ - :es:hs:\ - :co#80:li#1:\ - :ds=^L:fs=\E[K:ts=^M:tc=sun: -sun-e|sun-nic|sune|Sun Microsystems Workstation without insert character:\ - :ei@:ic@:im@:\ - :tc=sun: -sun-c|sun-cmd|Sun Microsystems Workstation console with scrollable history:\ - :li#35:\ - :te=\E[>4h:ti=\E[>4l:tc=sun: -sun-type4|Sun Workstation console with type 4 keyboard:\ - :kd=\E[221z:kl=\E[217z:kr=\E[219z:ku=\E[215z:tc=sun-il: - -#### Iris consoles -# - -# (wsiris: this had extension capabilities -# :HS=\E7F2:HE=\E7F7:\ -# :CT#2:CZ=*Bblack,red,green,yellow,blue,magenta,cyan,*Fwhite: -# See the note on Iris extensions near the end of this file. -# Finally, removed suboptimal :cl:=\EH\EJ and added :do: & -# :vb: from BRL -- esr) -wsiris|iris40|iris emulating a 40 line visual 50 (approximately):\ - :am:bs:nc:pt:\ - :co#80:it#8:kn#3:li#40:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:cl=\Ev:cm=\EY%+ %+ :dl=\EM:\ - :do=\EB:ho=\EH:is=\E7B0\E7F7\E7C2\E7R3:k0=\E0:k1=\E1:\ - :k2=\E2:k3=\E3:k4=\E4:k5=\E5:k6=\E6:k7=\E7:k8=\E8:k9=\E9:\ - :kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=^H:me=\E7F7:mh=\E7F2:nd=\EC:\ - :nl=\EB:se=\E0@:sf=^J:so=\E9P:sr=\EI:ta=^I:ue=\E7R3\E0@:\ - :up=\EA:us=\E7R2\E9P:vb=\E7F4\E7B1\013\E7F7\E7B0:ve=\E>:\ - :vs=\E;: - -#### NeWS consoles -# -# Console terminal windows under the NeWS (Sun's Display Postscript windowing -# environment). Note: these have nothing to do with Sony's News workstation -# line. -# - -# Entry for NeWS's psterm from Eric Messick & Hugh Daniel -# (psterm: unknown ":sl=\EOl:el=\ENl:" removed -- esr) -psterm|psterm-basic|NeWS psterm-80x34:\ - :am:bs:hs:km:ul:\ - :co#80:it#8:li#34:\ - :al=\EA:cd=\EB:ce=\EC:cl=^L:cm=\E%d;%d;:cs=\EE%d;%d;:\ - :dc=\EF:dl=\EK:do=\EP:ei=\ENi:fs=\ENl:ho=\ER:i1=\EN*:\ - :im=\EOi:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=\ET:ll=\EU:\ - :mb=\EOb:md=\EOd:me=\EN*:mr=\EOr:nd=\EV:rc=^\:sc=^]:se=\ENo:\ - :sf=\EW:so=\EOo:sr=\EX:ta=^I:te=\ENt:ti=\EOt:ts=\EOl:\ - :ue=\ENu:up=\EY:us=\EOu:vb=\EZ: -psterm-96x48|NeWS psterm 96x48:\ - :co#96:li#48:tc=psterm: -psterm-90x28|NeWS psterm 90x28:\ - :co#90:li#28:tc=psterm: -psterm-80x24|NeWS psterm 80x24:\ - :co#80:li#24:tc=psterm: -# This is a faster termcap for psterm. Warning: if you use this termcap, -# some control characters you type will do strange things to the screen. -# (psterm-fast: unknown ":sl=^Ol:el=^Nl:" -- esr) -psterm-fast|NeWS psterm fast version (flaky ctrl chars):\ - :am:bs:hs:km:ul:\ - :co#80:it#8:li#34:\ - :al=^A:cd=^B:ce=^C:cl=^L:cm=\004%d;%d;:cs=\005%d;%d;:dc=^F:\ - :dl=^K:do=^P:ei=^Ni:fs=^Nl:ho=^R:i1=^N*:im=^Oi:kd=\E[B:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^T:ll=^U:mb=^Ob:md=^Od:me=^N*:\ - :mr=^Or:nd=^V:rc=^\:sc=^]:se=^No:sf=^W:so=^Oo:sr=^X:ta=^I:\ - :te=^Nt:ti=^Ot:ts=^Ol:ue=^Nu:up=^Y:us=^Ou:vb=^Z: - -#### NeXT Consoles -# -# Use `glasstty' for the Workspace application -# - -# From: Dave Wetzel 22 Dec 1995 -next|NeXT console:\ - :am:xt:\ - :co#80:it#8:li#24:\ - :bl=^G:ce=\E[K:cl=^L:cm=\E[%i%d;%dH:cr=^M:do=^J:ho=\E[H:\ - :kb=^H:kd=^J:kl=^H:le=^H:me=\E[m:nd=\E[C:nw=^M^J:se=\E[4;1m:\ - :sf=^J:so=\E[4;2m:ta=^I:up=\E[A: -nextshell|NeXT Shell application:\ - :am:\ - :co#80:\ - :bl=^G:cr=^M:do=^J:kb=^H:kd=^J:kl=^H:le=^H:nw=^M^J:ta=^I: - -#### Common Desktop Environment -# - -# This ships with Sun's CDE in Solaris 2.5 -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -dtterm|CDE desktop terminal:\ - :am:mi:ms:xn:xo:\ - :co#80:it#8:li#24:lm#0:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:bl=^G:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ec=\E[%dX:\ - :ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E F\E>\E[?1l\E[?7h\E[?45l:k1=\E[11~:k2=\E[12~:\ - :k3=\E[13~:k4=\E[14~:k5=\E[15~:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:nw=\EE:\ - :rc=\E8:sc=\E7:se=\E[22;27m:sf=\ED:so=\E[2;7m:sr=\EM:\ - :st=\EH:ta=^I:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ - :ve=\E[?25h:vi=\E[?25l: - -### Non-Unix Consoles -# - -# This entry fits the Windows NT console when the _POSIX_TERM environment -# variable is set to 'on'. While the Windows NT POSIX console is seldom used, -# the obnoxious Telnet client supplied with both the Windows for WorkGroup -# 3.11 TCP/IP stack and the Win32 (i.e., Windows 95 and Windows NT 3.1 or -# later) operating systems is not, and (surprise!) they match very well. -# -# This was adapted from MS Knowledge Base item Q108581, dated 13-MAY-1997, -# titled "Setting Up VI POSIX Editor for Windows NT 3.1". True to Microsoft -# form, not are the installation instructions a pile of mind-numbing -# bureaucratese, but the termcap entry is actually broken and unusable as -# given; the :do: capability is misspelled "d". -# -ansi-nt|psx_ansi|Microsoft Windows NT console POSIX ANSI mode:\ - :am:bw:ms:\ - :co#80:it#8:li#25:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:cr=^M:do=^J:\ - :ho=\E[H:kb=^H:kd=\E[V:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :me=\E[0m:mr=\E[7m:nd=\E[C:nw=\r\E[S:rc=\E[u:sc=\E[s:\ - :se=\E[m:sf=\E[S:so=\E[7m:sr=\E[T:ta=^I:up=\E[A: - -######## COMMON TERMINAL TYPES -# -# This section describes terminal classes and maker brands that are still -# quite common, but have proprietary command sets not blessed by ANSI. -# - -#### Altos -# -# Altos made a moderately successful line of UNIX boxes. In 1990 they were -# bought out by Acer, a major Taiwanese manufacturer of PC-clones. -# Acer has a web site at http://www.acer.com. -# -# Altos descriptions from Ted Mittelstaedt 4 Sep 1993 -# His comments suggest they were shipped with the system. -# - -# (altos2: had extension capabilities -# :c0=^A`\r:c1=^Aa\r:c2=^Ab\r:c3=^Ac\r:\ -# :c4=^Ad\r:c5=^Ae\r:c6=^Af\r:c7=^Ag\r:\ -# :c8=^Ah\r:c9=^Ai\r:cA=^Aj\r:cB=^Ak\r:\ -# :cC=^Al\r:cD=^Am\r:cE=^An\r:cF=^Ao\r: -# :XU=^Aq\r:XD=^Ar\r:XR=^As\r:XL=^At\r:\ -# :YU=^AQ\r:YD=^AR\r:YR=^AS\r:YL=^AT\r:\ -# :HL=^AP\r:SP=\E[i:\ -# :IS=\E[@:DE=\E[P:IL=\E[L:NS=\E[S:PS=\E[T:\ -# :LO=\E[0q:LC=\E[5q:LL=\E[6q:\ -# Comparison with the k* capabilities makes it obvious that the c* things are -# shift keys. I have renamed them to keys 32 and up accordingly. Also, -# :sr: was given as a boolean-- esr) -altos2|alt2|altos-2|altos II:\ - :co#80:it#8:li#24:sg#0:\ - :*5=^Am\r:*8=^An\r:DL=\E[M:FM=^A`\r:FN=^Aa\r:FO=^Ab\r:\ - :FP=^Ac\r:FQ=^Ad\r:FR=^Ae\r:FS=^Af\r:FT=^Ag\r:FU=^Ah\r:\ - :FV=^Ai\r:FW=^Aj\r:FX=^Ak\r:RA=\E[?7l:SA=\E[?7h:al=\E[L:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :dc=\E[P:do=\E[1B:ei=:ho=\E[H:ic=\E[@:\ - :if=/usr/share/tabset/vt100:im=:\ - :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:k0=^AI\r:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kA=^AJ\r:kB=^AK\r:kC=^AL\r:\ - :kD=^AM\r:kE=^AN\r:kF=^AO\r:kb=^H:kd=\E[B:kh=\E[f:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=^H:me=\E[m:nd=\E[1C:nw=^M^J:se=\E[m:\ - :sf=^J:so=\E[7m:ta=^I:ue=\E[m:up=\E[1A:us=\E[4m: -# (altos3: had extension capabilities -# :c0=^A`\r:c1=^Aa\r:c2=^Ab\r:c3=^Ac\r:\ -# :c4=^Ad\r:c5=^Ae\r:c6=^Af\r:c7=^Ag\r:\ -# :c8=^Ah\r:c9=^Ai\r:cA=^Aj\r:cB=^Ak\r:\ -# :cC=^Al\r:cD=^Am\r:cE=^An\r:cF=^Ao\r: -# :XU=^Aq\r:XD=^Ar\r:XR=^As\r:XL=^At\r:\ -# :HL=^AP\r:SP=\E[i:\ -# :IS=\E[@:DE=\E[P:IL=\E[L:NS=\E[S:PS=\E[T:\ -altos3|altos5|alt3|alt5|altos-3|altos-5|altos III or V:\ - :mb=\E[5p:me=\E[p:sr=\EM:\ - :tc=altos2: -altos4|alt4|altos-4|altos IV:\ - :tc=wy50: -# (altos7: had extension capabilities: -# :GG#0:GI=\EH8:GF=\EH7:\ -# :c0=^A`\r:c1=^Aa\r:c2=^Ab\r:c3=^Ac\r:\ -# :c4=^Ad\r:c5=^Ae\r:c6=^Af\r:c7=^Ag\r:\ -# :c8=^Ah\r:c9=^Ai\r:cA=^Aj\r:cB=^Ak\r:\ -# :cC=^Al\r:cD=^Am\r:cE=^An\r:cF=^Ao\r: -# Comparison with the k* capabilities makes it obvious that the c* things are -# shift keys. I have renamed them to keys 32 and up accordingly. I have -# also made this entry relative to adm12 in order to give it an :sa:. The -# imported by use=adm+sgr may work, let me know. -- esr) -altos7|alt7|altos VII:\ - :am:mi:\ - :co#80:li#24:sg#0:\ - :*5=^Am\r:*8=^An\r:DL=\ER:FM=^A`\r:FN=^Aa\r:FO=^Ab\r:\ - :FP=^Ac\r:FQ=^Ad\r:FR=^Ae\r:FS=^Af\r:FT=^Ag\r:FU=^Ah\r:\ - :FV=^Ai\r:FW=^Aj\r:FX=^Ak\r:\ - :ac=l2m1k3j5t4u9v=w0q\072x6n8:al=\EE:cd=\EY:ce=\ET:\ - :cl=\E+^^:cm=\E=%+ %+ :cr=^M:dc=\EW:do=^J:ei=\Er:ho=^^:\ - :im=\Eq:is=\E`\072\Ee(\EO\Ee6\Ec41\E~4\Ec21\Eu\E~2:\ - :k0=^AI\r:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:\ - :k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:kA=^AJ\r:kB=^AK\r:\ - :kC=^AL\r:kD=^AM\r:kE=^AN\r:kF=^AO\r:kN=\EK:kP=\EJ:kb=^H:\ - :kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:mb=\EG2:md=\EGt:mh=\EGp:\ - :mk=\EG1:nd=^L:nw=^M^J:pf=\EJ:po=\Ed#:sf=^J:sr=\Ej:ta=^I:\ - :up=^K:\ - :tc=adm+sgr: -altos7pc|alt7pc|altos PC VII:\ - :@7=\ET:tc=altos7: - -#### Hewlett-Packard (hp) -# -# Hewlett-Packard -# 8000 Foothills Blvd -# Roseville, CA 95747 -# Vox: 1-(916)-785-4363 (Technical response line for VDTs) -# 1-(800)-633-3600 (General customer support) -# - -# Generic HP terminal - this should (hopefully) work on any HP terminal. -hpgeneric|hp|hewlett-packard generic terminal:\ - :am:bs:da:db:mi:pt:xs:\ - :co#80:li#24:lm#0:vt#6:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:ch=\E&a%dC:cl=\EH\EJ:\ - :cm=\E&a%r%dc%dY:cr=^M:ct=\E3:cv=\E&a%dY:dc=\EP:dl=\EM:\ - :do=^J:ei=\ER:im=\EQ:kB=\Ei:kb=^H:le=^H:me=\E&d@:nd=\EC:\ - :se=\E&d@:sf=^J:so=\E&dJ:st=\E1:ta=^I:ue=\E&d@:up=\EA:\ - :us=\E&dD: - -hp110|hewlett-packard model 110 portable:\ - :li#16:tc=hpgeneric: - -hp+pfk+cr|hp function keys with CR:\ - :k1=\Ep\r:k2=\Eq\r:k3=\Er\r:k4=\Es\r:k5=\Et\r:k6=\Eu\r:\ - :k7=\Ev\r:k8=\Ew\r: - -hp+pfk-cr|hp function keys w/o CR:\ - :k1=\Ep:k2=\Eq:k3=\Er:k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew: - -# The hp2621s use the same keys for the arrows and function keys, -# but not separate escape sequences. These definitions allow the -# user to use those keys as arrow keys rather than as function -# keys. -hp+pfk+arrows|hp alternate arrow definitions:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:kF=\Er\r:kH=\Eq\r:kR=\Es\r:\ - :kd=\Ew\r:kh=\Ep\r:kl=\Eu\r:kr=\Ev\r:ku=\Et\r: - -hp+arrows|hp arrow definitions:\ - :kF=\ES:kH=\EF:kR=\ET:kd=\EB:kh=\Eh:kl=\ED:kr=\EC:ku=\EA: - -# Generic stuff from the HP 262x series -# -hp262x|HP 262x terminals:\ - :xs:\ - :cd=\EJ:dc=\EP:ip=:kA=\EL:kD=\EP:kE=\EK:kF=\ES:kI=\EQ:kL=\EM:\ - :kM=\ER:kN=\EU:kP=\EV:kR=\ET:kS=\EJ:kd=\EB:ke=\E&s0A:kh=\Eh:\ - :kl=\ED:kr=\EC:ks=\E&s1A:ku=\EA:mb=\E&dA:me=\E&d@:mk=\E&dS:\ - :mr=\E&dB:\ - :se=\E&d@:sf=\ES:so=\E&dB:ta=\011:ue=\E&d@:us=\E&dD: - -# Note: no :ho: on HPs since that homes to top of memory, not screen. -# Due to severe 2621 braindamage, the only way to get the arrow keys to -# transmit anything at all is to turn on the function key labels -# with :ks:, and even then the user has to hold down shift! -# The default 2621 turns off the labels except when it has to to -# enable the function keys. If your installation prefers labels -# on all the time, or off all the time (at the "expense" of the -# function keys), use 2621-nl or 2621-wl. -# -# Note: there are newer ROMs for 2621's that allow you to set -# strap A so the regular arrow keys xmit \EA, etc, as with the -# 2645. However, even with this strap set, the terminal stops -# xmitting if you reset it, until you unset and reset the strap! -# Since there is no way to set/unset the strap with an escape -# sequence, we don't use it in the default. -# If you like, you can use 2621-ba (brain-damaged arrow keys). -hp2621-ba|2621 w/new rom and strap A set:\ - :ke@:ks@:\ - :kF=\ES:kH=\EF:kR=\ET:kd=\EB:kh=\Eh:kl=\ED:kr=\EC:ku=\EA:\ - :tc=hp2621: - -# hp2621 with function labels. Most of the time they are off, -# but inside vi, the function key labels appear. You have to -# hold down shift to get them to xmit. -hp2621|hp2621a|hp2621A|2621|2621a|2621A|hp2621-wl|2621-wl|hp 2621 w/labels:\ - :is=\E&jA\r:ke=\E&jA:\ - :tc=hp2621-fl: -hp2621-fl|hp 2621:\ - :xo:xs@:\ - :pb#19200:\ - :bt=\Ei:cm=\E&a%r%dc%dY:dc=\EP:ip=:is=\E&j@\r:ke=\E&j@:\ - :ks=\E&jB:me=\E&d@:se=\E&d@:so=\E&dD:ta=\011:ue=\E&d@:\ - :us=\E&dD:\ - :tc=hp+pfk+cr:tc=hpgeneric: - -# To use hp2621p printer, setenv TERM=2621p, PRINTER=2612p -hp2621p|hp 2621 with printer:\ - :pf=\E&p13C:po=\E&p11C:tc=hp2621: - -hp2621p-a|hp2621p with fn as arrows:\ - :tc=hp+pfk+arrows:tc=hp2621p: - -# hp2621 with k45 keyboard -hp2621-k45|hp2621k45|k45|hp 2621 with 45 keyboard:\ - :kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:ks=\E&s1A:\ - :ku=\EA:\ - :tc=hp2621: - -# 2621 using all 48 lines of memory, only 24 visible at any time. -hp2621-48|48 line 2621:\ - :li#48:\ - :cm=\E&a%r%dc%dR:cv=\E&a%dR:ho=\EH:tc=hp2621: - -# 2621 with no labels ever. Also prevents vi delays on escape. -hp2621-nl|hp 2621 with no labels:\ - :kd@:ke@:kh@:kl@:kr@:ks@:ku@:tc=hp2621-fl: - -# Needed for UCB ARPAVAX console, since lsi-11 expands tabs -# (wrong). -# -hp2621-nt|hp 2621 w/no tabs:\ - :ta@:tc=hp2621: - -# Hp 2624 B with 4 or 10 pages of memory. -# -# Some assumptions are made with this entry. These settings are -# NOT set up by the initialization strings. -# -# Port Configuration -# RecvPace=Xon/Xoff -# XmitPace=Xon/Xoff -# StripNulDel=Yes -# -# Terminal Configuration -# InhHndShk=Yes -# InhDC2=Yes -# XmitFnctn(A)=No -# InhEolWrp=No -# -# Note: the 2624 DOES have a true :ho:, believe it or not! -# -# The 2624 has an "error line" to which messages can be sent. -# This is CLOSE to what is expected for a "status line". However, -# after a message is sent to the "error line", the next carriage -# return is EATEN and the "error line" is turned back off again! -# So I guess we can't define :hs:, :es:, :ws:, :ds:, :fs:, :ts:. -# -# This entry supports emacs (and any other program that uses raw -# mode) at 4800 baud and less. I couldn't get the padding right -# for 9600. -# -# (hp2624: replaced NUL sequences in flash with mandatory pauses -- esr) -hp2624|hp2624a|hp2624b|hp2624b-4p|Hewlett Packard 2624 B:\ - :da:db:\ - :lm#96:\ - :vb=\E&w13F\E&w12F\E&w13F\E&w12F:tc=hp+labels:tc=scrhp: - -# This hp2626 entry does not use any of the fancy windowing stuff -# of the 2626. -# -# Indeed, terminfo does not yet handle such stuff. Since changing -# any window clears memory, it is probably not possible to use -# this for screen opt. -# -# ed is incredibly slow most of the time - I am guessing at the -# exact padding. Since the terminal uses xoff/xon this is intended -# only for cost computation, so that the terminal will prefer el -# or even dl1 which is probably faster! -# -# \ED\EJ\EC hack for ed from Ed Bradford - apparently ed is only -# extra slow on the last line of the window. -# -# The padding probably should be changed. -# -hp2626|hp2626a|hp2626p|hp 2626:\ - :da:db:\ - :lm#0:pb#19200:\ - :SF=\E&r%dD:SR=\E&r%dU:cd=\ED\EJ\EC:ip=:is=\E&j@\r:tc=hp+pfk+cr:tc=hp+labels:tc=scrhp: - -# This entry is for sysline. It allocates a 23 line window with -# a 115 line workspace for regular use, and a 1 line window for -# the status line. -# -# This assumes port 2 is being used. -# Turn off horizontal line, Create ws #1 with 115 lines, -# Create ws #2 with 1 line, Create window #1 lines 1-23, -# Create window #2 lines 24-24, Attach cursor to workspace #1. -# Note that this clears the tabs so it must be done by tset before -# it sets the tabs. -# -hp2626-s|hp 2626 using only 23 lines:\ - :es:hs:\ - :li#23:\ - :fs=\E&d@\E&w7f2p1I\E&w4f1I:\ - :i1=\E&q3t0{0H \E&w0f115n1I \E&w0f1n2I \E&w2f1i0d0u22l0S \E&w2f2i0d23u23l0S \E&w7f2p1I \r:\ - :ts=\E&w7f2p2I\E&w4f2I\r\EK\E&a%dC:\ - :tc=hp2626: -# Force terminal back to 24 lines after being 23. -hp2626-ns|hp 2626 using all 24 lines:\ - :i1=\E&q3t0{0H \E&w0f118n1I \E&w0f1n2I \E&w2f1i0d0u23l0S \E&w3f2I \E&w7f2p1I \r:tc=hp2626: -# Various entries useful for small windows on 2626. -hp2626-12|hewlett-packard 2626 12 lines:\ - :li#12:tc=hp2626: -hp2626-12x40|hewlett-packard 2626 12 lines 40 columns:\ - :co#40:li#12:tc=hp2626: -hp2626-x40|hewlett-packard 2626 40 columns:\ - :co#40:tc=hp2626: -hp2626-12-s|hewlett-packard 2626 11 lines plus status:\ - :li#11:tc=hp2626-s: - -# -# hp2627 color tubes from University of Wisconsin -# -hp2627a-rev|hp 2627 with reverse video colors:\ - :cr=^M:do=^J:\ - :is=\E&v0m1a0b0c1x1y1z1i0a0b1c1x1y1z0i0S\E&j@\r\E3\r:\ - :kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:ue=\E&v0S\E&d@:\ - :us=\E&dD\E&v1S:\ - :tc=hp2621-nl: -hp2627a|hp 2627 color terminal with no labels:\ - :cr=^M:do=^J:\ - :is=\E&v0m1a1b0c1i0a1b1c2i1a0b0c0i0S\E&j@\r\E3\r:\ - :kb=^H:kd=^J:kl=^H:nw=^M^J:se=\E&v0S:sf=^J:so=\E&v2S:ta=^I:\ - :ue=\E&v0S\E&d@:us=\E&dD\E&v1S:\ - :tc=hp2621-nl: -hp2627c|hp 2627 color (cyan) terminal with no labels:\ - :cr=^M:do=^J:\ - :is=\E&v0m1a0b0c2i1a1b0c1i0a1b1c0i0S\E&j@\r\E3\r:\ - :kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:\ - :tc=hp2627a: - -# hp2640a doesn't have the Y cursor addressing feature, and C is -# memory relative instead of screen relative, as we need. -# -hp2640a|hp 2640a:\ - :cm@:ke@:ks@:tc=hp2645: - -hp2640b|hp2644a|hp 264x series:\ - :ke@:ks@:tc=hp2645: - -# (hp2641a: removed unknown :gu: -- esr) -hp2641a|hp2645a|hp2647a|HP 264?A series BRL entry:\ - :am:da:db:mi:xs:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:ch=\E&a%2C:cl=\EH\EJ:\ - :cm=\E&a%r%2c%2Y:cr=^M:cv=\E&a%2Y:dc=\EP:dl=\EM:do=^J:\ - :ei=\ER:if=/usr/share/tabset/std:im=\EQ:is=500\EE:kb=^H:\ - :kd=^J:kl=^H:le=^H:nd=\EC:nw=^M^J:se=\E&d@:sf=^J:so=\E&dB:\ - :ta=^I:up=\EA: - -# This terminal should be used at 4800 baud or less. It needs padding for -# plain characters at 9600, I guessed at an appropriate cr delay. It really -# wants ^E/^F handshaking, but that doesn't work well even if you write -# software to support it. -hp2645|hp45|HP 2645 series:\ - :pb#9600:\ - :cr=\r:kA=\EL:kD=\EP:kE=\EK:kF=\ES:kI=\EQ:kL=\EM:kM=\ER:\ - :kN=\EU:kP=\EV:kR=\ET:kS=\EJ:kT=\E1:kd=\EB:ke=\E&s0A:kh=\Eh:\ - :kl=\ED:kr=\EC:ks=\E&s1A:kt=\E2:ku=\EA:mb=\E&dA:me=\E&d@:\ - :mh=\E&dH:mr=\E&dB:\ - :us=\E&dD:\ - :tc=hpgeneric: -# You should use this terminal at 4800 baud or less. -hp2648|hp2648a|HP 2648a graphics terminal:\ - :cl=\EH\EJ:cm=\E&a%r%dc%dY:dc=\EP:ip=:tc=hp2645: - -# The HP 150 terminal is a fairly vanilla HP terminal, with the -# clreol standout problem. It also has graphics capabilities and -# a touch screen, which we don't describe here. -hp150|hewlett packard Model 150:\ - :bs:tc=hp2622: - -# HP 2382a terminals, "the little ones." They don't have any -# alternate character set support and sending out ^N/^O will -# leave the screen blank. -hp2382a|hp2382|hewlett packard 2382a:\ - :da:db:\ - :lh#1:lm#48:\ - :ac@:ae@:as@:me=\E&d@:\ - :tc=hp+labels:tc=scrhp: - -hp2621-a|hp2621a-a|hp2621 with fn as arrows:\ - :tc=hp+pfk+arrows:tc=hp2621-fl: - -# newer hewlett packard terminals - -newhpkeyboard|generic entry for HP extended keyboard:\ - :kA=\EL:kB=\Ei:kC=\EJ:kD=\EP:kE=\EK:kF=\ET:kH=\EF:kI=\EQ:\ - :kL=\EM:kM=\ER:kN=\EU:kP=\EV:kR=\ES:kS=\EJ:kb=^H:kd=\EB:\ - :ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:ks=\E&s1A:ku=\EA:\ - :tc=hp+pfk-cr: - -newhp|generic entry for new hewlett packard terminals:\ - :am:bw:mi:xo:xs:\ - :co#80:li#24:pb#4800:\ - :ac=T1R\041U2S"W3O#V4P$t5u6w7v8\072'9(LQKWlRkT5I3@2[MAJSmFjGdHQ;Y+Z*X\0724>q\054x.n/:\ - :ae=^O:al=\EL:as=^N:bl=^G:bt=\Ei:cd=\EJ:ce=\EK:cr=^M:ct=\E3:\ - :dc=\EP:dl=\EM:do=^J:ei=\ER:i1=\E&jB:im=\EQ:ip=:le=^H:\ - :mb=\E&dA:md=\E&dF:me=\E&d@\017:mh=\E&dH:mk=\E&dS:\ - :mr=\E&dB:nd=\EC:nw=^M^J:\ - :r1=\Eg:\ - :se=\E&d@:sf=^J:so=\E&dJ:sr=\ET:st=\E1:ta=\011:ue=\E&d@:\ - :up=\EA:us=\E&dD:\ - :tc=newhpkeyboard: - -memhp|memory relative addressing for new HP ttys:\ - :vt#6:\ - :CM=\E&a%dr%dC:DO=\E&a+%dR:LE=\E&a-%dC:\ - :RI=\E&a+%dC:UP=\E&a-%dR:ch=\E&a%dC:cl=\EH\EJ:\ - :cm=\E&a%dr%dC:cv=\E&a%dR:ho=\EH:ll=\E&a23R\r:tc=newhp: - -scrhp|screen relative addressing for new HP ttys:\ - :CM=\E&a%dr%dC:DO=\E&a+%dR:LE=\E&a-%dC:\ - :RI=\E&a+%dC:UP=\E&a-%dR:ch=\E&a%dC:cl=\E&a0c0Y\EJ:\ - :cm=\E&a%dy%dC:cv=\E&a%dY:ho=\E&a0y0C:ll=\E&a0y0C\EA:\ - :tc=newhp: - -# (hp+labels: added label values from a BRL termcap -- esr) -hp+labels|"standard" label info for new HP ttys:\ - :Nl#8:lh#2:lw#8:\ - :LF=\E&j@:LO=\E&jB:l0=f1:l1=f2:l2=f3:l3=f4:l4=f5:l5=f6:l6=f7:\ - :l7=f8: - -hp+printer|"standard" printer info for HP ttys:\ - :ff=\E&p4u0C:pf=\E&p13C:po=\E&p11C:ps=\EH\E&p4dF: - - -# The new hp2621b is kind of a cross between the old 2621 and the -# new 262x series of machines. It has dip-switched options. -# The firmware has a bug in it such that if you give it a null -# length label, the following character is eaten! -hp2621b|hp 2621b with old style keyboard:\ - :Nl#8:lh#1:lm#48:lw#8:\ - :LO=\E&jB:kF=\ET:kH=\EF:kR=\ES:kd=\EB:kh=\Eh:kl=\ED:kr=\EC:\ - :ku=\EA:\ - :tc=hp2621: - -hp2621b-p|hp 2621b with printer:\ - :tc=hp+printer:tc=hp2621b: - -# hp2621b - new 2621b with new extended keyboard -# these are closer to the new 26xx series than the other 2621b -hp2621b-kx|hp 2621b with extended keyboard:\ - :tc=newhpkeyboard:tc=hp2621b: - -hp2621b-kx-p|hp 2621b with new keyboard & printer:\ - :tc=hp+printer:tc=hp2621b-kx: - -# Some assumptions are made in the following entries. -# These settings are NOT set up by the initialization strings. -# -# Port Configuration -# RecvPace=Xon/Xoff XmitPace=Xon/Xoff StripNulDel=Yes -# -# Terminal Configuration -# InhHndShk(G)=Yes InhDC2(H)=Yes -# XmitFnctn(A)=No InhEolWrp=No -# -# -# Hp 2622a & hp2623a display and graphics terminals -# -hp2622|hp2622a|hp 2622:\ - :da:db:\ - :lm#0:pb#19200:\ - :is=\E&dj@\r:tc=hp+pfk+cr:tc=hp+labels:tc=scrhp: - -# The 2623 is a 2622 with extra graphics hardware. -hp2623|hp2623a|hp 2623:\ - :tc=hp2622: - -hp2624b-p|hp2624b-4p-p|hewlett packard 2624 B with printer:\ - :tc=hp+printer:tc=hp2624: - -# The hewlett packard B can have an optional extra 6 pages of memory. -hp2624-10p|hp2624a-10p|hp2624b-10p|hewlett packard 2624 B w/ 10 pages of memory:\ - :lm#240:tc=hp2624: - -hp2624b-10p-p|hewlett packard 2624 B w/ extra memory & printer:\ - :lm#240:tc=hp2624b-p: - -# Color manipulations for HP terminals -hp+color|hp with colors:\ - :cc:\ - :Co#16:NC#17:pa#7:\ - :oc=\E&v0m1a1b1c0I\E&v1a1I\E&v1b2I\E&v1a1b3I\E&v1c4I\E&v1a1c5I\E&v1b1c6I\E&v1x1y7I:\ - :op=\E&v0S:sp=\E&v%dS: - -# :is: sets the screen to be 80 columns wide -hp2397a|hp2397|hewlett packard 2397A color terminal:\ - :is=\E&w6f80X:\ - :tc=memhp:tc=hp+labels:tc=hp+color: - -# HP 700/44 Setup parameters: -# Terminal Mode HP-PCterm -# Inhibit Auto Wrap NO -# Status Line Host Writable -# PC Character Set YES -# Twenty-Five Line Mode YES -# XON/XOFF @128 or 64 (sc) -# Keycode Mode NO or YES (sc) -# Backspace Key BS or BS/DEL -# -# :is: sets pcterm; autowrap; 25 lines; pc char set; prog DEL key; -# \E\\? does not turn off keycode mode -# sets alternate start/stop; keycode on -hpansi|hp700|hewlett packard 700/44 in HP-PCterm mode:\ - :am:eo:xn:xo:\ - :co#80:li#25:\ - :@7=\E[4~:RA=\E[?7l:S4=\E[>11h\EPO**x0/65;1/67\E\:\ - :S5=\E[>11l\EP1**x0/11;1/13\E[m\E\:SA=\E[?7h:XF=g:XN=e:\ - :ac=k\277l\332m\300j\331n\305w\302q\304u\264t\303v\301x\263:\ - :al=\E[L:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[2J\E[H:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :ic=\E[@:im=:\ - :is=\E[44"p\E[?7h\E[>10h\E[>12h\EP1;1|3/7F\E\:\ - :k1=\E[17~:k2=\E[18~:k3=\E[19~:k4=\E[20~:k5=\E[21~:\ - :k6=\E[23~:k7=\E[24~:k8=\E[25~:k9=\E[26~:k;=\E[28~:\ - :kB=\E[Z:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:kh=\E[1~:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=\E[D:me=\E[m:nd=\E[C:se=\E[m:sf=^J:\ - :so=\E[7m:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[?25h:\ - :vi=\E[?25l: -# -# (hp2392: copied :ei: here from hpex -- esr) -hp2392|239x series:\ - :co#80:\ - :bt=\Ei:cm=\E&a%dy%dC:cv=\E&a%dY:ei=\ER:im=\EQ:k1=\Ep\r:\ - :k2=\Eq\r:k3=\Er\r:k4=\Es\r:k5=\Et\r:k6=\Eu\r:k7=\Ev\r:\ - :k8=\Ew\r:kF=\EU:kN=\Eu:kP=\Ev:kR=\EV:kh=\Eh:ue=\E&d@:\ - :us=\E&dD:\ - :tc=hpsub: - -hpsub|hp terminals -- capability subset:\ - :am:da:db:mi:xo:xs:\ - :li#24:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:ch=\E&a%dC:cl=\EH\EJ:cr=^M:\ - :dc=\EP:dl=\EM:do=\EB:if=/usr/share/tabset/stdcrt:\ - :is=\E&s1A\E<\E&k0\:kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:\ - :kr=\EC:ks=\E&s1A:ku=\EA:le=^H:me=\E&d@:nd=\EC:se=\E&d@:\ - :sf=^J:so=\E&dB:ta=^I:up=\EA: - -# hpex: -# May be used for most 24 x 80 hp terminals, -# but has no padding added, so may allow runover in some terminals at high -# baud rates. Will not work for hp2640a or hp2640b terminals, hp98x6 and -# hp98x5 terminal emulators or hp98x6 consoles. -# Adds xy-cursor addressing, vertical cursor addressing, home, -# last line, and underline capabilities. -# -# (hpex: removed memory-lock capabilities ":ml=\El:mu=\Em:", -# moved :ei: here from hpsub -- esr) -hpex|hp extended capabilites:\ - :cm=\E&a%dy%dC:cr=^M:cv=\E&a%dY:do=^J:ei=\ER:im=\EQ:kb=^H:\ - :kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:ue=\E&d@:us=\E&dD:\ - :tc=hpsub: - -# From: Ville Sulko , 05 Aug 1996 -hp2|hpex2|hewlett-packard extended capabilities newer version:\ - :am:da:db:mi:xs:\ - :Nl#8:co#80:lh#2:li#24:lm#0:lw#8:sg#0:\ - :LF=\E&j@:LO=\E&jB:al=\EL:bl=^G:cd=\EJ:ce=\EK:ch=\E&a%dC:\ - :cl=\E&a0y0C\EJ:cm=\E&a%dy%dC:cr=^M:ct=\E3:cv=\E&a%dY:\ - :dc=\EP:dl=\EM:do=\EB:ei=\ER:im=\EQ:k1=\Ep:k2=\Eq:k3=\Er:\ - :k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:kA=\EL:kC=\EJ:kD=\EP:\ - :kE=\EK:kF=\ES:kH=\EF:kI=\EQ:kL=\EM:kM=\ER:kN=\EU:kP=\EV:\ - :kR=\ET:kS=\EJ:kT=\E1:ka=\E3:kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:\ - :kl=\ED:kr=\EC:ks=\E&s1A:kt=\E2:ku=\EA:le=^H:me=\E&d@:\ - :ml=\El:mu=\Em:nd=\EC:\ - :se=\E&d@:sf=^J:so=\E&dB:st=\E1:ta=^I:ue=\E&d@:up=\EA:\ - :us=\E&dD: - -# HP 236 console -# From: -hp236|hp236 internal terminal emulator:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EG:ce=\EK:cl=\EF:cm=\EE%+ %+ :dc=\EJ:dl=\EH:ei=:ic=\EI:\ - :im=:le=^H:me=\ECI:se=\ECI:so=\EBI:up=^K:ve=\EDE:vs=\EDB: - -# This works on a hp300 console running Utah 4.3 BSD -# From: Craig Leres -hp300h|HP Catseye console:\ - :am:bs:da:db:mi:xs:\ - :co#128:li#51:lm#0:sg#0:\ - :al=\EL:bl=^G:bt=\Ei:cd=\EJ:ce=\EK:ch=\E&a%dC:\ - :cl=\E&a0y0C\EJ:cm=\E&a%dy%dC:cr=^M:ct=\E3:cv=\E&a%dY:\ - :dc=\EP:dl=\EM:do=\EB:ei=\ER:if=/usr/share/tabset/stdcrt:\ - :im=\EQ:kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:\ - :ks=\E&s1A:ku=\EA:le=^H:me=\E&d@:nd=\EC:se=\E&d@:sf=^J:\ - :so=\E&dB:ta=^I:ue=\E&d@:up=\EA:us=\E&dD: -# From: Greg Couch -hp9837|hp98720|hp98721|HP 9000/300 workstations:\ - :am:bs:da:db:mi:xs:\ - :co#128:it#8:li#46:lm#0:\ - :al=\EL:bl=^G:bt=\Ei:cd=\EJ:ce=\EK:ch=\E&a%dC:\ - :cl=\E&a0y0C\EJ:cm=\E&a%dy%dC:ct=\E3:cv=\E&a%dY:dc=\EP:\ - :dl=\EM:do=\EB:ei=\ER:im=\EQ:is=\E&v0m1b0i&j@:kA=\EL:\ - :kD=\EP:kE=\EK:kI=\EQ:kL=\EM:kN=\EU:kP=\EV:kS=\EJ:kb=^H:\ - :kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:ks=\E&s1A:ku=\EA:\ - :le=^H:me=\E&d@:nd=\EC:se=\E&v0S:sf=^J:so=\E&v5S:st=\E1:\ - :ta=^I:ue=\E&d@:up=\EA:us=\E&dD: -# HP 9845 desktop computer from BRL -# (hp9845: removed unknown capability :gu: -- esr) -hp9845|HP 9845:\ - :am:bs:da:db:eo:mi:xs:\ - :co#80:li#21:\ - :al=\EL:bc=\ED:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\E&a%r%2c%2Y:\ - :dc=\EP:dl=\EM:ei=\ER:if=/usr/share/tabset/std:im=\EQ:\ - :nd=\EC:se=\E&d@:so=\E&dB:up=\EA: -# From: Charles A. Finnell of MITRE , developed 07SEP90 -# (hp98550: replaced /usr/share/tabset/9837 with std because :it#8:,:st=\E1:; -# added empty to avoid warnings re :as:/:ae: --esr) -hp98550|hp98550a|HP 9000 Series 300 color console:\ - :am:bs:da:db:mi:xs:\ - :co#128:it#8:li#49:lm#0:\ - :ac=:ae=^O:al=\EL:as=^N:bl=^G:bt=\Ei:cd=\EJ:ce=\EK:\ - :ch=\E&a%dC:cl=\EH\EJ:cm=\E&a%dy%dC:cr=^M:ct=\E3:\ - :cv=\E&a%dY:dc=\EP:dl=\EM:do=^J:ei=\ER:\ - :if=/usr/share/tabset/std:im=\EQ:k1=\Ep:k2=\Eq:k3=\Er:\ - :k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:kA=\EL:kC=\EJ:kD=\EP:\ - :kE=\EK:kF=\ES:kH=\EF:kI=\EQ:kL=\EM:kM=\ER:kN=\EU:kP=\EV:\ - :kR=\ET:kS=\EJ:kT=\E1:ka=\E3:kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:\ - :kl=\ED:kr=\EC:ks=\E&s1A:kt=\E2:ku=\EA:le=^H:mb=\E&dA:\ - :md=\E&dJ:me=\E&d@:mh=\E&dH:mk=\E&ds:mr=\E&dJ:nd=\EC:\ - :se=\E&d@:sf=^J:so=\E&dJ:st=\E1:ta=^I:ue=\E&d@:up=\EA:\ - :us=\E&dD:ve=\E*dQ:vi=\E*dR: -# From: Victor Duchovni -# (hp700-wy: removed obsolete ":nl=^J:"; -# replaced /usr/share/tabset/hp700-wy with std because :it#8:,:st=\E1: -- esr) -hp700-wy|HP700/41 emulating wyse30:\ - :am:bs:bw:mi:ms:\ - :co#80:it#8:li#24:sg#1:ug#1:\ - :al=0.7*\EE:bt=\EI:cd=\EY:ce=10\ET:cl=^Z:cm=\E=%+ %+ :\ - :cr=^M:ct=\E0:cv=\E[%+ :dc=\EW:dl=\ER:do=^V:ei=\Er:ho=^^:\ - :i1=\E~"\EC\Er\E(\EG0\003\E`9\E`1:\ - :if=/usr/share/tabset/stdcrt:im=\Eq:kB=\EI:kC=^Z:kE=\ET:\ - :kI=\Eq:kM=\Er:kS=\EY:kT=\EI:kb=\177:kd=^V:kh=^^:kl=^H:kr=^L:\ - :ku=^K:le=^H:ll=^^^K:me=10\EG0:nd=^L:se=10\EG0:so=10\EG4:\ - :sr=\Ej:st=\E1:ta=^I:ue=10\EG0:up=^K:us=10\EG8: -# (hp70092: added empty to avoid warnings re :as:/:ae: --esr) -hp70092|hp70092a|hp70092A|HP 700/92:\ - :am:da:db:xs:\ - :Nl#8:co#80:lh#2:li#24:lm#0:lw#8:\ - :LF=\E&j@:LO=\E&jB:ac=:ae=^O:al=\EL:as=^N:bl=^G:bt=\Ei:\ - :ce=\EK:ch=\E&a%dC:cl=\E&a0y0C\EJ:cm=\E&a%dy%dC:cr=^M:\ - :ct=\E3:cv=\E&a%dY:dc=\EP:dl=\EM:do=\EB:ei=\ER:im=\EQ:\ - :k1=\Ep:k2=\Eq:k3=\Er:k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:\ - :kA=\EL:kC=\EJ:kD=\EP:kE=\EK:kF=\ES:kH=\EF:kI=\EQ:kL=\EM:\ - :kM=\ER:kN=\EU:kP=\EV:kR=\ET:kS=\EJ:kT=\E1:ka=\E3:kb=^H:\ - :kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:ks=\E&s1A:kt=\E2:\ - :ku=\EA:le=^H:mb=\E&dA:md=\E&dB:me=\E&d@:mh=\E&dH:mr=\E&dB:\ - :nd=\EC:se=\E&d@:so=\E&dJ:sr=\ET:st=\E1:ta=^I:ue=\E&d@:\ - :up=\EA:us=\E&dD: - -bobcat|sbobcat|HP 9000 model 300 console:\ - :am:da:db:mi:xs:\ - :co#128:it#8:li#47:sg#0:\ - :al=10*\EL:bt=\Ei:cd=\EJ:ce=\EK:ch=6\E&a%dC:cl=\EH\EJ:\ - :cm=6\E&a%dy%dC:cr=^M:cv=6\E&a%dY:dc=\EP:dl=10*\EM:do=\EB:\ - :ei=\ER:im=\EQ:kb=^H:kd=\EB:ke=\E&s0A:kh=\Eh:kl=\ED:kr=\EC:\ - :ks=\E&s1A:ku=\EA:le=^H:me=\E&d@:nd=\EC:nw=^M^J:se=\E&d@:\ - :sf=^J:so=\E&dB:ta=^I:ue=\E&d@:up=\EA:us=\E&dD: -gator-t|HP 9000 model 237 emulating extra-tall AAA:\ - :li#94:tc=gator: -gator|HP 9000 model 237 emulating AAA:\ - :bw:km:mi:ul:\ - :co#128:it#8:li#47:\ - :AL=1*\E[%dL:DC=4\E[%dP:DL=1*\E[%dM:IC=4\E[%d@:al=\E[L:\ - :bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:ch=\E[%i%d`:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=^J:ei=:ho=\E[H:\ - :ic=\E[@:im=:kb=^H:kd=^J:kl=^H:le=^H:me=\E[m:mr=\E[7m:\ - :nd=\E[C:nw=^M^J:rp=1*%.\E[%db:se=\E[m:so=\E[7m:ta=^I:\ - :ue=\E[m:up=\EM:us=\E[4m: -gator-52|HP 9000 model 237 emulating VT52:\ - :co#128:li#47:tc=vt52: -gator-52t|HP 9000 model 237 emulating extra-tall VT52:\ - :li#94:tc=gator-52: - -#### Honeywell-Bull -# -# From: Michael Haardt 11 Jan 93 -# - -# Honeywell Bull terminal. Its cursor and function keys send single -# control characters and it has standout/underline glitch. Most programs -# do not like these features/bugs. Visual bell is realized by flashing the -# "keyboard locked" LED. -dku7003-dumb|Honeywell Bull DKU 7003 dumb mode:\ - :co#80:li#25:\ - :cd=^_:ce=\E[K:cl=^]^_:cm=\E[%i%d;%dH:cr=^M:do=^K:ho=^]:\ - :kb=^H:kd=^K:kh=^]:kl=^Y:kr=^X:ku=^Z:le=^Y:nd=^X:nw=^M^J:\ - :sf=^J:ta=^I:up=^Z:vb=\E[2h\E[2l: -dku7003|Honeywell Bull DKU 7003 all features described:\ - :ms:\ - :sg#1:ug#1:\ - :mb=\E[5m:md=\E[7m:me=\E[m:mh=\E[2m:mr=\E[7m:se=\E[m:\ - :so=\E[7m:ue=\E[m:us=\E[4m:\ - :tc=dku7003-dumb: - -#### Lear-Siegler (adm) -# -# These guys are long since out of the terminals business, but -# in 1995 many current terminals still have an adm type as one of their -# emulations (usually their stupidest, and usually labeled adm3, though -# these `adm3' emulations normally have adm3a+ capabilities). -# -# WARNING: Some early ADM terminals (including the ADM3 and ADM5) had a -# `diagnostic feature' that sending them a ^G while pin 22 (`Ring Indicator') -# was being held to ground would trigger a send of the top line on the screen. -# A quick fix might be to drop back to a cheesy 4-wire cable with pin 22 -# hanging in the air. -# - -adm1a|adm1|lsi adm1a:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cl=\E;:cm=\E=%+ %+ :cr=^M:do=^J:ho=^^:le=^H:nd=^L:\ - :sf=^J:up=^K: -adm2|lsi adm2:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=\E;:cm=\E=%+ %+ :cr=^M:\ - :dc=\EW:dl=\ER:do=^J:ei=:ho=^^:ic=\EQ:im=:kd=^J:kh=^^:kl=^H:\ - :kr=^L:ku=^K:le=^H:nd=^L:sf=^J:up=^K: -# (adm3: removed obsolete ":ma=^K^P:" -- esr) -adm3|lsi adm3:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cl=^Z:cr=^M:do=^J:le=^H:sf=^J: -# The following ADM-3A switch settings are assumed for normal operation: -# SPACE U/L_DISP CLR_SCRN 24_LINE -# CUR_CTL LC_EN AUTO_NL FDX -# Other switches may be set for operator convenience or communication -# requirements. I recommend -# DISABLE_KB_LOCK LOCAL_OFF 103 202_OFF -# ETX_OFF EOT_OFF -# Most of these terminals required an option ROM to support lower case display. -# Open the case and look at the motherboard; if you see an open 24-pin DIP -# socket, you may be out of luck. -# -# (adm3a: some capabilities merged in from BRl entry -- esr) -adm3a|lsi adm3a:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cl=1\032:cm=\E=%+ %+ :cr=^M:do=^J:ho=^^:kd=^J:kl=^H:\ - :kr=^L:ku=^K:le=^H:ma=^K^P:nd=^L:nl=^J:r1=^N:rs=^N:sf=^J:\ - :up=^K: -adm3a+|adm3a plus:\ - :kb=^H:tc=adm3a: -# (adm5: removed obsolete ":ma=^Hh^Jj^Kk^Ll^^H:" & duplicate ":do=^J:" -- esr) -adm5|lsi adm5:\ - :sg#1:\ - :bl=^G:cd=\EY:ce=\ET:cr=^M:do=^J:kb=^H:kh=^^:se=\EG:so=\EG:tc=adm3a+: -# A lot of terminals other than adm11s use these. Wherever you see -# use=adm+sgr with some of its capabilities disabled, try the -# disabled ones. They may well work but not have been documented or -# expressed in the using entry. We'd like to cook up an :sa: but the -# :ae:/:as: sequences of the using entries vary too much. -adm+sgr|adm style highlight capabilities:\ - :me=\EG0:mk=\EG1:mr=\EG4:se=\EG0:so=\EG4:ue=\EG0:us=\EG8: -# LSI ADM-11 from George William Hartwig, Jr. via BRL -# Status line additions from Stephen J. Muir -# :kh: from . :cl: could also -# be ^Z, according to his entry. -# (adm11: :us:=\EG4 was obviously erroneous because it also said -# :mr:=\EG4. Looking at other ADMs confirms this -- esr) -adm11|LSI ADM-11:\ - :am:bs:hs:\ - :co#80:kn#8:li#24:\ - :bl=^G:cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :cr=^M:do=^J:ds=\Eh:\ - :fs=\E(\r:ho=^^:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:kb=^H:kd=^J:kh=^^:\ - :kl=^H:kr=^L:ku=^K:le=^H:mb=\EG2:nd=^L:nl=^J:nw=^M^J:ta=^I:\ - :ts=\EF\E):up=^K:\ - :tc=adm+sgr: -# From: Andrew Scott Beals -# Corrected by Olaf Siebert , 11 May 1995 -# (adm12: removed obsolete ":kn:ma=j^Jk^P^K^Pl ^R^L^L :". This formerly had -# :is:=\Eq but that looked wrong; this :is: is from Dave Yost -# via BRL. That entry asserted :sg#1:, but I've left that out because -# neither earlier nor later ADMSs have it -- esr) -adm12|lsi adm12:\ - :am:bs:mi:pt:\ - :co#80:it#8:li#24:ug#1:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:ct=\E0:\ - :dc=\EW:dl=\ER:do=^J:ei=\Er:ho=^^:ic=\EQ:im=\Eq:\ - :is=\E0 \E1 \E1 \E1 \E1 \E1 \E1 \E1 \E1:\ - :k0=^A0\r:k1=^A1\r:k2=^A2\r:k3=^A3\r:k4=^A4\r:k5=^A5\r:\ - :k6=^A6\r:k7=^A7\r:k8=^A8\r:k9=^A9\r:kd=^J:kl=^H:kr=^L:\ - :ku=^K:le=^H:nd=^L:st=\E1:up=^K:\ - :tc=adm+sgr: -# (adm20: removed obsolete ":kn#7:" -- esr) -adm20|lear siegler adm20:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=^Z:\ - :cm=\E=%i%r%+^_%+^_:cr=^M:dc=\EW:dl=\ER:ei=:ho=^^:ic=\EQ:\ - :im=:k1=^A:k2=^B:k3=^W:k4=^D:k5=^E:k6=^X:k7=^Z:le=^H:me=\E(:\ - :nd=^L:se=\E(:so=\E):ta=^I:up=^K: -adm21|lear siegler adm21:\ - :sg#1:\ - :al=30*\EE:bl=^G:cd=\EY:ce=\ET:cr=^M:dc=\EW:dl=30*\ER:do=^J:\ - :ei=:ic=\EQ:im=:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:mk@:sf=^J:\ - :me=\EG0:mk=\EG1:mr=\EG4:se=\EG0:so=\EG4:ue=\EG0:us=\EG8:\ - :tc=adm3a: -# (adm22: ":em=:" was an obvious typo for ":ei=:"; also, -# removed obsolete ":kn#7:ma=j^Jk^P^K^Pl ^R^L^L :"; -# removed bogus-looking \200 from before :cm:. -- esr) -adm22|lsi adm22:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EE:bl=^G:bt=\EI:cd=\Ey:ce=\Et:cl=\E+:cm=\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=\ER:do=^J:ei=:ho=^^:ic=\EQ:im=:\ - :is=\E%\014\014\014\016\003\200\003\002\003\002\200\200\200\200\200\200\200\200\200\200\200:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:l1=F1:l2=F2:\ - :l3=F3:l4=F4:l5=F5:l6=F6:l7=F7:le=^H:me=\E(:nd=^L:se=\E(:\ - :so=\E):ta=\Ei:up=^K: -# ADM 31 DIP Switches -# -# This information comes from two versions of the manual for the -# Lear-Siegler ADM 31. -# -# Main board: -# rear of case -# +-||||-------------------------------------+ -# + S1S2 ||S + -# + ||3 + -# + + -# + ||S + -# + ||4 + -# + + -# + + -# + + -# + + -# + + -# +-+ +-+ -# + + -# + S5 S6 S7 + -# + == == == + -# +----------------------------------------------+ -# front of case (keyboard) -# -# S1 - Data Rate - Modem -# S2 - Data Rate - Printer -# ------------------------ -# Data Rate Setting -# ------------------- -# 50 0 0 0 0 -# 75 1 0 0 0 -# 110 0 1 0 0 -# 134.5 1 1 0 0 -# 150 0 0 1 0 -# 300 1 0 1 0 -# 600 0 1 1 0 -# 1200 1 1 1 0 -# 1800 0 0 0 1 -# 2000 1 0 0 1 -# 2400 0 1 0 1 -# 3600 1 1 0 1 -# 4800 0 0 1 1 -# 7200 1 0 1 1 -# 9600 0 1 1 1 -# x 1 1 1 1 -# -# S3 - Interface/Printer/Attributes -# --------------------------------- -# Printer Busy Control -# sw1 sw2 sw3 -# --------------- -# off off off Busy not active, CD disabled -# off off on Busy not active, CD enabled -# off on off Busy active on J5-20, CD disabled -# on off off Busy active on J5-19, CD disabled - Factory Set. -# on off on Busy active on J5-19, CD enabled -# -# sw4 Used in conjuction with S4 for comm interface control - Fact 0 -# -# sw5 Secondary Channel Control (Hardware implementation only) - Fact 0 -# -# sw6 ON enables printer BUSY active LOW - Factory Setting -# OFF enables printer BUSY active HIGH - If set to this, ADM31 senses -# -# sw7 ON - steady cursor - Factory Setting -# OFF - blinking cursor -# -# sw8 ON causes selected attribute character to be displayed -# OFF causes SPACE to be displayed instead - Factory Setting -# -# S4 - Interface -# -------------- -# Modem Interface -# S3 S4 S4 S4 S4 -# sw4 sw1 sw2 sw3 sw4 -# --------------------------- -# OFF ON OFF ON OFF Enable RS-232C interface, Direct Connect and -# Current Loop disabled - Factory Setting -# ON ON OFF ON OFF Enable Current Loop interface, Direct Connect -# disabled -# OFF OFF ON OFF ON Enable Direct Connect interface, RS-232C and -# Current Loop Disabled -# -# sw5 ON disables dot stretching mode - Factory Setting -# OFF enables dot stretching mode -# sw6 ON enables blanking function -# OFF enables underline function - Factory Setting -# sw7 ON causes NULLS to be displayed as NULLS -# OFF causes NULLS to be displayed as SPACES - Factory Setting -# -# S5 - Word Structure -# ------------------- -# sw1 ON enables BREAK key - Factory Setting -# OFF disables BREAK key -# sw2 ON selects 50Hz monitor refresh rate -# OFF selects 60Hz monitor refresh rate - Factory Setting -# -# Modem Port Selection -# sw3 sw4 sw5 -# --------------- -# ON ON ON Selects 7 DATA bits, even parity, 2 STOP bits -# OFF ON ON Selects 7 DATA bits, odd parity, 2 STOP bits -# ON OFF ON Selects 7 DATA bits, even parity, 1 STOP bit - Factory Set. -# OFF OFF ON Selects 7 DATA bits, odd parity, 1 STOP bit -# ON ON OFF Selects 8 DATA bits, no parity, 2 STOP bits -# OFF ON OFF Selects 8 DATA bits, no parity, 1 STOP bit -# ON OFF OFF Selects 8 DATA bits, even parity, 1 STOP bit -# OFF OFF OFF Selects 8 DATA bits, odd parity, 1 STOP bit -# -# sw6 ON sends bit 8 a 1 (mark) -# OFF sends bit 8 as 0 (space) - Factory Setting -# sw7 ON selects Block Mode -# OFF selects Conversation Mode - Factory Setting -# sw8 ON selects Full Duplex operation -# OFF selects Half Duplex operation - Factory Setting -# -# S6 - Printer -# ------------ -# sw1, sw2, sw6, sw7 Reserved - Factory 0 -# -# Printer Port Selection -# same as Modem above, bit 8 (when 8 DATA bits) is always = 0 -# -# sw8 ON enables Printer Port -# OFF disables Printer Port - Factory Setting -# -# S7 - Polling Address -# -------------------- -# sw1-7 Establish ASCII character which designates terminal polling address -# ON = logic 0 -# OFF = logic 1 - Factory Setting -# sw8 ON enables Polling Option -# OFF disables Polling Option - Factory Setting -# -# -# On some older adm31s, S4 does not exist, and S5-sw6 is not defined. -# -# This adm31 entry uses underline as the standout mode. -# If the adm31 gives you trouble with standout mode, check the DIP switch in -# position 6, bank @c11, 25% from back end of the circuit board. Should be -# OFF. If there is no such switch, you have an old adm31 and must use oadm31. -# (adm31: removed obsolete ":ma=j^Jk^P^K^Pl ^R^L^L :" -- esr) -adm31|lsi adm31 with sw6 set for underline mode:\ - :am:bs:mi:\ - :co#80:li#24:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :cr=^M:\ - :dc=\EW:dl=\ER:do=^J:ei=\Er:ho=^^:im=\Eq:is=\Eu\E0:k0=^A0\r:\ - :k1=^A1\r:k2=^A2\r:k3=^A3\r:k4=^A4\r:k5=^A5\r:k6=^A6\r:\ - :k7=^A7\r:k8=^A8\r:k9=^A9\r:kd=^J:kl=^H:kr=^L:ku=^K:le=^H:\ - :me=\EG0:nd=^L:se=\EG0:sf=^J:so=\EG1:ue=\EG0:up=^K:us=\EG1: -adm31-old|o31|old adm31:\ - :so=\EG4:ue@:us@:tc=adm31: -# LSI ADM-36 from Col. George L. Sicherman via BRL -adm36|LSI ADM36:\ - :bs:pt:\ - :kn#4:\ - :if=/usr/share/tabset/vt100:\ - :is=\E<\E>\E[6;?2;?7;?8h\E[4;20;?1;?3;?4;?5;?6;?18;?19l:tc=vt100: -# (adm42: removed obsolete ":ma=^K^P:" -- esr) -adm42|lsi adm42:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E;:cm=\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=\ER:do=^J:ei=\Er:im=\Eq:ip=:kd=^J:kh=^^:\ - :kl=^H:kr=^L:ku=^K:le=^H:mk@:nd=^L:pc=\177:sf=^J:ta=^I:ue@:\ - :up=^K:us@:vs=\EC\E3 \E3(:\ - :tc=adm+sgr: -# The following termcap for the Lear Siegler ADM-42 leaves the -# "system line" at the bottom of the screen blank (for those who -# find it distracting otherwise) -adm42-ns|lsi adm-42 with no system line:\ - :al=\EE\EF \011:bt=\EI\EF \011:cd=\EY\EF \011:\ - :ce=\ET\EF \011:cl=\E;\EF \011:cm=\E=%+ %+ \EF \011:\ - :dc=\EW\EF \011:dl=\ER\EF \011:ei=\Er\EF \011:\ - :im=\Eq\EF \011:tc=adm42: -# ADM 1178 terminal -- rather like an ADM-42. Manual is dated March 1 1985. -# The insert mode of this terminal is commented out because it's broken for our -# purposes in that it will shift the position of every character on the page, -# not just the cursor line! -# From: Michael Driscoll 10 July 1996 -adm1178|1178|lsi adm1178:\ - :am:\ - :co#80:li#24:sg#1:ug#1:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:cm=\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=\ER:do=^J:ho=^^:ip=6*:kb=^H:kd=^J:kl=^H:\ - :le=^H:md=\E(:me=\E):mr=\EG4:nd=^L:nw=^M^J:pc=\177:se=\EG0:\ - :sf=^J:so=\EG4:ta=^I:ue=\EG0:up=^K:us=\EG1:vs=\EC\E3 \E3(: - -#### Prime -# -# Yes, Prime makes terminals. These entries were posted by Kevin J. Cummings -# on 14 Dec 1992 and lightly edited by esr. -# - -# Standout mode is dim reverse-video. -pt100|pt200|wren|fenix|prime pt100/pt200:\ - :am:bw:mi:ms:\ - :co#80:it#8:li#24:\ - :DC=\E[%dP:DL=\E[M:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:\ - :UP=\E[%dA:al=\E[L\E[t:bt=\E[Z:cd=\E[J\E[r:ce=\E[K\E[t:\ - :cl=\E?:cm=\E0%+|%+|:cr=^M:dc=\E[P:do=\ED:ei=\E[4l:ho=\E$B:\ - :im=\E[4h:kb=^H:kd=\E[B:ke=\E[>13l:kh=\E$A:kl=\E[D:kr=\E[C:\ - :ks=\E[>13h:ku=\E[A:le=^H:me=\E[m:mh=\E[2m:nd=\E[C:nw=^M^J:\ - :se=\E[m:sf=^J:so=\E[2;7m:ta=^I:te=:\ - :ti=\E[>1l\E[>2l\E[>16l\E[4l\E[>9l\E[20l\E[>3l\E[>7h\E[>12l\E[1Q:\ - :ue=\E[m:up=\EM:us=\E[4m:vb=\E$\E$P: -pt100w|pt200w|wrenw|fenixw|prime pt100/pt200 in 132-column mode:\ - :co#132:\ - :cm=\E[%i%d;%dH:tc=pt100: -pt250|Prime PT250:\ - :se@:so@:tc=pt100: -pt250w|Prime PT250 in 132-column mode:\ - :se@:so@:tc=pt100w: - -#### Qume (qvt) -# -# Qume, Inc. -# 3475-A North 1st Street -# San Jose CA 95134 -# Vox: (800)-457-4447 -# Fax: (408)-473-1510 -# Net: josed@techsupp.wyse.com (Jose D'Oliveira) -# -# Qume was bought by Wyse, but still (as of early 1995) has its own support -# group and production division. -# -# Discontinued Qume models: -# -# The qvt101 and qvt102 listed here are long obsolete; so is the qvt101+ -# built to replace them, and a qvt119+ which was a 101+ with available wide -# mode (132 columns). There was a qvt103 which added vt100/vt131 emulations -# and an ANSI-compatible qvt203 that replaced it. Qume started producing -# ANSI-compatible terminals with the qvt323 and qvt61. -# -# Current Qume models (as of February 1995): -# -# All current Qume terminals have ANSI-compatible operation modes. -# Qume is still producing the qvt62, which features emulations for other -# popular lines such as ADDS, and dual-host capabilities. The qvt82 is -# designed for use as a SCO ANSI terminal. The qvt70 is a color terminal -# with many emulations including Wyse370, Wyse 325, etc. Their newest -# model is the qvt520, which is vt420-compatible. -# -# There are some ancient printing Qume terminals under `Daisy Wheel Printers' - -qvt101|qvt108|qume qvt 101 and QVT 108:\ - :sg#1:tc=qvt101+: - -# This used to have :vs=\E.2: but no :ve: or :vi:. The BSD termcap -# file had :vs=\EM4 \200\200\200:. I've done the safe thing and yanked -# both. The :mr: is from BSD, which also claimed bold=\E( and dim=\E). -# What seems to be going on here is that this entry was designed so that -# the normal highlight is bold and standout is dim plus something else -# (reverse-video maybe? But then, are there two :mr: sequences?) -qvt101+|qvt101p|qume qvt 101 PLUS product:\ - :am:bw:hs:ul:\ - :co#80:li#24:sg#0:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:\ - :ct=\E3:dc=\EW:dl=\ER:do=^J:ds=\Eg\Ef\r:ei=:fs=^M:ho=^^:\ - :ic=\EQ:im=:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:\ - :k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:kA=\EE:\ - :kB=\EI:kE=\ET:kI=\EQ:kL=\ER:kS=\EY:kb=^H:kd=^J:kh=^^:kl=^H:\ - :kr=^L:ku=^K:le=^H:mk@:nd=^L:pf=\EA:po=\E@:se=\E(:sf=^J:\ - :so=\E0P\E):st=\E1:ta=^I:ts=\Eg\Ef:up=^K:vb=\Eb\Ed:ve=\E.4:\ - :tc=adm+sgr: -qvt102|qume qvt 102:\ - :ve=\E.:tc=qvt101: -# (qvt103: added / based on init string -- esr) -qvt103|qume qvt 103:\ - :am:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :DO=\E[%dB:LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:\ - :UP=\E[%dA:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:do=^J:\ - :ho=\E[H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:\ - :ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: -qvt103-w|qume qvt103 132 cols:\ - :co#132:li#24:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?8h:tc=qvt103: -qvt119+|qvt119p|qvt119|qume qvt 119 and 119PLUS terminals:\ - :am:hs:mi:ms:\ - :co#80:li#24:sg#0:\ - :al=\EE:bl=^G:bt=\EI:cd=\Ey:ce=\Et:cl=\E*1:cm=\E=%+ %+ :\ - :cr=^M:ct=\E3:dc=\EW:dl=\ER:do=^J:ds=\Eg\Ef\r:ei=\Er:fs=^M:\ - :ho=^^:im=\Eq:is=\EDF\EC\EG0\Er\E(\E%EX:k0=^AI\r:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:\ - :ku=^K:le=^H:nd=^L:pf=\EA:po=\E@:sf=^J:sr=\EJ:st=\E1:ta=^I:\ - :ts=\Eg\Ef:up=^K:us=\EG8:vb=\En0\En1:ve=\E.4:vs=\E.2:\ - :tc=adm+sgr: -qvt119+-25|qvt119p-25|QVT 119 PLUS with 25 data lines:\ - :li#25:tc=qvt119+: -qvt119+-w|qvt119p-w|qvt119-w|QVT 119 and 119 PLUS in 132 column mode:\ - :co#132:\ - :is=\EDF\EC\EG0\Er\E(\E%\EX\En4:tc=qvt119+: -qvt119+-25-w|qvt119p-25-w|qvt119-25-w|QVT 119 and 119 PLUS 132 by 25:\ - :li#25:tc=qvt119+: -qvt203|qvt203+|qume qvt 203 Plus:\ - :al=\E[L:dc=\E[P:dl=\E[M:ei=\E[4l:im=\E[4h:ip=:k0=\E[29~:\ - :k1=\E[17~:k2=\E[18~:k3=\E[19~:k4=\E[20~:k5=\E[21~:\ - :k6=\E[23~:k7=\E[24~:k8=\E[25~:k9=\E[28~:sf=\n:\ - :tc=qvt103: -qvt203-w|qvt203-w-am|qume qvt 203 PLUS in 132 cols (w/advanced video):\ - :co#132:li#24:\ - :r2=\E>\E[?3h\E[?4l\E[?5l\E[?8h:tc=qvt203: -# -# Since a command is present for enabling 25 data lines, -# a specific terminfo entry may be generated for the 203. -# If one is desired for the QVT 119 PLUS then 25 lines must -# be selected in the status line (setup line 9). -# -qvt203-25|QVT 203 PLUS with 25 by 80 column mode:\ - :co#80:li#25:\ - :is=\E[=40h\E[?3l:tc=qvt203: -qvt203-25-w|QVT 203 PLUS with 25 by 132 columns:\ - :co#132:li#25:\ - :r2=\E[?3h\E[=40h:tc=qvt203: - -#### Televideo (tvi) -# -# TeleVideo -# 550 East Brokaw Road -# PO Box 49048 95161 -# San Jose CA 95112 -# Vox: (408)-954-8333 -# Fax: (408)-954-0623 -# -# -# There are some tvi terminals that require incredible amounts of padding and -# some that don't. I'm assuming tvi912 and tvi920 are the old slow ones, and -# tvi912b, tvi912c, tvi920b, tvi920c are the new ones that don't need padding. -# -# All of these terminals (912 to 970 and the tvipt) are discontinued. Newer -# Televideo terminals are ANSI and PC-ANSI compatible. - -tvi803|televideo 803:\ - :cl=\E*:tc=tvi950: - -# Vanilla tvi910 -- W. Gish 10/29/86 -# Switch settings are: -# -# S1 1 2 3 4 -# D D D D 9600 -# D D D U 50 -# D D U D 75 -# D D U U 110 -# D U D D 135 -# D U D U 150 -# D U U D 300 -# D U U U 600 -# U D D D 1200 -# U D D U 1800 -# U D U D 2400 -# U D U U 3600 -# U U D D 4800 -# U U D U 7200 -# U U U D 9600 -# U U U U 19200 -# -# S1 5 6 7 8 -# U D X D 7N1 (data bits, parity, stop bits) (X means ignored) -# U D X U 7N2 -# U U D D 7O1 -# U U D U 7O2 -# U U U D 7E1 -# U U U U 7E2 -# D D X D 8N1 -# D D X U 8N2 -# D U D D 8O1 -# D U U U 8E2 -# -# S1 9 Autowrap -# U on -# D off -# -# S1 10 CR/LF -# U do CR/LF when CR received -# D do CR when CR received -# -# S2 1 Mode -# U block -# D conversational -# -# S2 2 Duplex -# U half -# D full -# -# S2 3 Hertz -# U 50 -# D 60 -# -# S2 4 Edit mode -# U local -# D duplex -# -# S2 5 Cursor type -# U underline -# D block -# -# S2 6 Cursor down key -# U send ^J -# D send ^V -# -# S2 7 Screen colour -# U green on black -# D black on green -# -# S2 8 DSR status (pin 6) -# U disconnected -# D connected -# -# S2 9 DCD status (pin 8) -# U disconnected -# D duplex -# -# S2 10 DTR status (pin 20) -# U disconnected -# D duplex -# (tvi910: removed obsolete ":ma=^Kk^Ll^R^L:"; added :kh:, :le:, :do:, -# :sf:, , , :am:, :ms: from SCO entry -- esr) -tvi910|televideo model 910:\ - :am:bs:ms:\ - :co#80:it#8:li#24:sg#1:\ - :bl=^G:bt=\EI:cd=\EY:ce=\ET:ch=\E]%+ :cl=^Z:cm=\E=%+ %+ :\ - :cr=^M:cv=\E[%+ :do=^J:ho=\E=\001\001:\ - :if=/usr/share/tabset/stdcrt:k0=^AI\r:k1=^A@\r:k2=^AA\r:\ - :k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:\ - :k9=^AH\r:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:mk@:nd=^L:\ - :sf=^J:ta=^I:up=^K:\ - :tc=adm+sgr: -# From: Alan R. Rogers -# as subsequently hacked over by someone at SCO -# (tvi910+: removed obsolete ":ma=^K^P^L :" -- esr) -# -# Here are the 910+'s DIP switches (U = up, D = down, X = don't care): -# -# S1 1 2 3 4: -# D D D D 9600 D D D U 50 D D U D 75 D D U U 110 -# D U D D 135 D U D U 150 D U U D 300 D U U U 600 -# U D D D 1200 U D D U 1800 U D U D 2400 U D U U 3600 -# U U D D 4800 U U D U 7200 U U U D 9600 U U U U 19200 -# -# S1 5 6 7 8: -# U D X D 7N1 U D X U 7N2 U U D D 7O1 U U D U 7O2 -# U U U D 7E1 U U U U 7E2 D D X D 8N1 D D X U 8N2 -# D U D D 8O1 D U U U 8E2 -# -# S1 9 Autowrap (U = on, D = off) -# S1 10 CR/LF (U = CR/LF on CR received, D = CR on CR received) -# S2 1 Mode (U = block, D = conversational) -# S2 2 Duplex (U = half, D = full) -# S2 3 Hertz (U = 50, D = 60) -# S2 4 Edit mode (U = local, D = duplex) -# S2 5 Cursor type (U = underline, D = block) -# S2 6 Cursor down key (U = send ^J, D = send ^V) -# S2 7 Screen colour (U = green on black, D = black on green) -# S2 8 DSR status (pin 6) (U = disconnected, D = connected) -# S2 9 DCD status (pin 8) (U = disconnected, D = connected) -# S2 10 DTR status (pin 20) (U = disconnected, D = connected) -# -tvi910+|televideo 910+:\ - :al=\EE:dc=\EW:dl=\ER:ei=:ho=^^:ic=\EQ:im=:k0=^A@\r:k1=^AA\r:\ - :k2=^AB\r:k3=^AC\r:k4=^AD\r:k5=^AE\r:k6=^AF\r:k7=^AG\r:\ - :k8=^AH\r:k9=^AI\r:ll=\E=7 :\ - :tc=tvi910: - -# (tvi912: removed obsolete ":ma=^K^P^L :", added :vb: and -# :kh: from BRL entry -- esr) -tvi912|tvi914|tvi920|old televideo 912/914/920:\ - :am:bs:ms:pt:\ - :co#80:it#8:li#24:sg#1:ug#1:\ - :al=\EE:bl=^G:cd=\Ey:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:ct=\E3:\ - :dc=\EW:dl=\ER:do=^J:ei=:ho=^^:ic=\EQ:\ - :if=/usr/share/tabset/stdcrt:im=:k0=^AI\r:k1=^A@\r:\ - :k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:\ - :k8=^AG\r:k9=^AH\r:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:\ - :nd=^L:se=\Ek:sf=^J:so=\Ej:st=\E1:ta=^I:ue=\Em:up=^K:us=\El:\ - :vb=\Eb\Ed: -# the 912 has a key that's like shift: 8 xmits "^A8\r". -# The 920 has this plus real function keys that xmit different things. -# Terminfo makes you use the funct key on the 912 but the real keys on the 920. -tvi912c|tvi912b|new televideo 912:\ - :al=\EE:dl=\ER:tc=tvi912: -# set to page 1 when entering curses application (\E-17 ) -# reset to page 0 when exiting curses application (\E-07 ) -tvi912-2p|tvi920-2p|tvi-2p|televideo w/2 pages:\ - :te=\E-07 :ti=\E-17 :tc=tvi912: -# We got some new tvi912c terminals that act really weird on the regular -# termcap, so one of our gurus worked this up. Seems that cursor -# addressing is broken. -tvi912cc|tvi912 at cowell college:\ - :cm@:tc=tvi912c: - -# Here are the switch settings for the tvi920c: -# -# S1 (Line), and S3 (Printer) baud rates -- put one, and only one, switch down: -# 2: 9600 3: 4800 4: 2400 5: 1200 -# 6: 600 7: 300 8: 150 9: 75 -# 10: 110 -# -# S2 UART/Terminal options: -# Up Down -# 1: Not used Not allowed -# 2: Alternate character set Standard character set -# 3: Full duplex Half duplex -# 4: 50 Hz refresh 60 Hz refresh -# 5: No parity Send parity -# 6: 2 stop bits 1 stop bit -# 7: 8 data bits 7 data bits -# 8: Not used Not allowed on Rev E or lower -# 9: Even parity Odd parity -# 10: Steady cursor Blinking cursor -# (On Rev E or lower, use W25 instead of switch 10.) -# -# S5 UART/Terminal options: -# Open Closed -# 1: P3-6 Not connected DSR received on P3-6 -# 2: P3-8 Not connected DCD received on P3-8 -# -# 3 Open, 4 Open: P3-20 Not connected -# 3 Open, 4 Closed: DTR on when terminal is on -# 3 Closed, 4 Open: DTR is connected to RTS -# 3 Closed, 4 Closed: Not allowed -# -# 5 Closed: HDX printer (hardware control) Rev. K with extension port off, -# all data transmitted out of the modem port (P3) will also be -# transmitted out of the printer port (P4). -# -# 6 Open, 7 Open: Not allowed -# 6 Open, 7 Closed: 20ma current loop input -# 6 Closed, 7 Open: RS232 input -# 6 Closed, 7 Closed: Not allowed -# -# Jumper options: -# If the jumper is installed, the effect will occur (the next time the terminal -# is switched on). -# -# S4/W31: Enables automatic LF upon receipt of CR from -# remote or keyboard. -# S4/W32: Enables transmission of EOT at the end of Send. If not -# installed, a carriage return is sent. -# S4/W33: Disables automatic carriage return in column 80. -# S4/W34: Selects Page Print Mode as initial condition. If not -# installed, Extension Mode is selected. -# -tvi920b|tvi920c|new televideo 920:\ - :al=\EE:dl=\ER:k0=^AI\r:k1=^A@\r:k2=^AA\r:k3=^AB\r:\ - :k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:\ - :tc=tvi912: - -# Televideo 921 and variants -# From: Tim Theisen 22 Sept 1995 -# (tvi921: removed :ko=bt: before translation, I see no backtab cap; -# also added empty to suppress tic warning -- esr) -tvi921|televideo model 921 with sysline same as page & real vi function:\ - :am:bs:hs:pt:xn:xs:\ - :co#80:li#24:sg#0:\ - :ac=:ae=\E%:al=\EE:as=\E$:cd=\EY:ce=\ET:cl=^Z:cm=3\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=1*\ER:do=^V:ds=\Ef\r\Eg:ei=:fs=\Eg:ho=^^:\ - :ic=\EQ:if=/usr/share/tabset/stdcrt:im=:\ - :is=\El\E"\EF1\E.3\017\EA\E<:kA=\EE:kC=^Z:kD=\EW:kE=\ET:\ - :kI=\EQ:kL=1*\ER:kS=\EY:kb=^H:kd=^V:kl=^H:kr=^L:ku=^K:le=^H:\ - :mk@:nd=^L:nw=^M^J:sf=^J:ta=^I:ts=\Ef\EG0:up=^K:ve=\E.3:\ - :vs=\E.2:\ - :tc=adm+sgr: -# without the beeper -# (tvi92B: removed :ko=bt: before translation, I see no backtab cap; -# also added empty to suppress tic warning -- esr) -tvi92B|televideo model 921 with sysline same as page & real vi function:\ - :am:hs:xn:xs:\ - :co#80:li#24:sg#0:\ - :ac=:ae=\E%:al=\EE:as=\E$:cd=\EY:ce=\ET:cl=^Z:cm=3\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=1*\ER:do=^V:ds=\Ef\r\Eg:ei=:fs=\Eg:ho=^^:\ - :ic=\EQ:if=/usr/share/tabset/stdcrt:im=:\ - :is=\El\E"\EF1\E.3\017\EA\E<:kA=\EE:kC=^Z:kD=\EW:kE=\ET:\ - :kI=\EQ:kL=1*\ER:kS=\EY:kb=^H:kd=^V:kl=^H:kr=^L:ku=^K:le=^H:\ - :mk@:nd=^L:nw=^M^J:sf=^J:ta=^I:ts=\Ef\EG0:up=^K:vb=\Eb\Ed:\ - :ve=\E.3:vs=\E.2:\ - :tc=adm+sgr: -# (tvi92D: removed :ko=bt: before translation, I see no backtab cap -- esr) -tvi92D|tvi92B with DTR instead of XON/XOFF & better padding:\ - :al=2*\EE:dl=2*\ER:is=\El\E"\EF1\E.3\016\EA\E<:kA=2*\EE:\ - :kL=2*\ER:\ - :tc=tvi92B: - -# (tvi924: This used to have :ds=\Es0:, :fs=\031:. I put the new strings -# in from a BSD termcap file because it looks like they do something the -# old ones skip -- esr) -tvi924|televideo tvi924:\ - :am:bw:hs:in:mi:ms:xn:xo:\ - :co#80:it#8:li#24:sg#0:ws#80:\ - :F1=^AK\r:F2=^AL\r:F3=^AM\r:F4=^AN\r:F5=^AO\r:al=\EE:bl=^G:\ - :bt=\EI:cd=\Ey:ce=\Et:cl=\E*0:cm=\E=%+ %+ :cr=^M:\ - :cs=\E_%+ %+ :ct=\E3:dc=\EW:dl=\ER:do=^V:ds=\Es0\Ef\031:\ - :ei=:fs=\031\Es1:ho=^^:\ - :i1=\017\E%\E'\E(\EDF\EC\EG0\EN0\Es0\Ev0:ic=\EQ:\ - :if=/usr/share/tabset/stdcrt:im=:k0=^A@\r:k1=^AA\r:\ - :k2=^AB\r:k3=^AC\r:k4=^AD\r:k5=^AE\r:k6=^AF\r:k7=^AG\r:\ - :k8=^AH\r:k9=^AI\r:k;=^AJ\r:kA=\EE:kC=\E*0:kD=\EW:kE=\Et:\ - :kI=\EQ:kL=\ER:kS=\Ey:kb=^H:kd=^V:kh=^^:kl=^H:kr=^L:ku=^K:\ - :l0=F1:l1=F2:l2=F3:l3=F4:l4=F5:l5=F6:l6=F7:l7=F8:l8=F9:l9=F10:\ - :la=F11:le=^H:mb=\EG2:mk@:nd=^L:pk=\E|%+1%s\031:sf=^J:\ - :sr=\Ej:st=\E1:ta=^I:ts=\Ef:up=^K:vb=\Eb\Ed:ve=\E.3:vi=\E.0:\ - :vs=\E.1:\ - :tc=adm+sgr: - -# TVI925 DIP switches. In each of these, D = Down and U = Up, -# -# Here are the settings for the external (baud) switches (S1): -# -# Position Baud -# 7 8 9 10 [Printer] -# 1 2 3 4 [Main RS232] -# ----------------------------------------------------- -# D D D D 9600 -# D D D U 50 -# D D U D 75 -# D D U U 110 -# D U D D 135 -# D U D U 150 -# D U U D 300 -# D U U U 600 -# U D D D 1200 -# U D D U 1800 -# U D U D 2400 -# U D U U 3600 -# U U D D 4800 -# U U D U 7200 -# U U U D 9600 -# U U U U 19200 -# -# -# Settings for word length and stop-bits (S1) -# -# Position Description -# 5 6 -# --------------------------- -# U - 7-bit word -# D - 8-bit word -# - U 2 stop bits -# - D 1 stop bit -# -# -# S2 (external) settings -# -# Position Up Dn Description -# -------------------------------------------- -# 1 X Local edit -# X Duplex edit (transmit editing keys) -# -------------------------------------------- -# 2 X 912/920 emulation -# X 925 -# -------------------------------------------- -# 3 X -# 4 X No parity -# 5 X -# -------------------------------------------- -# 3 X -# 4 X Odd parity -# 5 X -# -------------------------------------------- -# 3 X -# 4 X Even parity -# 5 X -# -------------------------------------------- -# 3 X -# 4 X Mark parity -# 5 X -# -------------------------------------------- -# 3 X -# 4 X Space parity -# 5 X -# -------------------------------------------- -# 6 X White on black display -# X Black on white display -# -------------------------------------------- -# 7 X Half Duplex -# 8 X -# -------------------------------------------- -# 7 X Full Duplex -# 8 X -# -------------------------------------------- -# 7 X Block mode -# 8 X -# -------------------------------------------- -# 9 X 50 Hz -# X 60 Hz -# -------------------------------------------- -# 10 X CR/LF (Auto LF) -# X CR only -# -# S3 (internal switch) settings: -# -# Position Up Dn Description -# -------------------------------------------- -# 1 X Keyclick off -# X Keyclick on -# -------------------------------------------- -# 2 X English -# 3 X -# -------------------------------------------- -# 2 X German -# 3 X -# -------------------------------------------- -# 2 X French -# 3 X -# -------------------------------------------- -# 2 X Spanish -# 3 X -# -------------------------------------------- -# 4 X Blinking block cursor -# 5 X -# -------------------------------------------- -# 4 X Blinking underline cursor -# 5 X -# -------------------------------------------- -# 4 X Steady block cursor -# 5 X -# -------------------------------------------- -# 4 X Steady underline cursor -# 5 X -# -------------------------------------------- -# 6 X Screen blanking timer (ON) -# X Screen blanking timer (OFF) -# -------------------------------------------- -# 7 X Page attributes -# X Line attributes -# -------------------------------------------- -# 8 X DCD disconnected -# X DCD connected -# -------------------------------------------- -# 9 X DSR disconnected -# X DSR connected -# -------------------------------------------- -# 10 X DTR Disconnected -# X DTR connected -# -------------------------------------------- -# -# (tvi925: BSD has :cl=\E*:. I got :is: and :sr: from there -- esr) -tvi925|televideo 925:\ - :am:bs:bw:hs:ul:\ - :co#80:li#24:sg#1:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:\ - :ct=\E3:dc=\EW:dl=\ER:do=^V:ds=\Eh:ei=:fs=^M\Eg:ho=^^:ic=\EQ:\ - :im=:is=\El\E":k0=^AI\r:k1=^A@\r:k2=^AA\r:k3=^AB\r:\ - :k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:\ - :kA=\EE:kC=^Z:kD=\EW:kE=\ET:kI=\EQ:kL=\ER:kS=\EY:kb=^H:kd=^V:\ - :kh=^^:kl=^H:kr=^L:ku=^K:le=^H:mk@:nd=^L:sf=^J:sr=\Ej:st=\E1:\ - :ta=^I:ts=\Eh\Ef:up=^K:vb=\Eb\Ed:ve=\E.4:vs=\E.2:\ - :tc=adm+sgr: -# TeleVideo 925 from Mitch Bradley via BRL -# to avoid "magic cookie" standout glitch: -tvi925-hi|TeleVideo Model 925 with half intensity standout mode:\ - :sg@:\ - :kb=^H:kd=^J:kl=^H:se=\E(:so=\E):tc=tvi925: - -# From: Todd Litwin 28 May 1993 -# Originally Tim Curry, Univ. of Central Fla., 5/21/82 -# for additional capabilities, -# The following tvi descriptions from B:pjphar and virus!mike -# is for all 950s. It sets the following attributes: -# full duplex (\EDF) write protect off (\E() -# conversation mode (\EC) graphics mode off (\E%) -# white on black (\Ed) auto page flip off (\Ew) -# turn off status line (\Eg) clear status line (\Ef\r) -# normal video (\E0) monitor mode off (\EX or \Eu) -# edit mode (\Er) load blank char to space (\Ee\040) -# line edit mode (\EO) enable buffer control (^O) -# protect mode off (\E\047) duplex edit keys (\El) -# program unshifted send key to send line all (\E016) -# program shifted send key to send line unprotected (\E004) -# set the following to nulls: -# field delimiter (\Ex0\200\200) -# line delimiter (\Ex1\200\200) -# start-protected field delimiter (\Ex2\200\200) -# end-protected field delimiter (\Ex3\200\200) -# set end of text delimiter to carriage return/null (\Ex4\r\200) -# -# TVI 950 Switch Setting Reference Charts -# -# TABLE 1: -# -# S1 1 2 3 4 5 6 7 8 9 10 -# +-----------------------+-----+-----+-----------------------+ -# | Computer Baud Rate |Data |Stop | Printer Baud Rate | -# | |Bits |Bits | | -# +------+-----------------------+-----+-----+-----------------------+ -# | Up | See | 7 | 2 | See | -# +------+-----------------------+-----+-----+-----------------------+ -# | Down | TABLE 2 | 8 | 1 | TABLE 2 | -# +------+-----------------------+-----+-----+-----------------------+ -# -# -# S2 1 2 3 4 5 6 7 8 9 10 -# +-----+-----+-----------------+-----+-----------+-----+-----+ -# |Edit |Cursr| Parity |Video|Transmiss'n| Hz |Click| -# +------+-----+-----+-----------------+-----+-----------+-----+-----+ -# | Up | Dplx|Blink| See |GonBk| See | 60 | Off | -# +------+-----+-----+-----------------+-----+-----------+-----+-----+ -# | Down |Local|St'dy| TABLE 3 |BkonG| CHART | 50 | On | -# +------+-----+-----+-----------------+-----+-----------+-----+-----+ -# -# TABLE 2: -# -# +-----------+-----+-----+-----+-----+-----------+ -# | Display | 1 | 2 | 3 | 4 | Baud | -# +-----------+-----+-----+-----+-----+ | -# | Printer | 7 | 8 | 9 | 10 | Rate | -# +-----------+-----+-----+-----+-----+-----------+ -# | D | D | D | D | 9600 | -# | U | D | D | D | 50 | -# | D | U | D | D | 75 | -# | U | U | D | D | 110 | -# | D | D | U | D | 135 | -# | U | D | U | D | 150 | -# | D | U | U | D | 300 | -# | U | U | U | D | 600 | -# | D | D | D | U | 1200 | -# | U | D | D | U | 1800 | -# | D | U | D | U | 2400 | -# | U | U | D | U | 3600 | -# | D | D | U | U | 4800 | -# | U | D | U | U | 7200 | -# | D | U | U | U | 9600 | -# | U | U | U | U | 19200 | -# +-----+-----+-----+-----+-----------+ -# -# TABLE 3: -# +-----+-----+-----+-----------+ -# | 3 | 4 | 5 | Parity | -# +-----+-----+-----+-----------+ -# | X | X | D | None | -# | D | D | U | Odd | -# | D | U | U | Even | -# | U | D | U | Mark | -# | U | U | U | Space | -# +-----+-----+-----+-----------+ -# X = don't care -# -# CHART: -# +-----+-----+-----------------+ -# | 7 | 8 | Communication | -# +-----+-----+-----------------+ -# | D | D | Half Duplex | -# | D | U | Full Duplex | -# | U | D | Block | -# | U | U | Local | -# +-----+-----+-----------------+ -# -# (tvi950: early versions had obsolete ":ma=^Vj^Kk^Hh^Ll^^H:". -# I also inserted :ic: and :kI:; the :ko: string indicated that :IC: -# should be present and all tvi native modes use the same string for this. -# Finally, note that BSD has cud1=^V. -- esr) -tvi950|televideo 950:\ - :am:bs:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:sg#1:\ - :ac=d\rc\014e\nb\011i\013:ae=^X:al=\EE:as=^U:bl=^G:bt=\EI:\ - :cd=\Ey:ce=\Et:cl=\E*:cm=\E=%+ %+ :cr=^M:ct=\E3:dc=\EW:\ - :dl=\ER:do=^J:ds=\Eg\Ef\r:ei=\Er:fs=^M:ho=^^:ic=\EQ:im=\Eq:\ - :is=\EDF\EC\Ed\EG0\Eg\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\El\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200\Ef\r:\ - :k0=^A0\r:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:\ - :k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:kA=\EE:kB=\EI:kC=\E*:\ - :kD=\EW:kE=\Et:kI=\EQ:kL=\ER:kS=\Ey:kb=^H:kd=^V:kh=^^:kl=^H:\ - :kr=^L:ku=^K:le=^H:mk@:nd=^L:pf=\Ea:po=\E`:sf=^J:sr=\Ej:\ - :st=\E1:ta=^I:ts=\Eg\Ef:up=^K:vb=\Eb\Ed:\ - :tc=adm+sgr: -# -# is for 950 with two pages adds the following: -# set 48 line page (\E\\2) -# place cursor at page 0, line 24, column 1 (\E-07 ) -# set local (no send) edit keys (\Ek) -# -# two page 950 adds the following: -# when entering ex, set 24 line page (\E\\1) -# when exiting ex, reset 48 line page (\E\\2) -# place cursor at 0,24,1 (\E-07 ) -# set duplex (send) edit keys (\El) when entering vi -# set local (no send) edit keys (\Ek) when exiting vi -# -tvi950-2p|televideo950 w/2 pages:\ - :is=\EDF\EC\Ed\EG0\Eg\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\Ek\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200\E\2\E-07 \011:\ - :ke=\Ek:ks=\El:te=\E\2\E-07 :ti=\E\1\E-07 :\ - :tc=tvi950: -# -# is for 950 with four pages adds the following: -# set 96 line page (\E\\3) -# place cursor at page 0, line 24, column 1 (\E-07 ) -# -# four page 950 adds the following: -# when entering ex, set 24 line page (\E\\1) -# when exiting ex, reset 96 line page (\E\\3) -# place cursor at 0,24,1 (\E-07 ) -# -tvi950-4p|televideo950 w/4 pages:\ - :is=\EDF\EC\Ed\EG0\Eg\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\Ek\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200\E\3\E-07 \011:\ - :ke=\Ek:ks=\El:te=\E\3\E-07 :ti=\E\1\E-07 :\ - :tc=tvi950: -# -# :is: for reverse video 950 changes the following: -# set reverse video (\Ed) -# -# set vb accordingly (\Ed ...delay... \Eb) -# -tvi950-rv|televideo950 rev video:\ - :is=\EDF\EC\Eb\EG0\Eg\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\El\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200:\ - :vb=\Ed\Eb:\ - :tc=tvi950: - -# tvi950-rv-2p uses the appropriate entries from 950-2p and 950-rv -tvi950-rv-2p|televideo950 rev video w/2 pages:\ - :is=\EDF\EC\Eb\EG0\Eg\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\Ek\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200\E\2\E-07 :\ - :ke=\Ek:ks=\El:te=\E\2\E-07 :ti=\E\1\E-07 :vb=\Ed\Eb:\ - :tc=tvi950: - -# tvi950-rv uses the appropriate entries from 950-4p and 950-rv -tvi950-rv-4p|televideo950 rev video w/4 pages:\ - :is=\EDF\EC\Eb\EG0\Er\EO\E'\E(\E%\Ew\EX\Ee \017\011\Ek\E016\E004\Ex0\200\200\Ex1\200\200\Ex2\200\200\011\Ex3\200\200\Ex4\r\200\E\3\E-07 :\ - :ke=\Ek:ks=\El:te=\E\3\E-07 :ti=\E\1\E-07 :vb=\Ed\Eb:\ - :tc=tvi950: -# From: Andreas Stolcke -# (tvi955: removed obsolete ":ma:=^Vj^Kk^Hh^Ll^^H"; -# removed incorrect (and overridden) ":do=^J:"; fixed broken continuations in -# the :rs: string, inserted the :IC: implied by the termcap :ko: string. Note -# the :ko: string had :cl: in it, which means that one of the original -# :cl=\E*:, had to be wrong; set because that's what -# the 950 has. Finally, corrected the string to match the 950 and what -# ko implies -- esr) -# If the BSD termcap file was right, :cm=\E=%p1%{32}%+%c%p2%{32}%+%c: would -# also work. -tvi955|televideo 955:\ - :5i:bs:ms@:\ - :it#8:sg@:\ - :RA=\E[=7l:RX=^N:SA=\E[=7h:SX=^O:\ - :ac=0_`RjHkGlFmEnIoPqKsQtMuLvOwNxJ:ae=\E%:as=\E$:\ - :cm=\E[%i%d;%dH:do=^V:is=\E[=3l\EF1\Ed\EG0\E[=5l\E%\El:\ - :kM=\EQ:kN=\EK:kP=\EJ:kT=\E1:ka=\E3:kt=\E2:mb=\EG2:\ - :me=\EG0\E[=5l:mh=\E[=5h:mk=\EG1:ps=\EP:\ - :r1=\EDF\EC\Eg\Er\EO\E'\E(\Ew\EX\Ee \017\E0P\E6\200\E0p\E4\200\Ef\r:\ - :sf@:ve=\E.2:vi=\E.0:vs=\E.1:\ - :tc=tvi950: -tvi955-w|955-w|televideo955 w/132 cols:\ - :co#132:\ - :is=\E[=3h\EF1\Ed\EG0\E[=5l\E%\El:tc=tvi955: -# use half-intensity as normal mode, full intensity as :md: -tvi955-hb|955-hb|televideo955 half-bright:\ - :is=\E[=3l\EF1\Ed\EG0\E[=5h\E%\El:md=\E[=5l:\ - :me=\EG0\E[=5h:mh@:tc=tvi955: -# From: Humberto Appleton , 880521 UT Austin -# (tvi970: removed ":sg#0:"; removed :se:=\E[m, :ue:=\E[m; -# added :am:/:cs:/:ho:///:ti:/:te: from BRL. -# According to BRL we could have :ke:=\E>, :ks:=\E= but I'm not sure what -# it does to the function keys. I deduced /. -# also added empty to suppress tic warning, -- esr) -tvi970|televideo 970:\ - :am:bs:da:db:mi:ms:pt:\ - :co#80:it#8:li#24:\ - :RA=\E[?7h:SA=\E[?7l:ac=:ae=\E(B:al=\E[L:as=\E(B:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:ch=\E[%i%dG:cl=\E[H\E[2J:cm=\E[%i%d;%df:\ - :cs=\E[%i%d;%dr:cv=\E[%i%dd:dc=\E[P:dl=\E[M:do=\ED:\ - :ds=\Eg\Ef\r:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E<\E[?21l\E[19h\E[1Q\E[10l\E[7l\E[H\E[2J:k1=\E?a:\ - :k2=\E?b:k3=\E?c:k4=\E?d:k5=\E?e:k6=\E?f:k7=\E?g:k8=\E?h:\ - :k9=\E?i:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:me=\E[m:nd=\E[C:se=\E[m:so=\E[7m:sr=\EM:ta=^I:te=:\ - :ti=\E[?20l\E[?7h\E[1Q:ue=\E[m:up=\EM:us=\E[4m:\ - :vb=\E[5m\E[m:vs=\E[1Q: -tvi970-vb|televideo 970 with visual bell:\ - :vb=\E[?5h\200\200\200\200\200\200\200\200\200\200\200\200\200\E[?5l:tc=tvi970: -tvi970-2p|televideo 970 with using 2 pages of memory:\ - :te=\E[H\E[J\E[V:ti=\E[U\E[?20l\E[?7h\E[1Q:\ - :tc=tvi970: -# Works with vi and rogue. NOTE: Esc v sets autowrap on, Esc u sets 80 chars -# per line (rather than 40), Esc K chooses the normal character set. Not sure -# padding is needed, but adapted from the tvi920c termcap. The :so: and -# :us: strings are klutzy, but at least use no screen space. -# (tvipt: removed obsolete ":ma=^Kk^Ll^R^L:". I wish we knew , -# its absence means =\Ev isn't save to use. -- esr) -# From: Gene Rochlin 9/19/84. -# The :cd:/:k0:/:k1:/:kh:/, and caps are from BRL, which says: -# F1 and F2 should be programmed as ^A and ^B; required for UNIFY. -tvipt|televideo personal terminal:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EE:bt=\EI:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :dl=\ER:\ - :ho=^^:if=/usr/share/tabset/stdcrt:is=\Ev\Eu\EK:k0=^A:\ - :k1=^B:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:pf=^T:\ - :po=^R:se=\EF:so=\EG1@A\EH:ue=\EF:up=^K:us=\EG1B@\EH: -# From: Nathan Peterson , 03 Sep 1996 -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -tvi9065|televideo 9065:\ - :am:bw:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#25:lm#0:ma#4:vt#0:ws#30:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ae=\E%:\ - :al=\EE:as=\E$:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=^Z:\ - :cm=\E=%+ %+ :cr=^M:cs=\E[%i%d;%dr:ct=\E3:dc=\EW:dl=\ER:\ - :dm=\Er:do=^V:ds=\E_30\r:ec=\E[%d@:ed=\200:ei=\Er:fs=^M:\ - :ho=^^:\ - :i1=\E"\E%\E'\E(\EG@\EO\EX\E[=5l\E[=6l\E[=7h\Ed\Er:\ - :i2=\E<\E[=4l\E[=8h:if=/usr/share/tabset/stdcrt:im=\Eq:\ - :ip=:is=\EF2\EG0\E\\L:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:kD=\EW:kb=^H:\ - :kd=^V:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:ll=\E[25;1H:mb=\EG2:\ - :md=\EG\054:me=\EG0:mh=\EGp:mr=\EG4:nd=^L:nw=^M^J:\ - :rp=\E[%r%db%.:se=\EG0:sf=^J:so=\EGt:sr=\Ej:st=\E1:ta=^I:\ - :te=\E.3\Er\E[1;25r\E[25;0H:ti=\E.2:ts=\E[4;1v\E_30:\ - :uc=\EG8\EG0:ue=\EG0:up=^K:us=\EG8:vb=\Eb\Ed:ve=\E.3:\ - :vi=\E.0:vs=\E.2: - -#### Visual (vi) -# -# In September 1993, Visual Technology of Westboro, Massachusetts, -# merged with White Pine Software of Nashua, New Hampshire. -# -# White Pine Software may be contacted at +1 603/886-9050. -# Or visit White Pine on the World Wide Web at URL http://www.wpine.com. -# - -# Visual 50 from Beau Shekita, BTL-Whippany -# Recently I hacked together the following termcap for Visual -# Technology's Visual 50 terminal. It's a slight modification of -# the vt52 termcap. -# It's intended to run when the Visual 50 is in vt52 emulation mode -# (I know what you're thinking; if it's emulating a vt52, then why -# another termcap? Well, it turns out that the Visual 50 can handle -# :dl: and db(?) among other things, which the vt52 can't) -# The termcap works OK for the most part. The only problem is on -# character inserts. The whole line gets painfully redrawn for each -# character typed. Any suggestions? -# Beau's entry is combined with the vi50 entry from University of Wisconsin. -# Note especially the :al: function. :k4:-:k6: are really l4-l6 in -# disguise; :k7:-:k9: are really l1-l3. -vi50|visual 50:\ - :am:bs:da:db:ms:pt:\ - :co#80:it#8:li#24:\ - :al=\EL:bl=^G:bt=4\Ez:cd=\EJ:ce=16\EK:cl=\EH\EJ:\ - :cm=\EY%+ %+ :cr=^M:dl=3*\EM:do=\EB:ho=\EH:k1=\EP:k2=\EQ:\ - :k3=\ER:k4=\EV:k5=\EE:k6=\E]:k7=\EL:k8=\Ev:k9=\EM:kb=^H:\ - :kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:nl=^J:\ - :nw=^M^J:se=\ET:sf=^J:so=\EU:sr=\EI:ta=^I:ue=\EW:up=\EA:\ - :us=\ES: -# this one was BSD & SCO's vi50 -vi50adm|visual 50 in adm3a mode:\ - :am:ms:\ - :co#80:it#8:li#24:\ - :al=\EL:bl=^G:cd=\Ek:ce=\EK:cl=^Z:cm=\E=%+ %+ :cr=^M:dl=\EM:\ - :do=^J:ho=\EH:kb=^H:kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:\ - :nd=^L:se=\ET:sf=^J:so=\EU:ta=^I:up=^K: -# From: Jeff Siegal -vi55|Visual 55:\ - :am:bs:mi:ms:\ - :co#80:it#8:li#24:\ - :al=\EL:cd=\EJ:ce=\EK:cl=\Ev:cm=\EY%+ %+ :cs=\E_%+A%+A:\ - :dc=\Ew:dl=\EM:do=^J:ei=\Eb:ho=\EH:im=\Ea:\ - :is=\Ev\E_AX\Eb\EW\E9P\ET:kb=^H:kd=\EB:kl=\ED:kr=\EC:\ - :ku=\EA:le=^H:nd=\EC:se=\ET:so=\EU:sr=\EI:ta=^I:up=\EA: - -# Visual 200 from BRL -# The following switch settings are assumed for normal operation: -# FULL_DUPLEX SCROLL CR -# AUTO_NEW_LINE_ON VISUAL_200_EMULATION_MODE -# Other switches may be set for operator convenience or communication -# requirements. -# Character insertion is kludged in order to get around the "beep" misfeature. -# (This cap is commented out because :im:/:ei: is more efficient -- esr) -# Supposedly "4*" delays should be used for :al:, :cd:, :cl:, :dc:, -# and :dl: strings, but we seem to get along fine without them. -vi200|visual 200:\ - :am:bs:mi:ms:pt:\ - :co#80:it#8:kn#10:li#24:\ - :ac=:ae=\EG:al=\EL:as=\EF:bl=^G:bt=\Ez:cd=\Ey:ce=\Ex:cl=\Ev:\ - :cm=\EY%+ %+ :cr=^M:ct=\Eg:dc=\EO:dl=\EM:do=^J:ho=\EH:\ - :k0=\E?p:k1=\E?q:k2=\E?r:k3=\E?s:k4=\E?t:k5=\E?u:k6=\E?v:\ - :k7=\E?w:k8=\E?x:k9=\E?y:kA=\EL:kC=\Ev:kD=\EO:kE=\Et:kI=\Ei:\ - :kL=\EM:kM=\Ej:kS=\EJ:kT=\E1:kb=^H:kd=\EB:ke=\E>:kh=\EH:\ - :kl=\ED:kr=\EC:ks=\E=:kt=\E2:ku=\EA:le=^H:me=\E3\Eb:mh=\E4:\ - :mk=\Ea:nd=\EC:pf=\EX:po=\EW:ps=\EH\E]:\ - :r1=\E3\Eb\Ej\E\\El\EG\Ec\Ek\EX:se=\E3:sf=^J:so=\E4:\ - :sr=\EI:st=\E1:ta=^I:up=\EA:ve=\Ec:vs=\Ed: -# The older Visuals didn't come with function keys. This entry uses -# :ks: and :ke: so that the keypad keys can be used as function keys. -# If your version of vi doesn't support function keys you may want -# to use vi200-f. -vi200-f|visual 200 no function keys:\ - :is=\E3\Eb\Ej\E\\El\EG\Ed\Ek:k0=\E?p:k1=\E?q:k2=\E?r:\ - :k3=\E?s:k4=\E?t:k5=\E?u:k6=\E?v:k7=\E?w:k8=\E?x:k9=\E?y:\ - :ke=\E>:ks=\E=:se@:so@:\ - :tc=vi200: -vi200-rv|visual 200 reverse video:\ - :se=\E3:so=\E4:sr@:ve@:vs@:tc=vi200: - -# the function keys are programmable but we don't reprogram them to their -# default values with :is: because programming them is very verbose. maybe -# an initialization file should be made for the 300 and they could be stuck -# in it. -# (vi300: added / based on init string -- esr) -vi300|visual 300 ansi x3.64:\ - :am:bw:mi:xn:\ - :co#80:li#24:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E[7s\E[2;3;4;20;?5;?6l\E[12;?7h\E[1Q\E[0;1(D\E[8s:\ - :k1=\E_A\E\:k2=\E_B\E\:k3=\E_C\E\:k4=\E_D\E\:k5=\E_E\E\:\ - :k6=\E_F\E\:k7=\E_G\E\:k8=\E_H\E\:k9=\E_I\E\:kd=\E[B:\ - :kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:me=\E[m:nd=\E[C:\ - :se=\E[m:sf=^J:so=\E[1m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:\ - :us=\E[4m: -# some of the vi300s have older firmware that has the command -# sequence for setting editing extent reversed. -vi300-old|visual 300 with old firmware (set edit extent reversed):\ - :is=\E[7s\E[2;3;4;20;?5;?6l\E[12;?7h\E[2Q\E[0;1(D\E[8s:\ - :tc=vi300: - -# Visual 500 prototype entry from University of Wisconsin. -# The best place to look for the escape sequences is page A1-1 of the -# Visual 500 manual. The initialization sequence given here may be -# overkill, but it does leave out some of the initializations which can -# be done with the menus in set-up mode. -# The :xp: line below is so that emacs can understand the padding requirements -# of this slow terminal. :xp: is 10 time the padding factor. -# (vi500: removed unknown :xp#4: termcap; -# also added empty to suppress tic warning -- esr) -vi500|visual 500:\ - :am:mi:ms:\ - :co#80:it#8:li#33:\ - :ac=:ae=^O:al=3*\EL\Ex:as=^N:bt=4\Ez:cd=3*\Ey:ce=16\Ex:\ - :cl=6*\Ev:cm=\EY%+ %+ :cr=^M:cs=\E(%+ %+ :dc=3*\EO:\ - :dl=3*\EM:do=\EB:ei=\Ej:ho=\EH:im=\Ei:\ - :is=\E3\E\001\E\007\E\003\Ek\EG\Ed\EX\El\E>\Eb\E\:\ - :kb=^H:kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:\ - :nw=^M^J:se=\E^G:sf=^J:so=\E^H:ta=8\011:ue=\E^C:up=\EA:\ - :us=\E^D: - -# The visual 550 is a visual 300 with tektronix graphics, -# and with 33 lines. clear screen is modified here to -# also clear the graphics. -vi550|visual 550 ansi x3.64:\ - :li#33:\ - :cl=\030\E[H\E[2J:tc=vi300: - -vi603|visual603|visual 603:\ - :hs:mi:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:ds=\EP2;1~\E\:ei=\E[4l:\ - :fs=\E\:i1=\E>\E[?3l\E[?4l\E[?7h\E[?8h\E[1;24r:\ - :im=\E[4h:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:ts=\EP2~:ue=\E[24m:\ - :up=\E[A:us=\E[4m:\ - :tc=vt100: - -#### Wyse (wy) -# -# Wyse Technology -# 3471 North First Street -# San Jose, CA 95134 -# Vox: (408)-473-1200 -# Fax: (408) 473-1222 -# Web: http://www.wyse.com -# -# Wyse sales can be reached by phone at 1-800-GET-WYSE. Tech support is at -# (800)-800-WYSE (option 5 gets you a human). There's a Web page at the -# obvious address, http://www.wyse.com. -# -# Wyse bought out Link Technology, Inc. in 1990 and closed it down in 1995. -# They now own the Qume and Amdek brands, too. So these are the people to -# talk with about all Link, Qume, and Amdek terminals. -# -# Wyse has a BBS containing termcap and terminfo stuff for their terminals -# (though this may not last long -- I expect the Web will kill it off by -# mid-1997 or so). According to their tech support, at 800-800-9973, it's -# at 408-922-4400 thru 4405. The 4400 modem is flaky as of 5/96, so -# call 4401 etc. Come in at 9600 hard; don't use autospeed sense. -# -# All the following entries until (but not including) wy520 are direct from -# Wyse technical support and represent their best knowledge as of January 1995. -# I canceled the bel capacities in the vb entries. -# I made two trivial syntax fixes in the wyse30 entry. -# I made some entries relative to adm+sgr. -# -# -# Note: The wyse75, wyse85, and wyse99 have been discontinued. - -# Although the Wyse 30 can support more than one attribute -# it requires magic cookies to do so. Many applications do not -# function well with magic cookies. The following terminfo uses -# the protect mode to support one attribute (dim) without cookies. -# If more than one attribute is needed then the wy30-mc terminfo -# should be used. -# -wy30|wyse30|Wyse 30:\ - :5i:am:bs:bw:hs:mi:ms:xo:\ - :Nl#8:co#80:lh#1:li#24:lw#8:ma#1:ws#45:\ - :#2=\E{:&3=\Er:@8=\E7:LF=\EA11:LO=\EA10:\ - :ac=0wa_h[jukslrmqnxqzttuyv]wpxv:ae=\EH^C:al=\EE:\ - :as=\EH^B:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:cm=\E=%+ %+ :\ - :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:ei=\Er:fs=^M:\ - :ho=^^:im=\Eq:ip=:is=\E'\E(\E\1363\E`9\016\024:k1=^A@\r:\ - :k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:\ - :k8=^AG\r:kA=\EE:kB=\EI:kD=\EW:kE=\ET:kI=\EQ:kL=\ER:kN=\EK:\ - :kP=\EJ:kS=\EY:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:\ - :ll=^^^K:me=\E(\EH\003:mh=\E`7\E):mp=\E`7\E):nd=^L:\ - :nw=^M^J:pf=^T:pn=\Ez%+/%s\r:po=^X:ps=\EP:px=\Ez%+?%s\177:\ - :se=\E(:sf=\n:so=\E`7\E):sr=\Ej:st=\E1:ta=\011:ts=\EF:up=^K:\ - :vb=\E`8\E`9:ve=\E`1:vi=\E`0: -# -# This terminal description uses the non-hidden attribute mode -# (with magic cookie). -# -# (wy30-mc: added :ti: to suppress tic warning --esr) -wy30-mc|wyse30-mc|wyse 30 with magic cookies:\ - :ms@:\ - :ma@:sg#1:\ - :ae=\EG0\EH\003:as=\EG0\EH\002:mb=\EG2:\ - :me=\EG0\E(\EH\003:mh=\EGp:mp=\EG0\E):\ - :te=\EG0:ti=:\ - :me=\EG0:mk=\EG1:mr=\EG4:se=\EG0:so=\EG4:ue=\EG0:us=\EG8:\ - :tc=wy30: -# The mandatory pause used by :vb: does not work with -# older versions of terminfo. If you see this effect then -# unset xon and delete the / from the delay. -# i.e. change $<100/> to $<100> -wy30-vb|wyse30-vb|wyse 30 visible bell:\ - :bl@:tc=wy30: -# -# The Wyse 50 can support one attribute (e.g. Dim, Inverse, -# Normal) without magic cookies by using the protect mode. -# The following description uses this feature, but when more -# than one attribute is put on the screen at once, all attributes -# will be changed to be the same as the last attribute given. -# The Wyse 50 can support more attributes when used with magic -# cookies. The wy50-mc terminal description uses magic cookies -# to correctly handle multiple attributes on a screen. -# -wy50|wyse50|Wyse 50:\ - :5i:am:bs:bw:hs:mi:ms:xo:\ - :Nl#8:co#80:lh#1:li#24:lw#8:ma#1:ws#45:\ - :#2=\E{:%9=\EP:&3=\Er:@8=\E7:F1=^AJ\r:F2=^AK\r:F3=^AL\r:\ - :F4=^AM\r:F5=^AN\r:F6=^AO\r:LF=\EA11:LO=\EA10:\ - :ac=0wa_h[jukslrmqnxqzttuyv]wpxv:ae=\EH^C:al=\EE:\ - :as=\EH^B:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:cm=\E=%+ %+ :\ - :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:ei=\Er:fs=^M:\ - :ho=^^:i1=\E`\072\E`9:im=\Eq:ip=:is=\016\024\E'\E(:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:kA=\EE:kB=\EI:kD=\EW:\ - :kE=\ET:kI=\EQ:kL=\ER:kN=\EK:kP=\EJ:kS=\EY:kb=^H:kd=^J:kh=^^:\ - :kl=^H:kr=^L:ku=^K:le=^H:ll=^^^K:me=\E(\EH\003:mh=\E`7\E):\ - :mp=\E`7\E):mr=\E`6\E):nd=^L:nw=^M^J:pf=^T:pn=\Ez%+/%s\r:\ - :po=^X:ps=\EP:px=\Ez%+?%s\177:\ - :se=\E(:sf=\n:so=\E`6\E):sr=\Ej:st=\E1:ta=^I:ts=\EF:up=^K:\ - :vb=\E`8\E`9:ve=\E`1:vi=\E`0: -# -# This terminal description uses the non-hidden attribute mode -# (with magic cookie). -# -# The mandatory pause used by flash does not work with some -# older versions of terminfo. If you see this effect then -# unset :xo: and delete the / from the delay. -# i.e. change $<100/> to $<100> -# (wy50-mc: added :ti: to suppress tic warning --esr) -wy50-mc|wyse50-mc|wyse 50 with magic cookies:\ - :ms@:\ - :ma@:sg#1:\ - :ae=\EG0\EH\003:as=\EG0\EH\002:mb=\EG2:\ - :me=\EG0\E(\EH\003:mh=\EGp:mp=\EG0\E):\ - :so=\EGt:te=\EG0:ti=:\ - :me=\EG0:mk=\EG1:mr=\EG4:se=\EG0:so=\EG4:ue=\EG0:us=\EG8:\ - :tc=wy50: -wy50-vb|wyse50-vb|wyse 50 visible bell:\ - :bl@:tc=wy50: -wy50-w|wyse50-w|wyse 50 132-column:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cm=\Ea%i%dR%dC:dc=\EW:i1=\E`;\E`9:tc=wy50: -wy50-wvb|wyse50-wvb|wyse 50 132-column visible bell:\ - :bl@:\ - :tc=wy50-w: -# -# The Wyse 350 is a Wyse 50 with color. -# Unfortunately this means that it has magic cookies. -# The color attributes are designed to overlap the reverse, dim and -# underline attributes. This is nice for monochrome applications -# because you can make underline stuff green (or any other color) -# but for true color applications it's not so hot because you cannot -# mix color with reverse, dim or underline. -# To further complicate things one of the attributes must be -# black (either the foreground or the background). In reverse video -# the background changes color with black letters. In normal video -# the foreground changes colors on a black background. -# This terminfo uses some of the more advanced features of curses -# to display both color and blink. In the final analysis I am not -# sure that the wy350 runs better with this terminfo than it does -# with the wy50 terminfo (with user adjusted colors). -# -# The mandatory pause used by flash does not work with -# older versions of terminfo. If you see this effect then -# unset xon and delete the / from the delay. -# i.e. change $<100/> to $<100> -# -# Bug: The capability resets attributes. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -wy350|wyse350|Wyse 350:\ - :5i:am:bw:hs:mi:xo:\ - :Co#8:NC#55:Nl#8:co#80:lh#1:li#24:lw#8:pa#8:sg#1:ws#45:\ - :#2=\E{:%9=\EP:&3=\Er:@8=\E7:F1=^AJ\r:F2=^AK\r:F3=^AL\r:\ - :F4=^AM\r:F5=^AN\r:F6=^AO\r:LF=\EA11:LO=\EA10:Sb=:\ - :ac=0wa_h[jukslrmqnxqzttuyv]wpxv:ae=\EG0\EH\003:al=\EE:\ - :as=\EG0\EH\002:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:\ - :cm=\E=%+ %+ :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:\ - :ei=\Er:fs=^M:ho=^^:i1=\E`\072\E`9:i2=\E%?:im=\Eq:ip=:\ - :is=\016\024\E'\E(:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:\ - :kA=\EE:kB=\EI:kD=\EW:kE=\ET:kI=\EQ:kL=\ER:kN=\EK:kP=\EJ:\ - :kS=\EY:kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:ll=^^^K:\ - :mb=\EG2:me=\EG0\E(\EH\003%{0}%PA%{0}%PC:mh=\EGp:\ - :mp=\EG0\E):nd=^L:nw=^M^J:oc=\E%?:op=\EG0:pf=^T:\ - :pn=\Ez%+/%s\r:po=^X:ps=\EP:px=\Ez%+?%s\177:sf=\n:sr=\Ej:\ - :st=\E1:ta=^I:ts=\EF:up=^K:vb=\E`8\E`9:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: -wy350-vb|wyse350-vb|wyse 350 visible bell:\ - :bl@:tc=wy350: -wy350-w|wyse350-w|wyse 350 132-column:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cm=\Ea%i%dR%dC:dc=\EW:i1=\E`;\E`9:tc=wy350: -wy350-wvb|wyse350-wvb|wyse 350 132-column visible bell:\ - :bl@:\ - :tc=wy350-w: -# -# This terminfo description is untested. -# The wyse100 emulates an adm31, so the adm31 entry should work. -# -wy100|wyse 100:\ - :hs:mi:\ - :co#80:li#24:sg#1:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=\E;:cm=\E=%+ %+ :cr=^M:\ - :dc=\EW:dl=\ER:do=^J:ds=\EA31:ei=\Er:fs=^M:im=\Eq:is=\Eu\E0:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:kb=^H:kd=^J:kh=\E{:kl=^H:kr=^L:ku=^K:\ - :le=^H:mk@:nd=^L:sf=^J:ts=\EF:up=^K:\ - :tc=adm+sgr: -# -# The Wyse 120/150 has most of the features of the Wyse 60. -# This terminal does not need padding up to 9600 baud! -# :ms: should be set but the clear screen fails when in -# alt-charset mode. Try \EcE\s\s\E+\s if the screen is really clear -# then set :ms:. -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy120|wyse120|wy150|wyse150|Wyse 120/150:\ - :am:bw:hs:km:mi:ms:xo:\ - :co#80:it#8:li#24:pb#9601:ws#45:\ - :ae=\EcD:al=\EE:as=\EcE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:\ - :cm=\E=%+ %+ :cr=^M:dc=\EW:dl=\ER:do=^J:ds=\EF\r:ei=\Er:\ - :fs=^M:ho=^^:i1=\EcB0\EcC1:i2=\EwJ\Ew1:im=\Eq:ip=:\ - :is=\Ed$\EcD\E'\Er\EH\003\Ed/\EO\Ee1\Ed*\E`@\E`9\E`1\016\024\El:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kD=\EW:kI=\EQ:kN=\EK:kP=\EJ:\ - :kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:ll=^^^K:mb=\EG2:\ - :me=\E(\EH\003\EG0\EcD:mh=\EGp:nd=^L:nw=\r\n:sf=\n:\ - :so=\EGt:sr=\Ej:st=\E1:ta=\011:te=\Ew1:ti=\Ew0:ts=\EF:up=^K:\ - :vb=\E`8\E`9:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: -# -wy120-w|wyse120-w|wy150-w|wyse150-w|wyse 120/150 132-column:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cm=\Ea%i%dR%dC:dc=\EW:ip=:r2=\E`;:tc=wy120: -# -wy120-25|wyse120-25|wy150-25|wyse150-25|wyse 120/150 80-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy120: -# -wy120-25-w|wyse120-25-w|wy150-25-w|wyse150-25-w|wyse 120/150 132-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy120-w: -# -wy120-vb|wyse120-vb|wy150-vb|wyse150-vb|Wyse 120/150 visible bell:\ - :bl@:\ - :tc=wy120: -# -wy120-w-vb|wy120-wvb|wyse120-wvb|wy150-w-vb|wyse150-w-vb|Wyse 120/150 132-column visible bell:\ - :bl@:\ - :tc=wy120-w: -# -# The Wyse 60 is like the Wyse 50 but with more padding. -# The reset strings are slow and the pad times very depending -# on other parameters such as font loading. I have tried -# to follow the following outline: -# -# -> set personality -# -> set number of columns -# -> set number of lines -# :i1: -> select the proper font -# :is: -> do the initialization -# :i3: -> set up display memory (2 pages) -# -# The Wyse 60's that have vt100 emulation are slower than the -# older Wyse 60's. This change happened mid-1987. -# The capabilities effected are :dc: :dl: :al: :sf: :sr: -# -# The meta key is only half right. This terminal will return the -# high order bit set when you hit CTRL-function_key -# -# It may be useful to assign two function keys with the -# values \E=(\s look at old data in page 1 -# \E=W, look at bottom of page 1 -# where \s is a space ( ). -# -# Note: -# The Wyse 60 runs faster when the XON/XOFF -# handshake is turned off. -# -# (wy60: we use \E{ rather than ^^ for home (both are documented) to avoid -# a bug reported by Robert Dunn, -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy60|wyse60|Wyse 60:\ - :am:bs:bw:hs:km:mi:ms:\ - :co#80:li#24:ws#45:\ - :ae=\EcD:al=\EE:as=\EcE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:\ - :cm=\E=%+ %+ :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:\ - :ei=\Er:fs=^M:ho=\E{:i1=\EcB0\EcC1:i2=\EwJ\Ew1:im=\Eq:ip=:\ - :is=\Ed$\EcD\E'\Er\EH\003\Ed/\EO\Ee1\Ed*\E`@\E`9\E`1\016\024\El:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kD=\EW:kI=\EQ:kN=\EK:kP=\EJ:\ - :kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:ll=\E{^K:mb=\EG2:\ - :me=\E(\EH\003\EG0\EcD:mh=\EGp:nd=^L:nw=\r\n:sf=\n:\ - :so=\EGt:sr=\Ej:st=\E1:ta=\011:te=\Ew1:ti=\Ew0:ts=\EF:up=^K:\ - :vb=\E`8\E`9:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: -# -wy60-w|wyse60-w|wyse 60 132-column:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cm=\Ea%i%dR%dC:dc=\EW:ip=:r2=\EeF\E`;:tc=wy60: -# -wy60-25|wyse60-25|wyse 60 80-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy60: -wy60-25-w|wyse60-25-w|wyse 60 132-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy60-w: -# -wy60-42|wyse60-42|wyse 60 80-column 42-lines:\ - :li#42:\ - :al=\EE:cd=\Ey:cl=\E+:cm=\E=%+ %+ :dc=\EW:dl=\ER:\ - :i1=\EcB2\EcC3:ip=:nw=\r\n:r3=\Ee*:sf=\n:sr=\Ej:tc=wy60: -wy60-42-w|wyse60-42-w|wyse 60 132-column 42-lines:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cd=\Ey:cl=\E+:cm=\Ea%i%dR%dC:dc=\EW:ho=\036:ip=:nw=\r\n:\ - :r2=\EeF\E`;:\ - :tc=wy60-42: -# -wy60-43|wyse60-43|wyse 60 80-column 43-lines:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:r3=\Ee+:tc=wy60-42: -wy60-43-w|wyse60-43-w|wyse 60 132-column 43-lines:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:r3=\Ee+:tc=wy60-42-w: -# -wy60-vb|wyse60-vb|Wyse 60 visible bell:\ - :bl@:tc=wy60: -wy60-w-vb|wy60-wvb|wyse60-wvb|Wyse 60 132-column visible bell:\ - :bl@:\ - :tc=wy60-w: - -# The Wyse-99GT looks at lot like the Wyse 60 except that it -# does not have the 42/43 line mode. In the Wyse-60 the "lines" -# setup parameter controls the number of lines on the screen. -# For the Wyse 99GT the "lines" setup parameter controls the -# number of lines in a page. The screen can display 25 lines max. -# The Wyse-99GT also has personalities for the VT220 and -# Tektronix 4014. But this has no bearing on the native mode. -# -# (msgr) should be set but the clear screen fails when in -# alt-charset mode. Try \EcE\s\s\E+\s if the screen is really clear -# then set msgr, else use msgr@. -# -# u0 -> enter Tektronix mode -# u1 -> exit Tektronix mode -# -wy99gt|wyse99gt|Wyse 99gt:\ - :ms@:\ - :al=\EE:cd=\Ey:ce=\Et:cl=\E+:dc=\EW:dl=\ER:i2=\Ew0:ip=:nw@:\ - :r2=\E`\072:sf=\n:sr=\Ej:ta=\011:te=\Ew0:ti=\Ew1:\ - :u0=\E~>\E8:u1=\E[42h:vb=\E`8\E`9:tc=wy60: -# -wy99gt-w|wyse99gt-w|wyse 99gt 132-column:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cd=\Ey:cl=\E+:cm=\Ea%i%dR%dC:dc=\EW:ip=:r2=\E`;:tc=wy99gt: -# -wy99gt-25|wyse99gt-25|wyse 99gt 80-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r2=\E`\072:r3=\EwG\Ee):tc=wy99gt: -# -wy99gt-25-w|wyse99gt-25-w|wyse 99gt 132-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r2=\E`;:tc=wy99gt-w: -# -wy99gt-vb|wyse99gt-vb|Wyse 99gt visible bell:\ - :bl@:tc=wy99gt: -# -wy99gt-w-vb|wy99gt-wvb|wyse99gt-wvb|Wyse 99gt 132-column visible bell:\ - :bl@:\ - :tc=wy99gt-w: -# -# The Wyse 160 is combination of the WY-60 and the WY-99gt. -# The reset strings are slow and the pad times very depending -# on other parameters such as font loading. I have tried -# to follow the following outline: -# -# -> set personality -# -> set number of columns -# -> set number of lines -# :i1: -> select the proper font -# :is: -> do the initialization -# :i3: -> set up display memory (2 pages) -# -# The display memory may be used for either text or graphics. -# When "Display Memory = Shared" the terminal will have more pages -# but garbage may be left on the screen when you switch from -# graphics to text. If "Display Memory = Unshared" then the -# text area will be only one page long. -# -# (wy160: we use \E{ rather than ^^ for home (both are documented) to avoid -# a bug reported by Robert Dunn, -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy160|wyse160|Wyse 160:\ - :am:bw:hs:km:mi:ms:\ - :co#80:li#24:ws#38:\ - :ae=\EcD:al=\EE:as=\EcE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:\ - :cm=\E=%+ %+ :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:\ - :ei=\Er:fs=^M:ho=\E{:i1=\EcB0\EcC1:i2=\Ew0:im=\Eq:ip=:\ - :is=\Ed$\EcD\E'\Er\EH\003\Ed/\EO\Ee1\Ed*\E`@\E`9\E`1\016\024\El:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kD=\EW:kI=\EQ:kN=\EK:kP=\EJ:\ - :kb=^H:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:ll=\E{^K:mb=\EG2:\ - :me=\E(\EH\003\EG0\EcD:mh=\EGp:nd=^L:nw=\r\n:sf=\n:\ - :so=\EGt:sr=\Ej:st=\E1:ta=^I:te=\Ew0:ti=\Ew1:ts=\EF:up=^K:\ - :vb=\E`8\E`9:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: -# -wy160-w|wyse160-w|wyse 160 132-column:\ - :Nl#16:co#132:lw#7:ws#90:\ - :cm=\Ea%i%dR%dC:dc=\EW:r2=\EeF\E`;:tc=wy160: -# -wy160-25|wyse160-25|wyse 160 80-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy160: -wy160-25-w|wyse160-25-w|wyse 160 132-column 25-lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy160-w: -# -wy160-42|wyse160-42|wyse 160 80-column 42-lines:\ - :li#42:\ - :al=\EE:cd=\Ey:cl=\E+:dl=\ER:i1=\EcB2\EcC3:nw=\r\n:r3=\Ee*:\ - :sf=\n:sr=\Ej:\ - :tc=wy160: -wy160-42-w|wyse160-42-w|wyse 160 132-column 42-lines:\ - :Nl#16:co#132:lw#7:ws#90:\ - :cm=\Ea%i%dR%dC:dc=\EW:ip=:r2=\EeF\E`;:tc=wy160-42: -# -wy160-43|wyse160-43|wyse 160 80-column 43-lines:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:r3=\Ee+:tc=wy160-42: -wy160-43-w|wyse160-43-w|wyse 160 132-column 43-lines:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:r3=\Ee+:tc=wy160-42-w: -# -wy160-vb|wyse160-vb|Wyse 160 visible bell:\ - :bl@:tc=wy160: -wy160-w-vb|wy160-wvb|wyse160-wvb|Wyse 160 132-column visible bell:\ - :bl@:\ - :tc=wy160-w: -# -# The Wyse 75 is a vt100 lookalike without advanced video. -# -# The Wyse 75 can support one attribute (e.g. Dim, Inverse, -# Underline) without magic cookies. The following description -# uses this capability, but when more than one attribute is -# put on the screen at once, all attributes will be changed -# to be the same as the last attribute given. -# The Wyse 75 can support more attributes when used with magic -# cookies. The wy75-mc terminal description uses magic cookies -# to correctly handle multiple attributes on a screen. -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy75|wyse75|wyse 75:\ - :am:bs:hs:mi:ms:xn:xo:\ - :co#80:li#24:ma#1:pb#1201:ws#78:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ds=\E[>\\054\001\001\E[>-\001\001:ec=\E[%dX:ei=\E[4l:\ - :fs=^A:ho=\E[H:\ - :i1=\E[2;4;20;30l\E[?1;10l\E[12h\E[?7;8;25h:i2=\E[m:\ - :im=\E[4h:ip=:is=\E>\E(B:k1=\E[?5i:k2=\E[?3i:\ - :k3=\E[2i:k4=\E[@:k5=\E[M:k6=\E[17~:k7=\E[18~:k8=\E[19~:\ - :k9=\E[20~:kI=\E[@:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=\E>:\ - :kh=\E[H:kl=\E[D:kr=\E[C:ks=\E[?1l\E[?7h\E=:ku=\E[A:le=^H:\ - :me=\E[m\017:mh=\E[0t\E[2m:mr=\E[1t\E[7m:nd=\E[C:rc=\E8:\ - :sc=\E7:se=\E[m:sf=\n:so=\E[1t\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E[>\\054\001:ue=\E[m:up=\E[A:us=\E[2t\E[4m:\ - :vb=\E[30h\E\\054\E[30l:ve=\E[?25h:vi=\E[?25l: -# -# This terminal description uses the non-hidden attribute mode -# (with magic cookie). -# -wy75-mc|wyse75-mc|wyse 75 with magic cookies:\ - :ms@:\ - :ma@:sg#1:ug#1:\ - :ae=\E[0p\017:as=\E[0p\016:i2=\E[m\E[p:mb=\E[2p:\ - :me=\E[0p\017:mh=\E[1p:mk=\E[4p:mr=\E[16p:\ - :se=\E[0p:so=\E[17p:ue=\E[0p:us=\E[8p:\ - :tc=wy75: -wy75-vb|wyse75-vb|wyse 75 with visible bell:\ - :pb@:\ - :bl@:tc=wy75: -wy75-w|wyse75-w|wyse 75 in 132 column mode:\ - :co#132:ws#130:\ - :r2=\E[35h\E[?3h:tc=wy75: -wy75-wvb|wyse75-wvb|wyse 75 with visible bell 132 columns:\ - :pb@:\ - :bl@:tc=wy75-w: -# -# Wyse 85 emulating a vt220 7 bit mode. -# 24 line screen with status line. -# -# The vt220 mode permits more function keys but it wipes out -# the escape key. I strongly recommend that be set to -# escape (esc). -# The terminal may have to be set for 8 data bits and 2 stop -# bits for the arrow keys to work. -# The Wyse 85 runs faster with XON/XOFF enabled. Also the -# :DC: and :IC: work best when XON/XOFF is set. :IC: and -# :DC: leave trash on the screen when used without XON/XOFF. -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy85|wyse85|wyse 85:\ - :am:bs:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ds=\E[40l:\ - :ec=\E[%dX:ei=\E[4l:fs=\E[1;24r\E8:ho=\E[H:\ - :i1=\E[62;1"p\E[?5W:i2=\E>\E(B\E[m:im=\E[4h:ip=:\ - :is=\E[2;4;20;30l\E[?1;4;10;16l\E[12h\E[?7;8;25h:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:ke=\E>:kh=\E[26~:kl=\E[D:kr=\E[C:\ - :ks=\E[?1l\E=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[m:sf=\n:\ - :so=\E[7m:sr=\EM:st=\EH:ta=\011:\ - :ts=\E[40h\E7\E[25;%i%dH:ue=\E[m:up=\E[A:us=\E[4m:\ - :vb=\E[30h\E\\054\E[30l:ve=\E[?25h:vi=\E[?25l: -# -# Wyse 85 with visual bell. -wy85-vb|wyse85-vb|wyse 85 with visible bell:\ - :bl@:vb=\E[30h\E\\054\E[30l:tc=wy85: -# -# Wyse 85 in 132-column mode. -wy85-w|wyse85-w|wyse 85 in 132-column mode:\ - :co#132:ws#132:\ - :r2=\E[35h\E[?3h:tc=wy85: -# -# Wyse 85 in 132-column mode with visual bell. -wy85-wvb|wyse85-wvb|wyse 85 with visible bell 132-columns:\ - :bl@:\ - :tc=wy85-w: -# -# Wyse 185 emulating a vt320 7 bit mode. -# -# This terminal always displays 25 lines. These lines may be used -# as 24 data lines and a terminal status line (top or bottom) or -# 25 data lines. The 48 and 50 line modes change the page size -# and not the number of lines on the screen. -# -# The Compose Character key can be used as a meta key if changed -# by set-up. -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy185|wyse185|wyse 185:\ - :am:hs:km:mi:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOu:K3=\EOy:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ds=\E7\E[99;0H\E[K\E8:ec=\E[%dX:ei=\E[4l:\ - :fs=\E[1;24r\E8:ho=\E[H:i1=\E[?5W:\ - :i2=\E>\E(B\E[m:im=\E[4h:ip=:\ - :is=\E[2;4;20;30l\E[?1;4;10;16l\E[12h\E[?7;8;25h:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:ke=\E>:kh=\E[26~:kl=\E[D:kr=\E[C:\ - :ks=\E[?1l\E=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:sf=\n:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:te=\E[ R:ti=\E[ Q:\ - :ts=\E7\E[99;%i%dH:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[30h\E\\054\E[30l:ve=\E[34h\E[?25h:vi=\E[?25l:\ - :vs=\E[?25h\E[34l: -# -# Wyse 185 with 24 data lines and top status (terminal status) -wy185-24|wyse185-24|wyse 185 with 24 data lines:\ - :hs@:\ - :ds@:fs@:r3=\E[?5l\E[47h\E[40l\E[1;24r:ts@:tc=wy185: -# -# Wyse 185 with visual bell. -wy185-vb|wyse185-vb|wyse 185+flash:\ - :bl@:tc=wy185: -# -# Wyse 185 in 132-column mode. -wy185-w|wyse185-w|wyse 185 in 132-column mode:\ - :co#132:ws#132:\ - :DC=\E[%dP:IC=\E[%d@:dc=\E[P:ei=:im=:ip=:r2=\E[35h\E[?3h:tc=wy185: -# -# Wyse 185 in 132-column mode with visual bell. -wy185-wvb|wyse185-wvb|wyse 185+flash+132 cols:\ - :bl@:tc=wy185-w: - -# wy325 terminfo entries -# Done by Joe H. Davis 3-9-92 - -# lines 25 columns 80 -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -wy325|wyse325|Wyse epc:\ - :5i:am:bw:hs:mi:\ - :Nl#8:co#80:lh#1:li#24:lw#8:pb#9601:ws#45:\ - :#2=\E{:%9=\EP:&3=\Er:@8=\E7:F1=^AJ\r:F2=^AK\r:F3=^AL\r:\ - :F4=^AM\r:F5=^AN\r:F6=^AO\r:LF=\EA11:LO=\EA10:RA=\Ed.:\ - :SA=\Ed/:\ - :ac=+/\\054.0[Iha2fxgqh1jYk?lZm@nEqDtCu4vAwBx3yszr{c~~:\ - :ae=\EcD:al=\EE:as=\EcE:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E+:\ - :cm=\E=%+ %+ :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\EF\r:\ - :ei=\Er:fs=^M:ho=^^:i1=\EcB0\EcC1:i2=\Ew0:im=\Eq:ip=:\ - :is=\EcD\E'\Er\EH\003\Ed/\EO\Ee1\Ed*\E`@\E`9\E`1\016\024\El:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:kA=\EE:kB=\EI:kD=\EW:\ - :kE=\ET:kI=\Eq:kL=\ER:kN=\EK:kP=\EJ:kS=\EY:kb=^H:kd=^J:kh=^^:\ - :kl=^H:kr=^L:ku=^K:le=^H:ll=^^^K:mb=\EG2:\ - :me=\E(\EH\003\EG0\EcD:mh=\EGp:mp=\E):nd=^L:pf=^T:\ - :pl=\EZ2%+?%s\177:pn=\Ez%+/%s\r:po=\Ed#:ps=\EP:\ - :px=\EZ1%+?%s\177:r1=\E~\041\E~4:r2=\EeF\E`\072:\ - :r3=\EwG\Ee(:sf=\n:so=\EGt:sr=\Ej:st=\E1:ta=^I:te=\Ew0:\ - :ti=\Ew1:ts=\EF:up=^K:vb=\E`8\E`9:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: - -# -# lines 24 columns 80 vb -# -wy325-vb|wyse325-vb|wyse-325 with visual bell:\ - :bl@:tc=wy325: - -# -# lines 24 columns 132 -# -wy325-w|wyse325-w|wy325w-24|wyse-325 in wide mode:\ - :Nl#16:co#132:lw#7:ws#97:\ - :cm=\Ea%i%dR%dC:dc=\EW:ip=:r2=\E`;:tc=wy325: -# -# lines 25 columns 80 -# -wy325-25|wyse325-25|wy325-80|wyse-325|wyse-325 25 lines:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy325: -# -# lines 25 columns 132 -# -wy325-25w|wyse325-25w|wy325 132 columns:\ - :Nl@:lh@:li#25:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy325-w: -# -# lines 25 columns 132 vb -# -wy325-w-vb|wy325-wvb|wyse325-wvb|wyse-325 wide mode reverse video:\ - :bl@:\ - :tc=wy325-w: - -# -# lines 42 columns 80 -# -wy325-42|wyse325-42|wyse-325 42 lines:\ - :Nl@:lh@:li#42:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy325: -# -# lines 42 columns 132 -# -wy325-42w|wyse325-42w|wyse-325 42 lines wide mode:\ - :Nl@:lh@:li#42:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy325-w: -# -# lines 42 columns 132 vb -# -wy325-42w-vb|wy325-42wvb|wyse-325 42 lines wide mode visual bell:\ - :bl@:\ - :tc=wy325-w: -# -# lines 43 columns 80 -# -wy325-43|wyse325-43|wyse-325 43 lines:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:tc=wy325: -# -# lines 43 columns 132 -# -wy325-43w|wyse325-43w|wyse-325 43 lines wide mode:\ - :Nl@:lh@:li#43:lw@:\ - :pn@:r3=\EwG\Ee):tc=wy325-w: -# -# lines 43 columns 132 vb -# -wy325-43w-vb|wy325-43wvb|wyse-325 43 lines wide mode visual bell:\ - :bl@:\ - :tc=wy325-w: - -# Wyse 370 -- 24 line screen with status line. -# -# The terminal may have to be set for 8 data bits and 2 stop -# bits for the arrow keys to work. -# -# If you change keyboards the terminal will send different -# escape sequences. -# The following definition is for the basic terminal without -# function keys. -# -# -> enter Tektronix 4010/4014 mode -# -> exit Tektronix 4010/4014 mode -# -> enter ASCII mode (from any ANSI mode) -# -> exit ASCII mode (goto native ANSI mode) -# -> enter Tek 4207 ANSI mode (from any ANSI mode) -# -> exit Tek 4207 mode (goto native ANSI mode) -# -# Bug: The capability resets attributes. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy370-nk|wyse 370 without function keys:\ - :am:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:\ - :bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ds=\E[40l:\ - :ec=\E[%dX:ei=\E[4l:fs=\E[1;24r\E8:ho=\E[H:\ - :i1=\E[90;1"p\E[?5W:i2=\E>\017\E(B\E[63;0w\E[m:\ - :im=\E[4h:ip=:\ - :is=\E[2;4;20;30;40l\E[?1;10;16l\E[12h\E[?7;8;25h:\ - :ke=\E>:ks=\E[?1l\E=:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[27m:sf=\n:\ - :so=\E[7m:sr=\EM:st=\EH:ta=\011:te=\E[ R:ti=\E[ Q:\ - :ts=\E[40l\E[40h\E7\E[99;%i%dH:ue=\E[24m:up=\E[A:\ - :us=\E[4m:vb=\E[30h\E\\054\E[30l:ve=\E[34h\E[?25h:\ - :vi=\E[?25l:vs=\E[?25h\E[34l: -# -# Function key set for the ASCII (wy-50 compatible) keyboard -# This is the default 370. -# -wy370|wyse370|wy370-101k|Wyse 370 with 101 key keyboard:\ - :@8=\EOM:F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:\ - :F5=\E[28~:F6=\E[29~:k1=\E[?4i:k2=\E[?3i:k3=\E[2i:k4=\E[@:\ - :k5=\E[M:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ - :k;=\E[21~:kA=\EOP:kB=\E[Z:kD=\EOQ:kI=\EOP:kL=\EOQ:kN=\E[U:\ - :kP=\E[V:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :tc=wy370-nk: -# -# Function key set for the VT-320 (and wy85) compatible keyboard -# -wy370-105k|Wyse 370 with 105 key keyboard:\ - :%1=\E[28~:*6=\E[4~:@0=\E[1~:@8=\EOM:F1=\E[23~:F2=\E[24~:\ - :F3=\E[25~:F4=\E[26~:F5=\E[28~:F6=\E[29~:F7=\E[31~:\ - :F8=\E[32~:F9=\E[33~:FA=\E[34~:K1=\EOw:K2=\EOu:K3=\EOy:\ - :K4=\EOq:K5=\EOs:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kD=\E[3~:\ - :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:kh=\E[26~:\ - :kl=\E[D:kr=\E[C:ku=\E[A:l1=PF1:l2=PF2:l3=PF3:l4=PF4:\ - :tc=wy370-nk: -# -# Function key set for the PC compatible keyboard -# -wy370-EPC|Wyse 370 with 102 key keyboard:\ - :@7=\E[1~:@8=\EOM:F1=\E[23~:F2=\E[24~:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:k5=\E[M:k6=\E[17~:k7=\E[18~:k8=\E[19~:\ - :k9=\E[20~:k;=\E[21~:kB=\E[Z:kI=\E[2~:kN=\E[U:kP=\E[V:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :tc=wy370-nk: -# -# Wyse 370 with visual bell. -wy370-vb|Wyse 370 with visible bell:\ - :bl@:tc=wy370: -# -# Wyse 370 in 132-column mode. -wy370-w|Wyse 370 in 132-column mode:\ - :co#132:ws#132:\ - :r2=\E[35h\E[?3h:tc=wy370: -# -# Wyse 370 in 132-column mode with visual bell. -wy370-wvb|Wyse 370 with visible bell 132-columns:\ - :vb=\E[30h\E\\054\E[30l:tc=wy370-w: -wy370-rv|Wyse 370 reverse video:\ - :r3=\E[32h\E[?5h:tc=wy370: -# -# Wyse 99gt Tektronix 4010/4014 emulator, -# -wy99gt-tek|Wyse 99gt Tektronix 4010/4014 emulator:\ - :am:os:\ - :co#74:li#35:\ - :bl=^G:cl=\E^L:\ - :cr=^M:do=^J:ff=^L:\ - :hd=\036HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\037:\ - :ho=^]7`x @\037:\ - :hu=\036DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\037:\ - :is=\E8:le=^H:nd= :nw=^M^J:u0=\E~>\E8:u1=\E[42h:up=^K: -# -# Wyse 160 Tektronix 4010/4014 emulator, -# -wy160-tek|Wyse 160 Tektronix 4010/4014 emulator:\ - :ho=^]8`g @\037:\ - :tc=wy99gt-tek: -# -# Wyse 370 Tektronix 4010/4014 emulator, -# -wy370-tek|Wyse 370 Tektronix 4010/4014 emulator:\ - :am:os:\ - :co#80:li#36:\ - :bl=^G:cl=\E^L:\ - :cr=^M:do=^J:ff=^L:\ - :hd=\036HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\037:\ - :ho=^]8g @\037:\ - :hu=\036DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\037:\ - :is=\E8:kb=^H:kd=^J:kl=^H:kr=^I:ku=^K:le=^H:nd= :nw=^M^J:\ - :u0=\E[?38h\E8:u1=\E[?38l:up=^K: - -# Vendor-supplied Wyse entries end here. - -# -#TITLE: TERMINFO ENTRY WY520 -#DATE: 8/5/93 -# The WY520 terminfo is based on the WY285 entry published on the WYSE -# BBS with the addition of more function keys and special keys. -# -# rs1 -> set personality -# rs2 -> set number of columns -# rs3 -> set number of lines -# is1 -> select the proper font -# is2 -> do the initialization -# is3 -> If this string is empty then rs3 gets sent. -# -# Wyse 520 emulating a vt420 7 bit mode with default ANSI keyboard -# - The BS key is programmed to generate BS in smcup since -# is2 doesn't seem to work. -# - Remove and shift/Remove: delete a character -# - Insert : enter insert mode -# - Find : delete to end of file -# - Select : clear a line -# - F11, F12, F13: send default sequences (not ESC, BS, LF) -# - F14 : Home key -# - Bottom status line (host writable line) is used. -# - smkx,rmkx are removed because this would put the numeric -# keypad in Dec application mode which doesn't seem to work -# with SCO applications. -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -wy520|wyse520|wyse 520:\ - :am:hs:km:mi:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\EOw:K2=\EOy:K3=\EOu:K4=\EOq:K5=\EOs:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:ds=\E[0$~:\ - :ec=\E[%dX:ei=\E[4l:fs=\E[0$}:ho=\E[H:i1=\E[?5W:\ - :i2=\E>\E(B\017\E[m:im=\E[4h:ip=:\ - :is=\E[2;4;20;30l\E[?1;4;10;16l\E[12h\E[?7;8;25;67h:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:\ - :kb=^H:kd=\E[B:kh=\E[26~:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:\ - :rc=\E8:sc=\E7:se=\E[m:sf=\n:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :te=\E[ R:ti=\E[ Q\E[?67;8h:ts=\E[2$~\E[1$}\E[%i%d`:\ - :ue=\E[24m:up=\E[A:us=\E[4m:ve=\E[34h\E[?25h:vi=\E[?25l:\ - :vs=\E[?25h\E[34l: -# -# Wyse 520 with 24 data lines and status (terminal status) -wy520-24|wyse520-24|wyse 520 with 24 data lines:\ - :hs@:\ - :ds@:fs@:r3=\E[?5l\E[47h\E[40l\E[1;24r:ts@:tc=wy520: -# -# Wyse 520 with visual bell. -wy520-vb|wyse520-vb|wyse 520 with visible bell:\ - :vb=\E[30h\E\\054\E[30l:tc=wy520: -# -# Wyse 520 in 132-column mode. -wy520-w|wyse520-w|wyse 520 in 132-column mode:\ - :co#132:ws#132:\ - :DC=\E[%dP:IC=\E[%d@:dc=\E[P:ei=:im=:ip=:r2=\E[35h\E[?3h:tc=wy520: -# -# Wyse 520 in 132-column mode with visual bell. -wy520-wvb|wyse520-wvb|wyse 520 with visible bell 132-columns:\ - :vb=\E[30h\E\\054\E[30l:\ - :tc=wy520-w: -# -# -# Wyse 520 emulating a vt420 7 bit mode. -# The DEL key is programmed to generate BS in is2. -# With EPC keyboard. -# - 'End' key will clear till end of line on EPC keyboard -# - Shift/End : ignored. -# - Insert : enter insert mode. -# - Delete : delete a character (have to change interrupt character -# to CTRL-C: stty intr '^c') for it to work since the -# Delete key sends 7FH. -wy520-epc|wyse520-epc|wyse 520 with EPC kb:\ - :@7=\E[4~:k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:\ - :k4=\E[14~:k5=\E[15~:kD=\177:kE=\E[4~:kh=\E[H:\ - :tc=wy520: -# -# Wyse 520 with 24 data lines and status (terminal status) -# with EPC keyboard. -wy520-epc-24|wyse520-pc-24|wyse 520 with 24 data lines:\ - :hs@:\ - :ds@:fs@:r3=\E[?5l\E[47h\E[40l\E[1;24r:ts@:tc=wy520-epc: -# -# Wyse 520 with visual bell. -wy520-epc-vb|wyse520-pc-vb|wyse 520 with visible bell:\ - :vb=\E[30h\E\\054\E[30l:\ - :tc=wy520-epc: -# -# Wyse 520 in 132-column mode. -wy520-epc-w|wyse520-epc-w|wyse 520 in 132-column mode:\ - :co#132:ws#132:\ - :DC=\E[%dP:IC=\E[%d@:dc=\E[P:ei=:im=:ip=:r2=\E[35h\E[?3h:tc=wy520-epc: -# -# Wyse 520 in 132-column mode with visual bell. -wy520-epc-wvb|wyse520-p-wvb|wyse 520 with visible bell 132-columns:\ - :vb=\E[30h\E\\054\E[30l:\ - :tc=wy520-epc-w: -# -# Wyse 520 in 80-column, 36 lines -wy520-36|wyse520-36|wyse 520 with 36 data lines:\ - :hs@:\ - :li#36:\ - :ds@:fs@:r3=\E[?5l\E[36*|\E[36t\E[40l\E[1;36r:ts@:tc=wy520: -# -# Wyse 520 in 80-column, 48 lines -wy520-48|wyse520-48|wyse 520 with 48 data lines:\ - :hs@:\ - :li#48:\ - :ds@:fs@:r3=\E[?5l\E[48*|\E[48t\E[40l\E[1;48r:ts@:tc=wy520: -# -# Wyse 520 in 132-column, 36 lines -wy520-36w|wyse520-36w|wyse 520 with 36 data lines:\ - :co#132:ws#132:\ - :r2=\E[?3h:\ - :r3=\E[?5l\E[36*|\E[36t\E[40l\E[1;36r\E[132$|:tc=wy520-36: -# -# Wyse 520 in 132-column, 48 lines -wy520-48w|wyse520-48w|wyse 520 with 48 data lines:\ - :co#132:ws#132:\ - :r2=\E[?3h:\ - :r3=\E[?5l\E[48*|\E[48t\E[40l\E[1;48r\E[132$|:tc=wy520-48: -# -# -# Wyse 520 in 80-column, 36 lines with EPC keyboard -wy520-36pc|wyse520-36pc|wyse 520 with 36 data lines:\ - :hs@:\ - :li#36:\ - :ds@:fs@:r3=\E[?5l\E[36*|\E[36t\E[40l\E[1;36r:ts@:tc=wy520-epc: -# -# Wyse 520 in 80-column, 48 lines with EPC keyboard -wy520-48pc|wyse520-48pc|wyse 520 with 48 data lines:\ - :hs@:\ - :li#48:\ - :ds@:fs@:r3=\E[?5l\E[48*|\E[48t\E[40l\E[1;48r:ts@:tc=wy520-epc: -# -# Wyse 520 in 132-column, 36 lines with EPC keyboard -wy520-36wpc|wyse520-36wpc|wyse 520 with 36 data lines:\ - :co#132:ws#132:\ - :r2=\E[?3h:\ - :r3=\E[?5l\E[36*|\E[36t\E[40l\E[1;36r\E[132$|:tc=wy520-36pc: -# -# Wyse 520 in 132-column, 48 lines with EPC keyboard -wy520-48wpc|wyse520-48wpc|wyse 520 with 48 data lines:\ - :co#132:ws#132:\ - :r2=\E[?3h:\ - :r3=\E[?5l\E[48*|\E[48t\E[40l\E[1;48r\E[132$|:tc=wy520-48pc: - -# From: John Gilmore -# (wyse-vp: removed :if=/usr/share/tabset/wyse-adds:, there's no such -# file and we don't know what :st: is -- esr) -wyse-vp|wyse|Wyse 50 in ADDS Viewpoint emulation mode with "enhance" on:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :al=\EM:bl=^G:cd=\Ek:ce=\EK:cl=^L:cm=\EY%+ %+ :cr=^M:dc=\EW:\ - :dl=\El:do=^J:ei=\Er:ho=^A:im=\Eq:is=\E`\072\E`9\017\Er:\ - :kb=^H:kd=^J:kh=^A:kl=^U:kr=^F:ku=^Z:le=^H:ll=^A^Z:me=^O:\ - :nd=^F:nw=^M^J:r1=\E`\072\E`9\017\Er:se=^O:sf=^J:so=^N:\ - :ta=^I:ue=^O:up=^Z:us=^N: - -wy75ap|wyse75ap|wy-75ap|wyse-75ap|Wyse WY-75 Applications and Cursor keypad:\ - :is=\E[1;24r\E[?10;3l\E[?1;25h\E[4l\E[m\E(B\E=:kb=^H:\ - :kd=\EOB:ke=10\E[?1l\E>:kh=\EOH:kl=\EOD:kr=\EOC:\ - :ks=10\E[?1h\E=:ku=\EOA:tc=wy75: - -# From: Eric Freudenthal -wy100q|Wyse 100 for Quotron:\ - :bs:\ - :co#80:li#24:sg#1:\ - :al=\EE:bt=\EI:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :dc=\EW:\ - :dl=\ER:do=^J:ei=\Er:ho=^^:im=\Eq:\ - :is=\E`\072\200\EC\EDF\E0\E'\E(\EA21:kd=^J:kl=^H:kr=^L:\ - :ku=^K:le=^H:mk@:nd=^L:sr=\Ej:up=^K:\ - :tc=adm+sgr: - -#### Kermit terminal emulations -# -# Obsolete Kermit versions may be listed in the section describing obsolete -# non-ANSI terminal emulators later in the file. -# - -# KERMIT standard all versions. -# Straight ascii keyboard. :sr=\EI: not avail. many versions + bug prone in vi. -# (kermit: removed obsolete ":ma=^Hh^Jj^Kk^Ll^^H:" -- esr) -# From: greg small 9-25-84 -kermit|standard kermit:\ - :bs:\ - :co#80:li#24:\ - :cd=\EJ:ce=\EK:cl=\EE:cm=\EY%+ %+ :ho=\EH:\ - :is=K0 Standard Kermit 9-25-84\n:kd=^J:kh=^^:kl=^H:\ - :kr=^L:ku=^K:le=^H:nd=\EC:up=\EA: -kermit-am|standard kermit plus auto-margin:\ - :am:\ - :is=K1 Standard Kermit plus Automatic Margins\n:tc=kermit: -# IBMPC Kermit 1.2. -# Bugs: :cd:, :ce:: do not work except at beginning of line! :cl: does -# not work, but fake with :cl=\EH\EJ (since :cd=\EJ: works at beginning of -# line). -# From: greg small 8-30-84 -pckermit|pckermit12|UCB IBMPC Kermit 1.2:\ - :am:\ - :li#25:\ - :cd@:ce@:cl=\EH\EJ:\ - :is=K2 UCB IBMPC Kermit 1.2 8-30-84\n:tc=kermit: -# IBMPC Kermit 1.20 -# Cannot use line 25, now acts funny like ansi special scrolling region. -# Initialization must escape from that region by cursor position to line 24. -# Cannot use character insert because 1.20 goes crazy if insert at col 80. -# Does not use :am: because autowrap is lost when kermit dropped and restarted. -# From: greg small 12-19-84 -pckermit120|UCB IBMPC Kermit 1.20:\ - :it#8:li#24:\ - :al=\EL:dc=\EN:dl=\EM:do=\EB:ei@:im@:\ - :is=\EO\Eq\EJ\EY7 K3 UCB IBMPC Kermit 1.20 12-19-84\n:\ - :se=\Eq:so=\Ep:ta=^I:vs=\EO\Eq\EEK3:\ - :tc=kermit: -# MS-DOS Kermit 2.27 for the IBMPC -# Straight ascii keyboard. :sr=\EI: not avail. many versions + bug prone in vi. -# Cannot use line 25, now acts funny like ansi special scrolling region. -# Initialization must escape from that region by cursor position to line 24. -# Does not use am: because autowrap is lost when kermit dropped and restarted. -# Reverse video for standout like H19. -# (msk227: removed obsolete ":ma=^Hh^Jj^Kk^Ll^^H:" -- esr) -# From: greg small 3-17-85 -msk227|mskermit227|MS-DOS Kermit 2.27 for the IBMPC:\ - :am@:bs:\ - :co#80:it#8:li#24:\ - :al=\EL:cd=\EJ:ce=\EK:cl=\EE:cm=\EY%+ %+ :dc=\EN:dl=\EM:\ - :do=\EB:ei=\EO:ho=\EH:im=\E@:\ - :is=\EO\Eq\EG\Ew\EJ\EY7 K4 MS Kermit 2.27 for the IBMPC 3-17-85\n:\ - :kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:nd=\EC:rc=\Ek:sc=\Ej:\ - :se=\Eq:so=\Ep:ta=^I:up=\EA:vs=\EO\Eq\EG\EwK4: -# MS-DOS Kermit 2.27 with automatic margins -# From: greg small 3-17-85 -msk227am|mskermit227am|UCB MS-DOS Kermit 2.27 with automatic margins:\ - :am:\ - :is=\EO\Eq\EG\Ev\EJ\EY7 K5 MS Kermit 2.27 +automatic margins 3-17-85\n:\ - :vs=\EO\Eq\EG\EvK5:\ - :tc=msk227: -# MS-DOS Kermit 2.27 UCB 227.14 for the IBM PC -# Automatic margins now default. Use ansi :sa: for highlights. -# Define function keys. -# (msk22714: removed obsolete ":kn#10:" -- esr) -# From: greg small 3-17-85 -msk22714|mskermit22714|UCB MS-DOS Kermit 2.27 UCB 227.14 IBM PC:\ - :am:\ - :is=\EO\Eq\EG\Ev\EJ\EY7 K6 MS Kermit 2.27 UCB 227.14 IBM PC 3-17-85\n:\ - :k0=\E0:k1=\E1:k2=\E2:k3=\E3:k4=\E4:k5=\E5:k6=\E6:k7=\E7:\ - :k8=\E8:k9=\E9:md=\E[1m:me=\E[m:mr=\E[7m:se=\E[m:so=\E[1m:\ - :ue=\E[m:us=\E[4m:vs=\EO\Eq\EG\EvK6:\ - :tc=mskermit227: -# This was designed for a VT320 emulator, but it is probably a good start -# at support for the VT320 itself. -# Please send changes with explanations to bug-gnu-emacs@prep.ai.mit.edu. -# (vt320-k3: I added / based on the init string -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -vt320-k3|MS-Kermit 3.00's vt320 emulation:\ - :am:es:hs:km:mi:ms:xn:\ - :co#80:it#8:li#49:pb#9600:vt#3:\ - :AL=\E[%dL:CC=\E:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SR=\E[%dL:UP=\E[%dA:ae=\E(B:al=\E[L:\ - :as=\E(0:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ds=\E[0$~:ec=\E[%dX:ei=\E[4l:fs=\E[0$}:ho=\E[H:im=\E[4h:\ - :is=\E>\E F\E[?1l\E[?7h\E[r\E[2$~:k0=\E[21~:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:k8=\E[19~:\ - :k9=\E[20~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:\ - :ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=^M^J:rc=\E8:\ - :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E[1$}\r\E[K:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l\E[?5h\E[?5l\E[?5h\E[?5l:ve=\E[?25h:\ - :vi=\E[?25l: -# From: Joseph Gil 13 Dec 1991 -# ACS capabilities from Philippe De Muyter 30 May 1996 -# (I removed a bogus boolean :mo: and added :ms:, , -- esr) -vt320-k311|dec vt320 series as defined by kermit 3.11:\ - :am:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=^O:al=3\E[L:as=^N:bl=^G:cd=\E[J:ce=\E[K:cl=\E[;H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ds=\E[2$~\r\E[1$}\E[K\E[$}:ei=\E[4l:\ - :fs=\E[$}:ho=\E[H:im=\E[4h:\ - :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;24r\E[24;1H:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k6=\E[17~:k7=\E[18~:\ - :k8=\E[19~:k9=\E[20~:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l1=pf1:l2=pf2:l3=pf3:l4=pf4:\ - :le=^H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:nw=^M\ED:\ - :r1=\E[?3l:rc=\E8:rf=/usr/share/tabset/vt100:sc=\E7:\ - :se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E[2$~\E[1$}\E[1;%dH:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: - -######## NON-ANSI TERMINAL EMULATIONS -# - -#### Avatar -# -# These entries attempt to describe Avatar, a terminal emulation used with -# MS-DOS bulletin-board systems. It was designed to give ANSI-like -# capabilities, but with cheaper (shorter) control sequences. Messy design, -# excessively dependent on PC idiosyncracies, but apparently rather popular -# in the BBS world. -# -# No color support. Avatar doesn't fit either of the Tektronix or HP color -# models that terminfo knows about. An Avatar color attribute is the -# low 7 bits of the IBM-PC display-memory attribute. Bletch. -# -# I wrote these entries while looking at the Avatar spec. I don't have -# the facilities to test them. Let me know if they work, or don't. -# -# From: Eric S. Raymond 1 Nov 1995 -# (The :mb:/:md:/:mr:/:as:/:us:/:so: capabilities exist only to -# tell ncurses that the corresponding highlights exist; it should use :sa:, -# which is the only method that will actually work for multiple highlights.) -avatar0|avatar terminal emulator level 0:\ - :am:ms:ut:\ - :co#80:it#8:li#25:\ - :as=:ce=^V^G:cm=\026\010%.%.:cr=^M:do=^V^D:le=^V^E:\ - :mb=^A^V\177:md=^V^A^P:me=^V^A^G:mk=^V^A\200:mr=^A^Vp:\ - :nd=^V^F:r2=^L:rp=\031%.%d:\ - :sf=^J:so=^A^Vp:up=^V^C:us=^V^A:\ - :tc=klone+acs: -# From: Eric S. Raymond 1 Nov 1995 -avatar0+|avatar terminal emulator level 0+:\ - :dc=^V^N:ei=\026\n\200\200\200\200:im=^V^I:tc=avatar0: -# From: Eric S. Raymond 1 Nov 1995 -avatar|avatar1|avatar terminal emulator level 1:\ - :RA=^V":SA=^V$:al=^V+:dl=^V-:ei=^V^P:ve=^V'^A:vi=^V'^B:\ - :vs=^V^C:\ - :tc=avatar0+: - -#### RBcomm -# -# RBComm is a lean and mean terminal emulator written by the Interrupt List -# mantainer, Ralf Brown. It was fairly popular in the late DOS years (early -# '90s), especially in the BBS world, and still has some loyal users due to -# its very small memory footprint and to a cute macro language. -rbcomm|IBM PC with RBcomm and EMACS keybindings:\ - :am:bw:mi:ms:xn:\ - :co#80:it#8:li#25:\ - :AL=\E[%dL:DL=\E[%dM:al=^K:bl=^G:bt=\E[Z:cd=^F5:ce=^P^P:\ - :cl=^L:cm=\037%r%+ %+ :cr=^M:cs=\E[%i%d;%dr:dc=^W:dl=^Z:\ - :dm=:do=^C:ec=\E[%dX:ed=:ei=^]:im=^\:\ - :is=\017\035\E(B\E[?7h\E[?3l\E[>8g:kb=^H:kd=^N:\ - :ke=\E>:kh=^A:kl=^B:kr=^F:ks=\E=:ku=^P:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mk=\E[8m:mr=^R:nd=^B:nw=^M\ED:\ - :r1=\017\E(B\025\E[?3l\E[>8g:rc=\E8:rp=\030%.%.:\ - :sc=\E7:se=^U:sf=\ED:so=^R:sr=\EM:ta=^I:te=:ti=:ue=^U:up=^^:\ - :us=^T:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: -rbcomm-nam|IBM PC with RBcomm, no autowrap:\ - :am@:\ - :bl=^G:cr=^M:do=^J:\ - :is=\017\035\E(B\E[?7l\E[?3l\E[>8g:kb=^H:kd=^J:\ - :kl=^H:nw=^M^J:sf=^J:ta=^I:\ - :tc=rbcomm: -rbcomm-w|IBM PC with RBcomm, 132 column mode:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:\ - :is=\017\035\E(B\E[?7h\E[?3h\E[>8g:kb=^H:kd=^J:\ - :kl=^H:nw=^M^J:sf=^J:ta=^I:\ - :tc=rbcomm: - -######## OLDER TERMINAL TYPES -# -# This section is devoted to older commercial terminal brands that are now -# discontinued, but known to be still in use or represented by emulations. -# - -#### AT&T (att, tty) -# -# This section also includes Teletype-branded VDTs. -# -# The AT&T/Teletype terminals group was sold to SunRiver Data Systems (now -# Boundless Technologies); for details, see the header comment on the ADDS -# section. -# -# These are AT&T's official terminfo entries. All-caps aliases have been -# removed. -# -att2300|sv80|AT&T 2300 Video Information Terminal 80 column mode:\ - :am:eo:mi:ms:xo:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[11r:\ - :F2=\E[12r:F3=\E[13r:F4=\E[14r:F5=\E[15r:F6=\E[16r:\ - :IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:\ - :cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :k1=\E[1r:k2=\E[2r:k3=\E[3r:k4=\E[4r:k5=\E[5r:k6=\E[6r:\ - :k7=\E[7r:k8=\E[8r:k9=\E[9r:k;=\E[10r:kA=\E[L:kB=\E[Z:\ - :kC=\E[J:kD=\E[P:kI=\E[@:kL=\E[M:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:me=\E[m:mr=\E[7m:nd=\E[C:\ - :pf=\E[4i:po=\E[5i:ps=\E[0i:se=\E[m:sf=^J:so=\E[7m:ta=^I:\ - :up=\E[A: -att2350|AT&T 2350 Video Information Terminal 80 column mode:\ - :pf@:po@:ps@:\ - :tc=att2300: - -# Must setup RETURN KEY - CR, REC'VD LF - INDEX. -# Seems upward compatible with vt100, plus ins/del line/char. -# On sgr, the protection parameter is ignored. -# No check is made to make sure that only 3 parameters are output. -# standout= reverse + half-intensity = 3 | 5. -# bold= reverse + underline = 2 | 3. -# note that half-bright blinking doesn't look different from normal blinking. -# NOTE:you must program the function keys first, label second! -# (att4410: a BSD entry has been seen with the following capabilities: -# :is=\E[?6l:, :k1=\EOc:, :k2=\EOd:, :k3=\EOe:, :k4=\EOg:, -# :k6=\EOh:, :k7=\EOi:, :k8=\EOj:, -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -att5410v1|att4410v1|tty5410v1|AT&T 4410/5410 80 columns - version 1:\ - :am:hs:mi:ms:xo:\ - :Nl#8:co#80:it#8:lh#2:li#24:lw#8:ws#80:\ - :ac=``aaffhhggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~00++--\054\054..:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=:fs=\E8:ho=\E[H:i1=\E[?3l:\ - :i2=\E[1;03q f1 \EOP\E[2;03q f2 \EOQ\E[3;03q f3 \EOR\E[4;03q f4 \EOS\E[5;03q f5 \EOT\E[6;03q f6 \EOU\E[7;03q f7 \EOV\E[8;03q f8 \EOW:\ - :ic=\E[@:im=:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOT:\ - :k6=\EOU:k7=\EOV:k8=\EOW:kC=\E[2J:kH=\E[24;1H:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:ll=\E[24H:\ - :mb=\E[5m:md=\E[2;7m:me=\E[m\017:mh=\E[2m:mk=\E[8m:\ - :mr=\E[7m:nd=\E[C:nw=^M^J:r2=\Ec\E[?3l\E[2;0y:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:\ - :ts=\E7\E[25;%+^AH:ue=\E[m:up=\E[A:us=\E[4m: - -att4410v1-w|att5410v1-w|tty5410v1-w|AT&T 4410/5410 132 columns - version 1:\ - :co#132:ws#132:\ - :i1=\E[?3h:r2=\Ec\E[?3h\E[2;0y:tc=att5410v1: - -att4410|att5410|tty5410|AT&T 4410/5410 80 columns - version 2:\ - :bs:\ - :tc=att5410v1: - -att5410-w|att4410-w|4410-w|tty5410-w|5410-w|AT&T 4410/5410 in 132 column mode:\ - :co#132:ws#132:\ - :i1=\E[?3h:r2=\Ec\E[?3h\E[2;0y:tc=att4410: - -# 5410 in terms of a vt100 -# (v5410: added / based on init string -- esr) -v5410|att5410 in terms of a vt100:\ - :am:mi:ms:xo:\ - :co#80:it#8:li#24:vt#3:\ - :@8=\EOM:K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:RA=\E[?7l:\ - :SA=\E[?7h:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:eA=\E(B:ei=:ho=\E[H:\ - :ic=\E[@:im=:k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:kb=^H:\ - :kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:mr=\E[7m:\ - :nd=\E[C:r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[1;7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: - -# -# Teletype Model 5420 -- A souped up 5410, with multiple windows, -# even! the 5420 has three modes: scroll, window or page mode -# this terminfo should work in scroll or window mode, but doesn't -# take advantage of any of the differences between them. -# -# Has memory below (2 lines!) -# 3 pages of memory (plus some spare) -# The 5410 sequences for :cm:, :vs:, :DC:, :DL:, :ec:, :vb:, :ho:, -# , :st: would work for these, but these work in both scroll and window -# mode... Unset insert character so insert mode works -# :i1: sets 80 column mode, -# :is: escape sequence: -# 1) turn off all fonts -# 2) function keys off, keyboard lock off, control display off, -# insert mode off, erasure mode off, -# 3) full duplex, monitor mode off, send graphics off, nl on lf off -# 4) reset origin mode -# 5) set line wraparound -# 6) exit erasure mode, positional attribute mode, and erasure extent mode -# 7) clear margins -# 8) program ENTER to transmit ^J, -# We use \212 to program the ^J because a bare ^J will get translated by -# UNIX into a CR/LF. The enter key is needed for AT&T uOMS. -# 1 2 3 4 5 6 7 8 -# :i3: set screen color to black, -# No representation in terminfo for the delete word key: kdw1=\Ed -# Key capabilities assume the power-up send sequence... -# This :te: is not strictly necessary, but it helps maximize -# memory usefulness: :te=\Ez:, -# Alternate sgr0: :me=\E[m\EW^O:, -# Alternate sgr: :sa=\E[%?%p1%t2;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m%?%p8%t\EV%;%?%p9%t^N%e^O%;:, -# smkx programs the SYS PF keys to send a set sequence. -# It also sets up labels f1, f2, ..., f8, and sends edit keys. -# This string causes them to send the strings :k1:-:k8: -# when pressed in SYS PF mode. -# (att4415: I added / based on the init string -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -att4415|tty5420|att5420|AT&T 4415/5420 80 cols:\ - :bs:db:mi:xo:\ - :Nl#8:lh#2:lm#78:lw#8:ws#55:\ - :@1=\Et:@7=\Ez:@8=\Eent:AL=\E[%dL:CM=\E[%i%d;%dt:\ - :DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:LF=\E|:\ - :LO=\E~:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:SF=\E[%dE:SR=\E[%dF:\ - :UP=\E[%dA:bt=\E[Z:ch=\E[%+^AG:cl=\E[x\E[J:\ - :cm=\E[%i%d;%dx:ct=\E[3g:cv=\E[%+^Ad:ec=\E[%ds\E[%dD:\ - :ei=\E[4l:ho=\E[x:i1=\E[?3l:i2=\E[?5l:ic@:im=\E[4h:\ - :is=\E[m\017\E[1;2;3;4;6l\E[12;13;14;20l\E[?6;97;99l\E[?7h\E[4i\Ex\E[21;1j\212:\ - :k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:k5=\EOg:k6=\EOh:k7=\EOi:\ - :k8=\EOj:kA=\E[L:kB=\E[Z:kD=\E[P:kE=\E[2K:kF=\E[T:kH=\Eu:\ - :kI=\E[4h:kL=\E[M:kN=\E[U:kP=\E[V:kR=\E[S:\ - :ke=\E[19;0j\E[21;1j\212:ks=\E[19;1j\E[21;4j\Eent:\ - :l1=F1:l2=F2:l3=F3:l4=F4:l5=F5:l6=F6:l7=F7:l8=F8:ll=\Ew:\ - :me=\E[m\017:mp=\EV:pf=\E[?9i:po=\E[?4i:ps=\E[?2i:st=\EH:\ - :ts=\E7\E[25;%+^HH:vb=\E[?5h\E[?5l:ve=\E[11;0j:\ - :vs=\E[11;1j:\ - :tc=att4410: - -att4415-w|tty5420-w|att5420-w|AT&T 4415/5420 132 cols:\ - :co#132:lm#54:ws#97:\ - :i1=\E[?3h:tc=att4415: - -att4415-rv|tty5420-rv|att5420-rv|AT&T 4415/5420 80 cols/rv:\ - :i2=\E[?5h:vb=\E[?5l\E[?5h:\ - :tc=att4415: - -att4415-w-rv|tty5420-w-rv|att5420-w-rv|AT&T 4415/5420 132 cols/rv:\ - :co#132:lm#54:ws#97:\ - :i1=\E[?3h:i2=\E[?5h:vb=\E[?5l\E[?5h:tc=att4415: - -# Note that this mode permits programming USER PF KEYS and labels -# However, when you program user pf labels you have to reselect -# user pf keys to make them appear! -att4415+nl|tty5420+nl|att5420+nl|generic AT&T 4415/5420 changes for not changing labels:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@: - -att4415-nl|tty5420-nl|att5420-nl|AT&T 4415/5420 without changing labels:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:\ - :tc=att4415+nl:tc=att4415: - -att4415-rv-nl|tty5420-rv-nl|att5420-rv-nl|AT&T 4415/5420 reverse video without changing labels:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:\ - :tc=att4415+nl:tc=att4415-rv: - -att4415-w-nl|tty5420-w-nl|att5420-w-nl|AT&T 4415/5420 132 cols without changing labels:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:\ - :tc=att4415+nl:tc=att4415-w: - -att4415-w-rv-n|tty5420-w-rv-n|att5420-w-rv-n|AT&T 4415/5420 132 cols reverse without changing labels:\ - :k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:\ - :tc=att4415+nl:tc=att4415-w-rv: - -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att5420_2|AT&T 5420 model 2 80 cols:\ - :am:db:hs:mi:ms:xo:\ - :co#80:it#8:li#24:lm#78:ws#55:\ - :AL=\E[%dL:CM=\E[%i%d;%dt:DC=\E[%dP:DL=\E[%dM:\ - :IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:SF=\E[%dE:SR=\E[%dF:\ - :UP=\E[%dA:ae=^O:al=\E[L:as=^N:bt=\E[1Z:cd=\E[0J:ce=\E[0K:\ - :cl=\EH\EJ:cm=\E[%i%d;%dH:cr=\EG:cs=\E[%i%d;%dr:ct=\E[3g:\ - :dc=\E[P:dl=\E[M:do=\E[1B:ec=\E[%ds\E[%dD:ei=:fs=\E8:\ - :ho=\E[H:\ - :i1=\E[0;23r\Ex\Ey\E[2;0j\E[3;3j\E[4;0j\E[5;0j\E[6;0j\E[7;0j\E[8;0j\E[9;1j\E[10;0j\E[15;0j\E[16;1j\E[19;0j\E[20;1j\E[29;0j\E[1;24r:\ - :ic=\E[@:im=:k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:k5=\EOg:\ - :k6=\EOh:k7=\EOi:k8=\EOj:kD=\E[P:kH=\Eu:kI=\E[4h:kN=\E[U:\ - :kP=\E[V:kb=^H:kd=\E[B:ke=\E[19;0j:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\E[19;1j:ku=\E[A:le=^H:ll=\Ew:mb=\E[5m:me=\E[m\017:\ - :mh=\E[2m:mr=\E[7m:nd=\E[1C:nw=^M^J:rc=\E8:sc=\E7:se=\E[m:\ - :sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ts=\E7\E[25;%+^HH:ue=\E[m:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[11;0j:vs=\E[11;1j: -att5420_2-w|AT&T 5420 model 2 in 132 column mode:\ - :co#132:\ - :i1=\E[0;23r\Ex\Ey\E[2;0j\E[3;3j\E[4;0j\E[5;1j\E[6;0j\E[7;0j\E[8;0j\E[9;1j\E[10;0j\E[15;0j\E[16;1j\E[19;0j\E[20;1j\E[29;0j\E[1;24r:tc=att5420_2: - -att4418|att5418|AT&T 5418 80 cols:\ - :am:xo:\ - :co#80:li#24:\ - :@8=\E[:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[n:\ - :F2=\E[o:F3=\E[H:F4=\E[I:F5=\E[J:F8=\E[K:F9=\E[L:FA=\E[E:\ - :FB=\E[_:FC=\E[M:FD=\E[N:FE=\E[O:IC=\E[%d@:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[1L:as=\E(0:bl=^G:cd=\E[0J:ce=\E[0K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[1P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :i1=\E[?3l:ic=\E[1@:im=:is=\E?6l\E?5l:k1=\E[h:k2=\E[i:\ - :k3=\E[j:k6=\E[k:k7=\E[l:k8=\E[f:k9=\E[w:k;=\E[m:kC=\E[%:\ - :kd=\EU:kh=\Ec:kl=\E@:kr=\EA:ku=\ES:le=\E[D:mb=\E[5m:\ - :me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:\ - :se=\E[m:sf=^J:so=\E[7m:ue=\E[m:up=\E[A:us=\E[4m: -att4418-w|att5418-w|AT&T 5418 132 cols:\ - :co#132:\ - :i1=\E[?3h:tc=att5418: - -att4420|tty4420|teletype 4420:\ - :bs:da:db:eo:ms:ul:xo:\ - :co#80:li#24:lm#72:\ - :al=\EL:bl=^G:cd=\EJ:ce=\Ez:cl=\EH\EJ:cm=\EY%+ %+ :cr=\EG:\ - :dc=\EP:dl=\EM:dm@:do=\EB:ed@:ho=\EH:k0=\EU:k3=\E@:kA=\EL:\ - :kB=\EO:kC=\EJ:kD=\EP:kF=\ES:kI=\E\136:kL=\EM:kR=\ET:kd=\EB:\ - :kh=\EH:kl=^H:kr=\EC:ku=\EA:l0=segment advance:\ - :l3=cursor tab:le=\ED:nd=\EC:se=\E~:sf=\EH\EM\EY7 :so=\E}:\ - :ue=\EZ:up=\EA:us=\E\\: - -# The following is a terminfo entry for the Teletype 4424 -# asynchronous keyboard-display terminal. It supports -# the vi editor. The terminal must be set up as follows, -# -# HIGHLIGHT DEFINITION 3-TONE -# DISPLAY FUNCTION GROUP III -# -# The second entry below provides limited (a la adm3a) -# operation under GROUP II. -# -# This must be used with DISPLAY FUNCTION GROUP I or III -# and HIGHLIGHT DEFINITION 3-TONE -# The terminal has either bold or blink, depending on options -# -# (att4424: commented out :ti:=\E[1m, we don't need bright locked on -- esr) -att4424|tty4424|teletype 4424:\ - :am:bs:xo:\ - :co#80:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\EL:as=\E(0:bl=^G:bt=\EO:cd=\EJ:ce=\Ez:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\EF:\ - :dc=\EP:dl=\EM:do=\EB:ei=:ho=\E[H:ic=\E\136:im=:\ - :is=\E[20l\E[?7h:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kC=\EJ:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E3:\ - :md=\E3:me=\EX\E~\EZ\E4\E(B:mh=\EW:mr=\E}:nd=\EC:nw=\EE:\ - :se=\E~:sf=^J:so=\E}:sr=\ET:st=\EH:ta=^I:ue=\EZ:up=\EA:\ - :us=\E\\: - -att4424-1|tty4424-1|teletype 4424 in display function group I:\ - :kC@:kd=\EB:kh@:kl=\ED:kr=\EC:ku=\EA:\ - :tc=att4424: - -# This entry is not one of AT&T's official ones, it was translated from the -# 4.4BSD termcap file. The highlight strings are different from att4424. -# I have no idea why this is -- older firmware version, maybe? -# The following two lines are the comment originally attached to the entry: -# This entry appears to avoid the top line - I have no idea why. -# From: jwb Wed Mar 31 13:25:09 1982 remote from ihuxp -att4424m|tty4424m|teletype 4424M:\ - :am:da:db:mi:\ - :co#80:it#8:li#23:\ - :al=\EL:bl=^G:ce=\E[K:cl=\E[2;H\E[J:cm=\E[%i%2;%2H\E[B:\ - :cr=^M:dc=\EP:dl=\EM:do=^J:ei=:ic=\E\136:im=:ip=2:\ - :is=\E[m\E[2;24r:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:me=\E[m:\ - :nd=\E[C:nw=^M^J:se=\E[m:sf=^J:so=\E[7m:sr=\ET:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: - -# The Teletype 5425 is really version 2 of the Teletype 5420. It -# is quite similar, except for some minor differences. No page -# mode, for example, so all of the :cm: sequences used above have -# to change back to what's being used for the 5410. Many of the -# option settings have changed their numbering as well. -# -# This has been tested on a preliminary model. -# -# (att5425: added / based on the init string -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att5425|tty5425|att4425|AT&T 4425/5425:\ - :am:da:db:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:lm#78:ws#55:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dE:SR=\E[%dF:UP=\E[%dA:ae=^O:\ - :al=\E[L:as=^N:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ec=\E[%ds\E[%dD:ei=\E[4l:fs=\E8:ho=\E[H:\ - :i1=\E<\E[?3l:i2=\E[?5l:im=\E[4h:\ - :is=\E[m\017\E[1;2;3;4;6l\E[12;13;14;20l\E[?6;97;99l\E[?7h\E[4i\Ex\E[25;1j\212:\ - :k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:k5=\EOg:k6=\EOh:k7=\EOi:\ - :k8=\EOj:kD=\E[P:kI=\E[4h:kb=^H:kd=\E[B:\ - :ke=\E[21;0j\E[25;1j\212:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\E[21;1j\E[25;4j\Eent\E~:ku=\E[A:le=^H:ll=\E[24H:\ - :mb=\E[5m:md=\E[2;7m:me=\E[m\017:mh=\E[2m:mr=\E[7m:\ - :nd=\E[C:nw=^M^J:rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:\ - :sr=\EM:st=\EH:ta=^I:ts=\E7\E[25;%+^HH:ue=\E[m:\ - :up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[12;0j:\ - :vs=\E[12;1j: - -att5425-nl|tty5425-nl|att4425-nl|AT&T 4425/5425 80 columns no labels:\ - :ks=\E[21;1j\E[25;4j\Eent:\ - :tc=att4425: - -att5425-w|att4425-w|tty5425-w|teletype 4425/5425 in 132 column mode:\ - :co#132:lm#54:ws#97:\ - :i1=\E[?3h:tc=tty5425: - -# (att4426: his had bogus capabilities: :ri=\EM:, :ri=\E[1U:. -# I also added / -- esr) -att4426|tty4426|teletype 4426S:\ - :am:da:db:xo:\ - :co#80:li#24:lm#48:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:SF=\E[%dS:\ - :SR=\E[%dT:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\EL:as=\E(0:bl=^G:cd=\E[J:ce=\E[0K:ch=\E[%dG:\ - :cl=\E[H\E[2J\E[1U\E[H\E[2J\E[1V:cm=\E[%i%d;%dH:cr=^M:\ - :ct=\E[3g:cv=\E[%dd:dc=\EP:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :i1=\Ec\E[?7h:ic=\E\136:im=:is=\E[m\E[1;24r:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOT:k6=\EOU:k7=\EOV:k8=\EOW:\ - :kB=\EO:kC=\E[2J:kH=\E[24;1H:kb=^H:kd=\EB:kh=\E[H:kl=\ED:\ - :kr=\EC:ku=\EA:le=\E[D:ll=\E[24H:md=\E[5m:me=\E[m\E(B:\ - :mr=\E[7m:nd=\E[C:nw=^M^J:r2=\Ec\E[?3l\E[2;0y:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[5m:sr=\ET:st=\E1:ta=^I:ue=\E[m:\ - :up=\EA:us=\E[4m: - -# Terminfo entry for the AT&T 510 A Personal Terminal -# Function keys 9 - 16 are available only after the -# screen labeled (soft keys/action blocks) are labeled. Function key -# 9 corresponds to the leftmost touch target on the screen, -# function key 16 corresponds to the rightmost. -# -# This entry is based on one done by Ernie Rice at Summit, NJ and -# changed by Anne Gallup, Skokie, IL, ttrdc!anne -# (untranslatable capabilities removed to fit entry within 1023 bytes) -att510a|bct510a|AT&T 510A Personal Terminal:\ - :am:mi:ms:xn:xo:\ - :Nl#8:co#80:lh#2:li#24:lw#7:\ - :#4=\E[u:%i=\E[v:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:\ - :F1=\EOe:F2=\EOf:F3=\EOg:F4=\EOh:F5=\EOi:F6=\EOj:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:\ - :ac=hrisjjkkllmmnnqqttuuvvwwxx{{||}}~~-f\054h.e+g`b:\ - :ae=\E(B:al=\E[L:as=\E(1:bl=^G:bt=\E[Z:cb=\E[1K:cd=\E[0J:\ - :ce=\E[0K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:\ - :dc=\E[P:dl=\E[M:do=\E[1B:eA=\E(B:ff=^L:ho=\E[H:\ - :i1=\E(B\E[2l:i2=\E[21;1|\212:k1=\EOm:k2=\EOV:\ - :k3=\EOu:k4=\ENj:k5=\ENe:k6=\ENf:k7=\ENh:k8=\E[H:k9=\EOc:\ - :k;=\EOd:kB=\E[Z:kF=\E[S:kR=\E[T:kb=^H:kd=\E[B:ke=\E[19;0|:\ - :kl=\E[D:kr=\E[C:ks=\E[19;1|:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[2;7m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:nw=\EE:\ - :pf=\E[?8i:po=\E[?4i:ps=\E[0i:rc=\E8:sc=\E7:se=\E[m:sf=^J:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E[11;3|:vi=\E[11;0|:vs=\E[11;2|: - -# Terminfo entry for the AT&T 510 D Personal Terminal -# Function keys 9 through 16 are accessed by bringing up the -# system blocks. -# Function key 9 corresponds to the leftmost touch target on the screen, -# function key 16 corresponds to the rightmost. -# -# There are problems with soft key labeling. These are due to -# strangenesses in the native terminal that are impossible to -# describe in a terminfo. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att510d|bct510d|AT&T 510D Personal Terminal:\ - :am:da:db:mi:ms:xn:xo:\ - :co#80:li#24:lm#48:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ae=\E(B:\ - :al=\E[L:as=\E(1:bl=^G:bt=\E[Z:cd=\E[0J:ce=\E[0K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:dc=\E[P:dl=\E[M:do=\E[1B:\ - :ei=\E[4l:ff=^L:ho=\E[H:i1=\E(B\E[5;0|:\ - :i2=\E[21;1|\212:im=\E[4h:k1=\EOm:k2=\EOV:k3=\EOu:k4=\ENj:\ - :k5=\ENe:k6=\ENf:k7=\ENh:k8=\E[H:k9=\EOc:kb=^H:kd=\E[B:\ - :ke=\E[19;0|:kl=\E[D:kr=\E[C:ks=\E[19;1|:ku=\E[A:le=^H:\ - :ll=\E#2:mb=\E[5m:md=\E[2;7m:me=\E[m\017:mh=\E[2m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:rc=\E8:sc=\E7:se=\E[m:sf=^J:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E[11;3|:vs=\E[11;2|: - -# (att500: I merged this with the att513 entry, att500 just used att513 -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att500|att513|AT&T 513 using page mode:\ - :am:mi:ms:xn:xo:\ - :co#80:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dE:SR=\E[%dF:UP=\E[%dA:ae=^O:\ - :al=\E[L:as=^N:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=%i\E[%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ei=\E[4l:ho=\E[H:\ - :i1=\E?\E[3;3|\E[10;0|\E[21;1|\212\E[6;1|\E[1{\E[?99l:\ - :im=\E[4h:k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:k5=\EOg:k6=\EOh:\ - :k7=\EOi:k8=\EOj:kD=\ENf:kI=\ENj:kN=\E[U:kP=\E[V:kb=^H:\ - :kd=\E[B:ke=\E[19;0|\E[21;1|\212:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\E[19;1|\E[21;4|\Eent:ku=\E[A:le=^H:ll=\E#2:mb=\E[5m:\ - :md=\E[2;7m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:nw=\EE:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m:ve=\E[11;0|:vs=\E[11;1|: - -# 01-07-88 -# printer must be set to EMUL ANSI to accept ESC codes -# :up: stops at top margin -# :i1: sets cpi 10,lpi 6,form 66,left 1,right 132,top 1,bottom 66,font -# and alt font ascii,wrap on,tabs cleared -# :is: disables newline on LF,Emphasized off -# The capability sets form length -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att5310|att5320|AT&T Model 53210 or 5320 matrix printer:\ - :co#132:it#8:li#66:\ - :DO=\E[%de:RI=\E[%da:cr=^M:do=^J:ff=^L:i1=\Ec:is=\E[20l\r:\ - :nd= :ta=^I:up=\EM: - -# Teletype 5620, firmware version 1.1 (8;7;3) or earlier from BRL -# The following SET-UP modes are assumed for normal operation: -# CR_DEF=CR NL_DEF=INDEX DUPLEX=FULL -# Other SET-UP modes may be set for operator convenience or communication -# requirements. This termcap description is for the Resident Terminal Mode. -# No delays specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# The BRL entry also said: UNSAFE :ll=\E[70H: -att5620-1|tty5620-1|dmd1|Teletype 5620 with old ROMs:\ - :am:xo:\ - :co#88:it#8:li#70:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:SF=\E[%dS:\ - :SR=\E[%dT:al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=^J:ei=:ho=\E[H:\ - :ic=\E[@:im=:kC=\E[2J:kH=\E[70;1H:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:nd=\E[C:nw=^M^J:r1=\Ec:\ - :rc=\E8:sc=\E7:sf=^J:sr=\E[T:ta=^I:up=\E[A: - -# 5620 terminfo (2.0 or later ROMS with char attributes) -# The following SET-UP modes are assumed for normal operation: -# DUPLEX=FULL GEN_FLOW=ON NEWLINE=INDEX RETURN=CR -# Other SET-UP modes may be set for operator convenience or communication -# requirements. This termcap description is for Resident Terminal Mode. No -# delays are specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# assumptions: :sf: (scroll forward one line) is only done at screen bottom -# Be aware that older versions of the dmd have a firmware bug that affects -# parameter defaulting; for this terminal, the 0 in \E[0m is not optional. -# :ms: is from an otherwise inferior BRL for this terminal. That entry -# also has :ll:=\E[70H commented out and marked unsafe. -# For more, see the 5620 FAQ maintained by David Breneman . -att5620|dmd|tty5620|ttydmd|5620|5620 terminal 88 columns:\ - :NL:NP:am:bs:ms:xo:\ - :co#88:it#8:li#70:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:SF=\E[%dS:\ - :SR=\E[%dT:al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :ic=\E[@:im=:kC=\E[2J:kH=\E[70;1H:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:md=\E[2m:me=\E[0m:mh=\E[2m:\ - :mr=\E[7m:nd=\E[C:nw=^J:\ - :r1=\Ec:rc=\E8:sc=\E7:se=\E[0m:sf=\E[S:so=\E[7m:sr=\E[T:\ - :ta=^I:ue=\E[0m:up=\E[A:us=\E[4m: -att5620-24|tty5620-24|dmd-24|teletype dmd 5620 in a 24x80 layer:\ - :li#24:tc=att5620: -att5620-34|tty5620-34|dmd-34|teletype dmd 5620 in a 34x80 layer:\ - :li#34:tc=att5620: -# 5620 layer running the "S" system's downloaded graphics handler: -att5620-s|tty5620-s|layer|vitty|5620 S layer:\ - :am:bs:pt:\ - :co#80:it#8:li#72:\ - :al=\EI:bl=^G:ce=\EK:cl=^L:cm=\EY%r%+ %+ :cr=^M:dl=\ED:\ - :do=^J:kC=\E[2J:kH=\E[70;1H:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=^H:sf=^J:ta=^I:up=^K:vb=\E^G: - -# Entries for thru refer to the shifted system pf keys. -# -# Entries for thru refer to the alternate keypad mode -# keys: = * / + 7 8 9 - 4 5 6 , 1 2 3 0 . ENTER -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att605|AT&T 605 80 column 102key keyboard:\ - :am:eo:xo:\ - :co#80:li#24:ws#80:\ - :DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:ae=\E(B:al=\E[L:as=\E(0:\ - :bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:fs=\E8:\ - :i1=\E[8;0|\E[?\E[13;20l\E[?\E[12h:ic=\E[@:im=\E[4h:\ - :is=\E[m\017:k1=\EOc:k2=\EOd:k3=\EOe:k4=\EOf:k5=\EOg:\ - :k6=\EOh:k7=\EOi:k8=\EOj:k9=\ENo:kD=\E[P:kI=\E[@:kN=\E[U:\ - :kP=\E[V:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:ll=\E[24H:mb=\E[5m:md=\E[1m:me=\E[m\017:mh=\E[2m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:rc=\E8:sc=\E7:se=\E[m:sf=^J:\ - :so=\E[7m:ta=^I:ts=\E7\E[25;%i%dx:ue=\E[m:up=\E[A:\ - :us=\E[4m: -att605-pc|ATT 605 in pc term mode:\ - :@7=\E[F:AL=\E[L:S4=250\E[?11l\E[50;1|:S5=400\E[50;0|:\ - :XF=g:XN=e:\ - :ac=k\277l\332m\300j\331n\305w\302q\304u\264t\303v\301x\263:\ - :al=\E[L:bt=\E[Z:dc=\E[P:dl=\E[M:do=\E[B:ei=:ic=\E[@:im=:\ - :k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:k6=\E[R:k7=\E[S:\ - :k8=\E[T:k9=\E[U:k;=\E[V:kB=\E[Z:kD=\E[P:kI=\E[@:kL=\E[M:\ - :kN=\E[G:kP=\E[I:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=\E[D:nd=\E[C:up=\E[A:\ - :tc=att605: -att605-w|AT&T 605-w 132 column 102 key keyboard:\ - :co#132:ws#132:\ - :i1=\E[8;0|\E[?4;5;13;15l\E[13;20l\E[?3;7h\E[12h\E(B:tc=att605: -# (att610: I added / based on the init string. I also -# added :SF: and :SR: because the BSD file says the att615s have them, -# and the 615 is like a 610 with a big keyboard, and most of their other -# smart terminals support the same sequence -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att610|AT&T 610; 80 column; 98key keyboard:\ - :am:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ae=\E(B:\ - :al=\E[L:as=\E(0:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=\E[4l:fs=\E8:ho=\E[H:\ - :i1=\E[8;0|\E[?3;4;5;13;15l\E[13;20l\E[?7h\E[12h\E(B:\ - :i2=\E(B:im=\E[4h:is=\E[m\017:k1=\EOc:k2=\EOd:k3=\EOe:\ - :k4=\EOf:k5=\EOg:k6=\EOh:k7=\EOi:k8=\EOj:k9=\ENo:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:ll=\E[24H:\ - :mb=\E[5m:md=\E[1m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:\ - :nw=\EE:rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:\ - :ts=\E7\E[25;%i%dx:ue=\E[m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h\E[?12l:vi=\E[?25l:\ - :vs=\E[?12;25h: -att610-w|AT&T 610; 132 column; 98key keyboard:\ - :co#132:ws#132:\ - :i1=\E[8;0|\E[?4;5;13;15l\E[13;20l\E[?3;7h\E[12h:tc=att610: - -att610-103k|AT&T 610; 80 column; 103key keyboard:\ - :!1=\EOO:!2=\EOP:!3=\EOS:#1=\EOM:%0=\EOt:%1=\EOm:%2=\ENi:\ - :%3=\EOl:%4=\ENc:%5=\ENh:%6=\EOv:%7=\EOr:%8=\ENg:%9=\EOz:\ - :%a=\EOL:%b=\ENC:%c=\ENH:%d=\EOR:%e=\ENG:%f=\EOZ:%g=\EOT:\ - :%h=\EOY:%j=\EOQ:&0=\EOW:&1=\EOb:&2=\ENa:&3=\EOy:&4=\EOB:\ - :&5=\EOq:&6=\EOo:&7=\EOp:&8=\EOs:&9=\ENB:*0=\EOX:*1=\EOU:\ - :*2=\END:*3=\EON:*4=\ENF:*5=\ENE:*6=\ENI:*7=\ENN:*8=\EOA:\ - :*9=\EOK:@0=\EOx:@1=\E9:@2=\EOw:@3=\EOV:@4=\EOu:@5=\ENd:\ - :@6=\EOn:@7=\E0:@8=^M:@9=\EOk:F1@:F2@:F3@:F4@:k9@:k;@:kD=\ENf:\ - :kE=\EOa:kI=\ENj:kL=\ENe:kM=\ENj:kN=\E[U:kP=\E[V:\ - :tc=att610: -att610-103k-w|AT&T 610; 132 column; 103key keyboard:\ - :co#132:ws#132:\ - :i1=\E[8;0|\E[?4;5;13;15l\E[13;20l\E[?3;7h\E[12h:tc=att610-103k: -att615|AT&T 615; 80 column; 98key keyboard:\ - :#4=\E[ A:%i=\E[ @:F5=\EOC:F6=\EOD:F7=\EOE:F8=\EOF:F9=\EOG:\ - :FA=\EOH:FB=\EOI:FC=\EOJ:FD=\ENO:FE=\ENP:FF=\ENQ:FG=\ENR:\ - :FH=\ENS:FI=\ENT:FJ=\EOP:FK=\EOQ:FL=\EOR:FM=\EOS:FN=\EOw:\ - :FO=\EOx:FP=\EOy:FQ=\EOm:FR=\EOt:FS=\EOu:FT=\EOv:FU=\EOl:\ - :FV=\EOq:FW=\EOr:FX=\EOs:FY=\EOp:FZ=\EOn:Fa=\EOM:\ - :tc=att610: -att615-w|AT&T 615; 132 column; 98key keyboard:\ - :#4=\E[ A:%i=\E[ @:F5=\EOC:F6=\EOD:F7=\EOE:F8=\EOF:F9=\EOG:\ - :FA=\EOH:FB=\EOI:FC=\EOJ:FD=\ENO:FE=\ENP:FF=\ENQ:FG=\ENR:\ - :FH=\ENS:FI=\ENT:FJ=\EOP:FK=\EOQ:FL=\EOR:FM=\EOS:FN=\EOw:\ - :FO=\EOx:FP=\EOy:FQ=\EOm:FR=\EOt:FS=\EOu:FT=\EOv:FU=\EOl:\ - :FV=\EOq:FW=\EOr:FX=\EOs:FY=\EOp:FZ=\EOn:Fa=\EOM:\ - :tc=att610-w: -att615-103k|AT&T 615; 80 column; 103key keyboard:\ - :#4=\E[ A:%i=\E[ @:\ - :tc=att610-103k: -att615-103k-w|AT&T 615; 132 column; 103key keyboard:\ - :#4=\E[ A:%i=\E[ @:\ - :tc=att610-103k-w: -# (att620: I added / based on the init string and -# :SR:/:SF: from a BSD termcap -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att620|AT&T 620; 80 column; 98key keyboard:\ - :am:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:bt=\E[Z:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:fs=\E8:ho=\E[H:\ - :i1=\E[8;0|\E[?3;4;5;13;15l\E[13;20l\E[?7h\E[12h:\ - :i2=\E(B:im=\E[4h:is=\E[m\017:k1=\EOc:k2=\EOd:k3=\EOe:\ - :k4=\EOf:k5=\EOg:k6=\EOh:k7=\EOi:k8=\EOj:k9=\ENo:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:ll=\E[24H:\ - :mb=\E[5m:md=\E[1m:me=\E[m\E(B\017:mh=\E[2m:mr=\E[7m:\ - :nd=\E[C:nw=\EE:rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[7m:\ - :sr=\EM:ta=^I:ts=\E7\E[25;%i%dx:ue=\E[m:up=\E[A:\ - :us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[?25h\E[?12l:vi=\E[?25l:\ - :vs=\E[?12;25h: -att620-w|AT&T 620; 132 column; 98key keyboard:\ - :co#132:ws#132:\ - :i1=\E[8;0|\E[?4;5;13;15l\E[13;20l\E[?3;7h\E[12h:tc=att620: -att620-103k|AT&T 620; 80 column; 103key keyboard:\ - :!1=\EOO:!2=\EOP:!3=\EOS:#1=\EOM:%0=\EOt:%1=\EOm:%2=\ENi:\ - :%3=\EOl:%4=\ENc:%5=\ENh:%6=\EOv:%7=\EOr:%8=\ENg:%9=\EOz:\ - :%a=\EOL:%b=\ENC:%c=\ENH:%d=\EOR:%e=\ENG:%f=\EOZ:%g=\EOT:\ - :%h=\EOY:%j=\EOQ:&0=\EOW:&1=\EOb:&2=\ENa:&3=\EOy:&4=\EOB:\ - :&5=\EOq:&6=\EOo:&7=\EOp:&8=\EOs:&9=\ENB:*0=\EOX:*1=\EOU:\ - :*2=\END:*3=\EON:*4=\ENF:*5=\ENE:*6=\ENI:*7=\ENN:*8=\EOA:\ - :*9=\EOK:@0=\EOx:@1=\E9:@2=\EOw:@3=\EOV:@4=\EOu:@5=\ENd:\ - :@6=\EOn:@7=\E0:@8=^M:@9=\EOk:F1@:F2@:F3@:F4@:F5@:F6@:F7@:F8@:\ - :F9@:FA@:FB@:FC@:FD@:FE@:FF@:FG@:FH@:FI@:FJ@:FK@:FL@:FM@:FN@:FO@:FP@:\ - :FQ@:FR@:FS@:FT@:FU@:FV@:FW@:FX@:FY@:FZ@:Fa@:k9@:k;@:kD=\ENf:\ - :kE=\EOa:kI=\ENj:kL=\ENe:kM=\ENj:kN=\E[U:kP=\E[V:\ - :tc=att620: - -att620-103k-w|AT&T 620; 132 column; 103key keyboard:\ - :co#132:ws#132:\ - :i1=\E[8;0|\E[?4;5;13;15l\E[13;20l\E[?3;7h\E[12h:tc=att620-103k: - -# AT&T (formerly Teletype) 630 Multi-Tasking Graphics terminal -# The following SETUP modes are assumed for normal operation: -# Local_Echo=Off Gen_Flow=On Return=CR Received_Newline=LF -# Font_Size=Large Non-Layers_Window_Cols=80 -# Non-Layers_Window_Rows=60 -# Other SETUP modes may be set for operator convenience or communication -# requirements. Some capabilities assume a printer attached to the Aux EIA -# port. This termcap description is for the Fixed Non-Layers Window. No -# delays are specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# (att630: added :ic:, :mb: and :mh: from a BSD termcap file -- esr) -att630|AT&T 630 windowing terminal:\ - :NP:am:bs:da:db:mi:ms:xo:\ - :co#80:it#8:li#60:lm#0:\ - :@8=^M:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\ENq:\ - :F2=\ENr:F3=\ENs:F4=\ENt:F5=\ENu:F6=\ENv:F7=\ENw:F8=\ENx:\ - :F9=\ENy:FA=\ENz:FB=\EN{:FC=\EN|:FD=\EN}:FE=\EN~:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\ - :al=\E[L:bl=^G:bt=\E[Z:cb=\E[1K:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=\E[B:\ - :ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:is=\E[m:k9=\ENo:k;=\ENp:\ - :kA=\E[L:kB=\E[Z:kC=\E[2J:kD=\E[P:kI=\E[@:kL=\E[M:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :me=\E[m:mh=\E[2m:mr=\E[7m:nd=\E[C:nw=^M^J:pf=\E[?4i:\ - :po=\E[?5i:r2=\Ec:rc=\E8:\ - :sc=\E7:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: -att630-24|5630-24|5630DMD-24|630MTG-24|AT&T 630 windowing terminal 24 lines:\ - :li#24:tc=att630: - -# This entry was modified 3/13/90 by JWE. -# fixes include additions of , correcting :rp:, and modification -# of . (See comments below) -# att730 has status line of 80 chars -# These were commented out: :SF=\E[%p1%dS:, :SR=\E[%p1%dT:, -# the and up keys are used for shifted system Fkeys -# NOTE: JWE 3/13/90 The 98 key keyboard translation for shift/HOME is -# currently the same as :kh: (unshifted HOME or \E[H). On the 102, 102+1 -# and 122 key keyboards, the 730's translation is \E[2J. For consistency -# has been commented out. The user can uncomment if using the -# 102, 102+1, or 122 key keyboards -# kHOM=\E[2J, -# (att730: I added / based on the init string -- esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -att730|AT&T 730 windowing terminal:\ - :am:da:db:es:hs:mi:ms:xn:xo:\ - :co#80:it#8:li#60:lm#0:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(0:bl=^G:\ - :bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:fs=\E8:\ - :ho=\E[H:\ - :i1=\E[8;0|\E[?3;4;5;13;15l\E[13;20l\E[?7h\E[12h\E(B\E)B:\ - :i2=\E(B:im=\E[4h:is=\E[m\017:k1=\EOc:k2=\EOd:k3=\EOe:\ - :k4=\EOf:k5=\EOg:k6=\EOh:k7=\EOi:k8=\EOj:k9=\ENo:kI=\E[@:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m\017:mh=\E[2m:mr=\E[7m:nd=\E[C:\ - :nw=\EE:rc=\E8:sc=\E7:se=\E[27m:sf=\ED:so=\E[7m:sr=\EM:\ - :ta=^I:ts=\E7\E[;%i%dx:ue=\E[24m:up=\E[A:us=\E[4m:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h\E[?12l:vi=\E[?25l:\ - :vs=\E[?12;25h: -att730-41|730MTG-41|AT&T 730-41 windowing terminal Version:\ - :li#41:tc=att730: -att730-24|730MTG-24|AT&T 730-24 windowing terminal Version:\ - :li#24:tc=att730: -att730r|730MTGr|AT&T 730 rev video windowing terminal Version:\ - :i1=\E[8;0|\E[?3;4;13;15l\E[?5h\E[13;20l\E[?7h\E[12h\E(B\E)B:\ - :vb=\E[?5l\E[?5h:\ - :tc=att730: -att730r-41|730MTG-41r|AT&T 730r-41 rev video windowing terminal Version:\ - :li#41:tc=att730r: -att730r-24|730MTGr-24|AT&T 730r-24 rev video windowing terminal Version:\ - :li#24:tc=att730r: - -# The following represents the screen layout along with the associated -# bezel buttons for the 5430/pt505 terminal. The "kf" designations do -# not appear on the screen but are shown to reference the bezel buttons. -# The "CMD", "MAIL", and "REDRAW" buttons are shown in their approximate -# position relative to the screen. -# -# -# -# +----------------------------------------------------------------+ -# | | -# XXXX | kf0 kf24 | XXXX -# | | -# | | -# XXXX | kf1 kf23 | XXXX -# | | -# | | -# XXXX | kf2 kf22 | XXXX -# | | -# | | -# XXXX | kf3 kf21 | XXXX -# | | -# | | -# XXXX | kf4 kf20 | XXXX -# | | -# | | -# XXXX | kf5 kf19 | XXXX -# | | -# | | -# XXXX | kf6 kf18 | XXXX -# | | -# | | -# XXXX | | XXXX -# | | -# | | -# +----------------------------------------------------------------+ -# -# XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX -# -# Note: XXXX represents the screen buttons -# CMD REDRAW -# -# MAIL -# -# version 1 note: -# The character string sent by key 'kf26' may be user programmable -# to send either \E[16s, or \E[26s. -# The character string sent by key 'krfr' may be user programmable -# to send either \E[17s, or \E[27s. -# -# Depression of the "CMD" key sends \E! (kcmd) -# Depression of the "MAIL" key sends \E[26s (kf26) -# "REDRAW" same as "REFRESH" (krfr) -# -# "kf" functions adds carriage return to output string if terminal is in -# 'new line' mode. -# -# The following are functions not covered in the table above: -# -# Set keyboard character (SKC): \EPn1;Pn2w -# Pn1= 0 Back Space key -# Pn1= 1 Break key -# Pn2= Program char (hex) -# -# Screen Definition (SDF): \E[Pn1;Pn2;Pn3;Pn4;Pn5t -# Pn1= Window number (1-39) -# Pn2-Pn5= Y;X;Y;X coordinates -# -# Screen Selection (SSL): \E[Pnu -# Pn= Window number -# -# Set Terminal Modes (SM): \E[Pnh -# Pn= 3 Graphics mode -# Pn= > Cursor blink -# Pn= < Enter new line mode -# Pn= = Enter reverse insert/replace mode -# Pn= ? Enter no scroll mode -# -# Reset Terminal Mode (RM): \E[Pnl -# Pn= 3 Exit graphics mode -# Pn= > Exit cursor blink -# Pn= < Exit new line mode -# Pn= = Exit reverse insert/replace mode -# Pn= ? Exit no scroll mode -# -# Screen Status Report (SSR): \E[Pnp -# Pn= 0 Request current window number -# Pn= 1 Request current window dimensions -# -# Device Status Report (DSR): \E[6n Request cursor position -# -# Call Status Report (CSR): \E[Pnv -# Pn= 0 Call failed -# Pn= 1 Call successful -# -# Transparent Button String (TBS): \E[Pn1;Pn2;Pn3;{string -# Pn1= Button number to be loaded -# Pn2= Character count of "string" -# Pn3= Key mode being loaded: -# 0= Unshifted -# 1= Shifted -# 2= Control -# String= Text string (15 chars max) -# -# Screen Number Report (SNR): \E[Pnp -# Pn= Screen number -# -# Screen Dimension Report (SDR): \E[Pn1;Pn2r -# Pn1= Number of rows available in window -# Pn2= Number of columns available in window -# -# Cursor Position Report (CPR): \E[Pn1;Pn2R -# Pn1= "Y" Position of cursor -# Pn2= "X" Position of cursor -# -# Request Answer Back (RAB): \E[c -# -# Answer Back Response (ABR): \E[?;*;30;VSV -# *= 0 No printer available -# *= 2 Printer available -# V= Software version number -# SV= Software sub version number -# (printer-available field not documented in v1) -# -# Screen Alignment Aid: \En -# -# Bell (lower pitch): \E[x -# -# Dial Phone Number: \EPdstring\ -# string= Phone number to be dialed -# -# Set Phone Labels: \EPpstring\ -# string= Label for phone buttons -# -# Set Clock: \EPchour;minute;second\ -# -# Position Clock: \EPsY;X\ -# Y= "Y" coordinate -# X= "X" coordinate -# -# Delete Clock: \Epr\ -# -# Programming The Function Buttons: \EPfPn;string\ -# Pn= Button number (00-06, 18-24) -# (kf00-kf06, kf18-kf24) -# string= Text to sent on button depression -# -# The following in version 2 only: -# -# Request For Local Directory Data: \EPp12;\ -# -# Local Directory Data to host: \EPp11;LOCAL...DIRECTORY...DATA\ -# -# Request for Local Directory Data in print format: \EPp13;\ -# -# Enable 'Prt on Line' mode: \022 (DC2) -# -# Disable 'Prt on Line' mode: \024 (DC4) -# - -# 05-Aug-86: -# The following Terminfo entry describes functions which are supported by -# the AT&T 5430/pt505 terminal software version 2 and later. -att505|pt505|att5430|gs5430|AT&T Personal Terminal 505 or 5430 GETSET terminal:\ - :am:xo:\ - :co#80:it#8:li#24:\ - :&2=\E[27s:@4=\E\041:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ - :DO=\E[%dB:F8=\E[18s:F9=\E[19s:FA=\E[20s:FB=\E[21s:\ - :FC=\E[22s:FD=\E[23s:FE=\E24s:FG=\E26s:LE=\E[%dD:\ - :RA=\E[11;1j:RI=\E[%dC:SA=\E[11;0j:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:cb=\E2K:cd=\E[0J:\ - :ce=\E[0K:cl=\E[2J\E[H:cm=\E[%d;%dH:cr=^M:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=\E[4l:ho=\E[H:\ - :i1=\EPr\E[0u\E[2J\E[0;0H\E[m\E[3l\E[l\E[=l\E[?l:\ - :im=\E[4h:k0=\E[00s:k1=\E[01s:k2=\E[02s:k3=\E[03s:\ - :k4=\E[04s:k5=\E[05s:k6=\E[06s:kb=^H:kd=\E[B:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:pf=\E[4i:po=\E[5i:r1=\Ec:rc=\E8:sc=\E7:\ - :se=\E[m:sf=^J:so=\E[1m:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E[>l:vs=\E[>h: - -# The following Terminfo entry describes functions which are supported by -# the AT&T 5430/pt505 terminal software version 1. -att505-24|pt505-24|gs5430-24|AT&T PT505 or 5430 GETSET version 1 24 lines:\ - :li#24:\ - :RA@:SA@:pf@:po@:rc@:sc@:tc=att505: -tt505-22|pt505-22|gs5430-22|AT&T PT505 or 5430 GETSET version 1 22 lines:\ - :li#22:tc=att505: -# -# -------------------- TERMINFO FILE CAN BE SPLIT HERE ----------------------- -# This cut mark helps make life less painful for people running ncurses tic -# on machines with relatively little RAM. The file can be broken in half here -# cleanly and compiled in sections -- no `use' references cross this cut -# going forward. -# - -#### Ampex (Dialogue) -# -# Yes, these are the same people who are better-known for making audio- and -# videotape. I'm told they are located in Redwood City, CA. -# - -# From: Fri Sep 11 22:38:32 1981 -# (ampex80: some capabilities merged in from SCO's entry -- esr) -ampex80|a80|d80|dialogue|dialogue80|ampex dialogue 80:\ - :am:bs:bw:ul:\ - :co#80:it#8:li#24:\ - :al=\EE:bl=^G:bt=\EI:cd=\Ey:ce=\Et:cl=\E*:cm=\E=%+ %+ :\ - :cr=^M:ct=\E3:dc=\EW:dl=\ER:do=^J:ei=:ic=\EQ:im=:is=\EA:le=^H:\ - :nd=^L:se=\Ek:sf=^J:so=\Ej:st=\E1:ta=^I:ue=\Em:up=^K:us=\El: -# This entry was from somebody anonymous, Tue Aug 9 20:11:37 1983, who wrote: -ampex175|ampex d175:\ - :am:\ - :co#80:li#24:\ - :al=\EE:bl=^G:cd=\Ey:ce=\Et:cl=\E+:cm=\E=%+ %+ :cr=^M:\ - :dc=\EW:dl=\ER:do=^J:ei=:ho=^^:ic=\EQ:im=:is=\EX\EA\EF:\ - :kA=\EE:kD=\EW:kI=\EQ:kL=\ER:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:\ - :le=^H:ll=^^^K:nd=^L:se=\Ek:sf=^J:so=\Ej:te=\EF:ti=\EN:\ - :ue=\Em:up=^K:us=\El: -# No backspace key in the main QWERTY cluster. Fortunately, it has a -# NEWLINE/PAGE key just above RETURN that sends a strange single-character -# code. Given a suitable Unix (one that lets you set an echo-erase-as-BS-SP-BS -# mode), this key can be used as the erase key; I find I like this. Because -# some people and some systems may not, there is another termcap ("ampex175") -# that suppresses this little eccentricity by omitting the relevant capability. -ampex175-b|ampex d175 using left arrow for erase:\ - :kb=^_:\ - :tc=ampex175: -# From: Richard Bascove -# (ampex210: removed obsolete ":kn#10:" -- esr) -ampex210|a210|ampex a210:\ - :am:bs:hs:xn:\ - :co#80:it#8:li#24:sg#1:\ - :al=\EE:bt=\EI:cd=\Ey:ce=\Et:cl=\E*:cm=\E=%+ %+ :dc=\EW:\ - :dl=\ER:ei=:fs=\E.2:ho=^^:ic=\EQ:if=/usr/share/tabset/std:\ - :im=:is=\EC\Eu\E'\E(\El\EA\E%\E{\E.2\EG0\Ed\En:\ - :k0=^A0\r:k1=^A1\r:k2=^A2\r:k3=^A3\r:k4=^A4\r:k5=^A5\r:\ - :k6=^A6\r:k7=^A7\r:k8=^A8\r:k9=^A9\r:kd=^V:kh=^^:kl=^H:\ - :kr=^L:ku=^K:le=^H:mk@:nd=^L:ta=^I:ts=\E.0\Eg\E}\Ef:up=^K:\ - :vb=\EU\EX\EU\EX\EU\EX\EU\EX:\ - :tc=adm+sgr: -# (ampex219: I added / based on the init string, added :vs: -# from ampex219w, added :ve:=\E[?3l, irresistibly suggested by :vs:, -# and moved the padding to be *after* the caps -- esr) -ampex219|ampex-219|amp219|Ampex with Automargins:\ - :hs:xn:\ - :co#80:it#8:li#24:\ - :RA=\E[?7l:SA=\E[?7h:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=%i\E[%2;%2r:\ - :do=\E[B:ho=\E[H:\ - :is=\E>\E[?1l\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:k0=\E[21~:\ - :k1=\E[7~:k2=\E[8~:k3=\E[9~:k4=\E[10~:k5=\E[11~:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:kd=\E[B:ke=\E>:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[m:mh=\E[1m:mr=\E[7m:nd=\E[C:se=\E[m:sf=^J:so=\E[7m:\ - :sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[?3l:vs=\E[?3h: -ampex219w|ampex-219w|amp219w|Ampex 132 cols:\ - :co#132:li#24:\ - :bl=^G:cr=^M:do=^J:is=\E>\E[?3h\E[?4l\E[?5l\E[?7h\E[?8h:\ - :sf=^J:\ - :tc=ampex219: -# (ampex232: removed :if=/usr/share/tabset/ampex:, no file and no :st: --esr) -ampex232|ampex-232|Ampex Model 232:\ - :am:\ - :co#80:li#24:sg#1:\ - :al=5*\EE:bt=\EI:cd=\EY:ce=\ET:cl=\E+:cm=\E=%+ %+ :dc=\EW:\ - :dl=5*\ER:do=^V:ei=:ic=\EQ:im=:is=\Eg\El:k0=^A@\r:k1=^AA\r:\ - :k2=^AB\r:k3=^AC\r:k4=^AD\r:k5=^AE\r:k6=^AF\r:k7=^AG\r:\ - :k8=^AH\r:k9=^AI\r:kb=^H:kd=^V:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:\ - :mk@:nd=^L:ta=^I:up=^K:vb=\Eb\Ed:ve=\E.4:vi=\E.0:\ - :tc=adm+sgr: -# (ampex: removed :if=/usr/share/tabset/amp-132:, no file and no :st: -- esr) -ampex232w|Ampex Model 232 / 132 columns:\ - :co#132:li#24:\ - :is=\E\034Eg\El:tc=ampex232: - -#### Ann Arbor (aa) -# -# Ann Arbor made dream terminals for hackers -- large screen sizes and huge -# numbers of function keys. At least some used monitors in portrait mode, -# allowing up to 76-character screen heights! They were reachable at: -# -# Ann Arbor Terminals -# 6175 Jackson Road -# Ann Arbor, MI 48103 -# (313)-663-8000 -# -# But in 1996 the phone number reaches some kitschy retail shop, and Ann Arbor -# can't be found on the Web; I fear they're long dead. R.I.P. -# - - -# Originally from Mike O'Brien@Rand and Howard Katseff at Bell Labs. -# Highly modified 6/22 by Mike O'Brien. -# split out into several for the various screen sizes by dave-yost@rand -# Modifications made 3/82 by Mark Horton -# Modified by Tom Quarles at UCB for greater efficiency and more diversity -# status line moved to top of screen, :vb: removed 5/82 -# Some unknown person at SCO then hacked the init strings to make them more -# efficient. -# -# assumes the following setup: -# A menu: 0000 1010 0001 0000 -# B menu: 9600 0100 1000 0000 0000 1000 0000 17 19 -# C menu: 56 66 0 0 9600 0110 1100 -# D menu: 0110 1001 1 0 -# -# Briefly, the settings are for the following modes: -# (values are for bit set/clear with * indicating our preference -# and the value used to test these termcaps) -# Note that many of these settings are irrelevent to the terminfo -# and are just set to the default mode of the terminal as shipped -# by the factory. -# -# A menu: 0000 1010 0001 0000 -# Block/underline cursor* -# blinking/nonblinking cursor* -# key click/no key click* -# bell/no bell at column 72* -# -# key pad is cursor control*/key pad is numeric -# return and line feed/return for :cr: key * -# repeat after .5 sec*/no repeat -# repeat at 25/15 chars per sec. * -# -# hold data until pause pressed/process data unless pause pressed* -# slow scroll/no slow scroll* -# Hold in area/don't hold in area* -# functions keys have default*/function keys disabled on powerup -# -# show/don't show position of cursor during page transmit* -# unused -# unused -# unused -# -# B menu: 9600 0100 1000 0000 0000 1000 0000 17 19 -# Baud rate (9600*) -# -# 2 bits of parity - 00=odd,01=even*,10=space,11=mark -# 1 stop bit*/2 stop bits -# parity error detection off*/on -# -# keyboard local/on line* -# half/full duplex* -# disable/do not disable keyboard after data transmission* -# -# transmit entire page/stop transmission at cursor* -# transfer/do not transfer protected characters* -# transmit all characters/transmit only selected characters* -# transmit all selected areas/transmit only 1 selected area* -# -# transmit/do not transmit line separators to host* -# transmit/do not transmit page tab stops tabs to host* -# transmit/do not transmit column tab stop tabs to host* -# transmit/do not transmit graphics control (underline,inverse..)* -# -# enable*/disable auto XON/XOFF control -# require/do not require receipt of a DC1 from host after each LF* -# pause key acts as a meta key/pause key is pause* -# unused -# -# unused -# unused -# unused -# unused -# -# XON character (17*) -# XOFF character (19*) -# -# C menu: 56 66 0 0 9600 0110 1100 -# number of lines to print data on (printer) (56*) -# -# number of lines on a sheet of paper (printer) (66*) -# -# left margin (printer) (0*) -# -# number of pad chars on new line to printer (0*) -# -# printer baud rate (9600*) -# -# printer parity: 00=odd,01=even*,10=space,11=mark -# printer stop bits: 2*/1 -# print/do not print guarded areas* -# -# new line is: 01=LF,10=CR,11=CRLF* -# unused -# unused -# -# D menu: 0110 1001 1 0 -# LF is newline/LF is down one line, same column* -# wrap to preceding line if move left from col 1*/don't wrap -# wrap to next line if move right from col 80*/don't wrap -# backspace is/is not destructive* -# -# display*/ignore DEL character -# display will not/will scroll* -# page/column tab stops* -# erase everything*/erase unprotected only -# -# editing extent: 0=display,1=line*,2=field,3=area -# -# unused -# - -annarbor4080|aa4080|ann arbor 4080:\ - :am:bs:\ - :co#80:li#40:\ - :bl=^G:cl=\014:\ - :cr=^M:ct=^^P^P:do=^J:ho=^K:kb=^^:kd=^J:kh=^K:kl=^H:kr=^_:\ - :ku=^N:le=^H:nd=^_:sf=^J:st=^]^P1:ta=^I:up=^N: - -# Strange Ann Arbor terminal from BRL -aas1901|Ann Arbor K4080 w/S1901 mod:\ - :am:\ - :co#80:li#40:\ - :bl=^G:cl=^L:cr=^M:do=^J:ho=^K:kb=^H:kd=^J:kl=^H:le=^H:\ - :ll=^O\200c:nd=^_:nw=^M^J:sf=^J:ta=^I:up=^N: - -# If you're using the GNU termcap library, add -# :cS=\E[%p1%d;%p2%d;%p3%d;%p4%dp: -# to these capabilities. This is the nonstandard GNU termcap scrolling -# capability, arguments are: -# 1. Total number of lines on the screen. -# 2. Number of lines above desired scroll region. -# 3. Number of lines below (outside of) desired scroll region. -# 4. Total number of lines on the screen, the same as the first parameter. -# The generic Ann Arbor entry is the only one that uses this. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -aaa+unk|aaa-unk|ann arbor ambassador (internal - don't use this directly):\ - :am:bs:km:mi:xo:\ - :co#80:it#8:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :ct=\E[2g:dc=\E[P:dl=\E[M:do=^K:ei=:ho=\E[H:\ - :i1=\E[m\E7\E[H\E9\E8:i2=\E[1Q\E[>20;30l\EP`+x~M\E\:\ - :ic=\E[@:im=:k1=\EOA:k2=\EOB:k3=\EOC:k4=\EOD:k5=\EOE:\ - :k6=\EOF:k7=\EOG:k8=\EOH:k9=\EOI:kD=\E[P:kI=\E[@:kb=^H:\ - :kd=\E[B:\ - :ke=\EP`>y~[[J`8xy~[[A`4xy~[[D`6xy~[[C`2xy~[[B\E\:\ - :kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\EP`>z~[[J`8xz~[[A`4xz~[[D`6xz~[[C`2xz~[[B\E\:\ - :ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:mm=\E[>52h:\ - :mo=\E[>52l:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[m:sf=^K:\ - :so=\E[7m:st=\EH:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: - -aaa+rv|ann arbor ambassador in reverse video:\ - :i1=\E[7m\E7\E[H\E9\E8:mb=\E[5;7m:md=\E[1;7m:\ - :me=\E[7m\016:mk=\E[7;8m:mr=\E[m:r1=\E[H\E[7m\E[J:\ - :se=\E[7m:so=\E[m:ue=\E[7m:us=\E[4;7m: -# Ambassador with the DEC option, for partial vt100 compatibility. -aaa+dec|ann arbor ambassador in dec vt100 mode:\ - :ac=aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}:\ - :ae=^N:as=^O:cs=\E[%i%d;%dr:eA=\E(0: -aaa-18|ann arbor ambassador/18 lines:\ - :li#18:\ - :is=\E7\E[60;0;0;18p\E8:te=\E[60;0;0;18p\E[60;1H\E[K:\ - :ti=\E[18;0;0;18p:\ - :tc=aaa+unk: -aaa-18-rv|ann arbor ambassador/18 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-18: -aaa-20|ann arbor ambassador/20 lines:\ - :li#20:\ - :is=\E7\E[60;0;0;20p\E8:te=\E[60;0;0;20p\E[60;1H\E[K:\ - :ti=\E[20;0;0;20p:\ - :tc=aaa+unk: -aaa-22|ann arbor ambassador/22 lines:\ - :li#22:\ - :is=\E7\E[60;0;0;22p\E8:te=\E[60;0;0;22p\E[60;1H\E[K:\ - :ti=\E[22;0;0;22p:\ - :tc=aaa+unk: -aaa-24|ann arbor ambassador/24 lines:\ - :li#24:\ - :is=\E7\E[60;0;0;24p\E8:te=\E[60;0;0;24p\E[60;1H\E[K:\ - :ti=\E[24;0;0;24p:\ - :tc=aaa+unk: -aaa-24-rv|ann arbor ambassador/24 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-24: -aaa-26|ann arbor ambassador/26 lines:\ - :li#26:\ - :is=\E7\E[60;0;0;26p\E8:te=\E[60;0;0;26p\E[26;1H\E[K:\ - :ti=\E[H\E[J\E[26;0;0;26p:\ - :tc=aaa+unk: -aaa-28|ann arbor ambassador/28 lines:\ - :li#28:\ - :is=\E7\E[60;0;0;28p\E8:te=\E[60;0;0;28p\E[28;1H\E[K:\ - :ti=\E[H\E[J\E[28;0;0;28p:\ - :tc=aaa+unk: -aaa-30-s|aaa-s|ann arbor ambassador/30 lines w/status:\ - :es:hs:\ - :li#29:\ - :ds=\E7\E[60;0;0;30p\E[1;1H\E[K\E[H\E8\r\n\E[K:\ - :fs=\E[>51l:is=\r\n\E[A\E7\E[60;1;0;30p\E8:\ - :te=\E[60;1;0;30p\E[29;1H\E[K:\ - :ti=\E[H\E[J\E[30;1;0;30p\E[30;1H\E[K:\ - :ts=\E[>51h\E[1;%dH\E[2K:tc=aaa+unk: -aaa-30-s-rv|aaa-s-rv|ann arbor ambassador/30 lines+status+reverse video:\ - :tc=aaa+rv:tc=aaa-30-s: -aaa-s-ctxt|aaa-30-s-ctxt|ann arbor ambassador/30 lines+status+save context:\ - :te=\E[60;1;0;30p\E[59;1H\E[K:\ - :ti=\E[30;1H\E[K\E[30;1;0;30p:tc=aaa-30-s: -aaa-s-rv-ctxt|aaa-30-s-rv-ct|ann arbor ambassador/30 lines+status+save context:\ - :te=\E[60;1;0;30p\E[59;1H\E[K:\ - :ti=\E[30;1H\E[K\E[30;1;0;30p:tc=aaa-30-s-rv: -aaa|aaa-30|ambas|ambassador|ann arbor ambassador/30 lines:\ - :li#30:\ - :is=\E7\E[60;0;0;30p\E8:te=\E[60;0;0;30p\E[30;1H\E[K:\ - :ti=\E[H\E[J\E[30;0;0;30p:\ - :tc=aaa+unk: -aaa-30-rv|aaa-rv|ann arbor ambassador/30 lines in reverse video:\ - :tc=aaa+rv:tc=aaa-30: -aaa-30-ctxt|aaa-ctxt|ann arbor ambassador/30 lines; saving context:\ - :te=\E[60;0;0;30p\E[60;1H\E[K:ti=\E[30;0;0;30p:\ - :tc=aaa-30: -aaa-30-rv-ctxt|aaa-rv-ctxt|ann arbor ambassador/30 lines reverse video; saving context:\ - :te=\E[60;0;0;30p\E[60;1H\E[K:ti=\E[30;0;0;30p:\ - :tc=aaa+rv:tc=aaa-30: -aaa-36|ann arbor ambassador/36 lines:\ - :li#36:\ - :is=\E7\E[60;0;0;36p\E8:te=\E[60;0;0;36p\E[36;1H\E[K:\ - :ti=\E[H\E[J\E[36;0;0;36p:\ - :tc=aaa+unk: -aaa-36-rv|ann arbor ambassador/36 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-36: -aaa-40|ann arbor ambassador/40 lines:\ - :li#40:\ - :is=\E7\E[60;0;0;40p\E8:te=\E[60;0;0;40p\E[40;1H\E[K:\ - :ti=\E[H\E[J\E[40;0;0;40p:\ - :tc=aaa+unk: -aaa-40-rv|ann arbor ambassador/40 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-40: -aaa-48|ann arbor ambassador/48 lines:\ - :li#48:\ - :is=\E7\E[60;0;0;48p\E8:te=\E[60;0;0;48p\E[48;1H\E[K:\ - :ti=\E[H\E[J\E[48;0;0;48p:\ - :tc=aaa+unk: -aaa-48-rv|ann arbor ambassador/48 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-48: -aaa-60-s|ann arbor ambassador/59 lines+status:\ - :es:hs:\ - :li#59:\ - :ds=\E7\E[60;0;0;60p\E[1;1H\E[K\E[H\E8\r\n\E[K:\ - :fs=\E[>51l:is=\r\n\E[A\E7\E[60;1;0;60p\E8:\ - :ts=\E[>51h\E[1;%dH\E[2K:tc=aaa+unk: -aaa-60-s-rv|ann arbor ambassador/59 lines+status+reverse video:\ - :tc=aaa+rv:tc=aaa-60-s: -aaa-60-dec-rv|ann arbor ambassador/dec mode+59 lines+status+rev video:\ - :tc=aaa+dec:tc=aaa+rv:tc=aaa-60-s: -aaa-60|ann arbor ambassador/60 lines:\ - :li#60:\ - :is=\E7\E[60;0;0;60p\E[1Q\E[m\E[>20;30l\E8:tc=aaa+unk: -aaa-60-rv|ann arbor ambassador/60 lines+reverse video:\ - :tc=aaa+rv:tc=aaa-60: -aaa-db|ann arbor ambassador 30/destructive backspace:\ - :bs@:\ - :i2=\E[1Q\E[m\E[>20l\E[>30h:le=\E[D:tc=aaa-30: - -guru|guru-33|guru+unk|ann arbor guru/33 lines 80 cols:\ - :li#33:\ - :i2=\E[>59l:is=\E7\E[255;0;0;33;80;80p\E8\E[J:\ - :te=\E[255p\E[255;1H\E[K:ti=\E[33p:vb=\E[>59h\E[>59l:\ - :tc=aaa+unk: -guru+rv|guru changes for reverse video:\ - :i2=\E[>59h:vb=\E[>59l\E[>59h: -guru-rv|guru-33-rv|ann arbor guru/33 lines+reverse video:\ - :tc=guru+rv:tc=guru-33: -guru+s|guru status line:\ - :es:hs:\ - :ds=\E7\E[;0p\E[1;1H\E[K\E[H\E8\r\n\E[K:fs=\E[>51l:\ - :te=\E[255;1p\E[255;1H\E[K:ti=:\ - :ts=\E[>51h\E[1;%dH\E[2K: -guru-nctxt|guru with no saved context:\ - :ti=\E[H\E[J\E[33p\E[255;1H\E[K:tc=guru: -guru-s|guru-33-s|ann arbor guru/33 lines+status:\ - :li#32:\ - :is=\r\n\E[A\E7\E[255;1;0;33;80;80p\E8\E[J:\ - :ti=\E[33;1p\E[255;1H\E[K:tc=guru+s:\ - :tc=guru+unk: -guru-24|ann arbor guru 24 lines:\ - :co#80:li#24:\ - :is=\E7\E[255;0;0;24;80;80p\E8\E[J:ti=\E[24p:tc=guru+unk: -guru-44|ann arbor guru 44 lines:\ - :co#97:li#44:\ - :is=\E7\E[255;0;0;44;97;100p\E8\E[J:ti=\E[44p:tc=guru+unk: -guru-44-s|ann arbor guru/44 lines+status:\ - :li#43:\ - :is=\r\n\E[A\E7\E[255;1;0;44;80;80p\E8\E[J:\ - :ti=\E[44;1p\E[255;1H\E[K:tc=guru+s:\ - :tc=guru+unk: -guru-76|guru with 76 lines by 89 cols:\ - :co#89:li#76:\ - :is=\E7\E[255;0;0;76;89;100p\E8\E[J:ti=\E[76p:tc=guru+unk: -guru-76-s|ann arbor guru/76 lines+status:\ - :co#89:li#75:\ - :is=\r\n\E[A\E7\E[255;1;0;76;89;100p\E8\E[J:\ - :ti=\E[76;1p\E[255;1H\E[K:tc=guru+s:\ - :tc=guru+unk: -guru-76-lp|guru-lp|guru with page bigger than line printer:\ - :co#134:li#76:\ - :is=\E7\E[255;0;0;76;134;134p\E8\E[J:ti=\E[76p:tc=guru+unk: -guru-76-w|guru 76 lines by 178 cols:\ - :co#178:li#76:\ - :is=\E7\E[255;0;0;76;178;178p\E8\E[J:ti=\E[76p:tc=guru+unk: -guru-76-w-s|ann arbor guru/76 lines+status+wide:\ - :co#178:li#75:\ - :is=\r\n\E[A\E7\E[255;1;0;76;178;178p\E8\E[J:\ - :ti=\E[76;1p\E[255;1H\E[K:\ - :tc=guru+s:tc=guru+unk: -guru-76-wm|guru 76 lines by 178 cols with 255 cols memory:\ - :co#178:li#76:\ - :is=\E7\E[255;0;0;76;178;255p\E8\E[J:ti=\E[76p:tc=guru+unk: -aaa-rv-unk|ann arbor unknown type:\ - :Nl#0:lh#0:lw#0:\ - :ho=\E[H:i1=\E[7m\E7\E[H\E9\E8:mb=\E[5;7m:md=\E[1;7m:\ - :me=\E[7m:mk=\E[7;8m:mr=\E[m:r1=\E[H\E[7m\E[J:\ - :se=\E[7m:so=\E[m:ue=\E[7m:us=\E[4;7m: - -#### Applied Digital Data Systems (adds) -# -# ADDS itself is long gone. ADDS was bought by NCR, and the same group made -# ADDS and NCR terminals. When AT&T and NCR merged, the engineering for -# terminals was merged again. Then AT&T sold the terminal business to -# SunRiver, which later changed its name to Boundless Technologies. The -# engineers from Teletype, AT&T terminals, ADDS, and NCR (who are still there -# as of early 1995) are at: -# -# Boundless Technologies -# 100 Marcus Boulevard -# Hauppauge, NY 11788-3762 -# Vox: (800)-231-5445 -# Fax: (516)-342-7378 -# -# Their voice mail used to describe the place as "SunRiver (formerly ADDS)". -# In 1995 Boundless acquired DEC's terminals business. -# - -# Regent: lowest common denominator, works on all regents. -# (regent: renamed ":bc:" to ":le:" -- esr) -regent|Adds Regent Series:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cl=^L:cr=^M:do=^J:ho=\EY :le=^U:ll=^A:nd=^F:sf=^J:\ - :up=^Z: -# Regent 100 has a bug where if computer sends escape when user is holding -# down shift key it gets confused, so we avoid escape. -regent100|Adds Regent 100:\ - :sg#1:ug#1:\ - :bl=^G:cm=\013%+ %B\020%.:k0=^B1\r:k1=^B2\r:k2=^B3\r:\ - :k3=^B4\r:k4=^B5\r:k5=^B6\r:k6=^B7\r:k7=^B8\r:l0=F1:l1=F2:\ - :l2=F3:l3=F4:l4=F5:l5=F6:l6=F7:l7=F8:me=\E0@:se=\E0@:so=\E0P:\ - :ue=\E0@:us=\E0`:\ - :tc=regent: -regent20|Adds Regent 20:\ - :bl=^G:cd=\Ek:ce=\EK:cm=\EY%+ %+ :tc=regent: -regent25|Adds Regent 25:\ - :bl=^G:kd=^J:kh=^A:kl=^U:kr=^F:ku=^Z:tc=regent20: -regent40|Adds Regent 40:\ - :sg#1:ug#1:\ - :al=\EM:bl=^G:dl=\El:k0=^B1\r:k1=^B2\r:k2=^B3\r:k3=^B4\r:\ - :k4=^B5\r:k5=^B6\r:k6=^B7\r:k7=^B8\r:l0=F1:l1=F2:l2=F3:\ - :l3=F4:l4=F5:l5=F6:l6=F7:l7=F8:me=\E0@:se=\E0@:so=\E0P:\ - :ue=\E0@:us=\E0`:\ - :tc=regent25: -regent40+|Adds Regent 40+:\ - :is=\EB:tc=regent40: -regent60|regent200|Adds Regent 60:\ - :dc=\EE:ei=\EF:im=\EF:is=\EV\EB:kD=\EE:kI=\EF:kM=\EF:\ - :se=\ER\E0@\EV:so=\ER\E0P\EV:\ - :tc=regent40+: -# From: Thu Jul 9 09:27:33 1981 -# (viewpoint: added :kr:, function key, and :dl: capabilities -- esr) -viewpoint|addsviewpoint|adds viewpoint:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cd=\Ek:ce=\EK:cl=^L:cm=\EY%+ %+ :cr=^M:dl=\El:do=^J:\ - :is=\017\E0`:k0=^B1:k2=^B2:k3=^B\041:k4=^B":k5=^B#:kd=^J:\ - :kh=^A:kl=^U:kr=^F:ku=^Z:le=^H:ll=^A:me=^O:nd=^F:se=^O:sf=^J:\ - :so=^N:ue=^O:up=^Z:us=^N:ve=\017\E0`:vs=\017\E0P: -# Some viewpoints have bad ROMs that foo up on ^O -screwpoint|adds viewpoint with ^O bug:\ - :se@:so@:ue@:us@:vs@:tc=viewpoint: - -# From: Jay S. Rouman 5 Jul 92 -# The :vi:/:ve:/:sa:/:me: strings were added by ESR from specs. -# Theory; the vp3a+ wants \E0%c to set highlights, where normal=01000000, -# underline=01100000, rev=01010000, blink=01000010,dim=01000001, -# invis=01000100 and %c is the logical or of desired attributes. -# There is also a `tag bit' enabling attributes, set by \E) and unset by \E(. -vp3a+|viewpoint3a+|adds viewpoint 3a+:\ - :am:bw:\ - :co#80:it#8:li#24:\ - :cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :cr=^M:do=^J:ho=^^:kb=^H:\ - :kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:me=\E(:nd=^L:nw=^M^J:\ - :se=\E(:sf=^J:so=\E0Q\E):ta=^I:up=^K:ve=^X:vi=^W: -vp60|viewpoint60|addsvp60|adds viewpoint60:\ - :tc=regent40: -# -# adds viewpoint 90 - from cornell -# Note: emacs sends ei occasionally to insure the terminal is out of -# insert mode. This unfortunately puts the viewpoint90 IN insert -# mode. A hack to get around this is :ic=\EF\s\EF^U:. (Also, -# - :ei=:im=: must be present in the termcap translation.) -# - :xs: indicates glitch that attributes stick to location -# - :ms: means it's safe to move in standout mode -# - :cl=\EG\Ek:: clears screen and visual attributes without affecting -# the status line -# Function key and label capabilities merged in from SCO. -vp90|viewpoint90|adds viewpoint 90:\ - :bs:bw:ms:xs:\ - :co#80:li#24:\ - :cd=\Ek:ce=\EK:cl=\EG\Ek:cm=\EY%+ %+ :dc=\EE:dl=\El:do=^J:\ - :ei=:ho=\EY :ic=\EF \EF\025:im=:k0=^B1\r:k1=^B2\r:\ - :k2=^B3\r:k3=^B4\r:k4=^B5\r:k5=^B6\r:k6=^B7\r:k7=^B8\r:\ - :k8=^B9\r:k9=^B\072\r:k;=^B;\r:kb=^H:kd=^J:kh=^A:kl=^U:\ - :kr=^F:ku=^Z:l0=F1:l1=F2:l2=F3:l3=F4:l4=F5:l5=F6:l6=F7:l7=F8:\ - :l8=F9:l9=F10:la=F11:le=^H:ll=^A:me=\ER\E0@\EV:nd=^F:\ - :se=\ER\E0@\EV:sf=^J:so=\ER\E0Q\EV:ta=^I:ue=\ER\E0@\EV:\ - :up=^Z:us=\ER\E0`\EV: -# Note: if return acts weird on a980, check internal switch #2 -# on the top chip on the CONTROL pc board. -adds980|a980|adds consul 980:\ - :am:bs:\ - :co#80:li#24:\ - :al=\E\016:bl=^G:cl=\014\013@:cm=\013%+@\E\005%2:cr=^M:\ - :dl=\E\017:do=^J:k0=\E0:k1=\E1:k2=\E2:k3=\E3:k4=\E4:k5=\E5:\ - :k6=\E6:k7=\E7:k8=\E8:k9=\E9:le=^H:me=^O:nd=\E^E01:se=^O:\ - :sf=^J:so=^Y^^^N: - -#### C. Itoh Electronics -# -# As of 1995 these people no longer make terminals (they're still in the -# printer business). Their terminals were all clones of the DEC VT series. -# They're located in Orange County, CA. -# - -# CIT 80 - vt-52 emulator, the termcap has been modified to remove -# the delay times and do an auto tab set rather than the indirect -# file used in vt100. -cit80|cit-80|citoh 80:\ - :am:bs:\ - :co#80:li#24:\ - :cd=\EJ:ce=\EK:cl=\E[H\EJ:cm=\E[%i%2;%2H:cr=^M:ff=^L:\ - :is=\E>:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:nd=\E[C:sf=^J:up=\E[A: -# From: Tim Wood Fri Sep 27 09:39:12 PDT 1985 -# (cit101: added / based on init string, merged this with c101 -- esr) -cit101|citc|C.itoh fast vt100:\ - :am:bs:xn:\ - :co#80:li#24:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:ei=:ic=\E[@:\ - :im=:is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[3g\E[>5g:\ - :kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:me=\E[m:nd=\E[C:se=\E[m:so=\E[7m:ue=\E[m:\ - :up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:ve=\E[V\E8:vs=\E7\E[U: -# CIE Terminals CIT-101e from Geoff Kuenning via BRL -# The following termcap entry was created from the Callan cd100 entry. The -# last two lines (with the capabilities in caps) are used by RM-cobol to allow -# full selection of combinations of reverse video, underline, and blink. -# (cit101e: emoved unknown :f0=\EOp:f1=\EOq:f2=\EOr:f3=\EOs:f4=\EOt:f5=\EOu:\ -# f6=\EOv:f7=\EOw:f8=\EOx:f9=\EOy:AB=\E[0;5m:AL=\E[m:AR=\E[0;7m:AS=\E[0;5;7m:\ -# :NB=\E[0;1;5m:NM=\E[0;1m:NR=\E[0;1;7m:NS=\E[0;1;5;7m: -- esr) -cit101e|C. Itoh CIT-101e:\ - :am:bs:mi:ms:pt:\ - :co#80:it#8:li#24:\ - :ac=:ae=^O:al=\E[L:as=^N:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%2;%2H:cs=\E[%i%2;%2r:dc=\E[P:dl=\E[M:do=\E[B:\ - :ei=\E[4l:if=/usr/share/tabset/vt100:im=\E[4h:k0=\EOT:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOm:k6=\EOl:k7=\EOM:\ - :k8=\EOn:kd=\E[B:ke=\E>:kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:\ - :nd=\E[C:rc=\E8:sc=\E7:se=\E[m:so=\E[7m:sr=\EM:ue=\E[m:\ - :up=\E[A:us=\E[4m:ve=:vs=\E[?1l\E[?4l\E[?7h: -cit101e-n|CIT-101e w/o am:\ - :am@:\ - :kb=^H:kd=^J:kl=^H:vs=\E[?1l\E[?4l\E[?7l:tc=cit101e: -cit101e-132|CIT-101e, 132 cols:\ - :co#132:\ - :kb=^H:kd=^J:kl=^H:tc=cit101e: -cit101e-n132|CIT-101e, 132 cols w/o am:\ - :am@:\ - :co#132:\ - :kb=^H:kd=^J:kl=^H:vs=\E[?1l\E[?4l\E[?7l:tc=cit101e: -# CIE Terminals CIT-500 from BRL -# The following SET-UP modes are assumed for normal operation: -# GENERATE_XON/XOFF:YES DUPLEX:FULL NEWLINE:OFF -# AUTOWRAP:ON MODE:ANSI SCREEN_LENGTH:64_LINES -# DSPLY_CNTRL_CODES?NO PAGE_WIDTH:80 EDIT_MODE:OFF -# Other SET-UP modes may be set for operator convenience or communication -# requirements. -# Hardware tabs are assumed to be set every 8 columns; they can be set up -# by the "reset", "tset", or "tabs" utilities. No delays are specified; use -# "stty ixon -ixany" to enable DC3/DC1 flow control! -# (cit500: I added / based on the init string -- esr) -cit500|CIE Terminals CIT-500:\ - :bs:mi:ms:pt:xo:\ - :co#80:it#8:kn#10:li#64:vt#3:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:RA=\E[?7l:\ - :RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:ac=:ae=\E(B:al=\E[L:as=\E(0:\ - :bl=^G:bt=\E[Z:cd=\EJ:ce=\EK:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:dl=\E[M:do=^J:\ - :ei=\E[4l:ho=\E[H:im=\E[4h:is=\E<:k0=\EOP:k1=\EOQ:\ - :k2=\EOR:k3=\EOS:k4=\EOU:k5=\EOV:k6=\EOW:k7=\EOX:k8=\EOY:\ - :k9=\EOZ:kA=\E[L:kB=\E[Z:kD=\E[P:kE=\EK:kI=\E[4h:kL=\E[M:\ - :kM=\E[4l:kS=\EJ:kb=^H:kd=\EOB:ke=\E[?1l\E>:kh=\E[H:\ - :kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l0=PF1:l1=PF2:l2=PF3:\ - :l3=PF4:l4=F15:l5=F16:l6=F17:l7=F18:l8=F19:l9=F20:le=^H:\ - :ll=\E[64H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :nw=\EE:\ - :r1=\E<\E2\E[20l\E[?6l\E[r\E[m\E[q\E(B\017\E>:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\EM:us=\E[4m: - -# C. Itoh printers begin here -citoh|ci8510|8510|c.itoh 8510a:\ - :co#80:it#8:\ - :is=\E(009\054017\054025\054033\054041\054049\054057\054065\054073.:\ - :le@:md=\E\041:me=\E"\EY:rp=\ER%r%03%.:sr=\Er:ue=\EY:\ - :us=\EX:\ - :tc=lpr: -citoh-pica|citoh in pica:\ - :i1=\EN:tc=citoh: -citoh-elite|citoh in elite:\ - :co#96:\ - :i1=\EE:\ - :is=\E(009\054017\054025\054033\054041\054049\054057\054065\054073\054081\054089.:tc=citoh: -citoh-comp|citoh in compressed:\ - :co#136:\ - :i1=\EQ:\ - :is=\E(009\054017\054025\054033\054041\054049\054057\054065\054073\054081\054089\054097\054105\054113\054121\054129.:tc=citoh: -# citoh has infinite cols because we don't want lp ever inserting \n\t**. -citoh-prop|citoh-ps|ips|citoh in proportional spacing mode:\ - :co#32767:\ - :i1=\EP:tc=citoh: -citoh-6lpi|citoh in 6 lines per inch mode:\ - :i2=\EA:tc=citoh: -citoh-8lpi|citoh in 8 lines per inch mode:\ - :li#88:\ - :i2=\EB:tc=citoh: - -#### Control Data (cdc) -# - -cdc456|cdc 456 terminal:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=^X:ce=^V:cl=^Y^X:cm=\E1%+ %+ :cr=^M:dl=\EJ:\ - :do=^J:ho=^Y:le=^H:nd=^L:sf=^J:up=^Z: - -# Assorted CDC terminals from BRL (improvements by DAG & Ferd Brundick) -cdc721|CDC Viking:\ - :am:bs:\ - :co#80:li#24:\ - :ce=^K:cl=^L:cm=\002%r%+ %+ :ho=^Y:kd=^J:kh=^Y:kl=^H:kr=^I:\ - :ku=^W:nd=^X:up=^W: -cdc721ll|CDC Vikingll:\ - :am:bs:\ - :co#132:li#24:\ - :ce=^K:cl=^L:cm=\002%r%+ %+ :ho=^Y:kd=^J:kh=^Y:kl=^H:kr=^I:\ - :ku=^W:nd=^X:up=^W: -# (cdc752: the BRL entry had :ll=\E1 ^Z: commented out -cdc752|CDC 752:\ - :am:bs:bw:xs:\ - :co#80:li#24:\ - :bl=^G:ce=^V:cl=\030\E1 :cm=\E1%r%+ %+ :cr=^M:do=^J:\ - :ho=\E1 :le=^H:ll=^Y:nd=^U:r1=\E1 \030\002\003\017:\ - :sf=^J:up=^Z: -# CDC 756 -# The following switch/key settings are assumed for normal operation: -# 96 chars SCROLL FULL duplex not BLOCK -# Other switches may be set according to communication requirements. -# Insert/delete-character cannot be used, as the whole display is affected. -# "so" & "se" are commented out until jove handles "sg" correctly. -cdc756|CDC 756:\ - :am:bs:bw:\ - :co#80:kn#10:li#24:\ - :al=6*\EL:bl=^G:cd=^X:ce=^V:cl=^Y^X:cm=\E1%r%+ %+ :cr=^M:\ - :dl=6*\EJ:do=^J:ho=^Y:k0=\EA:k1=\EB:k2=\EC:k3=\ED:k4=\EE:\ - :k5=\EF:k6=\EG:k7=\EH:k8=\Ea:k9=\Eb:kA=\EL:kD=\EI:kE=^V:\ - :kI=\EK:kL=\EL:kS=^X:kT=^O:kb=^H:kd=^J:kh=^Y:kl=^H:kr=^U:\ - :ku=^Z:l0=F1:l1=F2:l2=F3:l3=F4:l4=F5:l5=F6:l6=F7:l7=F8:l8=F9:\ - :l9=F10:le=^H:ll=^Y^Z:nd=^U:r1=\031\030\002\003\017:sf=^J:\ - :up=^Z: -# -# CDC 721 from Robert Viduya, Ga. Tech. via BRL. -# -# Part of the long initialization string defines the "DOWN" key to the left -# of the tab key to send an ESC. The real ESC key is positioned way out -# in right field. -# -# The termcap won't work in 132 column mode due to the way it it moves the -# cursor. Termcap doesn't have the capability (as far as I could tell) to -# handle the 721 in 132 column mode. -# -# (cdc721: changed :ri: to :sr: -- esr) -cdc721-esc|Control Data 721:\ - :am:bs:bw:ms:pt:xo:\ - :co#80:it#8:kn#10:li#30:\ - :al=^^R:bl=^G:bt=^^^K:cd=^^P:ce=^K:cl=^L:cm=\002%r%+ %+ :\ - :ct=^^^RY:dc=^^N:dl=^^Q:do=^Z:ei=:ho=^Y:ic=^^O:im=:\ - :is=\036\022B\003\036\035\017\022\025\035\036E\036\022H\036\022J\036\022L\036\022N\036\022P\036\022Q\036\022\\036\022\136\036\022b\036\022i\036W =\036\022Z\036\011C1-` `\041k/o:\ - :k0=^^q:k1=^^r:k2=^^s:k3=^^t:k4=^^u:k5=^^v:k6=^^w:k7=^^x:\ - :k8=^^y:k9=^^z:kb=^H:kd=^Z:ke=^^^Rl:kh=^Y:kl=^H:kr=^X:\ - :ks=^^^Rk:ku=^W:le=^H:ll=^B =:mb=^N:\ - :me=\017\025\035\036E\036\022\:mh=^\:mk=^^^R[:mr=^^D:\ - :nd=^X:se=^^E:sf=\036W =\036U:so=^^D:sr=\036W =\036V:\ - :st=^^^RW:ue=^]:up=^W:us=^\: - -#### Getronics -# -# Getronics is a Dutch electronics company that at one time was called -# `Geveke' and made async terminals; but (according to the company itself!) -# they've lost all their documentation on the command set. The hardware -# documentation suggests the terminals were actually manufactured by a -# Taiwanese electronics company named Cal-Comp. There are known -# to have been at least two models, the 33 and the 50. -# - -# The 50 seems to be a top end vt220 clone, with the addition of a higher -# screen resolution, a larger screen, at least 1 page of memory above and -# below the screen, apparently pages of memory right and left of the screen -# which can be panned, and about 75 function keys (15 function keys x normal, -# shift, control, func A, func B). It also has more setup possibilities than -# the vt220. The monitor case is dated November 1978 and the keyboard case is -# May 1982. -# -# The vt100 emulation works as is. The entry below describes the rather -# non-conformant (but more featureful) ANSI mode. -# -# From: Stephen Peterson , 27 May 1995 -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -visa50|geveke visa 50 terminal in ansi 80 character mode:\ - :bw:mi:ms:\ - :co#80:li#25:\ - :AL=\E[%dL:DC=\E[%dX:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :K1=\E[f:K2=\EOP:K3=\EOQ:K4=\EOR:K5=\EOS:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E[3l:al=\E[L:as=\E3h:bl=^G:\ - :bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[X:dl=\E[M:do=\E[B:\ - :ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:\ - :is=\E0;2m\E[1;25r\E[25;1H\E[?3l\E[?7h\E[?8h:k0=\E010:\ - :k1=\E001:k2=\E002:k3=\E003:k4=\E004:k5=\E005:k6=\E006:\ - :k7=\E007:k8=\E008:k9=\E009:kD=\177:kb=^H:kd=\E[A:ke=\E>:\ - :kh=\E[f:kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:le=\E[D:mb=\E[5m:\ - :md=\E[1m:me=\E[0;2m:mh=\E[2m:mr=\E[7m:nd=\E[C:nw=^M^J:\ - :se=\E[0;2m:sf=^J:so=\E[2;7m:ta=^I:ue=\E[0m:up=\E[A:\ - :us=\E[4m:vb=\E[?5h\E[?5l: - -#### Human Designed Systems (Concept) -# -# Human Designed Systems -# 400 Fehley Drive -# King of Prussia, PA 19406 -# Vox: (610)-277-8300 -# Fax: (610)-275-5739 -# Net: support@hds.com -# -# John Martin is their termcap expert. They're mostly out of -# the character-terminal business now (1995) and making X terminals. In -# particular, the whole `Concept' line described here was discontinued long -# ago. -# - -# From: Sat Jun 27 07:41:20 1981 -# Extensive changes to c108 by arpavax:eric Feb 1982 -# Some unknown person at SCO then translated it to terminfo. -# -# There seem to be a number of different versions of the C108 PROMS -# (with bug fixes in its Z-80 program). -# -# The first one that we had would lock out the keyboard of you -# sent lots of short lines (like /usr/dict/words) at 9600 baud. -# Try that on your C108 and see if it sends a ^S when you type it. -# If so, you have an old version of the PROMs. -# -# You should configure the C108 to send ^S/^Q before running this. -# It is much faster (at 9600 baud) than the c100 because the delays -# are not fixed. -# new status line display entries for c108-8p: -# :i3: - init str #3 - setup term for status display - -# set programmer mode, select window 2, define window at last -# line of memory, set bkgnd stat mesg there, select window 0. -# -# :ts: - to status line - select window 2, home cursor, erase to -# end-of-window, 1/2 bright on, goto(line#0, col#?) -# -# :fs: - from status line - 1/2 bright off, select window 0 -# -# :ds: - disable status display - set bkgnd status mesg with -# illegal window # -# -# There are probably more function keys that should be added but -# I don't know what they are. -# -# No delays needed on c108 because of ^S/^Q handshaking -# -c108|concept108|c108-8p|concept108-8p|concept 108 w/8 pages:\ - :i2=\EU\E z"\Ev\001\177 \041p\E ;"\E z \Ev \001\177p\Ep\n:\ - :te=\Ev \001\177p\Ep\r\n:\ - :tc=c108-4p: -c108-4p|concept108-4p|concept 108 w/4 pages:\ - :bs:es:hs:xo:\ - :pb@:\ - :ac=l\\qLkTxUmMjE:ae=\Ej :as=\Ej\041:\ - :cr=^M:dc=\E 1:ds=\E ;\177:fs=\Ee\E z :i1=\EK\E\041\E F:\ - :i2=\EU\E z"\Ev\177 \041p\E ;"\E z \Ev \001 p\Ep\n:\ - :sf=^J:te=\Ev \001 p\Ep\r\n:ti=\EU\Ev 8p\Ep\r\E\025:\ - :ts=\E z"\E?\E\005\EE\Ea %+ :ve=\Ew:vs=\EW:\ - :tc=c100: -c108-rv|c108-rv-8p|concept 108 w/8 pages in reverse video:\ - :te=\Ev \002 p\Ep\r\n:ti=\EU\Ev 8p\Ep\r:\ - :tc=c108-rv-4p: -c108-rv-4p|concept108rv4p|concept 108 w/4 pages in reverse video:\ - :i1=\Ek:se=\Ee:so=\EE:vb=\EK\Ek:\ - :tc=c108-4p: -c108-w|c108-w-8p|concept108-w-8|concept108-w8p|concept 108 w/8 pages in wide mode:\ - :co#132:\ - :i1=\E F\E":te=\Ev ^A0\001D\Ep\r\n:\ - :ti=\EU\Ev 8\001D\Ep\r:tc=c108-8p: - -# Concept 100: -# These have only window relative cursor addressing, not screen -# relative. To get it to work right here, smcup/rmcup (which -# were invented for the concept) lock you into a one page -# window for screen style programs. -# -# To get out of the one page window, we use a clever trick: -# we set the window size to zero ("\Ev " in rmcup) which the -# terminal recognizes as an error and resets the window to all -# of memory. -# -# This trick works on c100 but does not on c108, sigh. -# -# Some tty drivers use cr3 for concept, others use nl3, hence -# the delays on cr and ind below. This padding is only needed at -# 9600 baud and up. One or the other is commented out depending on -# local conventions. -# -# 2 ms padding on :te: isn't always enough. 6 works fine. Maybe -# less than 6 but more than 2 will work. -# -# Note: can't use function keys f7-f10 because they are -# indistinguishable from arrow keys (!), also, del char and -# clear eol use xon/xoff so they probably won't work very well. -# -# Also note that we don't define insrt/del char/delline/eop/send -# because they don't transmit unless we reset them - I figured -# it was a bad idea to clobber their definitions. -# -# The sequence changes the escape character to ^^ so that -# escapes will be passed through to the printer. Only trouble -# is that ^^ won't be - ^^ was chosen to be unlikely. -# Unfortunately, if you're sending raster bits through to be -# plotted, any character you choose will be likely, so we lose. -# -# \EQ"\EY(^W (send anything from printer to host, for xon/xoff) -# cannot be # in is2 because it will hang a c100 with no printer -# if sent twice. -c100|concept100|concept|c104|c100-4p|hds concept 100:\ - :am:bs:eo:mi:ul:xn:\ - :co#80:li#24:pb#9600:vt#8:\ - :al=\E\022:bl=^G:cd=\E\005:ce=\E\025:cl=\E?\E\005:\ - :cm=\Ea%+ %+ :cr=\r:dc=\E\021:dl=\E\002:do=^J:ei=\E :\ - :i1=\EK:i2=\Ev \Ep\n:im=\E^P:ip=:\ - :is=\EU\Ef\E7\E5\E8\El\ENH\E\200\Eo&\200\Eo'\E\Eo\041\200\E\007\041\E\010A@ \E4#\072"\E\072a\E4#;"\E\072b\E4#<"\E\072c:\ - :k1=\E5:k2=\E6:k3=\E7:k4=\E8:k5=\E9:k6=\E\072a:k7=\E\072b:\ - :k8=\E\072c:kA=\E^R:kB=\E':kD=\E^Q:kE=\E^S:kF=\E[:kI=\E^P:\ - :kL=\E^B:kM=\E\200:kN=\E-:kP=\E.:kR=\E\:kS=\E^C:kT=\E]:\ - :kb=^H:kd=\E<:ke=\Ex:kh=\E?:kl=\E>:kr=\E=:ks=\EX:kt=\E_:\ - :ku=\E;:le=^H:mb=\EC:me=\EN@:mh=\EE:mk=\EH:mp=\EI:mr=\ED:\ - :nd=\E=:pf=\036o \E\EQ\041\EYP\027:\ - :po=\EQ"\EY(\027\EYD\Eo \036:rp=\Er%.%+ :se=\Ed:sf=^J:\ - :so=\ED:ta=\011:te=\Ev \Ep\r\n:\ - :ti=\EU\Ev 8p\Ep\r\E\025:ue=\Eg:up=\E;:us=\EG:vb=\Ek\EK: -c100-rv|c100-rv-4p|concept100-rv|c100 rev video:\ - :i1=\Ek:se=\Ee:so=\EE:vb=\EK\Ek:ve@:vs@:tc=c100: -oc100|oconcept|c100-1p|old 1 page concept 100:\ - :in:\ - :i3@:tc=c100: - -# :ta: through :ce: included to specify padding needed in raw mode. -# (avt-ns: added empty to suppress a tic warning --esr) -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -avt-ns|concept avt no status line:\ - :am:bs:eo:mi:ul:xn:xo:\ - :co#80:it#8:li#24:lm#192:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:al=\E[L:as=\E(1:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[2g:dc=\E[P:dl=\E[M:do=^J:ei=\E4l:\ - :ho=\E[H:i1=\E[=103l\E[=205l:ic=\E[@:im=\E1:ip=:\ - :is=\E[1*q\E[2\041t\E[7\041t\E[=4;101;119;122l\E[=107;118;207h\E[1Q\EW\E[\041y\E[\041z\E>\E[0\0720\07232\041r\E[0*w\E[w\E2\r\n\E[2;27\041t:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kD=\E^B\r:kI=\E^A\r:kb=^H:\ - :kd=\E[B:ke=\E[\041z\E[0;2u:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\E[1\041z\E[0;3u:ku=\E[A:le=^H:ll=\E[24H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mh=\E[1\041{:mr=\E[7m:nd=\E[C:rc=\E8:\ - :sc=\E7:se=\E[7\041{:sf=\n:so=\E[7m:sr=\EM:st=\EH:ta=\011:\ - :te=\E[w\E2\r\n:ti=\E[=4l\E[1;24w\E2\r:ue=\E[4\041{:\ - :up=\E[A:us=\E[4m:ve=\E[=119l:vs=\E[=119h: -avt-rv-ns|concept avt in reverse video mode/no status line:\ - :i1=\E[=103l\E[=205h:vb=\E[=205l\E[=205h:\ - :tc=avt-ns: -avt-w-ns|concept avt in 132 column mode/no status line:\ - :i1=\E[=103h\E[=205l:ti=\E[H\E[1;24;1;132w:\ - :tc=avt-ns: -avt-w-rv-ns|concept avt in 132 column mode/no status line/reverse video:\ - :i1=\E[=103h\E[=205h:ti=\E[H\E[1;24;1;132w:\ - :vb=\E[=205l\E[=205h:tc=avt-ns: - -# Concept AVT with status line. We get the status line using the -# "Background status line" feature of the terminal. We swipe the -# first line of memory in window 2 for the status line, keeping -# 191 lines of memory and 24 screen lines for regular use. -# The first line is used instead of the last so that this works -# on both 4 and 8 page AVTs. (Note the lm#191 or 192 - this -# assumes an 8 page AVT but lm isn't currently used anywhere.) -# -avt+s|concept avt status line changes:\ - :es:hs:\ - :lm#191:\ - :ds=\E[0*w:fs=\E[1;1\041w:\ - :i2=\E[2w\E[2\041w\E[1;1;1;80w\E[H\E[2*w\E[1\041w\E2\r\n:\ - :te=\E[2w\E2\r\n:ti=\E[2;25w\E2\r:\ - :ts=\E[2;1\041w\E[;%dH\E[2K: -avt|avt-s|concept-avt|avt w/80 columns:\ - :tc=avt+s:tc=avt-ns: -avt-rv|avt-rv-s|avt reverse video w/sl:\ - :i1=\E[=103l\E[=205h:vb=\E[=205l\E[=205h:tc=avt+s:tc=avt-ns: -avt-w|avt-w-s|concept avt 132 cols+status:\ - :i1=\E[=103h\E[=205l:ti=\E[H\E[1;24;1;132w:tc=avt+s:tc=avt-ns: -avt-w-rv|avt-w-rv-s|avt wide+status+rv:\ - :i1=\E[=103h\E[=205h:ti=\E[H\E[1;24;1;132w:\ - :vb=\E[=205l\E[=205h:tc=avt+s:\ - :tc=avt-ns: - -#### Contel Business Systems. -# - -# Contel c300 and c320 terminals. -contel300|contel320|c300|Contel Business Systems C-300 or C-320:\ - :am:in:xo:\ - :co#80:li#24:sg#1:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EI:cl=\EK:cm=\EX%+ \EY%+ :cr=^M:\ - :ct=\E3:dc=\EO:dl=\EM:do=^J:ei=:ho=\EH:ic=\EN:im=:ip=:k0=\ERJ:\ - :k1=\ERA:k2=\ERB:k3=\ERC:k4=\ERD:k5=\ERE:k6=\ERF:k7=\ERG:\ - :k8=\ERH:k9=\ERI:kb=^H:le=^H:ll=\EH\EA:me=\E\041\200:\ - :nd=\EC:se=\E\041\200:sf=^J:so=\E\041\r:st=\E1:up=\EA:\ - :vb=\020\002\020\003: -# Contel c301 and c321 terminals. -contel301|contel321|c301|c321|Contel Business Systems C-301 or C-321:\ - :ei=:ic@:im=:ip@:se=\E\041\200:so=\E\041\r:vb@:\ - :tc=contel300: - -#### Data General (dg) -# -# According to James Carlson writing in January 1995, -# the terminals group at Data General was shut down in 1991; all these -# terminals have thus been discontinued. -# - -# According to the 4.4BSD termcap file, the dg200 :cm: should be the -# termcap equivalent of \020%p2%{128}%+%c%p1%{128}%+%c (in termcap -# notation that's "^P%r%+\200%+\200"). Those \200s are suspicious, -# maybe they were originally nuls (which would fit). -dg200|data general dasher 200:\ - :NL:am:bs:bw:\ - :co#80:li#24:\ - :bl=^G:ce=^K:cl=^L:cm=\020%r%.%.:cr=^M:do=^Z:ho=^H:k0=^^z:\ - :k1=^^q:k2=^^r:k3=^^s:k4=^^t:k5=^^u:k6=^^v:k7=^^w:k8=^^x:\ - :k9=^^y:kd=^Z:kh=^H:kl=^Y:kr=^X:ku=^W:l0=f10:le=^Y:nd=^X:\ - :nw=^J:se=^^E:sf=^J:so=^^D:ue=^U:up=^W:us=^T: -# Data General 210/211 (and 410?) from Lee Pearson (umich!lp) via BRL -dg210|dg-ansi|Data General 210/211:\ - :am:\ - :co#80:li#24:\ - :cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:do=\E[B:ho=\E[H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:nl=\E[B:\ - :nw=\r\E[H\E[A\n:se=\E[0;m:so=\E[7;m:ue=\E[0;m:up=\E[A:\ - :us=\E[4;m: -# From: Peter N. Wan -# courtesy of Carlos Rucalde of Vantage Software, Inc. -# (dg211: this had :cm=\020%r%.%:., which was an ancient termcap hangover. -# I suspect the d200 function keys actually work on the dg211, check it out.) -dg211|Data General d211:\ - :k0@:k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:k9@:kb=^Y:l0@:nw=^M^Z:\ - :se=00\036E\200/>:sf@:so=5\036D:ta=^I:te=^L:ti=^L^R:ve=^L:\ - :vs=^L^R:\ - :tc=dg200: -# dg450 from cornell -dg450|dg6134|data general 6134:\ - :le@:nd=^X:tc=dg200: -# Note: lesser Dasher terminals will not work with vi because vi insists upon -# having a command to move straight down from any position on the bottom line -# and scroll the screen up, or a direct vertical scroll command. The 460 and -# above have both, the D210/211, for instance, has neither. We must use ANSI -# mode rather than DG mode because standard UNIX tty drivers assume that ^H is -# backspace on all terminals. This is not so in DG mode. -# (dg460-ansi: removed obsolete ":kn#6:"; also removed ":mu=\EW:", on the -# grounds that there is no matching ":ml:" -# fixed garbled ":k9=\E[00\:z:" capability -- esr) -dg460-ansi|Data General Dasher 460 in ANSI-mode:\ - :am:bs:ms:ul:\ - :co#80:it#8:li#24:\ - :al=\E[L:cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%2;%2H:dc=\E[P:\ - :dl=\E[M:do=\E[B:ei=:ho=\E[H:ic=\E[@:im=:is=^^F@:k0=\E[001z:\ - :k1=\E[002z:k2=\E[003z:k3=\E[004z:k4=\E[005z:k5=\E[006z:\ - :k6=\E[007z:k7=\E[008z:k8=\E[009z:k9=\E[010z:kb=\E[D:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:l0=f1:l1=f2:l2=f3:\ - :l3=f4:l4=f5:l5=f6:l6=f7:l7=f8:l9=f10:le=^H:mb=\E[5m:me=\E[m:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:nl=\ED:se=\E[m:sf=\E[S:so=\E[7m:\ - :sr=\E[T:ta=^I:ue=\E[05:up=\E[A:us=\E[4m: -# From: Wayne Throop -# Data General 605x -# Ought to work for a Model 6242, Type D210 as well as a 605x. -# Note that the cursor-down key transmits ^Z. Job control users, beware! -# This also matches a posted description of something called a `Dasher 100' -# so there's a dg100 alias here. -# (dg6053: the 4.4BSD file had :le=^H:, :do=^J:, :nd=^S:. -- esr) -dg6053|dg100|data general 6053:\ - :am:bs:bw:ul:\ - :co#80:li#24:\ - :bc=^Y:bl=^G:ce=^K:cl=^L:cm=\020%r%.%.:cr=^M:do=^Z:ho=^H:\ - :is=^R:k0=^^q:k1=^^r:k2=^^s:k3=^^t:k4=^^u:k5=^^v:k6=^^w:\ - :k7=^^x:k8=^^y:k9=^^z:kb=^Y:kd=^Z:kh=^H:kl=^Y:kr=^X:ku=^W:\ - :le=^Y:nd=^X:se=\200^^E:so=\200\200\200\200\200\036D:\ - :ta=^I:te=^L:ti=^L^R:ue=^U:up=^W:us=^T:ve=^L:vs=^L^R: - -#### Datamedia (dm) -# -# Datamedia was headquartered in Nashua, New Hampshire in 1993. -# As of early 1996, at least one company called `Datamedia' has been taken -# over by: -# -# Axent Technologies, Inc. -# 2400 Research Boulevard -# Rockville, Maryland 20850 -# voice: +1 301/258-5043 -# fax: +1 301/330-5756 -# email: -# -# makers of OmniGuard client/server security software. They are a software -# only company and no longer make terminals. However, the operator there -# told me that she had once spoken to a customer looking for Datamedia -# terminals who'd mentioned a Datamedia in New Jersey. This is backed up -# by comp.terminals poosting describing the ID plate on the back of a -# "Datamedia 3000" terminal. Was this an earlier incarnation of Axent? -# Inquiring minds want to know... -# - -cs10|colorscan|Datamedia Color Scan 10:\ - :ms:\ - :co#80:li#24:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%02;%02H:cr=^M:\ - :do=^J:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kd=\E[B:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=^H:me=\E[m:nd=\E[C:se=\E[m:sf=^J:\ - :so=\E[7m:ue=\E[m:up=\E[A:us=\E[4m: -cs10-w|Datamedia Color Scan 10 with 132 columns:\ - :co#132:\ - :cm=\E[%i%02;%03H:tc=cs10: - -# (dm1520: removed obsolete ":ma=^\ ^_^P^YH:" -- esr) -dm1520|dm1521|datamedia 1520:\ - :am:bs:xn:\ - :co#80:it#8:li#24:\ - :bl=^G:cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :cr=^M:do=^J:ho=^Y:\ - :kd=^J:kh=^Y:kl=^H:kr=^\:ku=^_:le=^H:nd=^\:sf=^J:ta=^I:up=^_: -dm2500|datamedia2500|datamedia 2500:\ - :bs:nc:\ - :co#80:li#24:\ - :al=\020\n\030\035\030\035:bl=^G:ce=^W:cl=^^^^\177:\ - :cm=\014%r%n%.%.:dc=\020\010\030\035:\ - :dl=\020\032\030\035:dm=^P:do=^J:ed=^X^]:\ - :ei=\377\377\030\035:ho=^B:ic=\020\034\030\035:im=^P:\ - :le=^H:nd=^\:pc=\377:se=^X^]:sf=^J:so=^N:up=^Z: -# dmchat is like DM2500, but DOES need "all that padding" (jcm 1/31/82) -# also, has a meta-key. -# From: -# (dmchat: ":MT:" changed to ":km:" -- esr) -dmchat|dmchat version of datamedia 2500:\ - :km:\ - :al=1*\020\n\030\035\030\035:dl=2\020\032\030\035:tc=dm2500: -# (dm3025: ":MT:" changed to ":km:" -- esr) -dm3025|datamedia 3025a:\ - :bs:km:\ - :co#80:it#8:li#24:\ - :al=\EP\n\EQ:bl=^G:cd=\EJ:ce=\EK:cl=\EM:cm=\EY%r%+ %+ :\ - :cr=^M:dc=\010:dl=\EP\EA\EQ:dm=\EP:do=^J:ed=\EQ:ei=\EQ:\ - :ho=\EH:im=\EP:ip=:is=\EQ\EU\EV:le=^H:nd=\EC:se=\EO0:sf=^J:\ - :so=\EO1:ta=^I:up=\EA: -dm3045|datamedia 3045a:\ - :am:bs:eo:km@:ul:xn:\ - :al@:dc=\EB:dl@:dm@:ed@:ei=\EP:is=\EU\EV:k0=\Ey\r:k1=\Ep\r:\ - :k2=\Eq\r:k3=\Er\r:k4=\Es\r:k5=\Et\r:k6=\Eu\r:k7=\Ev\r:\ - :k8=\Ew\r:k9=\Ex\r:kh=\EH:kr=\EC:ku=\EA:pc=\177:se@:so@:\ - :tc=dm3025: -# Datamedia DT80 soft switches: -# 1 0=Jump 1=Smooth -# Autorepeat 0=off 1=on -# Screen 0=Dark 1=light -# Cursor 0=u/l 1=block -# -# 2 Margin Bell 0=off 1=on -# Keyclick 0=off 1=on -# Ansi/VT52 0=VT52 1=Ansi -# Xon/Xoff 0=Off 1=On -# -# 3 Shift3 0=Hash 1=UK Pound -# Wrap 0=Off 1=On -# Newline 0=Off 1=On -# Interlace 0=Off 1=On -# -# 4 Parity 0=Odd 1=Even -# Parity 0=Off 1=On -# Bits/Char 0=7 1=8 -# Power 0=60Hz 1=50Hz -# -# 5 Line Interface 0=EIA 1=Loop -# Aux Interface 0=EIA 1=Loop -# Local Copy 0=Off 1=On -# Spare -# -# 6 Aux Parity 0=Odd 1=Even -# Aux Parity 0=Off 1=On -# Aux Bits/Char 0=7 1=8 -# CRT Saver 0=Off 1=On -# dm80/1 is a vt100 lookalike, but it doesn't seem to need any padding. -dm80|dmdt80|dt80|datamedia dt80/1:\ - :cd=\E[J:ce=\E[K:cl=\E[2J\E[H:cm=%i\E[%d;%dH:do=^J:\ - :ho=\E[H:me=\E[m:nd=\E[C:pf=\E[4i:po=\E[5i:ps=\E[0i:\ - :se=\E[m:so=\E[7m:sr=\EM:ue=\E[m:up=\E[A:us=\E[4m:\ - :tc=vt100: -# except in 132 column mode, where it needs a little padding. -# This is still less padding than the vt100, and you can always turn on -# the ^S/^Q handshaking, so you can use vt100 flavors for things like -# reverse video. -dm80w|dmdt80w|dt80w|datamedia dt80/1 in 132 char mode:\ - :co#132:\ - :cd=20\E[0J:ce=20\E[0K:cl=50\E[H\E[2J:cm=5\E[%i%d;%dH:\ - :do=^J:up=5\E[A:\ - :tc=dm80: -# From: Adam Thompson Sept 10 1995 -dt80-sas|Datamedia DT803/DTX for SAS usage:\ - :am:bw:\ - :co#80:li#24:\ - :ac=``a1fxgqh0jYk?lZm@nEooppqDrrsstCu4vAwBx3yyzz{{||}}~~:\ - :ae=\EG:al=\EL:as=\EF:bl=^G:cd=^K:ce=^]:cl=^L:\ - :cm=\E=%r%+ %+ :cr=^M:\ - :ct=\E'0:dl=\EM:do=\EB:ff=^L:ho=^Y:is=\E)0\E<\EP\E'0\E$2:\ - :kC=^L:kE=^]:kS=^K:kd=^J:kh=^Y:kl=^H:kr=^\:ku=^_:le=^H:me=^X:\ - :mr=\E$2\004:nd=^\:pf=^O:po=^N:se=^X:sf=\EB:so=\E$2\004:\ - :sr=\EI:st=\E'1:ta=^I:up=^_: - -# Datamedia Excel 62, 64 from Gould/SEL UTX/32 via BRL -# These aren't end-all Excel termcaps; but do insert/delete char/line -# and name some of the extra function keys. (Mike Feldman ccvaxa!feldman) -# The naming convention has been bent somewhat, with the use of E? (where -# E is for 'Excel') as # a name. This was done to distinguish the entries -# from the other Datamedias in use here, and yet to associate a model of -# the Excel terminals with the regular datamedia terminals that share -# major characteristics. -excel62|excel64|datamedia Excel 62:\ - :dc=\E[P:ei=\E[4l:im=\E[4h:k5=\EOu:k6=\EOv:k7=\EOw:k8=\EOx:\ - :k9=\EOy:kb=^H:kd=^J:kl=^H:\ - :tc=dt80: -excel62-w|excel64-w|datamedia Excel 62 in 132 char mode:\ - :dc=\E[P:ei=\E[4l:im=\E[4h:k5=\EOu:k6=\EOv:k7=\EOw:k8=\EOx:\ - :k9=\EOy:kb=^H:kd=^J:kl=^H:\ - :tc=dt80w: -excel62-rv|excel64-rv|datamedia Excel 62 in reverse video mode:\ - :dc=\E[P:ei=\E[4l:im=\E[4h:k5=\EOu:k6=\EOv:k7=\EOw:k8=\EOx:\ - :k9=\EOy:kb=^H:kd=^J:kl=^H:vb=\E[?5l\E[?5h:\ - :tc=dt80: - -#### Falco -# -# Falco Data Products -# 440 Potrero Avenue -# Sunnyvale, CA 940864-196 -# Vox: (800)-325-2648 -# Fax: (408)-745-7860 -# Net: techsup@charm.sys.falco.com -# -# Current Falco models as of 1995 are generally ANSI-compatible and support -# emulations of DEC VT-series, Wyse, and Televideo types. -# - -# Test version for Falco ts-1. See for info -# This terminal was released around 1983 and was discontinued long ago. -# The standout and underline highlights are the same. -falco|ts1|ts-1|falco ts-1:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET\EG0\010:cl=\E*:cm=\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=\ER:do=^J:ei=\Er:ho=^^:im=\Eq:is=\Eu\E3:\ - :k0=^A0\r:kd=^J:kl=^H:kr=^L:ku=^K:le=^H:me=\Eg0:nd=^L:\ - :se=\Eg0:sf=^J:so=\Eg1:ta=^I:ue=\Eg0:up=^K:us=\Eg1: -falco-p|ts1p|ts-1p|falco ts-1 with paging option:\ - :am:bs:da:db:mi:ms:ul:\ - :co#80:it#8:li#24:\ - :al=\EE:bl=^G:bt=\EI:cd=\EY:ce=\ET\EG0\010\Eg0:cl=\E*:\ - :cm=\E=%+ %+ :cr=^M:dc=\EW:dl=\ER:do=\E[B:ei=\Er:im=\Eq:\ - :is=\EZ\E3\E_c:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:me=\Eg0:nd=\E[C:se=\Eg0:sf=^J:so=\Eg4:ta=^I:te=\E_b:\ - :ti=\E_d:ue=\Eg0:up=\E[A:us=\Eg1: -# (ts100: I added / based on the init string -- esr) -ts100|ts100-sp|falco ts100-sp:\ - :am:mi:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:\ - :@8=\EOM:DO=\E[%dB:K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E~E:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :ct=\E[3g:dc=\E~W:dl=\E~R:do=^J:eA=\E(B:ei=:ho=\E[H:\ - :i1=\E~)\E~ea:ic=\E~Q:im=:k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:mr=\E[7m:\ - :nd=\E[C:r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[1;7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: -ts100-ctxt|falco ts-100 saving context:\ - :te=\E~_b:ti=\E~_d\E[2J:tc=ts100: - -#### Florida Computer Graphics -# - -# Florida Computer Graphics Beacon System, using terminal emulator program -# "host.com", as provided by FCG. This description is for an early release -# of the "host" program. Known bug: :cd: clears the whole screen, so it's -# commented out. - -# From: David Bryant 1/7/83 -beacon|FCG Beacon System:\ - :am:da:db:\ - :co#80:li#32:\ - :al=\EE:bl=\ESTART\r\E37\r\EEND\r:ce=\ET:cl=\EZ:\ - :cm=\E=%+ %+ :cr=^M:dc=\EW:dl=\ER:do=^J:ei=:ho=\EH:ic=\EQ:\ - :im=:le=^H:mb=\ESTART\r\E61\0541\r\EEND\r:\ - :me=\ESTART\r\E78\r\E70\0540\r\EEND\r:\ - :mr=\ESTART\r\E59\0541\r\EEND\r:nd=\EV:\ - :se=\ESTART\r\E70\0540\r\EEND\r:sf=^J:\ - :so=\ESTART\r\E70\0546\r\EEND\r:te=:\ - :ti=\ESTART\r\E2\0540\r\E12\r\EEND\r:\ - :ue=\ESTART\r\E60\0540\r\EEND\r:up=\EU:\ - :us=\ESTART\r\E60\0541\r\EEND\r: - -#### Fluke -# - -# The f1720a differences from ANSI: no auto margin, destructive -# tabs, # of lines, funny highlighting and underlining -f1720|f1720a|fluke 1720A:\ - :xt:\ - :co#80:li#16:sg#1:ug#1:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :do=\E[B:is=\E[H\E[2J:kd=^]:kl=^_:kr=^^:ku=^\:le=^H:me=\E[m:\ - :nd=\E[C:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ue=\E[m:up=\E[A:\ - :us=\E[4m: - -#### Liberty Electronics (Freedom) -# -# Liberty Electronics -# 48089 Fremont Blvd -# Fremont CA 94538 -# Vox: (510)-623-6000 -# Fax: (510)-623-7021 - -# From: -# (f100: added empty to suppress a tic warning; -# made this relative to adm+sgr -- note that isn't -# known to work for f100 but does on the f110. --esr) -f100|freedom|freedom100|freedom model 100:\ - :am:bs:bw:hs:mi:ms:xo:\ - :co#80:li#24:\ - :ac=:ae=\E$:al=\EE:as=\E%:bl=^G:bt=\EI:cd=\EY:ce=\ET:\ - :ch=\E]%+ :cl=^Z:cm=\E=%+ %+ :cr=^M:ct=\E3:cv=\E[%+ :\ - :dc=\EW:dl=\ER:do=^J:ds=\Eg\Ef\r:ei=\Er:fs=^M:ho=^^:im=\Eq:\ - :ip=:is=\Eg\Ef\r\Ed:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:\ - :kB=\EI:kb=^H:kd=^V:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:sf=^J:\ - :sr=\Ej:st=\E1:ta=^I:ts=\Eg\Ef:up=^K:vb=\Eb\Ed:\ - :tc=adm+sgr: -f100-rv|freedom-rv|freedom 100 in reverse video:\ - :is=\Eg\Ef\r\Eb:vb=\Ed\Eb:tc=f100: -# The f110 and f200 have problems with vi(1). They use the ^V -# code for the down cursor key. When kcud1 is defined in terminfo -# as ^V, the Control Character Quoting capability (^V in insert mode) -# is lost! It cannot be remapped in vi because it is necessary to enter -# a ^V to to quote the ^V that is being remapped!!! -# -# f110/f200 users will have to decide whether -# to lose the down cursor key or the quoting capability. We will opt -# initially for leaving the quoting capability out, since use of VI -# is not generally applicable to most interactive applications -# (f110: added :ta:, :kh: & from f100 -- esr) -f110|freedom110|Liberty Freedom 110:\ - :bw@:es:\ - :it#8:ws#80:\ - :ae=\E%%:al=\EE:as=\E$:dl=\ER:do=^V:ds=\Ef\r:ei=\Er\EO:\ - :im=\EO\Eq:ip@:is@:k0=^AI\r:k;@:kA=\EE:kC=^^:kD=\EW:kE=\ET:\ - :kI=\EQ:kL=\ER:kS=\EY:mb=\EG2:md=\EG0:mh=\EG@:pf=\Ea:po=\E`:\ - :so=\EG<:sr=\EJ:ts=\Ef:vb=\Eb\Ed:ve=\E.2:vi=\E.1:vs=\E.2:\ - :tc=f100: -f110-14|Liberty Freedom 110 14inch:\ - :dc@:tc=f110: -f110-w|Liberty Freedom 110 - 132 cols:\ - :co#132:tc=f110: -f110-14w|Liberty Freedom 110 14in/132 cols:\ - :co#132:\ - :dc@:tc=f110: -# (f200: added to suppress tic warnings re :as:/:ae: --esr) -f200|freedom200|Liberty Freedom 200:\ - :am:bs:es:hs:mi:ms:xo:\ - :co#80:it#8:li#24:ws#80:\ - :ac=:ae=\E%%:al=\EE:as=\E$:bl=^G:bt=\EI:cd=\EY:ce=\ET:\ - :ch=\E]%+ :cl=^Z:cm=\E=%+ %+ :cr=^M:cs=\Em0%+ %+ :ct=\E3:\ - :cv=\E[%+ :dc=\EW:dl=\ER:do=^V:ds=\Ef\r:ei=\Er:fs=^M:ho=^^:\ - :im=\Eq:k0=^AI\r:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:kA=\EE:kC=^^:\ - :kD=\EW:kE=\ET:kI=\EQ:kL=\ER:kS=\EY:kb=^H:kd=^V:kl=^H:kr=^L:\ - :ku=^K:le=^H:mb=\EG2:md=\EG0:mh=\EG@:nd=^L:pf=\Ea:po=\E`:\ - :sf=^J:so=\EG<:sr=\EJ:st=\E1:ts=\Ef:up=^K:vb=\Eo\En:ve=\E.1:\ - :vi=\E.0:vs=\E.1:\ - :tc=adm+sgr: -f200-w|Liberty Freedom 200 - 132 cols:\ - :co#132:tc=f200: -# The f200 has the ability to reprogram the down cursor key. The key is -# reprogrammed to ^J (linefeed). This value is remembered in non-volatile RAM, -# so powering the terminal off and on will not cause the change to be lost. -f200vi|Liberty Freedom 200 for vi:\ - :kd=^J:vb=\Eb\Ed:tc=f200: -f200vi-w|Liberty Freedom 200 - 132 cols for vi:\ - :co#132:tc=f200vi: - -#### GraphOn (go) -# -# Graphon Corporation -# 544 Division Street -# Campbell, CA 95008 -# Vox: (408)-370-4080 -# Fax: (408)-370-5047 -# Net: troy@graphon.com (Troy Morrison) -# -# -# The go140 and go225 have been discontinued. GraphOn now makes X terminals, -# including one odd hybrid that starts out life on power-up as a character -# terminal, than can be switched to X graphics mode (driven over the serial -# line) by an escape sequence. No info on this beast yet. -# (go140: I added / based on the init string -- esr) -go140|graphon go-140:\ - :bs:\ - :co#80:it#8:li#24:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:cd=10\E[J:ce=\E[K:\ - :cl=10\E[H\E[2J:cm=\E[%i%2;%2H:dc=\E[P:dl=\E[M:ei=\E[4l:\ - :if=/usr/share/tabset/vt100:im=\E[4h:\ - :is=\E<\E=\E[?3l\E[?7l\E(B\E[J\E7\E[;r\E8\E[m\E[q:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kd=\EOB:ke=\E[?1l\E>:\ - :kh=\E[H:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:\ - :me=\E[m:nd=\E[C:se=\E[m:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: -go140w|graphon go-140 in 132 column mode:\ - :am:\ - :co#132:\ - :is=\E<\E=\E[?3h\E[?7h\E(B\E[J\E7\E[;r\E8\E[m\E[q:tc=go140: -# Hacked up vt200 termcap to handle GO-225/VT220 -# From: -# (go225: I added / based on the init string -- esr) -go225|go-225|Graphon 225:\ - :am:bs:mi:xn:\ - :co#80:it#8:li#25:vt#3:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=^J:\ - :ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kb=^H:kd=\E[B:ke=\E>:kh=\E[H:kl=\E[D:\ - :kr=\E[C:ks=\E=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:r1=\E[\041p\E[?7h\E[2;1;1#w:rc=\E8:\ - :rf=/usr/share/tabset/vt100:sc=\E7:se=\E[27m:sf=\ED:\ - :so=\E[7m:sr=\EM:ta=^I:te=\E[\041p\E[?7h\E[2;1;1#w:\ - :ti=\E[2;0#w\E[1;25r:ue=\E[24m:up=\E[A:us=\E[4m: - -#### Harris (Beehive) -# -# Bletch. These guys shared the Terminal Brain Damage laurels with Hazeltine. -# Their terminal group is ancient history now (1995) though the parent -# company is still in business. -# - -# Beehive documentation is undated and marked Preliminary and has no figures -# so we must have early Superbee2 (Model 600, according to phone conversation -# with mfr.). It has proved reliable except for some missing padding -# (notably after \EK and at bottom of screen). -# -# The key idea is that AEP mode is poison for :cm: & that US's in -# the local memory should be avoided like the plague. That means -# that the 2048 character local buffer is used as 25 lines of 80 -# characters, period. No scrolling local memory, folks. It also -# appears that we cannot use naked INS LINE feature since it uses -# US. The sbi fakes :al: with an 80-space insert that may be too -# slow at low speeds; also spaces get converted to \040 which is -# too long for some programs (not vi). DEL LINE is ok but slow. -# -# The string is designed for last line of screen ONLY; cup to -# 25th line corrects the motion inherent in scrolling to Page 1. -# -# There is one understood bug. It is that the screen appears to -# pop to a new (blank) page after a :nw:, or leave a half-line -# ellipsis to a quad that is the extra 48 memory locations. The -# data received is dumped into memory but not displayed. Not to -# worry if :cm: is being used; the lines not displayed will be, -# whenever the cursor is moved up there. Since :cm: is addressed -# relative to MEMORY of window, nothing is lost; but beware of -# relative cursor motion (:up:,:do:,:nd:,:le:). Recommended, -# therefore, is setenv MORE -c . -# -# WARNING: Not all features tested. -# -# Timings are assembled from 3 sources. Some timings may reflect -# SB2/Model 300 that were used if more conservative. -# Tested on a Model 600 at 1200 and 9600 bd. -# -# The BACKSPACEkb option is cute. The NEWLINE key, so cleverly -# placed on the keyboard and useless because of AEP, is made -# into a backspace key. In use ESC must be pressed twice (to send) -# and sending ^C must be prefixed by ESC to avoid that weird -# transmit mode associated with ENTER key. -# -# IF TERMINAL EVER GOES CATATONIC with the cursor buzzing across -# the screen, then it has dropped into ENTER mode; hit -# RESET--ONLINE--!tset. -# -# As delivered this machine has a FATAL feature that will throw -# it into that strange transmit state (SPOW) if the space bar is -# hit after a CR is received, but before receiving a LF (or a -# few others). -# -# The circuits MUST be modified to eliminate the SPOW latch. -# This is done by strapping on chip A46 of the I/O board; cut -# the p.c. connection to Pin 5 and strap Pin 5 to Pin 8 of that -# chip. This mod has been checked out on a Mod 600 of Superbee II. -# With this modification absurdly high timings on cr are -# unnecessary. -# -# NOTE WELL that the rear panel switch should be set to CR/LF, -# not AEP! -# -sb1|beehive superbee:\ - :am:bs:bw:da:db:mi:ul:xb:\ - :co#80:li#25:sg#1:ug#1:\ - :al=\EN\EL\EQ \EP \EO\ER\EA:\ - :bl=^G:bt=\E`:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EF%r%03%03:cr=\r:\ - :ct=\E3:dc=\EP:dl=\EM:do=^J:ei=\ER:ho=\EH:im=\EQ\EO:\ - :is=\EE\EX\EZ\EO\Eb\Eg\ER:k0=\E2:k1=\Ep:k2=\Eq:k3=\Er:\ - :k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:k9=\E1:kE=\EK:kI=\EQ\EO:\ - :kL=\EM:kM=\ER:kS=\EJ:kb=^_:kd=\EB:kh=\EH:kl=\ED:kr=\EC:\ - :ku=\EA:l0=TAB CLEAR:l9=TAB SET:le=^H:me=\E_3:nd=\EC:\ - :se=\E_3:sf=^J:so=\E_1:st=\E1:ta=^I:te=:ti=\EO:ue=\E_3:\ - :up=\EA:us=\E_0: -sbi|superbee|beehive superbee at Indiana U.:\ - :xb:\ - :al=1\EN\EL\EQ \EP \EO\ER\EA:cr=\r:tc=sb1: -# Alternate (older) description of Superbee - f1=escape, f2=^C. -# Note: there are at least 3 kinds of superbees in the world. The sb1 -# holds onto escapes and botches ^C's. The sb2 is the best of the 3. -# The sb3 puts garbage on the bottom of the screen when you scroll with -# the switch in the back set to CRLF instead of AEP. This description -# is tested on the sb2 but should work on all with either switch setting. -# The f1/f2 business is for the sb1 and the :xb: can be taken out for -# the other two if you want to try to hit that tiny escape key. -# This description is tricky: being able to use cup depends on there being -# 2048 bytes of memory and the hairy string. -superbee-xsb|beehive super bee:\ - :am:da:db:xb:\ - :co#80:it#8:li#25:\ - :cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EF%r%3%3:cr=\r:ct=\E3:dc=\EP:\ - :dl=\EM:do=^J:ho=\EH:is=\EH\EJ:k1=\Ep:k2=\Eq:k3=\Er:k4=\Es:\ - :k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:kd=\EB:kh=\EH:kl=\ED:kr=\EC:\ - :ku=\EA:le=^H:me=\E_3:nd=\EC:se=\E_3:\ - :sf=\n\200\200\200\n\200\200\200\EA\EK\200\200\200\ET\ET:\ - :so=\E_1:st=\E1:ta=^I:up=\EA:ve=^J: -# This loses on lines > 80 chars long, use at your own risk -superbeeic|super bee with insert char:\ - :ei=\ER:ic=:im=\EQ:tc=superbee-xsb: -sb2|sb3|fixed superbee:\ - :xb@:tc=superbee: - -# Reports are that most of these Beehive entries (except superbee) have not -# been tested and do not work right. :se: is a trouble spot. Be warned. - -# (bee: :ic: was empty, which is obviously bogus -- esr) -beehive|bee|harris beehive:\ - :am:bs:mi:\ - :co#80:li#24:\ - :al=\EL:bt=\E>:cd=\EJ:ce=\EK:cl=\EE:cm=\EF%+ %+ :dc=\EP:\ - :dl=\EM:do=\EB:ei=\E@:ho=\EH:im=\EQ:kA=\EL:kB=\E>:kC=\EE:\ - :kD=\EP:kE=\EK:kI=\EQ:kL=\EM:kM=\E@:kb=^H:kd=\EB:kh=\EH:\ - :kl=\ED:kr=\EC:ku=\EA:le=^H:me=\Ed@:nd=\EC:se=\Ed@:so=\EdP:\ - :ue=\Ed@:up=\EA:us=\Ed`: -# set tab is ^F, clear (one) tab is ^V, no way to clear all tabs. -# good grief - does this entry make :sg:/:ug: when it doesn't have to? -# look at those spaces in :se:/:so:. Seems strange to me... -# (beehive: :if=/usr/share/tabset/beehive: removed, no such file. If you -# really care, cook up one using ^F -- esr) -beehive3|bh3m|beehiveIIIm|harris beehive 3m:\ - :am:bs:\ - :co#80:it#8:li#20:\ - :al=\023:bl=^G:cd=^R:ce=^P:cl=^E^R:cr=^M:dl=\021:do=^J:ho=^E:\ - :le=^H:ll=^E^K:nd=^L:se= ^_:sf=^J:so=^] :st=^F:ta=^I:up=^K: -beehive4|bh4|beehive 4:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EE:cr=^M:do=^J:ho=\EH:le=\ED:nd=\EC:\ - :sf=^J:up=\EA: -microb|microbee|micro bee series:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EE:cm=\EF%+ %+ :cr=^M:do=^J:k1=\Ep:\ - :k2=\Eq:k3=\Er:k4=\Es:k5=\Et:k6=\Eu:k7=\Ev:k8=\Ew:k9=\Ex:\ - :kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:me=\Ed@:nd=\EC:\ - :se=\Ed@:sf=^J:so= \EdP:ta=^I:ue=\Ed@:up=\EA:us=\Ed`: - -# 8675, 8686, and bee from Cyrus Rahman -# (8675: changed k10, k11...k16 to k;, F1...F6 -- esr) -ha8675|harris 8675:\ - :F1=^W:F2=\ER:F3=\EE:F4=\EI:F5=\Ei:F6=\Eg:\ - :is=\ES\E#\E*\Eh\Em\E?\E1\E9\E@\EX\EU:k1=^F:k2=^P:k3=^N:\ - :k4=^V:k5=^J:k6=^T:k7=^H:k8=\177:k9=\Ee:k;=\Ed:\ - :tc=bee: -# (8686: changed k10, k11...k16 to k;, F1...F6; fixed broken continuation -# in :is: -- esr) -ha8686|harris 8686:\ - :F1=\EW:F2=\002\E{\003:F3=\002\E|\003:F4=\002\E}\003:\ - :F5=\002\E~\003:F6=\002\E\177\003:\ - :is=\ES\E#\E*\Eh\Em\E?\E1\E9\E@\EX\EU\E"*Z01\E"8F35021B7C83#\E"8F45021B7D83#\E"8F55021B7E83#\E"8F65021B7F83#\E"8F75021B7383#\E"8F851BD7#\E"8F95021B7083#\E"8FA5021B7183#\E"8FB5021B7283#:\ - :k1=\002\Ep\003:k2=\002\Eq\003:k3=\002\Er\003:\ - :k4=\002\Es\003:k5=\E3:k6=\EI:k7=\ER:k8=\EJ:k9=\E(:k;=\Ej:tc=bee: - -#### Hazeltine -# -# Hazeltine appears to be out of the business now (1995). These guys were -# co-owners of the Terminal Brain Damage Hall Of Fame along with Harris. -# They have a hazeltine.com domain and can be reached at: -# -# Hazeltine -# 450 East Pulaski Road -# Greenlawn, New York 11740 -# -# As late as 1993, manuals for the terminal product line could still be -# purchased from: -# -# TRW Customer Service Division -# 15 Law Drive -# P.O. Box 2076 -# Fairfield, NJ 07007-2078 -# - -# Since :nd: is blank, when you want to erase something you -# are out of luck. You will have to do ^L's a lot to -# redraw the screen. h1000 is untested. It doesn't work in -# vi - this terminal is too dumb for even vi. (The code is -# there but it isn't debugged for this case.) -hz1000|hazeltine 1000:\ - :bs:\ - :co#80:li#12:\ - :bl=^G:cl=^L:cr=^M:do=^J:ho=^K:le=^H:nd= :sf=^J: -# From: Thu Aug 20 09:09:18 1981 -hz1420|hazeltine 1420:\ - :am:bs:\ - :co#80:li#24:\ - :al=\E^Z:bl=^G:cd=\E^X:ce=\E^O:cl=\E^\:cm=\E\021%r%.%+ :\ - :cr=^M:dl=\E^S:do=^J:le=^H:nd=^P:se=\E^Y:sf=^J:so=\E^_:ta=^N:\ - :up=\E^L: -# New "safe" cursor movement (11/87) from . Prevents -# freakout with out-of-range args and tn3270. No hz since it needs to -# receive tildes. -hz1500|hazeltine 1500:\ - :am:bs:hz:\ - :co#80:li#24:\ - :al=~\032:bl=^G:cd=~\030:ce=~^O:cl=~^\:\ - :cm=~\021%r%>^^ %+`%+`:cr=^M:dl=~\023:do=~^K:ho=~^R:kd=^J:\ - :kh=~^R:kl=^H:kr=^P:ku=~^L:le=^H:nd=^P:se=~^Y:sf=^J:so=~^_:\ - :up=~^L: -# h1510 assumed to be in sane escape mode. Else use h1500. -# (h1510: early versions of this entry apparently had ":se=\E^_:, -# :so=\E^Y:, but these caps were commented out in 8.3; also, -# removed incorrect and overridden ":do=^J:" -- esr) -hz1510|hazeltine 1510:\ - :am:bs:\ - :co#80:li#24:\ - :al=\E^Z:bl=^G:cd=\E^X:ce=\E^O:cl=\E^\:cm=\E\021%r%.%.:\ - :cr=^M:dl=\E^S:do=\E^K:le=^H:nd=^P:sf=^J:up=\E^L: -# Hazeltine 1520 -# The following switch settings are assumed for normal operation: -# FULL CR U/L_CASE ESCAPE -# FORMAT_OFF EOM_A_OFF EOM_B_OFF WRAPAROUND_ON -# Other switches may be set for operator convenience or communication -# requirements. -hz1520|Hazeltine 1520:\ - :am:bs:bw:ms:\ - :co#80:li#24:\ - :al=\E^Z:bl=^G:cd=\E^X:ce=\E^O:cl=\E^\:cm=\E\021%r%.%.:\ - :cr=^M:dl=\E^S:do=^J:ho=\E^R:kA=\E^Z:kC=\E^\:kE=\E^O:\ - :kL=\E^S:kS=\E^X:kb=^H:kd=\E^K:kh=\E^R:kl=^H:kr=^P:ku=\E^L:\ - :le=^H:md=\E^_:me=\E^Y:nd=^P:r1=\E$\E\005\E?\E\031:\ - :se=\E^Y:sf=^J:so=\E^_:up=\E^L: -# This version works with the escape switch off -# (h1520: removed incorrect and overridden ":do=^J:" -- esr) -hz1520-noesc|hazeltine 1520:\ - :am:hz:\ - :co#80:li#24:\ - :al=~^Z:bl=^G:cd=~^X:ce=~^O:cl=~^\:cm=~\021%r%.%.:cr=^M:\ - :dl=~^S:do=~^K:ho=~^R:le=^H:nd=^P:se=~^Y:sf=^J:so=~^_:up=~^L: -# Note: the h1552 appears to be the first Hazeltine terminal which -# is not braindamaged. It has tildes and backprimes and everything! -# Be sure the auto lf/cr switch is set to cr. -hz1552|hazeltine 1552:\ - :bs:\ - :al=\EE:dl=\EO:do=^J:k1=\EP:k2=\EQ:k3=\ER:l1=blue:l2=red:\ - :l3=green:\ - :tc=vt52: -hz1552-rv|hazeltine 1552 reverse video:\ - :do=^J:se=\ET:so=\ES:tc=hz1552: -# Note: h2000 won't work well because of a clash between upper case and ~'s. -hz2000|hazeltine 2000:\ - :am:bs:nc:\ - :co#74:li#27:\ - :al=~\032:bl=^G:cl=~\034:cm=~\021%r%.%.:dl=~\023:do=^J:\ - :ho=~^R:le=^H:pc=\177:sf=^J: -# Date: Fri Jul 23 10:27:53 1982. Some unknown person wrote: -# I tested this termcap entry for the Hazeltine Esprit with vi. It seems -# to work ok. There is one problem though if one types a lot of garbage -# characters very fast vi seems not able to keep up and hangs while trying -# to insert. That's in insert mode while trying to insert in the middle of -# a line. It might be because the Esprit doesn't have insert char and delete -# char as a built in function. Vi has to delete to end of line and then -# redraw the rest of the line. -esprit|Hazeltine Esprit I:\ - :am:bs:bw:\ - :co#80:li#24:\ - :al=\E^Z:bl=^G:bt=\E^T:cd=\E^W:ce=\E^O:cl=\E^\:\ - :cm=\E\021%r%.%.:cr=^M:dl=\E^S:do=\E^K:ho=\E^R:is=\E?:\ - :k0=^B0^J:k1=^B1^J:k2=^B2^J:k3=^B3^J:k4=^B4^J:k5=^B5^J:\ - :k6=^B6^J:k7=^B7^J:k8=^B8^J:k9=^B9^J:kb=^H:kd=\E^K:ke=\E>:\ - :kh=\E^R:kl=^H:kr=^P:ks=\E<:ku=\E^L:l0=0:l1=1:l2=2:l3=3:l4=4:\ - :l5=5:l6=6:l7=7:l8=8:l9=9:le=^H:nd=^P:se=\E^Y:sf=^J:so=\E^_:\ - :up=\E^L: -esprit-am|hazeltine esprit auto-margin:\ - :am:tc=esprit: -# Hazeltine Modular-1 from Cliff Shackelton via BRL -# Vi it seems always wants to send a control J for "do" and it turned out -# that the terminal would work somewhat if the auto LF/CR was turned off. -# (hmod1: removed :dn=~^K: -- esr) -hmod1|Hazeltine Modular 1:\ - :am:bs:hz:\ - :co#80:li#24:\ - :al=~^Z:bl=^G:bt=~^T:cl=~^\:cm=~\021%r%.%.:cr=^M:dl=~^S:\ - :do=~^K:ho=~^R:kd=~^K:kh=~^R:kl=^H:kr=^P:ku=~^L:le=^H:me=~^Y:\ - :nd=^P:rc=~^Q:sc=~^E:se=~^Y:sf=^J:so=~^_:up=~^L: -# -# Hazeltine Executive 80 Model 30 (1554?) -# from Will Martin via BRL -# Like VT100, except for different "am" behavior. -hazel|exec80|h80|he80|Hazeltine Executive 80:\ - :am:bs:pt:\ - :co#80:it#8:li#24:vt#3:\ - :bl=^G:cd=50\E[J:ce=3\E[K:cl=50\E[;H\E[2J:\ - :cm=5\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:do=^J:ho=\E[H:\ - :is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:mb=2\E[5m:md=2\E[1m:me=2\E[m:mr=2\E[7m:\ - :nd=2\E[C:nl=^J:r1=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :rc=\E8:rf=/usr/share/tabset/vt100:sc=\E7:se=2\E[m:\ - :so=2\E[7m:sr=5\EM:ta=^I:ue=2\E[m:up=2\E[A:us=2\E[4m: - -#### IBM -# - -ibm327x|line mode IBM 3270 style:\ - :gn:\ - :ce=^M:cl=^M^J:ho=^M: - -# Beware! The 3101 entry IBM shipped with AIX 3 is *wrong*. Losers... -# From: J.B. Nicholson-Owens 8 Mar 94 -# (ibm3101: :if=/usr/share/tabset/ibm3101: removed, no such file -- esr) -ibm3101|i3101|IBM 3101-10:\ - :am:bs:xo:\ - :co#80:li#24:\ - :bl=^G:cd=\EJ:ce=\EI:cl=\EK:cm=\EY%+ %+ :cr=^M:ct=\E1:do=^J:\ - :ho=\EH:kb=^H:kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:\ - :nw=^M^J:sf=^J:st=\E0:ta=^I:up=\EA: -# Received from the IBM terminals division (given to DRB) -# June 1988 for PS/2 OS 2.2.3 cut -ibm3151|i3151|IBM 3151:\ - :me=\E4@:\ - :se=\E4@:so=\E4A:ue=\E4@:us=\E4B:\ - :tc=ibm3163: -# From: Mark Easter 29 Oct 1992 -# I've commented out or translated some IBM extensions. -ibm3161|ibm3163|wy60-316X|wyse60-316X|IBM 3161/3163 display:\ - :am:bs:mi:ms:\ - :co#80:it#8:li#24:\ - :F1=\Ek\r:F2=\El\r:F3=\E\041a\r:F4=\E\041b\r:\ - :F5=\E\041c\r:F6=\E\041d\r:F7=\E\041e\r:F8=\E\041f\r:\ - :F9=\E\041g\r:FA=\E\041h\r:FB=\E\041i\r:FC=\E\041j\r:\ - :FD=\E\041k\r:FE=\E\041l\r:\ - :al=\EN:ac=l\354q\361k\353x\370j\352m\355w\367u\365v\366t\364n\356:\ - :bl=^G:cd=\EJ:ce=\EI:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:dc=\EQ:\ - :dl=\EO:do=\EB:ho=\EH:k1=\Ea\r:k2=\Eb\r:k3=\Ec\r:k4=\Ed\r:\ - :k5=\Ee\r:k6=\Ef\r:k7=\Eg\r:k8=\Eh\r:k9=\Ei\r:k;=\Ej\r:\ - :kA=\EN:kB=\E2:kC=\EL\r:kD=\EQ:kE=\EI:kI=\EP \010:kL=\EO:\ - :kS=\EJ:kT=\E0:ka=\E 1:kb=^H:kd=\EB:kh=\EH:kl=\ED:kr=\EC:\ - :kt=\E1:ku=\EA:le=\ED:mb=\E4D:md=\E4H:me=\E4@\E<@:mk=\E4P:\ - :mr=\E4A:nd=\EC:\ - :se=\E4@:sf=^J:so=\E4A:te=\E>A:ti=\E>A:ue=\E4@:up=\EA:\ - :us=\E4B: - -# How the 3164 sgr string works: -# %{32} # push space for no special video characteristics -# %?%p2%t%{1}%|%; # if p2 set, then OR the 1 bit for reverse -# %?%p3%t%{4}%|%; # if p3 set, then OR the 4 bit for blink -# %?%p4%t%{2}%|%; # if p4 set, then OR the 2 bit for underline -# %c # pop Pa1 -# %{39}%p1%- # calculate 32 + (7 - p1) for foreground -# %c # pop Pa2 -# %{64} # use only black background for now -# %c # pop Pa3 -ibm3164|i3164|IBM 3164:\ - :mb=\E4D:md=\E4H:me=\E4@:\ - :tc=ibm3163: - -ibmaed|IBM Experimental display:\ - :am:bs:eo:ms:\ - :co#80:it#8:li#52:\ - :al=\EN:cd=\EJ:ce=\EI:cl=\EH\EK:cm=\EY%+ %+ :dc=\EQ:dl=\EO:\ - :do=\EB:ei=:ho=\EH:ic=\EP:im=:kb=^H:kd=\EB:kl=\ED:kr=\EC:\ - :ku=\EA:le=^H:me=\E0:nd=\EC:se=\E0:so=\E0:ta=^I:up=\EA:\ - :vb=\EG: -ibm-apl|apl|IBM apl terminal simulator:\ - :li#25:tc=dm1520: -# (ibmmono: this had an unknown `sb' boolean, I changed it to `bs'. -# Also it had ":I0=f10:" which pretty obviously should be "l0=f10" -- esr) -ibmmono|ibm5151|IBM workstation monochrome:\ - :es:hs:\ - :al=\EL:dl=\EM:ds=\Ej\EY8 \EI\Ek:fs=\Ek:k0=\E<:k1=\ES:\ - :k2=\ET:k3=\EU:k4=\EV:k5=\EW:k6=\EP:k7=\EQ:k8=\ER:k9=\EY:\ - :kF=\EE:kI=\200:kN=\EE:kP=\Eg:kR=\EG:kb=^H:kh=\EH:l0=f10:\ - :md=\EZ:me=\Ew\Eq\Ez\EB:mk=\EF\Ef0;\Eb0;:mr=\Ep:se=\Ez:\ - :so=\EZ:sr=\EA:ts=\Ej\EY8%+ \Eo:ue=\Ew:us=\EW:\ - :tc=ibm3101: -ibmega|ibm5154|IBM Enhanced Color Display:\ - :cr=^M:do=^J:kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:tc=ibmmono: -ibmega-c|ibm5154-c|IBM Enhanced Color Display:\ - :se=\EB:so=\EF\Ef3;:ue=\EB:us=\EF\Ef2;:tc=ibmmono: -ibmvga-c|IBM VGA display color termcap:\ - :cr=^M:do=^J:kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:tc=ibmega-c: -ibmvga|IBM VGA display:\ - :cr=^M:do=^J:kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:tc=ibmega: -# ibmapa* and ibmmono entries come from ACIS 4.3 distribution -rtpc|ibmapa16|ibm6155|IBM 6155 Extended Monochrome Graphics Display:\ - :li#32:\ - :ds=\Ej\EY@ \EI\Ek:ts=\Ej\EY@%+ \Eo:tc=ibmmono: -# Advanced Monochrome (6153) and Color (6154) Graphics Display: -ibmapa8c|ibmapa8|ibm6154|ibm6153|IBM 6153/4 Advanced Graphics Display:\ - :li#31:\ - :ds=\Ej\EY? \EI\Ek:ts=\Ej\EY?%+ \Eo:tc=ibmmono: -ibmapa8c-c|ibm6154-c|IBM 6154 Advanced Color Graphics Display:\ - :li#31:\ - :ds=\Ej\EY? \EI\Ek:mh=\EF\Ef7;:ts=\Ej\EY?%+ \Eo:tc=ibmega-c: -# From: Marc Pawliger -# also in /usr/lpp/bos/bsdsysadmin. -# (hft-c: this entry had :kb=\E[D:kf=\E[C: on the line with ku/kd/kh; this was -# pretty obviously mislabeled for :le: and :nd:; also ":ul=\E[4m:" was clearly -# a typo for ":us=\E[4m:"; also ":el=\E[K:" was a typo for ":ce=\E[K:". -# I also added / based on the terminal reset string. -# There was an unknown boolean ":ht:" which I assume was meant to set hardware -# tabs, so I have inserted it#8. Finally, :ac=^N: paired with the :ae: looked -# like a typo for :as=^N:; finally, added empty to quiet tic -- esr) -ibm8512|ibm8513|hft-c|IBM High Function Terminal:\ - :am:mi:ms:\ - :co#80:it#8:li#25:\ - :AL=\E[%dL:DL=\E[%dM:RA=\E[?7l:SA=\E[?7h:ac=:ae=^O:al=\E[L:\ - :as=^N:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:dl=\E[M:\ - :dm=\E[4h:do=^J:ec=\E[%dX:ed=\E[4l:ei=\E[4l:ho=\E[H:\ - :im=\E[4h:is=\Eb\E[m\017\E[?7h:k0=\E[010q:k1=\E[001q:\ - :k2=\E[002q:k3=\E[003q:k4=\E[004q:k5=\E[005q:k6=\E[006q:\ - :k7=\E[007q:k8=\E[008q:k9=\E[009q:kd=\E[B:kh=\E[H:ku=\E[A:\ - :le=\E[D:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :r1=\Eb\E[m\017\E[?7h\E[H\E[J:rc=\E[u:sc=\E[s:se=\E[m:\ - :so=\E[7m:te=\E[20h:ti=\E[20;4l\E[?7h\Eb:ue=\E[m:up=\E[A:\ - :us=\E[4m: -hft|AIWS High Function Terminal:\ - :am:xo:\ - :co#80:li#25:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=^J:ei=\E6:ho=\E[H:\ - :ic=\E[@:im=\E6:k1=\E[001q:k2=\E[002q:k3=\E[003q:\ - :k4=\E[004q:k5=\E[005q:k6=\E[006q:k7=\E[007q:k8=\E[008q:\ - :k9=\E[009q:kN=\E[153q:kP=\E[159q:ka=\E[010q:kb=^H:\ - :kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mk=\E[8m:mr=\E[7m:nd=\E[C:se=\E[m:sf=^J:\ - :so=\E[7m:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -ibm-system1|system1|ibm system/1 computer:\ - :am:xt:\ - :co#80:li#24:\ - :bl=^G:cl=^Z:cm=\005%+ %+ :ho=^K:le=^H:nd=^\:sf=^J:up=^^: - -# From: -ibm5081|ibmmpel|IBM 5081 1024x1024 256/4096 color display:\ - :es:hs:\ - :li#33:\ - :ds=\Ej\EYA \EI\Ek:fs=\Ek:ts=\Ej\EYA%+ \Eo:tc=ibmmono: -ibm5081-c|ibmmpel-c|IBM 5081 1024x1024 256/4096 enhanced color display:\ - :es:hs:\ - :li#33:\ - :ds=\Ej\EYA \EI\Ek:fs=\Ek:ts=\Ej\EYA%+ \Eo:tc=ibmega-c: -ibm8514|IBM 8514 color display:\ - :es:hs:\ - :li#41:\ - :cr=^M:do=^J:ds=\Ej\EYI \EI\Ek:fs=\Ek:kb=^H:kd=^J:kl=^H:\ - :nw=^M^J:sf=^J:ta=^I:ts=\Ej\EYI%+ \Eo:\ - :tc=ibmega: -ibm8514-c|IBM 8514 color display:\ - :es:hs:\ - :li#41:\ - :cr=^M:do=^J:ds=\Ej\EYI \EI\Ek:fs=\Ek:kb=^H:kd=^J:kl=^H:\ - :nw=^M^J:sf=^J:ta=^I:ts=\Ej\EYI%+ \Eo:\ - :tc=ibmega-c: - -# -# AIX entries. IBM ships these with AIX 3. -# AIX extension caps are commented out, -# except for box1 which has been translated to an string. -# -aixterm-m|IBM AIXterm Monochrome Terminal Emulator:\ - :es:hs:\ - :ac=llqqkkxxjjmmwwuuvvttnn:ds=\E[?E:fs=\E[?F:md=\E[1m:\ - :me=\E[0;10m\E(B:s0=\E(B:s1=\E(0:\ - :sr@:ts=\E[?%dT:\ - :tc=ibm6153: -aixterm-m-old|IBM AIXterm Monochrome Terminal Emulator:\ - :es:hs:\ - :ds=\E[?E:fs=\E[?F:md=\E[1m:\ - :sr@:ts=\E[?%dT:\ - :tc=ibm6153: -jaixterm-m|IBM Kanji AIXterm Monochrome Terminal Emulator:\ - :ac@:\ - :tc=aixterm-m: - -#### Infoton/General Terminal Corp. -# - -# gt100 sounds like something DEC would come out with. Let's hope they don't. -i100|gt100|gt100a|General Terminal 100A (formerly Infoton 100):\ - :am:bs:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:cl=^L:cm=\Ef%r%+ %+ :cr=^M:\ - :dl=\EM:do=^J:ho=\EH:le=^H:nd=\EC:se=\Ea:sf=^J:so=\Eb:up=\EA:\ - :vb=\Eb\Ea: -i400|infoton 400:\ - :am:bs:\ - :co#80:li#25:\ - :al=\E[L:bl=^G:ce=\E[N:cl=\E[2J:cm=%i\E[%3;%3H:cr=^M:\ - :dc=\E[4h\E[2Q\E[P\E[4l\E[0Q:dl=\E[M:do=^J:\ - :ei=\E[4l\E[0Q:im=\E[4h\E[2Q:le=^H:nd=\E[C:sf=^J:up=\E[A: -# (addrinfo: removed obsolete ":bc=^Z:" -- esr) -addrinfo:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=^K:cl=^L:cr=^M:\ - :do=^J:ho=^H:le=^Z:ll=^H^\:nd=^Y:sf=^J:up=^\: -# (infoton: used to have the no-ops , , -- esr) -infoton:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=^K:cl=^L:cr=^M:do=^J:le=^Z:ll=^H^\:nd=^Y:sf=^J:\ - :up=^\: - -#### Interactive Systems Corp -# -# ISC used to sell OEMed and customized hardware to support ISC UNIX. -# ISC UNIX still exists in 1995, but ISC itself is no more; they got -# bought out by Sun. -# - -# From: Wed Sep 16 08:06:44 1981 -# (intext: removed obsolete ":ma=^K^P^R^L^L ::bc=^_:", also the -# ":le=^_:" later overridden -- esr) -intext|Interactive Systems Corporation modified owl 1200:\ - :am:bs:\ - :co#80:it#8:li#24:sg#1:\ - :al=\020:bl=^G:bt=^Y:cd=\026J:ce=^Kp^R:cl=\014:\ - :cm=\017%+ %+ :cr=^M:dc=\022:dl=\021:do=^J:ei=^V<:im=^V;:\ - :ip=:k0=^VJ\r:k1=^VA\r:k2=^VB\r:k3=^VC\r:k4=^VD\r:k5=^VE\r:\ - :k6=^VF\r:k7=^VG\r:k8=^VH\r:k9=^VI\r:kb=^H:kd=^J:ke=^V9:\ - :kh=^Z:kl=^_:kr=^^:ks=\036\072\264\026%:ku=^\:le=^H:nd=^^:\ - :se=^V# :sf=^J:so=^V$\054:ta=^I:up=^\: -intext2|intextii|INTERACTIVE modified owl 1251:\ - :am:bw:ul:\ - :co#80:li#24:sg#0:\ - :al=\E[L:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:ch=\E[%+^AG:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=:ic=\E[@:im=:k0=\E@\r:k1=\EP\r:k2=\EQ\r:\ - :k3=\ES\r:k4=\ET\r:k5=\EU\r:k6=\EV\r:k7=\EW\r:k8=\EX\r:\ - :k9=\EY\r:kb=^H:kd=\EB\r:kh=\ER\r:kl=\ED\r:kr=\EC\r:\ - :ku=\EA\r:l0=REFRSH:l1=DEL CH:l2=TABSET:l3=GOTO:l4=+PAGE:\ - :l5=+SRCH:l6=-PAGE:l7=-SRCH:l8=LEFT:l9=RIGHT:nd=\E[C:\ - :se=\E[2 D:sf=\E[S:so=\E[6 D:sr=\E[T:ta=^I:ue=\E[2 D:\ - :up=\E[A:us=\E[18 D:\ - :vb=\E[;;;;;;;;;2;;u\E[;;;;;;;;;1;;u: - -#### Kimtron (abm, kt) -# -# Kimtron entries include (undocumented) codes for: enter dim mode, -# enter bold mode, enter reverse mode, turn off all attributes. -# - -# Kimtron ABM 85 added by Dual Systems -# (abm85: removed duplicated ":kd=^J:" -- esr) -abm85|Kimtron ABM 85:\ - :am:bs:bw:ms:\ - :co#80:it#8:li#24:sg#1:ug#1:\ - :al=\EE:bt=\EI:cd=\Ey:ce=\Et:cl=\E*:cm=\E=%+ %+ :dc=\EW:\ - :dl=\ER:do=^J:ei=\Er:if=/usr/share/tabset/stdcrt:im=\EQ:\ - :is=\EC\EX\Eg\En\E%\Er\E(\Ek\Em\Eq:kb=^H:kd=^J:kh=^^:\ - :kl=^H:kr=^L:ku=^K:le=^H:nd=^L:se=\Ek:so=\Ej:ta=^I:ue=\Em:\ - :up=^K:us=\El: -# Kimtron ABM 85H added by Dual Systems. -# Some notes about the abm85h entries: -# 1) there are several firmware revs of 85H in the world. Use abm85h-old for -# firmware revs prior to SP51 -# 2) Make sure to use abm85h entry if the terminal is in 85h mode and the -# abm85e entry if it is in tvi920 emulation mode. They are incompatible -# in some places and NOT software settable i.e., :is: can't fix it) -# 3) In 85h mode, the arrow keys and special functions transmit when -# the terminal is in dup-edit, and work only locally in local-edit. -# Vi won't swallow `del char' for instance, but :ti: turns on -# dup-edit anyway so that the arrow keys will work right. If the -# arrow keys don't work the way you like, change :ti:, :te:, and -# :is:. Note that 920E mode does not have software commands to toggle -# between dup and local edit, so you get whatever was set last on the -# terminal. -# 4) :vb: attribute is nice, but seems too slow to work correctly -# (\Eb:pc:\Ed) -# 5) Make sure `hidden' attributes are selected. If `embedded' attributes -# are selected, the entry should be removed. -# 6) auto new-line should be on (selectable from setup mode only) -# -# From: Erik Fair Sun Oct 27 07:21:05 1985 -abm85h|Kimtron ABM 85H native mode:\ - :hs:\ - :sg@:\ - :bl=^G:ds=\Ee:fs=^M:im=\EZ:\ - :is=\EC\EN\EX\024\016\EA\Ea\E%\E9\Ee\Er\En\E"\E}\E'\E(\Ef\r\EG0\Ed\E.4\El:\ - :kd=^V:me=\E(\EG0:mh=\E):mk@:ts=\Eg\Ef:vb@:ve=\E.4:vs=\E.2:\ - :me=\EG0:mk=\EG1:mr=\EG4:se=\EG0:so=\EG4:ue=\EG0:us=\EG8:\ - :tc=abm85: -abm85e|Kimtron ABM 85H in 920E mode:\ - :sg@:\ - :bl=^G:im=\EZ:\ - :is=\EC\EX\EA\E%\E9\Ee\Er\En\E"\E}\E'\E(\Ef\r\Ek\Eq\Em:\ - :me=\E(\Ek:mh=\E):mr=\Ej:vb@:\ - :tc=abm85: -abm85h-old|oabm85h|o85h|Kimtron ABM 85H with old firmware rev.:\ - :sg@:\ - :bl=^G:im=\EZ:\ - :is=\E}\EC\EX\Ee\En\E%\Er\E(\Ek\Em\Eq\Ed\ET\EC\E9\EF:\ - :me=\E(\Ek:mh=\E):mr=\Ej:\ - :tc=abm85: -# From: -# (kt7: removed obsolete :ma=^V^J^L :" -- esr) -kt7|kimtron model kt-7:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :al=\EE:bt=\EI:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :dc=\EW:\ - :dl=\ER:do=^V:ei=:fs=\Eg:ho=^^:ic=\EQ:\ - :if=/usr/share/tabset/stdcrt:im=:is=\El\E":k0=^AI\r:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kA=\EE:kB=\EI:kC=^Z:kD=\EW:\ - :kE=\ET:kI=\EQ:kL=\ER:kS=\EY:kb=^H:kd=^V:kh=^^:kl=^H:kr=^L:\ - :ku=^K:le=^H:mk@:nd=^L:ta=^I:ts=\Ef:up=^K:\ - :tc=adm+sgr: -# Renamed TB=^I to :ta:, BE=^G to :bl:, BS=^H to :kb:, N to :kS: (based on the -# other kt7 entry and the adjacent key capabilities). Removed EE which is -# identical to :mh:. Removed :ES=\EGD: which is some kind of highlight -# but we can't figure out what. -kt7ix|kimtron model kt-7 or 70 in IX mode:\ - :am:bw:\ - :co#80:it#8:li#25:\ - :@7=\EY:PU=\EK:ac=lZm@k?jYt4uCvAwBqDx3nE:ae=\E%:al=\EE:\ - :as=\E$:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :\ - :cr=^M:dc=\EW:dl=\ER:do=^V:ds=\Ef\r:ei=:fs=^M:ho=^^:ic=\EQ:\ - :im=:is=\EG0\E s\017\E~:k0=^AI\r:k1=^A@\r:k2=^AA\r:\ - :k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:\ - :k9=^AH\r:kA=\EE:kB=\EI:kC=\E*:kE=\ET:kI=\EQ:kL=\ER:kN=\EJ:\ - :kS=\EY:kb=^H:kd=\E[B:kh=^^:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :mb=\EG2:me=\EG0:mh=\EG@:nd=^L:nw=^M^J:se=\EG0:sf=^J:\ - :so=\EG4:ta=^I:ts=\Ef:ue=\EG0:up=^K:us=\EG8:ve=\E.3:vi=\E.0: - -#### Microdata/MDIS -# -# This was a line of terminals made by McDonnell-Douglas Information Systems. -# These entries come direct from MDIS documentation. I have edited them only -# to move primary names of the form p[0-9] * to aliases, and to comment out -# :ae:/:as: in a couple of entries without strings. I have -# also removed the change history; the last version indicates this is -# version 4.3 by A.Barkus, September 1990 (earliest entry is October 1989). -# - -# McDonnell Information Systems Terminal Family History -# ========================================= -# -# Prism-1, Prism-2 and P99: -# Ancient Microdata and CMC terminals, vaguely like Adds Regent 25. -# -# Prism-4 and Prism-5: -# Slightly less ancient range of Microdata terminals. Follow-on from -# Prism-2, but with many enhancements. P5 has eight display pages. -# -# Prism-6: -# A special terminal for use with library systems, primarily in Germany. -# Limited numbers. Similar functionality to P5 (except attributes?). -# -# Prism-7, Prism-8 and Prism-9: -# More recent range of MDIS terminals, in which P7 and P8 -# replace the P4 & P5, with added functionality, and P9 is the flagship. -# The P9 has two emulation modes - P8 and ANSI - and includes a -# large number of the DEC VT220 control sequences. Both -# P8 and P9 support 80c/24ln/8pg and 132cl/24li/4pg formats. -# -# Prism-12 and Prism-14: -# Latest range, functionally very similar to the P9. The P14 has a -# black-on-white overscanning screen. -# -# The terminfo definitions given here are: -# -# p2 - Prism-2 (or Prism-1 or P99). -# -# p4 - Prism-4 (and older P7s & P8s). -# p5 - Prism-5 (or Prism-6). -# -# p7 - Prism-7. -# p8 - Prism-8 (in national or multinational mode). -# p8-w - 132 column version of p8. -# p9 - Prism-9 in ANSI mode. -# p9-w - 132 column version of p9. -# p9-8 - Prism-9 in Prism-8 emulation mode. -# p9-8-w - As p9-8, but with 132 columns. -# -# p12 - Prism-12 in ANSI mode. -# p12-w - 132 column version of p12. -# p12-m - Prism-12 in MDC emulation mode. -# p12-m-w - As p12-m, but with 132 columns. -# p14 - Prism-14 in ANSI mode. -# p14-w - 132 column version of p14. -# p14-m - Prism-14 in MDC emulation mode. -# p14-m-w - As p14-m, but with 132 columns. -# -# p2: Prism-2 -# ----------- -# -# Includes Prism-1 and basic P99 without SP or MP loaded. -# The simplest form of Prism-type terminal. -# Basic cursor movement and clearing operations only. -# No video attributes. -# Notes: -# Horizontal cursor qualifiers of NUL, XON and XOFF are mapped to the next -# value up, followed by backspace. -# -P2|MDC Prism-2:\ - :am:bw:ms:\ - :co#80:li#24:\ - :bl=^G:cd=\EJ:ce=\EK:\ - :cl=\014:\ - :cr=^M:cv=\013%+ :do=^J:ho=^A:kb=^H:kh=^A:le=^H:nd=^F:sf=^J:\ - :up=^Z: - -# p4: Prism-4 -# ----------- -# -# Includes early versions of P7 & P8. -# Basic family definition for most Prisms (except P2 and P9 ANSI). -# Notes: -# Horizontal cursor qualifiers of NUL, XON and XOFF are mapped to the next -# value up, followed by backspace. -# Cursor key definitions removed because they interfere with vi and csh keys. -# -prism4|p4|P4|MDC Prism-4:\ - :5i:am:bw:hs:ms:\ - :co#80:li#24:sg#1:ug#1:ws#72:\ - :bl=^G:cd=\EJ:ce=\EK:\ - :cl=\014:\ - :cr=^M:cv=\013%+ :do=^J:ds=\035\343\035\345:fs=^]\345:\ - :ho=^A^J:kb=^H:kh=^A:le=^H:mb=^CB:me=^C :mh=^CA:mk=^CH:\ - :mr=^CD:nd=^F:pf=\ET:po=\ER:ps=\EU:\ - :se=^C :sf=^J:so=^CD:ts=^]\343:ue=^C :up=^Z:us=^CP:\ - :ve=^]\342:vi=^]\344: - -# p5: Prism-5 -# ----------- -# -# Same definition as p4. Includes Prism-6 (not tested!). -# Does not use any multi-page features. -# -prism5|p5|P5|MDC Prism-5:\ - :tc=p4: - -# p7: Prism-7 -# ----------- -# -# Similar definition to p4. Uses ANSI cursor motion to avoid network problems. -# Notes: -# Use p4 for very early models of P7. -# Rev-index removed; can't send nulls to terminal in 8-bit modes. -# -prism7|p7|P7|MDC Prism-7:\ - :ch@:cm=\E[%i%d;%dH:cv@:tc=p4: - -# p8: Prism-8 -# ----------- -# -# Similar definition to p7. Uses ANSI cursor motion to avoid network problems. -# Supports national and multinational character sets. -# Notes: -# Alternate char set operations only work in multinational mode. -# Use p4 for very early models of P8. -# Rev-index removed; can't send nulls to terminal in 8-bit modes. -# (esr: commented out :as:/:ae: because there's no ) -# -prism8|p8|P8|MDC Prism-8:\ - :ch=\E[%i%d`:cm=\E[%i%d;%dH:cv=\E[%i%dd:is=\E[<12h:tc=p4: - -# p8-w: Prism-8 in 132 column mode -# -------------------------------- -# -# 'Wide' version of p8. -# Notes: -# Rev-index removed; can't send nulls to terminal in 8-bit modes. -# -prism8-w|p8-w|P8-W|MDC Prism-8 in 132 column mode:\ - :co#132:\ - :is=\E[<12h\E[<14h:tc=p8: - -# p9: Prism-9 in ANSI mode -# ------------------------- -# -# The "flagship" model of this generation of terminals. -# ANSI X3.64 (ISO 6429) standard sequences, plus many DEC VT220 ones. -# Notes: -# Tabs only reset by "reset". Otherwise assumes default (8 cols). -# Fixes to deal with terminal firmware bugs: -# . 'ri' uses insert-line since rev index doesn't always -# . 'sgr0' has extra '0' since esc[m fails -# . 'fsl' & 'dsl' use illegal char since cr is actioned wrong on line 25 -# Not covered in the current definition: -# . Labels -# . Programming Fn keys -# . Graphic characters (defaults correctly to vt100) -# . Padding values (sets xon) -# (esr: commented out :as:/:ae: because there's no ) -# -# (untranslatable capabilities removed to fit entry within 1023 bytes) -prism9|p9|P9|MDC Prism-9 in ANSII mode:\ - :5i:am:bw:hs:ms:xn:xo:\ - :co#80:it#8:li#24:vt#3:ws#72:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[23~:\ - :F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:F6=\E[29~:\ - :F7=\E[31~:F8=\E[32~:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:\ - :al=\E[L:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:ch=\E[%i%d`:cl=^L:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%d%%v:ct=\E[2g:\ - :cv=\E[%i%dd:dc=\E[P:dl=\E[M:do=^J:ds=\E[%}\024:ec=\E[%dX:\ - :ei=\E[4l:fs=^T:ho=\E[H:im=\E[4h:is=\E[&p\E[<12l\E F:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kC=^L:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[0m:mp=\E[32%{:mr=\E[7m:nd=\E[C:\ - :nw=^M^J:pf=\E[4i:po=\E[5i:ps=\E[i:\ - :r2=\E[&p\E[<12l\E F\E[3g\E[9;17;25;33;41;49;57;65;73 N:\ - :rc=\E[%z:rp=\E[%r%db%.:sc=\E[%y:se=\E[27m:sf=^J:so=\E[7m:\ - :sr=\E[L:st=\EH:ta=^I:ts=\E[%i%d%%}:ue=\E[24m:up=\E[A:\ - :us=\E[4m:ve=\E[<4h:vi=\E[<4l: - -# p9-w: Prism-9 in 132 column mode -# -------------------------------- -# -# 'Wide' version of p9. -# -prism9-w|p9-w|P9-W|MDC Prism-9 in 132 column mode:\ - :co#132:\ - :is=\E[&p\E[<12l\E F\E[<14h:\ - :r2=\E[&p\E[<12l\E F\E[<14h:tc=p9: - -# p9-8: Prism-9 in P8 mode -# ------------------------ -# -# P9 terminal in P8 emulation mode. -# Similar to p8 definition. -# Insertion and deletion operations possible. -# -prism9-8|p9-8|P9-8|MDC Prism-9 in P8 mode:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:al=\E[L:dc=\E[P:\ - :dl=\E[M:ei=:ic=\E[@:im=:\ - :tc=p8: - -# p9-8-w: Prism-9 in P8 and 132 column modes -# ------------------------------------------ -# -# P9 terminal in P8 emulation mode and 132 column mode. -# -prism9-8-w|p9-8-w|P9-8-W|MDC Prism-9 in Prism 8 emulation and 132 column mode:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:IC=\E[%d@:al=\E[L:dc=\E[P:\ - :dl=\E[M:ei=:ic=\E[@:im=:\ - :tc=p8-w: - -# p12: Prism-12 in ANSI mode -# --------------------------- -# -# See p9 definition. -# -prism12|p12|P12|MDC Prism-12 in ANSI mode:\ - :tc=p9: - -# p12-w: Prism-12 in 132 column mode -# ---------------------------------- -# -# 'Wide' version of p12. -# -prism12-w|p12-w|P12-W|MDC Prism-12 in 132 column mode:\ - :tc=p9-w: - -# p12-m: Prism-12 in MDC emulation mode -# ------------------------------------- -# -# P12 terminal in MDC emulation mode. -# Similar to p8 definition. -# Insertion and deletion operations possible. -# -prism12-m|p12-m|P12-M|MDC Prism-12 in MDC emulation mode:\ - :tc=p9-8: - -# p12-m-w: Prism-12 in MDC emulation and 132 column modes -# ------------------------------------------------------- -# -# P12 terminal in MDC emulation mode and 132 column mode. -# -prism12-m-w|p12-m-w|P12-M-W|MDC Prism-12 in MDC emulation and 132 column mode:\ - :tc=p9-8-w: - -# p14: Prism-14 in ANSII mode -# --------------------------- -# -# See p9 definition. -# -prism14|p14|P14|MDC Prism-14 in ANSII mode:\ - :tc=p9: - -# p14-w: Prism-14 in 132 column mode -# ---------------------------------- -# -# 'Wide' version of p14. -# -prism14-w|p14-w|P14-W|MDC Prism-14 in 132 column mode:\ - :tc=p9-w: - -# p14-m: Prism-14 in MDC emulation mode -# ------------------------------------- -# -# P14 terminal in MDC emulation mode. -# Similar to p8 definition. -# Insertion and deletion operations possible. -# -prism14-m|p14-m|P14-M|MDC Prism-14 in MDC emulation mode:\ - :tc=p9-8: - -# p14-m-w: Prism-14 in MDC emulation and 132 column modes -# ------------------------------------------------------- -# -# P14 terminal in MDC emulation mode and 132 column mode. -# -prism14-m-w|p14-m-w|P14-M-W|MDC Prism-14 in MDC emulation and 132 column mode:\ - :tc=p9-8-w: - -# End of McDonnell Information Systems Prism definitions - -# These things were popular in the Pick database community at one time -# From: George Land 24 Sep 1996 -p8gl|prism8gl|McDonnell-Douglas Prism-8 alternate definition:\ - :am:bw:hs:mi:\ - :co#80:li#24:ma#1:sg#1:ug#1:ws#78:\ - :F2=^AJ\r:F3=^AK\r:F4=^AL\r:F5=^AM\r:F6=^AN\r:F7=^AO\r:\ - :bl=^G:cd=\EJ:ce=\EK:cl=^L:cm=\E[%i%d;%dH:cr=^M:dc= ^H:\ - :dl=^P:do=^J:ho=^A:k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:\ - :k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:k;=^AI\r:\ - :kD= ^H:kE=\EK:kL=^P:kS=\EJ:kb=^H:kd=^J:kh=^A:kl=^U:kr=^F:\ - :ku=^Z:l1=F1:l2=F2:l3=F3:l4=F4:l5=F5:l6=F6:l7=F7:l8=F8:l9=F9:\ - :la=F10:le=^U:mb=^CB:me=^C :mh=^CA:mk=^CH:mr=^CD:nd=^F:\ - :nw=^J^M:pc=\200:se=^C :sf=^J:so=^CE:ue=^C :up=^Z:us=^C0: - -#### Microterm (act, mime) -# -# The mime1 entries refer to the Microterm Mime I or Mime II. -# The default mime is assumed to be in enhanced act iv mode. -# - -# New "safe" cursor movement (5/87) from . Prevents -# freakout with out-of-range args on Sytek multiplexors. No :so=^N: and -# :se=^N: since it gets confused and it's too dim anyway. No :ic: -# since Sytek insists ^S means xoff. -# (act4: found ":ic=2^S:ei=:im=:ip=.1*^V:" commented out in 8.3 -- esr) -act4|microterm|microterm act iv:\ - :am:bs:\ - :co#80:li#24:\ - :al=2.3*\001<2.3*/>:bl=^G:cd=2.2*\037:ce=.1*\036:\ - :cl=12\014:cm=\024%+^X%>/0%+P:cr=^M:dc=.1*\004:\ - :dl=2.3*\027:do=^K:ho=^]:kd=^K:kl=^H:kr=^X:ku=^Z:le=^H:nd=^X:\ - :sf=^J:up=^Z: -# The padding on :sr: and :ta: for act5 and mime is a guess and not final. -# The act 5 has hardware tabs, but they are in columns 8, 16, 24, 32, 41 (!)... -# (microterm5: removed obsolete ":ma==^Z^P^Xl^Kj:" -- esr) -act5|microterm5|microterm act v:\ - :kd=^K:kl=^H:kr=^X:ku=^Z:sr=\EH:uc=^H\EA:tc=act4: -# Mimes using brightness for standout. Half bright is really dim unless -# you turn up the brightness so far that lines show up on the screen. -mime-fb|full bright mime1:\ - :is=^S\E:se=^S:so=^Y:tc=mime: -mime-hb|half bright mime1:\ - :is=^Y\E:se=^Y:so=^S:tc=mime: -# (mime: removed obsolete ":ma=^X ^K^J^Z^P:"; removed ":do=^K:" that overrode -# the more plausible ":do=^J:" -- esr) -# uc was at one time disabled to get around a curses bug, be wary of it -mime|mime1|mime2|mimei|mimeii|microterm mime1:\ - :am:bs:\ - :co#80:it#8:li#24:vt#9:\ - :al=\001:bl=^G:cd=^_:ce=^^:cl=^]^C:cm=\024%+^X%> 0%+P:\ - :cr=^M:dl=\027:do=^J:ho=^]:is=^S\E^Q:kd=^K:kl=^H:kr=^X:ku=^Z:\ - :le=^H:nd=^X:sf=^J:sr=\022:ta=\011:uc=^U:up=^Z: -# These termcaps (for mime2a) put the terminal in low intensity mode -# since high intensity mode is so obnoxious. -mime2a-s|microterm mime2a (emulating an enhanced soroc iq120):\ - :am:bs:\ - :co#80:li#24:\ - :al=\001:bl=^G:cd=\EJ:ce=\EK:cl=\EL:cm=\E=%+ %+ :cr=^M:\ - :dc=\ED:dl=\027:do=^J:ei=^Z:ho=^^:im=\EE:ip=:is=\E):kd=^J:\ - :kl=^H:kr=^L:ku=^K:le=^H:nd=^L:se=\E;:sf=^J:so=\E\072:sr=\EI:\ - :ue=\E7:up=\EI:us=\E6: -# This is the preferred mode (but ^X can't be used as a kill character) -mime2a|mime2a-v|microterm mime2a (emulating an enhanced vt52):\ - :bs:\ - :co#80:it#8:li#24:\ - :al=\001:bl=^G:cd=\EQ:ce=\EP:cl=\EL:cm=\EY%+ %+ :cr=^M:\ - :dc=^N:dl=\027:do=^J:ei=^Z:ho=\EH:im=^O:ip=:is=^Y:kd=\EB:\ - :kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:se=\E9:sf=^J:so=\E8:\ - :sr=\EA:ta=^I:ue=\E5:up=\EA:us=\E4: -# (mime3a: removed obsolete ":ma=^X ^K^J^Z^P:" -- esr) -mime3a|mime1 emulating 3a:\ - :am@:\ - :kd=^K:kl=^H:kr=^X:ku=^Z:tc=adm3a: -mime3ax|mime-3ax|mime1 emulating enhanced 3a:\ - :it#8:\ - :al=\001:cd=^_:ce=^X:dl=\027:ta=\011:tc=mime3a: -# Wed Mar 9 18:53:21 1983 -# We run our terminals at 2400 baud, so there might be some timing problems at -# higher speeds. The major improvements in this model are the terminal now -# scrolls down and insert mode works without redrawing the rest of the line -# to the right of the cursor. This is done with a bit of a kludge using the -# exit graphics mode to get out of insert, but it does not appear to hurt -# anything when using vi at least. If you have some users using act4s with -# programs that use curses and graphics mode this could be a problem. -mime314|mm314|mime 314:\ - :am:\ - :co#80:li#24:\ - :al=^A:cd=^_:ce=^^:cl=^L:cm=\024%.%.:dc=^D:dl=^W:ei=^V:ho=^]:\ - :im=^S:kd=^K:kl=^H:kr=^X:ku=^Z:le=^H:nd=^X:ta=^I:up=^Z: -# Microterm mime 340 from University of Wisconsin -mm340|mime340|mime 340:\ - :co#80:li#24:\ - :al=46\EU:cd=2*\037:ce=2.1\EL:cl=12\032:cm=\E=%+ %+ :\ - :cr=^M:dc=2.1*\E#:dl=49.6\EV:do=^J:is=\E\054:kb=^H:kd=^J:\ - :kl=^H:ku=^K:le=^H:nd=^L:nw=^M^J:sf=^J:ta=^I:up=^K: -# This came from University of Wisconsin marked "astro termcap for jooss". -# (mt4520-rv: removed obsolete ":kn#4:" and incorrect ":ri=\E[C:"; -# also added / based on the init string -- esr) -mt4520-rv|micro-term 4520 reverse video:\ - :am:hs:ms:xn:xo:\ - :co#80:it#8:li#24:ws#80:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:ct=\E[g:dc=\E[P:dl=\E[M:do=\E[B:ei=:\ - :fs=\E[?5l\E[?5h:ho=\E[H:ic=\E[@:im=:\ - :is=\E(B\E[2l\E>\E[20l\E[?3l\E[?5h\E[?7h\E[1;24r\E[24;1H\E[H\E[J:\ - :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:ll=\E[24;1H:me=\E[m:\ - :nd=\E[C:nw=\EE:\ - :r1=\E(B\E[2l\E>\E[20l\E[?3l\E[?5h\E[?7h\E[H\E[J:\ - :rc=\E8:rf=/usr/share/tabset/vt100:sc=\E7:se=\E[0m:\ - :sf=\ED:so=\E[7m:sr=\EM:st=\EH:ta=^I:ts=\E[25;1H:ue=\E[24m:\ - :up=\E[A:us=\E[4m:vb=\E[?5l\E[?5h:ve=\E[0V\E8:\ - :vs=\E7\E[0U: - -# Fri Aug 5 08:11:57 1983 -# This entry works for the ergo 4000 with the following setups: -# ansi,wraparound,newline disabled, xon/xoff disabled in both -# setup a & c. -# -# WARNING!!! There are multiple versions of ERGO 4000 microcode -# Be advised that very early versions DO NOT WORK RIGHT !! -# Microterm does have a ROM exchange program- use it or lose big -# (ergo400: added / based on the init string -- esr) -ergo4000|microterm ergo 4000:\ - :da:db:ms:\ - :co#80:li#66:\ - :AL=\E[1L:RA=\E[?7l:SA=\E[?7m:bl=^G:cd=\E[0J:ce=\E[0K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:dc=\E[1P:dl=\E[1M:\ - :do=\E[B:ei=\E[4l:im=\E[4h:\ - :is=\E<\E=\E[?1l\E[?4l\E[?5l\E[?7h\E[?8h:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:kd=\E[B:ke=\E=:kl=\E[D:kr=\E[C:\ - :ks=\E=:ku=\E[A:l1=pf1:l2=pf2:l3=pf3:l4=pf4:le=^H:me=\E[m:\ - :nd=\E[C:se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:up=\E[A: - -#### NCR -# -# NCR's terminal group was merged with AT&T's when AT&T bought the company. -# For what happened to that group, see the ADDS section. -# -# There is an NCR4103 terminal that's just a re-badged Wyse-50. -# - -# NCR7900 DIP switches: -# -# Switch A: -# 1-4 - Baud Rate -# 5 - Parity (Odd/Even) -# 6 - Don't Send or Do Send Spaces -# 7 - Parity Enable -# 8 - Stop Bits (One/Two) -# -# Switch B: -# 1 - Upper/Lower Shift -# 2 - Typewriter Shift -# 3 - Half Duplex / Full Duplex -# 4 - Light/Dark Background -# 5-6 - Carriage Return Without / With Line Feed -# 7 - Extended Mode -# 8 - Suppress Keyboard Display -# -# Switch C: -# 1 - End of line entry disabled/enabled -# 2 - Conversational mode / (Local?) Mode -# 3 - Control characters displayed / not displayed -# 4 - (2-wire?) / 4-wire communications -# 5 - RTS on and off for each character -# 6 - (50Hz?) / 60 Hz -# 7 - Exit after level zero diagnostics -# 8 - RS-232 interface -# -# Switch D: -# 1 - Reverse Channel (yes / no) -# 2 - Manual answer (no / yes) -# 3-4 - Cursor appearance -# 5 - Communication Rate -# 6 - Enable / Disable EXT turnoff -# 7 - Enable / Disable CR turnoff -# 8 - Enable / Disable backspace -# -# From , init string hacked by SCO. -ncr7900i|ncr7900|ncr 7900 model 1:\ - :am:bw:ul:\ - :co#80:li#24:sg#1:ug#1:\ - :bl=^G:cd=\Ek:ce=\EK:cl=^L:cm=\E1%r%.%.:cr=^M:do=^J:\ - :is=\E0@\010\E3\E4\E7:kd=^J:kh=^A:kl=^U:kr=^F:ku=^Z:le=^H:\ - :ll=^A:mb=\E0B:me=\E0@:mh=\E0A:mr=\E0P:nd=^F:pf=^T:po=^R:\ - :se=\E0@:sf=^J:so=\E0Q:ue=\E0@:up=^Z:us=\E0`: -ncr7900iv|ncr 7900 model 4:\ - :am:bw:es:hs:\ - :co#80:li#24:\ - :al=\E^N:bl=^G:cl=^L:cm=\013%+@\E\005%02:cr=^M:dl=\E^O:\ - :do=^J:ds=\Ey1:fs=\Ek\Ey5:ho=\013@\E^E00:k1=\ES:k2=\ET:\ - :k3=\EU:k4=\EV:k5=\EW:k6=\EP:k7=\EQ:k8=\ER:kb=^H:kd=\EB:\ - :kh=\EH:kl=\ED:kr=\EC:ku=\EA:l6=blue:l7=red:l8=white:le=^H:\ - :nw=^M^J:sf=^J:ts=\Ej\Ex5\Ex1\EY8%+ \Eo: -ncr7901|ncr 7901 model:\ - :am:bw:ul:\ - :co#80:li#24:\ - :bl=^G:cd=\Ek:ce=\EK:ch=\020%+^J:cl=^L:cm=\EY%+ %+ :cr=^M:\ - :cv=\013%+@:do=^J:is=\E4^O:kC=^L:kd=^J:kh=^H:kl=^U:kr=^F:\ - :ku=^Z:le=^H:ll=^A:mb=\E0B:me=^O:mh=\E0A:mr=\E0P:nd=^F:pf=^T:\ - :po=^R:\ - :se=^O:sf=^J:so=\E0Q\016:ue=^O:up=^Z:us=\E0`\016:ve=^X:\ - :vi=^W: - -#### Perkin-Elmer (Owl) -# -# These are official terminfo entries from within Perkin-Elmer. -# - -bantam|pe550|pe6100|perkin elmer 550:\ - :bs:\ - :co#80:li#24:\ - :bl=^G:ce=\EI:cl=\EK:cm=\EX%+ \EY%+ :cr=^M:do=^J:ho=\EH:\ - :le=^H:ll=\EH\EA:nd=\EC:sf=^J:up=\EA: -fox|pe1100|perkin elmer 1100:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cd=\EJ:ce=\EI:cl=\EH\EJ:cm=\EX%+ \EY%+ :cr=^M:\ - :ct=\E3:do=^J:ho=\EH:le=^H:ll=\EH\EA:nd=\EC:sf=^J:st=\E1:\ - :up=\EA:vb=\020\002\020\003: -owl|pe1200|perkin elmer 1200:\ - :am:bs:in:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EI:cl=\EH\EJ:cm=\EX%+ \EY%+ :\ - :cr=^M:ct=\E3:dc=\EO:dl=\EM:do=^J:ei=:ho=\EH:ic=\EN:im=:ip=:\ - :k0=\ERJ:k1=\ERA:k2=\ERB:k3=\ERC:k4=\ERD:k5=\ERE:k6=\ERF:\ - :k7=\ERG:k8=\ERH:k9=\ERI:kb=^H:le=^H:ll=\EH\EA:\ - :me=\E\041\200:nd=\EC:se=\E\041\200:sf=^J:so=\E\041^H:\ - :st=\E1:up=\EA:vb=\020\002\020\003: -pe1251|pe6300|pe6312|perkin elmer 1251:\ - :am:\ - :co#80:it#8:li#24:pb#300:sg#1:vt#8:\ - :bl=^G:cd=\EJ:ce=\EI:cl=\EK:cm=\EX%+ \EY%+ :cr=^M:ct=\E3:\ - :do=\EB:ho=\EH:k0=\ERA:k1=\ERB:k2=\ERC:k3=\ERD:k4=\ERE:\ - :k5=\ERF:k6=\ERG:k7=\ERH:k8=\ERI:k9=\ERJ:k;=\ERK:le=\ED:\ - :nd=\EC:sf=^J:st=\E1:up=\EA: -# (pe7000m: this had -# rmul=\E!\0, smul=\E!\040, -# which is probably wrong, it collides with kf0 -pe7000m|perkin elmer 7000 series monochrome monitor:\ - :am:\ - :co#80:li#24:\ - :bl=^G:bt=\E\041Y:cd=\EJ:ce=\EI:cl=\EK:cm=\ES%+ %+ :cr=^M:\ - :do=\EB:ho=\EH:i1=\E\041\200\EW 7o\Egf\ES7 :\ - :k0=\E\041\200:k1=\E\041^A:k2=\E\041^B:k3=\E\041^C:\ - :k4=\E\041^D:k5=\E\041^E:k6=\E\041^F:k7=\E\041^G:\ - :k8=\E\041^H:k9=\E\041^I:k;=\E\041^J:kb=^H:kd=\E\041U:\ - :kh=\E\041S:kl=\E\041V:kr=\E\041W:ku=\E\041T:le=\ED:\ - :ll=\ES7 :nd=\EC:sf=^J:sr=\ER:up=\EA: -pe7000c|perkin elmer 7000 series colour monitor:\ - :i1=\E\041\200\EW 7o\Egf\Eb0\Ec7\ES7 :se=\Eb0:so=\Eb2:\ - :ue=\E\041\200:us=\E\041 :\ - :tc=pe7000m: - -#### Sperry Univac -# -# Sperry Univac has merged with Burroughs to form Unisys. -# - -# This entry is for the Sperry UTS30 terminal running the TTY -# utility under control of CP/M Plus 1R1. The functionality -# provided is comparable to the DEC vt100. -# (uts30: I added / based on the init string -- esr) -uts30|sperry uts30 with cp/m@1R1:\ - :am:bw:hs:\ - :co#80:li#24:ws#40:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7m:SF=\E[%dB:\ - :SR=\E[%dA:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\Ed:al=\EN:as=\EF:bl=^G:cd=\E[J:ce=\E[K:cl=^L:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\EU%+ %+ :dc=\EM:dl=\EL:do=\EB:\ - :ei=:fs=^M:ho=\E[H:ic=\EO:im=:is=\E[U 7\E[24;1H:kb=^H:\ - :kd=\EOB:kh=\E[H:kl=\EOD:kr=\EOC:ku=\EOA:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\EC:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\EX:\ - :rf=/usr/share/tabset/vt100:sc=\EW:se=\E[m:sf=^J:\ - :so=\E[7m:sr=\EI:ta=^I:ts=\E]:uc=\EPB:ue=\E[m:up=\E[A:\ - :us=\E[4m:ve=\ES:vi=\ER: - -#### Tandem -# -# Tandem builds these things for use with its line of fault-tolerant -# transaction-processing computers. They aren't generally available -# on the merchant market, and so are fairly uncommon. -# - -tandem6510|adm3a repackaged by Tandem:\ - :tc=adm3a: - -# A funny series of terminal that TANDEM uses. The actual model numbers -# have a fourth digit after 653 that designates minor variants. These are -# natively block-mode and rather ugly, but they have a character mode which -# this doubtless(?) exploits. There is a 6520 that is slightly dumber. -# (tandem653: had ":sb=\ES:", probably someone's mistake for sf; also, -# removed :if=/usr/share/tabset/tandem653:, no such file -- esr) -tandem653|t653x|Tandem 653x multipage terminal:\ - :am:bs:da:db:hs:\ - :co#80:li#24:sg#1:ug#1:ws#64:\ - :cd=\EJ:ce=\EK:cl=\EI:cm=\023%+ %+ :do=^J:ds=\Eo\r:fs=^M:\ - :ho=\EH:le=^H:me=\E6 :nd=\EC:se=\E6 :sf=\ES:so=\E6$:sr=\ET:\ - :ts=\Eo:ue=\E6 :up=\EA:us=\E60: - -#### Tandy/Radio Shack -# -# Tandy has a line of VDTs distinct from its microcomputers. -# - -dmterm|deskmate terminal:\ - :am:bw:\ - :co#80:li#24:\ - :al=\EP:bl=^G:cd=\EJ:ce=\EK:cl=\Ej:cm=\EY%+ %+ :cr=^M:\ - :dc=\ES:dl=\ER:do=\EB:ei=:ho=\EH:ic=\EQ:im=:k0=\E1:k1=\E2:\ - :k2=\E3:k3=\E4:k4=\E5:k5=\E6:k6=\E7:k7=\E8:k8=\E9:k9=\E0:\ - :kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:l0=f1:l1=f2:l2=f3:l3=f4:\ - :l4=f5:l5=f6:l6=f7:l7=f8:l8=f9:l9=f10:le=^H:ll=\EE:mk@:nd=\EC:\ - :sf=\EX:ta=^I:ue@:up=\EA:us@:ve=\EG6:vi=\EG5:\ - :tc=adm+sgr: -dt100|dt-100|Tandy DT-100 terminal:\ - :xo:\ - :co#80:li#24:sg#1:ug#1:\ - :ac=kkllmmjjnnwwvvttuuqqxx:ae=\E(B:al=\E[L:as=\E(0:bl=^G:\ - :cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\010\E[%i%d;%dH:cr=^M:\ - :cs=\E[%2;%2r:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:ic=\E[@:\ - :im=:is=\E[?3l\E(B:k1=\E[?3i:k2=\E[2i:k3=\E[@:k4=\E[M:\ - :k5=\E[17~:k6=\E[18~:k7=\E[19~:k8=\E[20~:k9=\E[21~:\ - :k;=\E[?5i:kN=\E[29~:kP=\E[28~:kd=\E[B:kh=\E[H:kl=\E[D:\ - :kr=\E[C:ku=\E[A:l1=f1:l2=f2:l3=f3:l4=f4:l5=f5:l6=f6:l7=f7:\ - :l8=f8:le=^H:me=\E[m:nd=\E[C:se=\E[m:sf=^J:so=\E[7m:sr=\EM:\ - :ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[?25h:vi=\E[?25l: -dt100w|dt-100w|Tandy DT-100 terminal (wide mode):\ - :co#132:tc=dt100: -dt110|Tandy DT-110 emulating ansi:\ - :xo:\ - :co#80:li#24:\ - :@7=\E[K:ac=kkllmmjjnnwwvvuuttqqxx:ae=\E(B:al=\E[0L:as=\E(0:\ - :bl=^G:cd=\E[0J:ce=\E[0K:cl=\E[H\E[2J:cm=\010\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:dc=\E[0P:dl=\E[0M:do=\E[0B:\ - :eA=\E(B:ei=:ho=\E[H:ic=\E[0@:im=:is=\E[?3l\E(B:\ - :k1=\E[1~:k2=\E[2~:k3=\E[3~:k4=\E[4~:k5=\E[5~:k6=\E[6~:\ - :k7=\E[7~:k8=\E[8~:k9=\E[9~:k;=\E[10~:kI=\E[@:kN=\E[26~:\ - :kP=\E[25~:kd=\E[B:kh=\E[G:kl=\E[D:kr=\E[C:ku=\E[A:l0=f1:\ - :l1=f2:l2=f3:l3=f4:l4=f5:l5=f6:l6=f7:l7=f8:l8=f9:l9=f10:le=^H:\ - :me=\E[m:nd=\E[C:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:\ - :ue=\E[m:up=\E[0A:us=\E[4m:ve=\E[?25h:vi=\E[?25l: -pt210|TRS-80 PT-210 printing terminal:\ - :hc:os:\ - :co#80:\ - :bl=^G:cr=^M:do=^J:sf=^J: -# From -# http://www.ordersomewherechaos.com/rosso/fetish/m102/web100/docs/termcap.html -# via Christian Biere -# Termcap for the radio shack model 100 computer running its built-in -# terminal emulator. The termcap entry was prepared at Microsoft as was -# the model 100's standard software. -# escape A cursor up -# escape B cursor down -# escape C cursor right -# escape D cursor left -# escape E clear screen and home cursor -# e H home cursor -# e J erase to end of screen -# e K erase to end of line -# e L insert line -# e M delete line -# e P turn off cursor -# e Q turn on cursor -# e T set system line? -# e U reset system line? -# e V turn off LCD ? -# e W turn on LCD ? -# e Y row/col cursor motion -# e j clear screen don't move cursor -# e l erase line don't move cursor -# e p begin rev video -# e q end rev video -# e del change char under cursor to space -m10|m100|trs100|TRS100|radio shack model 100:\ - :am:bs:le=^H:li#8:co#40:\ - :ku=^^:kd=^_:kl=^]:kr=^\:up=\EA:nd=\EC:ho=\EH:ce=\EK:\ - :cd=\EJ:cl=\EE:xt:cm=\EY%+ %+ :\ - :so=\Ep:se=\Eq:al=\EL:dl=\EM: -m100v|radio shack model 100 with video:\ - :co#80:do=^_:is=\ED:le=^]:li#24:nd:^\:sr=\EI:up=^^:tc=m100: -m200|trs200|TRS200|radio shack model 200:\ - :am:bs:le=^H:li#16:co#40:\ - :ku=^^:kd=^_:kl=^]:kr=^\:up=\EA:nd=\EC:ho=\EH:ce=\EK:\ - :cd=\EJ:cl=\EE:xt:cm=\EY%+ %+ :\ - :so=\Ep:se=\Eq:al=\EL:dl=\EM: - -#### Tektronix (tek) -# -# Tektronix tubes are graphics terminals. Most of them use modified -# oscilloscope technology incorporating a long-persistence green phosphor, -# and support vector graphics on a main screen with an attached "dialogue -# area" for interactive text. -# - -tek|tek4012|tektronix 4012:\ - :bs:os:\ - :co#75:li#35:\ - :bl=^G:cl=\E\014:cr=^M:do=^J:ff=\014:is=\E^O:le=^H: -# (tek4013: added to suppress tic warnings re :as:/:ae: --esr) -tek4013|tektronix 4013:\ - :ac=:ae=\E^O:as=\E^N:tc=tek4012: -tek4014|tektronix 4014:\ - :co#81:li#38:\ - :is=\E\017\E9:tc=tek4012: -# (tek4015: added to suppress tic warnings re :as:/:ae: --esr) -tek4015|tektronix 4015:\ - :ac=:ae=\E^O:as=\E^N:tc=tek4014: -tek4014-sm|tektronix 4014 in small font:\ - :co#121:li#58:\ - :is=\E\017\E\072:tc=tek4014: -# (tek4015-sm: added to suppress tic warnings re :as:/:ae: --esr) -tek4015-sm|tektronix 4015 in small font:\ - :ac=:ae=\E^O:as=\E^N:tc=tek4014-sm: -# Tektronix 4023 from Andrew Klossner -# -# You need to have "stty nl2" in effect. Some versions of tset(1) know -# how to set it for you. -# -# It's got the Magic Cookie problem around stand-out mode. If you can't -# live with Magic Cookie, remove the :so: and :se: fields and do without -# reverse video. If you like reverse video stand-out mode but don't want -# it to flash, change the letter 'H' to 'P' in the :so: field. -tek4023|tektronix 4023:\ - :am:bs:\ - :co#80:dN#4:li#24:sg#1:vt#4:\ - :bl=^G:cl=4\E\014:cm=\034%r%+ %+ :cr=^M:do=^J:kb=^H:le=^H:\ - :nd=^I:nl=^J:se=^_@:so=^_P: -# It is recommended that you run the 4025 at 4800 baud or less; -# various bugs in the terminal appear at 9600. It wedges at the -# bottom of memory (try "cat /usr/dict/words"); ^S and ^Q typed -# on keyboard don't work. You have to hit BREAK twice to get -# one break at any speed - this is a documented feature. -# Can't use cursor motion because it's memory relative, and -# because it only works in the workspace, not the monitor. -# Same for home. Likewise, standout only works in the workspace. -# -# :ce: was commented out since vi and rogue seem to work better -# simulating it with lots of spaces! -# -# :al: and :AL: had 145ms of padding, but that slowed down vi's ^U -# and didn't seem necessary. -# -tek4024|tek4025|tek4027|tektronix 4024/4025/4027:\ - :am:bs:da:db:\ - :co#80:it#8:li#34:lm#0:\ - :AL=\037up\r\037ili %d\r:CC=^_:DL=\037dli %d\r\006:\ - :DO=\037dow %d\r:LE=\037lef %d\r:RI=\037rig %d\r:\ - :UP=\037up %d\r:al=\037up\r\037ili\r:bl=^G:\ - :cd=\037dli 50\r:cl=\037era\r\n\n:cr=^M:dc=\037dch\r:\ - :dl=\037dli\r\006:do=^F^J:ei=:ic=\037ich\r \010:im=:\ - :is=\041com 31\r\n\037sto 9 17 25 33 41 49 57 65 73\r:\ - :ke=\037lea p2\r\037lea p4\r\037lea p6\r\037lea p8\r\037lea f5\r:\ - :ks=\037lea p4 /h/\r\037lea p8 /k/\r\037lea p6 / /\r\037lea p2 /j/\r\037lea f5 /H/\r:\ - :le=^H:nd=\037rig\r:sf=^F^J:ta=^I:up=^K: -tek4025-17|tek 4025 17 line window:\ - :li#17:tc=tek4025: -tek4025-17-ws|tek 4025 17 line window in workspace:\ - :is=\041com 31\r\n\037sto 9 17 25 33 41 49 57 65 73\r\037wor 17\r\037mon 17\r:\ - :se=\037att s\r:so=\037att e\r:te=\037mon h\r:\ - :ti=\037wor h\r:\ - :tc=tek4025-17: -tek4025-ex|tek4027-ex|tek 4025/4027 w/!:\ - :is=\037com 33\r\n\041sto 9 17 25 33 41 49 57 65 73\r:\ - :te=\037com 33\r:ti=\041com 31\r:\ - :tc=tek4025: -# Tektronix 4025a -# From: Doug Gwyn -# The following status modes are assumed for normal operation (replace the -# initial "!" by whatever the current command character is): -# !COM 29 # NOTE: changes command character to GS (^]) -# ^]DUP -# ^]ECH R -# ^]EOL -# ^]RSS T -# ^]SNO N -# ^]STO 9 17 25 33 41 49 57 65 73 -# Other modes may be set according to communication requirements. -# If the command character is inadvertently changed, termcap can't restore it. -# Insert-character cannot be made to work on both top and bottom rows. -# Clear-to-end-of-display emulation via !DLI 988 is too grotty to use, alas. -# There also seems to be a problem with vertical motion, perhaps involving -# delete/insert-line, following a typed carriage return. This terminal sucks. -# Delays not specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# (tek4025a: removed obsolete ":xx:". This may mean the tek4025a entry won't -# work any more. -- esr) -tek4025a|Tektronix 4025A:\ - :am:bs:bw:da:db:pt:xo:\ - :co#80:it#8:li#34:\ - :CC=^]:DC=\035dch %d;:DL=\035dli %d;:DO=\035dow %d;:\ - :LE=\035lef %d;:RI=\035rig %d;:SF=\035dow %d;:\ - :UP=\035up %d;:al=\013\035ili;:bl=^G:bt=\035bac;:\ - :ce=\035dch 80;:ch=\r\035rig %d;:cl=\035era;\n\035rup;:\ - :cr=^M:ct=\035sto;:dc=\035dch;:dl=\035dli;:do=^J:le=^H:\ - :nd=\035rig;:\ - :rs=\041com 29\035del 0\035rss t\035buf\035buf n\035cle\035dis\035dup\035ech r\035eol\035era g\035for n\035pad 203\035pad 209\035sno n\035sto 9 17 25 33 41 49 57 65 73\035wor 0;:\ - :sf=^J:ta=^I:up=^K: -# From: cbosg!teklabs!davem Wed Sep 16 21:11:41 1981 -# Here's the command file that I use to get rogue to work on the 4025. -# It should work with any program using the old curses (e.g. it better -# not try to scroll, or cursor addressing won't work. Also, you can't -# see the cursor.) -# (This "learns" the arrow keys for rogue. I have adapted it for termcap - mrh) -tek4025-cr|tek 4025 for curses and rogue:\ - :am:bs:\ - :co#80:it#8:li#33:\ - :cl=\037era;:cm=\037jum%i%d\054%d;:do=^F^J:\ - :is=\041com 31\r\n\037sto 9 17 25 33 41 49 57 65 73\r:\ - :le=^H:nd=\037rig;:sf=^F^J:ta=^I:te=\037wor 0:\ - :ti=\037wor 33h:up=^K: -# next two lines commented out since curses only allows 128 chars, sigh. -# :ti=\037lea p1/b/\037lea p2/j/\037lea p3/n/\037lea p4/h/\037lea p5/ /\037lea p6/l/\037lea p7/y/\037lea p8/k/\037lea p9/u/\037lea p./f/\037lea pt/`era w/13\037lea p0/s/\037wor 33h:\ -# :te=\037lea p1\037lea p2\037lea p3\037lea p4\037lea pt\037lea p5\037lea p6\037lea p7\037lea p8\037lea p9/la/13\037lea p.\037lea p0\037wor 0: -tek4025ex|4025ex|4027ex|tek 4025 w/!:\ - :is=\037com 33\r\n\041sto 9\05417\05425\05433\05441\05449\05457\05465\05473\r:\ - :te=\037com 33\r:ti=\041com 31\r:\ - :tc=tek4025: -tek4105|tektronix 4105:\ - :am:bs:mi:ms:ul:xn:xt:\ - :co#79:it#8:li#29:\ - :ac=:ae=\E[m:al=\E[1L:as=\E[1m:bl=^G:bt=\E[Z:cd=\E[J:\ - :ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%2;%2H:cr=^M:ct=\E[1g:\ - :dc=\E[1P:dl=\E[1M:do=\E[1B:ei=\E[4l:ho=\E[H:i1=\E%!1\E[m:\ - :im=\E[4h:is=\E%!1\E[?6141\E[m:kb=^H:kd=\E[1B:kl=\E[1D:\ - :kr=\E[1C:ku=\E[1A:mb=\E[=3;<7m:md=\E[=7;<4m:\ - :me=\E[=0;<1m:mh=\E[=1;<6m:mk=\E[=6;<5:mr=\E[=1;<3m:\ - :nd=\E[1C:se=\E[=0;<1m:sf=\E[S:so=\E[=2;<3m:sr=\E[T:ta=^I:\ - :te=:ti=\E%!1\E[?6l\E[2J:ue=\E[=0;<1m:up=\E[1A:\ - :us=\E[=5;<2m: - -# (tek4105-30: I added / based on the init string -- esr) -tek4105-30|4015 emulating 30 line vt100:\ - :am:mi:ms:xn:xo:\ - :co#80:it#8:li#30:vt#3:\ - :@8=\EOM:DO=\E[%dB:K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:do=^J:\ - :eA=\E(B:ho=\E[H:k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:me=\E[m\017:mr=\E[7m:\ - :nd=\E[C:r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[1;7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: - -# Tektronix 4105 from BRL -# The following setup modes are assumed for normal operation: -# CODE ansi CRLF no DABUFFER 141 -# DAENABLE yes DALINES 30 DAMODE replace -# DAVISIBILITY yes ECHO no EDITMARGINS 1 30 -# FLAGGING input INSERTREPLACE replace LFCR no -# ORIGINMODE relative PROMPTMODE no SELECTCHARSET G0 B -# SELECTCHARSET G1 0 TABS -2 -# Other setup modes may be set for operator convenience or communication -# requirements; I recommend -# ACURSOR 1 0 AUTOREPEAT yes AUTOWRAP yes -# BYPASSCANCEL CURSORKEYMODE no DAINDEX 1 0 0 -# EOFSTRING '' EOLSTRING EOMCHARS -# GAMODE overstrike GCURSOR 0 100 0 GSPEED 10 1 -# IGNOREDEL no KEYEXCHAR
NVDEFINE -53 "" -# PROMPTSTRING '' QUEUESIZE 2460 WINDOW 0 0 4095 3132 -# XMTDELAY 0 -# and factory color maps. After setting these modes, save them with NVSAVE. No -# delays are specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# "IC" cannot be used in combination with "im" & "ei". -# "tek4105a" is just a guess: -tek4105a|Tektronix 4105:\ - :bs:ms:pt:xo:\ - :co#80:it#8:kn#8:li#30:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:\ - :RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ac=:ae=^O:al=\E[L:\ - :as=^N:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ec=\E[%dX:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E%!1:k0=\EOA:k1=\EOB:k2=\EOC:k3=\EOD:k4=\EOP:k5=\EOQ:\ - :k6=\EOR:k7=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l0=F1:l1=F2:l2=F3:l3=F4:l4=F5:\ - :l5=F6:l6=F8:le=^H:ll=\E[30;H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:rc=\E8:\ - :rs=\030\E%!0\EKC\E\014\EKR0\EKF0\ENM0\ELBH=\ETF8000010F40\ELI100\ELLA>\ELM0\EKE0\ENF1\EKS0\END0\E%!1\Ec\E[?3;5l\E[?7;8h\E[r\E[m\E>:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :te=\E%!0\ELBH=\E%!1:ti=\E[?6l:ue=\E[m:up=\EM:us=\E[4m:\ - :ve=\E%!0\ETD10\E%!1:vi=\E%!0\ETD00\E%!1:\ - :vs=\E%!0\ETD70\E%!1: - -# -# Tektronix 4106/4107/4109 from BRL -# The following setup modes are assumed for normal operation: -# CODE ansi COLUMNMODE 80 CRLF no -# DABUFFER 141 DAENABLE yes DALINES 32 -# DAMODE replace DAVISIBILITY yes ECHO no -# EDITMARGINS 1 32 FLAGGING input INSERTREPLACE replace -# LFCR no LOCKKEYBOARD no ORIGINMODE relative -# PROMPTMODE no SELECTCHARSET G0 B SELECTCHARSET G1 0 -# TABS -2 -# Other setup modes may be set for operator convenience or communication -# requirements; I recommend -# ACURSOR 1 0 AUTOREPEAT yes AUTOWRAP yes -# BYPASSCANCEL CURSORKEYMODE no DAINDEX 1 0 0 -# EOFSTRING '' EOLSTRING EOMCHARS -# GAMODE overstrike GCURSOR 0 100 0 GSPEED 9 3 -# IGNOREDEL no KEYEXCHAR
NVDEFINE -53 "" -# PROMPTSTRING '' QUEUESIZE 2620 WINDOW 0 0 4095 3132 -# XMTDELAY 0 -# and factory color maps. After setting these modes, save them with NVSAVE. No -# delays are specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -# "IC" cannot be used in combination with "im" & "ei". -tek4106brl|tek4107brl|tek4109brl|Tektronix 4106, 4107, or 4109:\ - :ms:xo:\ - :co#80:it#8:li#32:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:\ - :RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ac=:ae=^O:al=\E[L:\ - :as=^N:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[P:\ - :dl=\E[M:do=^J:ec=\E[%dX:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E%!1:k0=\EOA:k1=\EOB:k2=\EOC:k3=\EOD:k4=\EOP:k5=\EOQ:\ - :k6=\EOR:k7=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l0=F1:l1=F2:l2=F3:l3=F4:l4=F5:\ - :l5=F6:l6=F8:le=^H:ll=\E[32;H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:nw=\EE:\ - :r1=\030\E%!0\EKC\E\014\EKR0\EKF0\ENM0\ELBH=\ETF8000010F40\ELI100\ELLB0\ELM0\EKE0\ENF1\EKS0\END0\ERE0\E%!1\Ec\E[?3;5l\E[?7;8h\E[r\E[m\E>:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7;42m:sr=\EM:st=\EH:\ - :ta=^I:te=\E%!0\ELBH=\E%!1:ti=\E[?6l:ue=\E[m:up=\EM:\ - :us=\E[4m:ve=\E%!0\ETD10\E%!1:vi=\E%!0\ETD00\E%!1:\ - :vs=\E%!0\ETD70\E%!1: - -tek4107|tek4109|tektronix terminals 4107 4109:\ - :am:bs:mi:ms:ul:xn:xt:\ - :co#79:it#8:li#29:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\ELZ:cm=\EY%+ %+ :cr=^M:do=^J:kb=^H:\ - :kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=^H:mb=\E%!1\E[5m\E%!0:\ - :md=\E%!1\E[1m\E%!0:me=\E%!1\E[m\E%!0:\ - :mh=\E%!1\E[<0m\E%!0:mr=\E%!1\E[7m\E%0:nd=\EC:\ - :se=\E%!1\E[m\E%!0:sf=^J:so=\E%!1\E[7;5m\E%!0:sr=\EI:\ - :ta=^I:ue=\E%!1\E[m\E%!0:up=\EA:us=\E%!1\E[4m\E%!0:\ - :ve=\E%!0:vs=\E%!3: -# Tektronix 4207 with sysline. In the ancestral termcap file this was 4107-s; -# see the note attached to tek4207. -tek4207-s|Tektronix 4207 with sysline but no memory:\ - :es:hs:\ - :ds=\E7\E[?6l\E[2K\E[?6h\E8:fs=\E[?6h\E8:\ - :i1=\E%!1\E[2;32r\E[132D\E[2g\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[J:\ - :is=\E7\E[?6l\E[2K\E[?6h\E8:\ - :ts=\E7\E[?6l\E[2K\E[;%i%df:tc=tek4107: - -# The 4110 series may be a wonderful graphics series, but they make the 4025 -# look good for screen editing. In the dialog area, you can't move the cursor -# off the bottom line. Out of the dialog area, ^K moves it up, but there -# is no way to scroll. -# -# Note that there is a floppy for free from Tek that makes the -# 4112 emulate the vt52 (use the vt52 termcap). There is also -# an expected enhancement that will use ANSI standard sequences. -# -# 4112 in non-dialog area pretending to scroll. It really wraps -# but vi is said to work (more or less) in this mode. -# -# 'vi' works reasonably well with this entry. -# -otek4112|o4112-nd|otek4113|otek4114|old tektronix 4110 series:\ - :am:\ - :co#80:li#34:\ - :bl=^G:cl=\E^L:cr=^M:do=^J:le=^H:sf=^J:te=\EKA1\ELV1:\ - :ti=\EKA0\ELV0\EMG0:up=^K: -# The 4112 with the ANSI compatibility enhancement -tek4112|tek4114|tektronix 4110 series:\ - :am:bs:db:\ - :co#80:li#34:\ - :al=\E[L:bt=\E[Z:cd=\E[0J:ce=\E[0K:cl=\E[2J\E[0;0H:\ - :cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:ei=:ic=\E[@:im=:\ - :is=\E3\0411:le=^H:me=\E[m:nd=\E[C:se=\E[m:\ - :sf=\E7\E[0;0H\E[M\E8:so=\E[7m:sr=\E7\E[0;0H\E[L\E8:\ - :ue=\E[m:up=\EM:us=\E[4m: -tek4112-nd|4112 not in dialog area:\ - :ns:\ - :up=^K:tc=tek4112: -tek4112-5|4112 in 5 line dialog area:\ - :li#5:tc=tek4112: -# (tek4113: this used to have ":nd=\LM1\s\LM0:", someone's mistake; -# removed ":as=\E^N:, :ae=\E^O:", which had been commented out in 8.3. -# Note, the !0 and !1 sequences in :te:/:ti:/:ve:/:vi: were -# previously \0410 and \0411 sequences...I don't *think* they were supposed -# to be 4-digit octal -- esr) -tek4113|tektronix 4113 color graphics with 5 line dialog area:\ - :am:bs:da:eo:\ - :co#80:li#5:\ - :cl=\ELZ:do=^J:is=\EKA1\ELL5\ELV0\ELV1:le=^H:\ - :nd=\ELM1 \ELM0:uc=\010\ELM1_\ELM0:\ - :vb=\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERB0: -tek4113-34|tektronix 4113 color graphics with 34 line dialog area:\ - :li#34:\ - :is=\EKA1\ELLB2\ELV0\ELV1:tc=tek4113: -# :ns: left off to allow vi visual mode. APL font (:as=\E^N:/:ae=\E^O:) not -# supported here. :uc: is slow, but looks nice. Suggest setenv MORE -up . -# :vb: needs enough delay to let you see the background color being toggled. -tek4113-nd|tektronix 4113 color graphics with no dialog area:\ - :am:bs:eo:\ - :co#80:it#8:li#34:\ - :cl=\E^L:do=^J:ho=\ELF7l\177 @:is=\ELZ\EKA0\ELF7l\177 @:\ - :le=^H:ll=\ELF hl @:nd=^I:se=\EMT1:so=\EMT2:ta=^I:\ - :uc=\010\EMG1_\EMG0:up=^K:\ - :vb=\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERBA4\ERB0:\ - :vs=\ELZ\EKA0: -# This entry is from Tek. Inc. (Brian Biehl) -# (tek4115: :bc: renamed to :le:, / added based on init string -- esr) -otek4115|Tektronix 4115:\ - :am:bs:da:db:eo:\ - :co#80:it#8:li#34:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:do=\E[B:\ - :ei=\E[4l:ho=\E[H:if=/usr/share/tabset/vt100:im=\E[4h:\ - :is=\E%!0\E%\014\ELV0\EKA1\ELBB2\ENU@=\ELLB2\ELM0\ELV1\EKYA?\E%!1\E[<1l\E[?7h\E[?8h\E[34;1H\E[34B\E[m:\ - :kb=^H:ke=\E>:ks=\E=:le=\E[D:me=\E[m:nd=\E[C:se=\E[m:\ - :so=\E[7m:sr=\EM:ta=^I:te=\E%!0\ELBG8\E%!1\E[34;1H\E[J:\ - :ti=\E%!0\ELBB2\E%!1:ue=\E[m:up=\E[A:us=\E[4m:\ - :ve=\E%!0\ELBG8\E%!1\E[34;1H:vs=\E%!0\ELBB2\E%!1: -tek4115|newer tektronix 4115 entry with more ANSI capabilities:\ - :am:xo:\ - :co#80:li#34:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:\ - :RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:al=\E[L:bl=^G:\ - :bt=\E[Z:cd=\E[J:ce=\E[K:ch=\E[%+^AG:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:cr=^M:ct=\E[2g:cv=\E[%+^Ad:dc=\E[P:\ - :dl=\E[M:do=^J:ei=:ho=\E[H:ic=\E[@:im=:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mk=\E[8m:mr=\E[7m:nd=\E[C:\ - :se=\E[m:sf=^J:so=\E[7m:st=\EH:ta=^I:ue=\E[m:up=\E[A:\ - :us=\E[4m: -# The tek4125 emulates a vt100 incorrectly - the scrolling region -# command is ignored. The following entry replaces :cs: with the needed -# :AL:, :AL:, and :im:; removes some cursor pad commands that the tek4125 -# chokes on; and adds a lot of initialization for the tek dialog area. -# Note that this entry uses all 34 lines and sets the cursor color to green. -# Steve Jacobson 8/85 -# (tek4125: there were two "\!"s in the is that I replaced with "\E!"; -# commented out, :im:=\E1 because there's no :ei: -- esr) -tek4125|tektronix 4125:\ - :li#34:\ - :al=\E[1L:cs@:dl=\E[1M:\ - :is=\E%\E\0410\EQD1\EUX03\EKA\ELBB2\ELCE0\ELI100\ELJ2\ELLB2\ELM0\ELS1\ELX00\ELV1\E%\E\0411\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:\ - :ks=\E=:rc@:sc@:\ - :tc=vt100: - -# From: -# (tek4207: This was the termcap file's entry for the 4107/4207, but SCO -# supplied another, less capable 4107 entry. So we'll use that for 4107 and -# note that if jcoker wasn't confused you may be able to use this one. -# I merged in :ms:,:sf:,:sr:,,:ct: from a BRL entry -- esr) -tek4207|Tektronix 4207 graphics terminal with memory:\ - :am:bw:mi:ms:ul:xn:\ - :co#80:it#8:li#32:\ - :al=3\E[L:bt=\E[Z:cd=\E[J:ce=5\E[K:cl=156\E[H\E[J:\ - :cm=\E[%i%d;%dH:ct=\E[1g:dc=4\E[P:dl=3\E[M:do=^J:ei=:\ - :ho=\E[H:ic=4\E[@:im=:\ - :is=\E%!0\ELBP0\E%!1\E[H\E[2g\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[8C\EH\E[J:\ - :kd=\ED:kh=\E[H:kl=\E[D:kr=\E[C:ku=\EM:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mk=\E[=6;<5:mr=\E[7m:nd=\E[C:se=\E[m:\ - :sf=\E[S:so=\E[7m:sr=\E[T:ta=^I:\ - :te=\E[?6h\E%!0\ELBP0\E%!1\E[32;1f:ti=\E[?6l\E[H\E[J:\ - :ue=\E[m:up=\EM:us=\E[4m: - -# From: Thu Oct 31 12:54:27 1985 -# (tek4404: There was a "\!" in :ti: that I replaced with "\E!". -# Tab had been given as \E2I,that must be the tab-set capability -- esr) -tek4404|tektronix 4404:\ - :bs:\ - :co#80:it#8:li#32:\ - :al=\E[1L:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[1M:do=^J:ei=\E[4l:ho=\E[H:\ - :im=\E[4h:kd=\E[B:ke=\E[?1h:kl=\E[D:kr=\E[C:ks=\E[?1l:\ - :ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[m:nd=\E[C:rc=\E8:\ - :sc=\E7:se=\E[27m:so=\E[7m:st=\E[2I:ta=^I:\ - :te=\E[1;1H\E[0J\E[?6h\E[?1l:\ - :ti=\E%\E\0411\E[1;32r\E[?6l\E>:ue=\E[m:up=\E[A:\ - :us=\E[4m: -# Some unknown person wrote: -# I added the is string - straight Unix has ESC ; in the login -# string which sets a ct8500 into monitor mode (aka 4025 snoopy -# mode). The is string here cleans up a few things (but not -# everything). -ct8500|tektronix ct8500:\ - :am:bw:da:db:\ - :co#80:li#25:\ - :al=\E^L:bl=^G:bt=\E^I:cd=\E^U:ce=\E^T:cl=\E^E:\ - :cm=\E|%+ %+ :cr=^M:dc=\E^]:dl=\E^M:do=^J:ei=:ic=\E^\:im=:\ - :is=\037\EZ\Ek:le=^H:me=\E :nd=\ES:se=\E :sf=^J:so=\E$:\ - :sr=\E^A:ta=^I:ue=\E :up=\ER:us=\E\041: - -# Tektronix 4205 terminal. -# -# am is not defined because the wrap around occurs not when the char. -# is placed in the 80'th column, but when we are attempting to type -# the 81'st character on the line. (esr: hmm, this is like the vt100 -# version of xenl, perhaps am + xenl would work!) -# -# Bold, dim, and standout are simulated by colors and thus not allowed -# with colors. The tektronix color table is mapped into the RGB color -# table by setf/setb. All colors are reset to factory specifications by oc. -# The cap uses RGB notation to define colors. for arguments 1-3 the -# interval (0-1000) is broken into 8 smaller sub-intervals (125). Each sub- -# interval then maps into pre-defined value. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -tek4205|tektronix 4205:\ - :cc:mi:ms:\ - :Co#8:NC#49:co#80:it#8:li#30:pa#63:\ - :AL=\E[%dL:DO=\E[%dB:IC=\E[%d@:LE=\E[%dD:RI=\E[%dC:\ - :UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[1L:as=\E(0:bl=^G:bt=\E[Z:cb=\E[1K:cd=\E[J:\ - :ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:ct=\E[1g:\ - :dc=\E[1P:dl=\E[1M:do=\E[B:eA=\E(B:ec=\E%dX:ei=\E[4l:\ - :ho=\E[H:i1=\E%!0\ETM1\E%!1\E[m:im=\E[4h:k0=\EOA:k1=\EOB:\ - :k2=\EOC:k3=\EOD:k4=\EP:k5=\EQ:k6=\ER:k7=\ES:kb=^H:kd=\E[B:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:md=\E[=7;<4m:\ - :me=\E[=0;<1m\E[24;25;27m\017:mh=\E[=1;<6m:mk=\E[=6;<5:\ - :mr=\E[7m:nd=\E[C:\ - :oc=\E%!0\n\ETFB0\n0000\n1F4F4F4\n2F400\n30F40\n4A4C because of a bug in old vi (if stty says you have -# a "newline" style terminal (-crmode) vi figures all it needs is nl -# to get crlf, even if :cr: is not ^M.) -# (tty40: removed obsolete ":nl=\EG\EB:", it's just do+cr -- esr) -tty40|ds40|ds40-2|dataspeed40|teletype dataspeed 40/2:\ - :bs:xo:\ - :co#80:li#24:\ - :al=\EL:cd=\EJ:cl=\EH\EJ:cr=\EG:ct=\EH\E2:dc=\EP:dl=\EM:\ - :do=\EB:ei=:ho=\EH:ic=\E\136:im=:kb=^]:kl=^H:le=^H:nd=\EC:\ - :pf=^T:po=\022:r2=\023\ER:se=\E4:sf=\ES:so=\E3:sr=\ET:\ - :st=\E1:ta=\E@:up=\E7: -tty43|model 43 teletype:\ - :am:bs:hc:os:xo:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:kb=^H:le=^H:sf=^J: - -#### Tymshare -# - -# You can add :is=\E<: to put this 40-column mode, though I can't -# for the life of me think why anyone would want to. -scanset|sc410|sc415|Tymshare Scan Set:\ - :am:bw:ms:\ - :co#80:li#24:\ - :ac=l:\ - :rc=^C:sc=^B:sf=^J:up=^K: - -#### Volker-Craig (vc) -# -# If you saw a Byte Magazine cover with a terminal on it during the early -# 1980s, it was probably one of these. Carl Helmers liked them because -# they could crank 19.2 and were cheap (that is, until he tried to program -# one...) -# - -# Missing in vc303a and vc303 descriptions: they scroll 2 lines at a time -# every other linefeed. -vc303|vc103|vc203|volker-craig 303:\ - :am:bs:ns:\ - :co#80:li#24:\ - :bl=^G:cl=\014:cr=^M:do=^J:ho=\013:kd=^J:kl=^H:kr=^I:ku=^N:\ - :le=^H:ll=\017W:nd=^I:up=^N: -vc303a|vc403a|volker-craig 303a:\ - :ce=\026:cl=\030:ho=\031:kr=^U:ku=^Z:ll=^P:nd=^U:up=^Z:tc=vc303: -# (vc404: removed obsolete ":ma=^Z^P^U :" -- esr) -vc404|volker-craig 404:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cd=\027:ce=\026:cl=\030:cm=\020%+ %+ :cr=^M:do=^J:\ - :ho=\031:kd=^J:kl=^H:kr=^U:ku=^Z:le=^H:nd=^U:sf=^J:up=^Z: -vc404-s|volker-craig 404 w/standout mode:\ - :do=^J:se=^O:so=^N:tc=vc404: -# From: -# (vc414: merged in cup/dl1/home from an old vc414h-noxon) -vc414|vc414h|Volker-Craig 414H in sane escape mode.:\ - :am:bs:\ - :co#80:li#24:\ - :al=\E\032:cd=\E^X:ce=10\E\017:cl=\E\034:cm=\E\021%r%.%.:\ - :dc=\E3:dl=\E\023:do=\E^K:ei=:ho=\E^R:ic=\E\072:im=:k0=\EA:\ - :k1=\EB:k2=\EC:k3=\ED:k4=\EE:k5=\EF:k6=\EG:k7=\EH:kd=\E^K:\ - :kh=\E^R:kl=^H:kr=^P:ku=\E^L:l0=PF1:l1=PF2:l2=PF3:l3=PF4:\ - :l4=PF5:l5=PF6:l6=PF7:l7=PF8:nd=^P:se=\E^_:so=\E^Y:up=\E^L: -vc415|volker-craig 415:\ - :cl=^L:tc=vc404: - -######## OBSOLETE PERSONAL-MICRO CONSOLES AND EMULATIONS -# - -#### IBM PC and clones -# - -# The pcplot IBM-PC terminal emulation program is really messed up. It is -# supposed to emulate a vt-100, but emulates the wraparound bug incorrectly, -# doesn't support scrolling regions, ignores add line commands, and ignores -# delete line commands. Consequently, the resulting behavior looks like a -# crude adm3a-type terminal. -# Steve Jacobson 8/85 -pcplot|pc-plot terminal emulation program:\ - :xn@:\ - :AL@:DL@:al@:cs@:dl@:rc@:sc@:tc=vt100: -# KayPro II from Richard G Turner -# I've found that my KayPro II, running MDM730, continues to emulate an -# ADM-3A terminal, just like I was running TERM.COM. On our 4.2 UNIX -# system the following termcap entry works well: -# I have noticed a couple of minor glitches, but nothing I can't work -# around. (I added two capabilities from the BRL entry -- esr) -kaypro|kaypro2|kaypro II:\ - :am:bs:\ - :co#80:li#24:\ - :al=\EE:bl=^G:cd=^W:ce=^X:cl=1\032:cm=\E=%+ %+ :cr=^M:\ - :dl=\ER:do=^J:ho=^^:kd=^J:kr=^L:ku=^K:nd=^L:sf=^J:up=^K: - -# From IBM, Thu May 5 19:35:27 1983 -# (ibmpc: commented out :im:=\200R because we don't know :ei: -- esr) -ibmpc|ibm-pc|ibm5051|5051|IBM Personal Computer (no ANSI.SYS):\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cl=^L^K:cr=^M^^:do=^J:ho=^K:kd=^_:le=^]:nd=^\:sf=\n:\ - :up=^^: - -#### Apple II -# -# Apple II firmware console first, then various 80-column cards and -# terminal emulators. For two cents I'd toss all these in the UFO file -# along with the 40-column apple entries. -# - -# From: brsmith@umn-cs.cs.umn.edu (Brian R. Smith) via BRL -# 'it#8' tells UNIX that you have tabs every 8 columns. This is a -# function of TIC, not the firmware. -# The clear key on a IIgs will do something like clear-screen, -# depending on what you're in. -appleIIgs|appleIIe|appleIIc|Apple 80 column firmware interface:\ - :am:bs:bw:eo:ms:\ - :co#80:it#8:li#24:\ - :bl=^G:cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :cr=^M:do=^J:ho=^Y:\ - :kC=^X:kD=\177:kb=^H:kd=^J:kl=^H:kr=^U:ku=^K:le=^H:nd=^\:\ - :nw=^M^W:se=^N:sf=^W:so=^O:sr=^V:ta=^I:up=^_: -# Apple //e with 80-column card, entry from BRL -# The modem interface is permitted to discard LF (maybe DC1), otherwise -# passing characters to the 80-column firmware via COUT (PR#3 assumed). -# Auto-wrap does not work right due to newline scrolling delay, which also -# requires that you set "stty cr2". -# Note: Cursor addressing is only available via the Pascal V1.1 entry, -# not via the BASIC PR#3 hook. All this nonsense can be avoided only by -# using a terminal emulation program instead of the built-in firmware. -apple2e|Apple //e:\ - :bw:ms:\ - :co#80:li#24:\ - :bl=^G:cd=4*\013:ce=4\035:cl=100\014:do=^J:ho=^Y:is=^R^N:\ - :kb=^H:kd=^J:kl=^H:kr=^U:ku=^K:le=^H:me=^N:mr=^O:nw=100\r:\ - :r1=^R^N:se=^N:sf=^W:so=^O:sr=^V:ta=^I:up=^_: -# mcvax!vu44!vu45!wilcke uses the "ap" entry together with Ascii Express Pro -# 4.20, with incoming and outgoing terminals both on 0, emulation On. -apple2e-p|Apple //e via Pascal:\ - :cm=\036%r%+ %+ :kb=^H:kd=^J:kl=^H:tc=apple2e: -# (ASCII Express) MouseTalk "Standard Apple //" emulation from BRL -# Enable DC3/DC1 flow control with "stty ixon -ixany". -apple-ae|ASCII Express:\ - :am:bs:bw:ms:nx:xo:\ - :co#80:it#8:li#24:\ - :bl=500\007:cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :cr=^M:do=^J:\ - :ho=^Y:is=^R^N:kC=^X:kd=^J:kl=^H:kr=^U:ku=^K:le=^H:me=^N:\ - :mr=^O:nd=^U:r1=^R^N:se=^N:sf=^W:so=^O:sr=^V:up=^_: -appleII|apple ii plus:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :do=^J:ho=\E^Y:\ - :is=\024T1\016:kd=^J:kr=^U:le=^H:me=^N:nd=^\:se=^N:so=^O:\ - :ta=^I:up=^_:vb=\024G1\024T1:ve=^TC2:vs=^TC6: -# Originally by Gary Ford 21NOV83 -# From: Fri Oct 11 21:27:00 1985 -apple-80|apple II with smarterm 80 col:\ - :am:bs:bw:\ - :co#80:li#24:\ - :bt=^R:cd=10*\013:ce=10\035:cl=10*\014:cm=\036%r%+ %+ :\ - :cr=10*\r:do=^J:ho=^Y:le=^H:nd=^\:up=^_: -apple-soroc|apple emulating soroc 120:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :cr=^M:do=^J:ho=^^:\ - :kd=^J:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:sf=^J:up=^K: -# From Peter Harrison, Computer Graphics Lab, San Francisco -# ucbvax!ucsfmis!harrison .....uucp -# ucbvax!ucsfmis!harrison@BERKELEY .......ARPA -# "These two work. If you don't have the inverse video chip for the -# Apple with videx then remove the :so: and :se: fields." -# (apple-videx: this used to be called DaleApple -- esr) -apple-videx|Apple with videx videoterm 80 column board with inverse video:\ - :am:bs:xn:\ - :co#80:it#8:li#24:\ - :cd=^K:ce=^]:cl=300\014:cm=\036%r%+ %+ :do=^J:ho=^Y:kd=^J:\ - :kh=^Y:kl=^H:kr=^U:le=^H:me=^Z2:nd=^\:se=^Z2:so=^Z3:ta=^I:\ - :up=^_: -# My system [for reference] : Apple ][+, 64K, Ultraterm display card, -# Apple Cat ][ 212 modem, + more all -# controlled by ASCII Express: Pro. -# From Dave Shaver -apple-uterm-vb|Videx Ultraterm for Apple micros with Visible Bell:\ - :am:bs:eo:xt:\ - :co#80:li#24:\ - :ac=:cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :ho=^Y:\ - :is=^V4^W06\017\rVisible Bell Installed.\016\r\n:\ - :nd=^\:se=^N:so=^O:up=^_:vb=^W35^W06: -apple-uterm|Ultraterm for Apple micros:\ - :am:bs:eo:xt:\ - :co#80:li#24:\ - :ac=:cd=^K:ce=^]:cl=^L:cm=\036%r%+ %+ :ho=^Y:\ - :is=^V4^W06\016:nd=^\:se=^N:so=^O:up=^_: -# from trwrba!bwong (Bradley W. Wong): -# -# This entry assumes that you are using an apple with the UCSD Pascal -# language card. SYSTEM.MISCINFO is assumed to be the same as that -# supplied with the standard apple except that screenwidth should be set -# using SETUP to 80 columns. Note that the right arrow in not mapped in -# this termcap entry. This is because that key, on the Apple, transmits -# a ^U and would thus preempt the more useful "up" function of vi. -# -# HMH 2/23/81 -apple80p|80-column apple with Pascal card:\ - :am:bw:\ - :co#80:li#24:\ - :cd=^K:ce=^]:cl=^Y^L:cm=\036%r%+ %+ :ho=^Y:kl=^H:nd=^\\072:\ - :up=^_: -# -# Apple II+ equipped with Videx 80 column card -# -# Terminfo from ihnp4!ihu1g!djc1 (Dave Christensen) via BRL; -# manually converted by D A Gwyn -# -# DO NOT use any terminal emulation with this data base, it works directly -# with the Videx card. This has been tested with vi 1200 baud and works fine. -# -# This works great for vi, except I've noticed in pre-R2, ^U will scroll back -# 1 screen, while in R2 ^U doesn't. -# For inverse alternate character set add: -# :as:=^O::ae:=^N: -# (apple-v: added it#8 -- esr) -apple-videx2|Apple II+ w/ Videx card (similar to Datamedia h1520):\ - :am:xn:\ - :co#80:it#8:li#24:\ - :bl=100\007:cd=16*\013:ce=^]:cl=16*\014:cm=\036%r%+ %+ :\ - :cr=^M:do=^J:ho=^Y:kb=^H:kd=^J:kh=^Y:kl=^H:kr=^\:ku=^_:le=^H:\ - :nd=^\:se=^Z2:sf=^J:so=^Z3:ta=8\011:up=^_: -apple-videx3|vapple|Apple II with 80 col card:\ - :am:bs:\ - :co#80:li#24:\ - :ce=\Ex:cl=\Ev:cm=\EY%+ %+ :ho=\EH:k0=\EP:k1=\EQ:k2=\ER:\ - :k3=\E :k4=\E\041:k5=\E":k6=\E#:k7=\E$:k8=\E%:k9=\E&:kd=\EB:\ - :kh=\EH:kl=\ED:kr=\EC:ku=\EA:nd=\EC:up=\EA: -#From: decvax!cbosgd!cbdkc1!mww Mike Warren via BRL -aepro|Apple II+ running ASCII Express Pro--vt52:\ - :bs:\ - :co#80:li#24:\ - :cd=\EJ:ce=\EK:cl=300\014:cm=\EY%+ %+ :ho=\EH:nd=\EC:\ - :up=\EA: -# UCSD addition: Yet another termcap from Brian Kantor's Micro Munger Factory -apple-vm80|ap-vm80|apple with viewmax-80:\ - :bs:\ - :co#80:li#24:\ - :cd=300\013:ce=^]:cl=300\014:cm=100\036%+ %+ :ho=200\031:\ - :nd=^\\072:up=^_: - -#### Apple Lisa & Macintosh -# - -# (lisa: changed :vs: to :ve: -- esr) -lisa|apple lisa console display (black on white):\ - :am:bs:eo:ms:\ - :co#88:it#8:li#32:\ - :ac=lfmekcjdttuvvuwsqax`nb:ae=\E[10m:al=\E[L:as=\E[11m:\ - :cd=\E[J:ce=\E[K:cl=^L:cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:\ - :do=\E[B:ei=:ho=\E[H:ic=\E[@:im=:is=\E>\E[m\014:kb=^H:\ - :kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:me=\E[m:nd=\E[C:\ - :se=\E[m:so=\E[7m:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[5l:\ - :vi=\E[5h: -liswb|apple lisa console display (white on black):\ - :is=\E>\E[0;7m\014:se=\E[0;7m:so=\E[m:ue=\E[0;7m:\ - :us=\E[4m:tc=lisa: - -# lisaterm from ulysses!gamma!epsilon!mb2c!jed (John E. Duncan III) via BRL; -# :is: revised by Ferd Brundick -# -# These entries assume that the 'Auto Wraparound' is enabled. -# Xon-Xoff flow control should also be enabled. -# -# The vt100 uses :rs2: and :rf: rather than :is2:/:tbc:/:hts: because the tab -# settings are in non-volatile memory and don't need to be reset upon login. -# Also setting the number of columns glitches the screen annoyingly. -# You can type "reset" to get them set. -# -lisaterm|Apple Lisa or Lisa/2 running LisaTerm vt100 emulation:\ - :am:bs:pt:xn:xo:\ - :co#80:it#8:kn#4:li#24:vt#3:\ - :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:do=^J:ho=\E[H:k0=\EOP:k1=\EOQ:\ - :k2=\EOR:k3=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l0=F1:l1=F2:l2=F3:l3=F4:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:\ - :r1=\E>\E[?1l\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;24r:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\E[A:us=\E[4m: -# Lisaterm in 132 column ("wide") mode. -lisaterm-w|Apple Lisa with Lisaterm in 132 column mode:\ - :co#132:\ - :kb=^H:kd=^J:kl=^H:tc=lisaterm: -# Although MacTerminal has insert/delete line, it is commented out here -# since it is much faster and cleaner to use the "lock scrolling region" -# method of inserting and deleting lines due to the MacTerminal implementation. -# Also, the "Insert/delete ch" strings have an extra character appended to them -# due to a bug in MacTerminal V1.1. Blink is disabled since it is not -# supported by MacTerminal. -mac|macintosh|Macintosh with MacTerminal:\ - :xn:\ - :dN#30:\ - :dc=7\E[P:ei=:ic=9\E[@:im=:ip=7:mb@:tc=lisa: -# Lisaterm in 132 column ("wide") mode. -mac-w|macterminal-w|Apple Macintosh with Macterminal in 132 column mode:\ - :co#132:tc=mac: - -#### Radio Shack/Tandy -# - -# (coco3: This had "ta" used incorrectly as a boolean and bl given as "bl#7". -# I read these as mistakes for ":it#8:" and ":bl=\007:" respectively -- esr) -# From: <{pbrown,ctl}@ocf.berkeley.edu> 12 Mar 90 -coco3|os9LII|Tandy CoCo3 24*80 OS9 Level II:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :al=^_0:bl=^G:cd=^K:ce=^D:cl=5*\014:cm=2\002%r%+ %+ :\ - :dl=^_1:do=^J:ho=^A:kd=^J:kl=^H:kr=^I:ku=^L:le=^H:mb=^_":\ - :md=\E\072^A:me=\037\041\E\072\200:mr=^_ :nd=^F:\ - :se=^_\041:so=^_ :ue=^_#:up=^I:us=^_":ve=^E\041:vi=^E : -# (trs2: removed obsolete ":nl=^_:" -- esr) -trs2|trsII|trs80II|Radio Shack Model II using P&T CP/M:\ - :am:bs:ms:\ - :co#80:it#8:li#24:\ - :al=^D:bl=^G:cd=^B:ce=^A:cl=^L:cm=\EY%+ %+ :cr=^M:dl=^K:\ - :do=^_:ho=^F:kb=^H:kd=^_:kl=^\:kr=^]:ku=^^:le=^H:me=^O:nd=^]:\ - :se=^O:sf=^J:so=^N:ta=^I:up=^^: -# From: Kevin Braunsdorf -# (This had extension capabilities -# :BN=\E[?33h:BF=\E[?33l:UC=\E[_ q:BC=\E[\177 q:\ -# :CN=\ERC:CF=\ERc:NR=\ERD:NM=\ER@: -# I also deleted the unnecessary ":kn#2:", ":sg#0:" -- esr) -trs16|trs-80 model 16 console:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :ac=l_mbk`javewcquxs:ae=\ERg:al=\EL:as=\ERG:bl=^G:cd=\EJ:\ - :ce=\EK:cl=^L:cm=\EY%+ %+ :cr=^M:dc=\EQ:dl=\EM:do=\EB:ei=:\ - :ho=\EH:ic=\EP:im=:k0=^A:k1=^B:k2=^D:k3=^L:k4=^U:k5=^P:k6=^N:\ - :k7=^S:kb=^H:kd=\EB:kh=^W:kl=\ED:kr=\EC:ku=\EA:l0=f1:l1=f2:\ - :l2=f3:l3=f4:l4=f5:l5=f6:l6=f7:l7=f8:le=^H:me=\ER@:nd=\EC:\ - :pf=\E]+:po=\E]=:se=\ER@:sf=^J:so=\ERD:ta=^I:up=\EA:ve=\ERC:\ - :vi=\ERc: - -#### Atari ST -# - -# From: Simson L. Garfinkel -atari|atari st:\ - :am:bs:\ - :co#80:it#8:li#25:\ - :al=\EL:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :dl=\EM:do=\EB:\ - :kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=\ED:me=\Eq:nd=\EC:se=\Eq:\ - :so=\Ep:sr=\EI:ta=^I:up=\EA: -# UniTerm terminal program for the Atari ST: 49-line VT220 emulation mode -# From: Paul M. Aoki -uniterm|uniterm49|UniTerm VT220 emulator with 49 lines:\ - :li#49:\ - :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h\E[1;49r\E[49;1H:tc=vt220: -# MiNT VT52 emulation. 80 columns, 25 rows. -# MiNT is Now TOS, the operating system which comes with all Ataris now -# (mainly Atari Falcon). This termcap is for the VT52 emulation you get -# under tcsh/zsh/bash/sh/ksh/ash/csh when you run MiNT in `console' mode -# From: Per Persson , 27 Feb 1996 -st52|Atari ST with VT52 emulation:\ - :am:km:\ - :co#80:li#25:\ - :K1=\E#7:K2=\E#9:K3=\E#5:K4=\E#1:K5=\E#3:al=\EL:bl=^G:\ - :cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:dl=\EM:do=\EB:\ - :ho=\EH:k0=\E#D:k1=\E#;:k2=\E#<:k3=\E#=:k4=\E#>:k5=\E#?:\ - :k6=\E#@:k7=\E#A:k8=\E#B:k9=\E#C:kA=\E#R:kC=\E#7:kF=\E#2:\ - :kR=\E#8:kb=^H:kd=\E#P:kh=\E#G:kl=\E#K:kr=\E#M:ku=\E#H:\ - :l0=f10:le=\ED:me=\Eq:nd=\EC:nw=^M^J:r1=\Ez_\Eb@\EcA:\ - :rc=\Ek:sc=\Ej:se=\Eq:sf=^J:so=\Ep:sr=\EI:ta=^I:te=:ti=\Ee:\ - :up=\EA:ve=\Ee:vi=\Ef: - -#### Commodore Business Machines -# -# Formerly located in West Chester, PA; went spectacularly bust in 1994 -# after years of shaky engineering and egregious mismanagement. Made one -# really nice machine (the Amiga) and boatloads of nasty ones (PET, C-64, -# C-128, VIC-20). The C-64 is said to have been the most popular machine -# ever (most units sold); they can still be found gathering dust in closets -# everywhere. -# - -# From: Kent Polk , 30 May 90 -# Added a few more entries, converted caret-type control sequence (^x) entries -# to '\0xx' entries since a couple of people mentioned losing '^x' sequences. -# -# :as:, :ae: Support for alternate character sets. -# :ve=\E[\040p:vi=\E[\060\040p: cursor visible/invisible. -# :xn: vt100 kludginess at column 80/NEWLINE ignore after 80 cols(Concept) -# This one appears to fix a problem I always had with a line ending -# at 'width+1' (I think) followed by a blank line in vi. The blank -# line tended to disappear and reappear depending on how the screen -# was refreshed. Note that this is probably needed only if you use -# something like a Dnet Fterm with the window sized to some peculiar -# dimension larger than 80 columns. -# :k0=\E9~: map F10 to k0 - could have F0-9 -> k0-9, but ... F10 was 'k;' -# (amiga: removed obsolete :kn#10:, -# also added empty to suppress a warning --esr) -amiga|Amiga ANSI:\ - :am:bs:bw:xn:\ - :co#80:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:ac=:\ - :ae=^O:al=\E[L:as=^N:bl=^G:bt=\E[Z:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:do=\E[B:ei=:\ - :ho=\E[H:ic=\E[@:im=:is=\E[20l:k0=\E[9~:k1=\E[0~:k2=\E[1~:\ - :k3=\E[2~:k4=\E[3~:k5=\E[4~:k6=\E[5~:k7=\E[6~:k8=\E[7~:k9=\E[8~:\ - :kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:mb=\E[7;2m:\ - :md=\E[1m:me=\E[m:mh=\E[2m:mk=\E[8m:mr=\E[7m:nd=\E[C:\ - :rs=\Ec:se=\E[m:sf=\E[S:so=\E[7m:sr=\E[T:ue=\E[m:up=\E[A:\ - :us=\E[4m:ve=\E[ p:vi=\E[0 p: - -# From: Hans Verkuil , 4 Dec 1995 -# (amiga: added empty to suppress a warning --esr) -amiga-bad|Amiga ANSI:\ - :bs:bw:ms:\ - :co#80:li#24:\ - :DC=\233%dP:DO=\233%dB:IC=\233%d@:LE=\233%dD:RI=\233%dC:\ - :SF=\233%dS:SR=\233%dT:UP=\233%dA:ac=:ae=^O:as=^N:bl=^G:\ - :bt=\233Z:cd=\233J:ce=\233K:cl=\233H\233J:\ - :cm=\233%i%d;%dH:cr=^M:dc=\233P:do=\233B:ec=\233%dP:ei=:\ - :ho=\233H:ic=\233@:im=:is=\23320l:k0=\2339~:k1=\2330~:\ - :k2=\2331~:k3=\2332~:k4=\2333~:k5=\2334~:k6=\2335~:\ - :k7=\2336~:k8=\2337~:k9=\2338~:kD=\177:kb=^H:kd=\233B:\ - :kl=\233D:kr=\233C:ku=\233A:le=\233D:mb=\2337;2m:\ - :md=\2331m:me=\2330m:mh=\2332m:mk=\2338m:mr=\2337m:\ - :nd=\233C:nw=\233B\r:r1=\Ec:se=\2330m:sf=\233S:so=\2337m:\ - :sr=\233T:ta=^I:te=\233?7h:ti=\233?7l:ue=\2330m:up=\233A:\ - :us=\2334m:vb=^G:ve=\233 p:vi=\2330 p: - -# Commodore B-128 microcomputer from Doug Tyrol -# I'm trying to write a termcap for a commodore b-128, and I'm -# having a little trouble. I've had to map most of my control characters -# to something that unix will accept (my delete-char is a ctrl-t, etc), -# and create some functions (like cm), but thats life. -# The problem is with the arrow keys - right, and up work fine, but -# left deletes the previous character and down I just can't figure out. -# Jove knows what I want, but I don't know what it's sending to me (it -# isn't thats bound to next-line in jove). -# Anybody got any ideas? Here's my termcap. -# DAG -- I changed his "^n" entries to "\n"; see if that works. -# -commodore|b-128|Commodore B-128 micro:\ - :am:bw:\ - :co#80:dN#20:li#24:pb#150:\ - :al=10\Ei:bc=^H:ce=10\Eq:cl=10\E\006:\ - :cm=20\E\013%2\054%2\054:cr=^M:dc=10*\177:dl=10*\Ed:\ - :do=^J:ei=:ho=\E^E:ic=5\E\n:im=:kd=^J:kh=\E^E:kl=^B:kr=^F:\ - :ku=^P:nd=^F:nl=^M:ta=5\011:up=^P: - -#### North Star -# -# North Star Advantage from Lt. Fickie via BRL -northstar|North Star Advantage:\ - :bs:\ - :co#80:li#24:\ - :cd=200\017:ce=200\016:cl=200\004:cm=1\E=%+ %+ :\ - :ho=200\034\032: - -#### Osborne -# -# Thu Jul 7 03:55:16 1983 -# -# As an aside, be careful; it may sound like an anomaly on the -# Osborne, but with the 80-column upgrade, it's too easy to -# enter lines >80 columns! -# -# I've already had several comments... -# The Osborne-1 with the 80-col option is capable of being -# 52, 80, or 104 characters wide; default to 80 for compatibility -# with most systems. -# -# The tab is destructive on the Ozzie; make sure to 'stty -tabs'. -osborne-w|osborne1-w|osborne I in 104-column mode:\ - :ms:ul:xt:\ - :co#104:li#24:\ - :al=\EE:bl=^G:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:dc=\EW:dl=\ER:\ - :do=^J:ei=:ic=\EQ:im=:kd=^J:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:\ - :se=\E(:sf=^J:so=\E):ue=\Em:up=^K:us=\El: -# Osborne I from ptsfa!rhc (Robert Cohen) via BRL -osborne|osborne1|osborne I in 80-column mode:\ - :am:bs:mi:ms:ul:xs:\ - :co#80:dB#4:li#24:\ - :al=\EE:ce=\ET:cl=^Z:cm=\E=%+ %+ :dc=4\EW:dl=\ER:do=^J:ei=:\ - :im=\EQ:is=^Z:kb=^H:kd=^J:kl=^H:kr=^L:ku=^K:le=\010:nd=^L:\ - :se=\E):so=\E(:ue=\Em:up=^K:us=\El: -# -# Osborne Executive definition from BRL -# Similar to tvi920 -# Added by David Milligan and Tom Smith (SMU) -osexec|Osborne executive:\ - :am:bs:\ - :co#80:li#24:sg#1:ug#1:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :cr=^M:ct=\E3:\ - :dc=\EW:dl=\ER:do=^J:ei=:ho=^^:ic=\EQ:im=:\ - :is=\Eq\Ek\Em\EA\Ex0:k0=^A@\r:k1=^AA\r:k2=^AB\r:k3=^AC\r:\ - :k4=^AD\r:k5=^AE\r:k6=^AF\r:k7=^AG\r:k8=^AH\r:k9=^AI\r:\ - :kb=^H:kd=^J:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:nl=^J:se=\Ek:\ - :so=\Ej:st=\E1:ue=\Em:up=^K:us=\El: - -#### Console types for obsolete UNIX clones -# -# Coherent, Minix, Venix, and several lesser-known kin were OSs for 8088 -# machines that tried to emulate the UNIX look'n'feel. Coherent and Venix -# were commercial, Minix an educational tool sold in conjunction with a book. -# Memory-segmentation limits and a strong tendency to look like V7 long after -# it was obsolete made all three pretty lame. Venix croaked early. Coherent -# and Minix were ported to 32-bit Intel boxes, only to be run over by a -# steamroller named `Linux' (which, to be fair, traces some lineage to Minix). -# Coherent's vendor, the Mark Williams Company, went belly-up in 1994. There -# are also, I'm told, Minix ports that ran on Amiga and Atari machines and -# even as single processes under SunOS and the Macintosh OS. -# - -# This is the entry provided with minix 1.7.4, with bogus :ri: removed. -minix|minix console (v1.7):\ - :am:xn:\ - :co#80:it#8:li#25:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:cd=\E[0J:\ - :ce=\E[K:cl=\E[H\E[0J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:\ - :dl=\E[M:do=\E[B:ei=:ho=\E[H:ic=\E[@:im=:is=\E[0m:k0=\E[Y:\ - :k1=\E[V:k2=\E[U:k3=\E[T:k4=\E[S:k5=\E[G:kb=^H:kd=\E[B:\ - :kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:l0=End:l1=PgUp:l2=PgDn:\ - :l3=Num +:l4=Num -:l5=Num 5:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[0m:mr=\E[7m:nd=\E[C:nw=^M^J:se=\E[0m:sf=^J:so=\E[7m:\ - :sr=\EM:ta=^I:ue=\E[0m:up=\E[A:us=\E[4m: -# Corrected Jan 14, 1997 by Vincent Broman -minix-old|minix console (v1.5):\ - :xo:\ - :co#80:it#8:li#25:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:al=\E[L:bl=^G:cd=\E[0J:\ - :ce=\E[K:cl=\E[H\E[0J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:\ - :dl=\E[M:do=\E[B:ei=:ho=\E[H:ic=\E[@:im=:k0=\E[Y:k1=\E[V:\ - :k2=\E[U:k3=\E[T:k4=\E[S:k5=\E[G:kb=^H:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:me=\E[0m:\ - :mr=\E[7m:nd=\E[C:nw=^M^J:se=\E[0m:sf=^J:so=\E[7m:sr=\EM:\ - :ta=^I:ue=\E[0m:up=\E[A:us=\E[4m: -# The linewrap option can be specified by editing /usr/include/minix/config.h -# before recompiling the minix 1.5 kernel. -minix-old-am|minix console with linewrap:\ - :am:tc=minix-old: - -pc-minix|minix console on an Intel box:\ - :ac=`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o~q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~\376.\031-\030\054\021+^P0\333p\304r\304y\363z\362{\343|\330}\234:\ - :ae=\E[10m:as=\E[11m:\ - :tc=minix: - -# According to the Coherent 2.3 manual, the PC console is similar -# to a z19. The differences seem to be (1) 25 lines, (2) no status -# line, (3) standout is broken, (4) ins/del line is broken, (5) -# has blinking and bold. -pc-coherent|pcz19|coherent|IBM PC console running Coherent:\ - :am:mi:\ - :co#80:it#8:li#25:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EE:cm=\EY%+ %+ :cr=^M:dc=\EN:\ - :do=\EB:ei=\EO:ho=\EH:im=\E@:kb=^H:kd=\EB:kh=\EH:kl=\ED:\ - :kr=\EC:ku=\EA:le=^H:me=\Eq:nd=\EC:se=\Eq:sf=^J:so=\Ep:\ - :sr=\EI:ta=^I:up=\EA: - -# According to the Venix 1.1 manual, the PC console is similar -# to a DEC vt52. Differences seem to be (1) arrow keys send -# different strings, (2) enhanced standout, (3) added insert/delete line. -# Note in particular that it doesn't have automatic margins. -# There are other keys (f1-f10, kpp, knp, kcbt, kich1, kdch1) but they -# not described here because this derives from an old termcap entry. -pc-venix|venix|IBM PC console running Venix:\ - :co#80:it#8:li#25:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:\ - :dl=\EM:do=^J:kb=^H:kd=\EP:kh=\EG:kl=\EK:kr=\EM:ku=\EH:le=^H:\ - :nd=\EC:sf=^J:sr=\EI:ta=^I:up=\EA: - -#### Miscellaneous microcomputer consoles -# -# If you know anything more about any of these, please tell me. -# - -# basis from Peter Harrison, Computer Graphics Lab, San Francisco -# ucbvax!ucsfmis!harrison ...uucp / ucbvax!ucsfmis!harrison@BERKELEY ...ARPA -# (basis: removed obsolete ":ma=^K^P^R^L^L :nl=5000*^J:" -- esr) -basis|BASIS108 computer with terminal translation table active:\ - :cd=\EY:ce=\ET:cl=300\E*:do=5000\n:kb=^H:kd=^J:kl=^H:kr=^L:\ - :ku=^K:me=\E):se=\E):so=\E(:\ - :tc=adm3a: -# luna's BMC terminal emulator -luna|luna68k|LUNA68K Bitmap console:\ - :co#88:li#46:tc=ansi-mini: -megatek|pegasus workstation terminal emulator:\ - :am:os:\ - :co#83:li#60: -# The Xerox 820 was a Z80 micro with a snazzy XEROX PARC-derived -# interface (pre-Macintosh by several years) that went nowhere. -xerox820|x820|Xerox 820:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=^Q:ce=^X:cl=1^Z:cm=\E=%+ %+ :cr=^M:do=^J:ho=^^:\ - :le=^H:nd=^L:sf=^J:up=^K: - -#### Videotex and teletext -# - -# \E\:1} switch to te'le'informatique mode (ascii terminal/ISO 6429) -# \E[?3l 80 columns -# \E[?4l scrolling on -# \E[12h local echo off -# \Ec reset: G0 U.S. charset (to get #,@,{,},...), 80 cols, clear screen -# \E(0 G0 DEC set (line graphics) -# -# From: Igor Tamitegama , 18 Jan 1997 -m2-nam|minitel|minitel-2|minitel-2-nam|France Telecom Minitel 2 mode te'le'informatique:\ - :bs:es:hs:xn:\ - :co#80:it#8:li#24:sg#0:ws#72:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:\ - :RI=\E[%dC:SF=^J:SR=\EM:UP=\E[%dA:\ - :ac=aaffggjjkkllmmnnooqqssttuuvvwwxx:ae=\E(B:al=\E[L:\ - :as=\E(0:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:\ - :fs=^J:ho=\E[H:i1=\E\0721}\Ec\E[?4l\E[12h:\ - :i2=\E[?3l kbs=\010:im=\E[4h:ip=7:is=\Ec\E[12h:\ - :k0=\EOp:k1=\EOq:k2=\EOr:k3=\EOs:k4=\EOt:k5=\EOu:k6=\EOv:\ - :k7=\EOw:k8=\EOx:k9=\EOy:k;=\EOp:kA=\E[4l:kC=\E[2J:kD=\E[P:\ - :kI=\E[4h:kL=\E[M:kN=\EOn:kP=\EOR:kd=\E[B:kh=\E[H:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=\E[D:ll=\E[24;80H:mb=\E[5m:md=\E[1m:\ - :me=\E[m:mr=\E[7m:nd=\E[C:nw=^M^J:ps=\E[i:\ - :r1=\Ec\E[?4l\E[12h:r2=\Ec:rc=\E8:sc=\E7:se=\E[27m:\ - :sf=^J:so=\E[7m:sr=\EM:ta=^I:ts=^_@A:u6=\E[%i%d;%dR:\ - :u7=\E[6n:ue=\E[24m:up=\E[A:us=\E[4m:vb=^G:ve=\E[<1l:\ - :vi=\E[<1h: - -######## OBSOLETE VDT TYPES -# -# These terminals are *long* dead -- these entries are retained for -# historical interest only. - -#### Amtek Business Machines -# - -# (abm80: early versions of this entry apparently had ":se=\E^_:so=\E^Y", -# but these caps were commented out in 8.3; also, removed overridden -# ":do=^J:" -- esr) -abm80|amtek business machines 80:\ - :am:bs:bw:\ - :co#80:li#24:\ - :al=\E^Z:bt=^T:cd=\E^X:ce=\E^O:cl=\E^\:cm=\E\021%r%+ %+ :\ - :dl=\E^S:do=\E^K:ho=\E^R:le=^H:nd=^P:up=\E^L: - -#### Bell Labs blit terminals -# -# These were AT&T's official entries. The 5620 FAQ maintained by -# David Breneman has this to say: -# -# Actually, in the beginning was the Jerq, and the Jerq was white with a -# green face, and Locanthi and Pike looked upon the Jerq and said the Jerq -# was good. But lo, upon the horizon loomed a mighty management-type person -# (known now only by the initials VP) who said, the mighty Jerq must stay -# alone, and could not go forth into the world. So Locanthi and Pike put the -# Jerq to sleep, cloned its parts, and the Blit was brought forth unto the -# world. And the Jerq lived the rest of its days in research, but never -# strayed from those paths. -# -# In all seriousness, the Blit was originally known as the Jerq, but when -# it started to be shown outside of the halls of the Bell Labs Research -# organization, the management powers that be decided that the name could -# not remain. So it was renamed to be Blit. This was in late 1981. -# -# (The AT&T 5620 was the commercialized Blit. Its successors were the 630, -# 730, and 730+.) -# - -blit|jerq|blit running teletype rom:\ - :am:eo:ul:xo:\ - :co#87:it#8:li#72:\ - :AL=\EF%+ :DC=\Ee%+ :DL=\EE%+ :IC=\Ef%+ :al=\EF\041:bl=^G:\ - :ce=\EK:cl=^L:cm=\EY%r%+ %+ :cr=^M:dc=\Ee\041:dl=\EE\041:\ - :do=^J:ei=:ic=\Ef\041:im=:k1=\Ex:k2=\Ey:k3=\Ez:kb=^H:kd=\EB:\ - :kl=\ED:kr=\EC:ku=\EA:le=\ED:nd=\EC:sf=^J:ta=^I:up=\EA: - -# (cbblit: here's a BSD termcap that says :do=\EG: -- esr) -cbblit|fixterm|blit running columbus code:\ - :co#88:\ - :cd=\EJ:ei=\ER:ic@:im=\EQ:pO=\EP%03:pf=^T:po=^R:se=\EV\041:\ - :so=\EU\041:ue=\EV":us=\EU":vb=\E^G:\ - :tc=blit: - -oblit|ojerq|first version of blit rom:\ - :am:da:db:eo:mi:ul:xo:\ - :co#88:it#8:li#72:\ - :AL=\Ef%+ :DL=\Ee%+ :al=\EF:bl=^G:cd=\EJ:ce=\EK:cl=^L:\ - :cm=\EY%r%+ %+ :cr=^M:dc=\EO:dl=\EE:do=^J:ei=\ER:im=\EQ:\ - :kb=^H:le=\ED:nd=\EC:sf=^J:ta=^I:up=\EA:vb=\E^G: - -#### Bolt, Beranek & Newman (bbn) -# -# The BitGraph was a product of the now-defunct BBN Computer Corporation. -# The parent company, best known as the architects of the Internet, is -# still around. -# - -# Entries for the BitGraph terminals. The problem -# with scrolling in vi can only be fixed by getting BBN to put -# smarter scroll logic in the terminal or changing vi or padding -# scrolls with about 500 ms delay. -# -# I always thought the problem was related to the terminal -# counting newlines in its input buffer before scrolling and -# then moving the screen that much. Then vi comes along and -# paints lines in on the bottom line of the screen, so you get -# this big white gap. - -bitgraph|bg2.0nv|bg3.10nv|bbn bitgraph 2.0 or later (normal video):\ - :is=\E>\E[?5l\E[?7h:vb=\E[?5h\E[?5l:\ - :tc=bg2.0: -bg2.0rv|bg3.10rv|bbn bitgraph 2.0 (reverse video):\ - :is=\E>\E[?5h\E[?7h:vb=\E[?5l\E[?5h:tc=bg2.0: -bg2.0|bg3.10|bbn bitgraph 2.0 or later (no init):\ - :bs:xn:\ - :co#85:li#64:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=%i\E[%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:dl=\E[M:do=\E[B:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kd=\E[B:ke=\E>:kl=\E[D:kr=\E[C:ks=\E=:\ - :ku=\E[A:l1=PF1:l2=PF2:l3=PF3:l4=PF4:le=^H:me=\E[m:nd=\E[C:\ - :rc=\E8:sc=\E7:se=\E[m:sf=\n:so=\E[7m:ta=^I:up=\E[A: - -bg1.25rv|bbn bitgraph 1.25 (reverse video):\ - :is=\E>\E[?5h\E[?7h:vb=\E[?5l\E[?5h:tc=bg1.25: -bg1.25nv|bbn bitgraph 1.25 (normal video):\ - :is=\E>\E[?5l\E[?7h:vb=\E[?5h\E[?5l:tc=bg1.25: -# (bg1.25: I added / based on the init string -- esr) -bg1.25|bbn bitgraph 1.25:\ - :co#85:li#64:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=%i\E[%d;%dH:cr=^M:dl=\E[M:do=\E[B:k1=\EP:\ - :k2=\EQ:k3=\ER:k4=\ES:kd=\EB:ke=\E>:kl=\ED:kr=\EC:ks=\E=:\ - :ku=\EA:l1=PF1:l2=PF2:l3=PF3:l4=PF4:le=^H:ll=\E[64;1H:\ - :me=\E[m:nd=\E[C:se=\E[m:sf=\n:so=\E[7m:ta=^I:up=\E[A: - -#### Chromatics -# - -# I have put the long strings in :ti:/:te:. Ti sets up a window -# that is smaller than the screen, and puts up a warning message -# outside the window. Te erases the warning message, puts the -# window back to be the whole screen, and puts the cursor at just -# below the small window. I defined :ve: and :vi: to really turn -# the cursor on and off, but I have taken this out since I don't -# like the cursor being turned off when vi exits. -cg7900|chromatics|chromatics 7900:\ - :am:\ - :co#80:li#40:\ - :al=^A>2:bl=^G:cd=^Al:ce=^A`:cl=^L:cm=\001M%r%d\054%d\054:\ - :cr=^M:dc=^A<1:dl=^A<2:do=^J:ei=:ho=^\:ic=^A>1:im=:le=^H:\ - :ll=^A|:nd=^]:se=\001C1\054\001c2\054:sf=^J:\ - :so=\001C4\054\001c7\054:\ - :te=\001W0\05440\05485\05448\054\014\001W0\0540\05485\05448\054\001M0\05440\054:\ - :ti=\001P0\001O1\001R1\001C4\054\001c0\054\014\001M0\05442\054WARNING DOUBLE ENTER ESCAPE and \025\001C1\054\001c2\054\001W0\0540\05479\05439\054:\ - :uc=\001\001_\001\200:up=^K: - -#### Computer Automation -# - -ca22851|computer automation 22851:\ - :am:\ - :co#80:li#24:\ - :bl=^G:cd=^\:ce=^]:cl=\014:cm=\002%i%.%.:cr=^M:do=^J:ho=^^:\ - :kd=^W:kh=^^:kl=^U:ku=^V:le=^U:nd=^I:sf=^J:up=^V: - -#### Cybernex -# - -# This entry has correct padding and the undocumented "ri" capability -cyb83|xl83|cybernex xl-83:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cd=\020:ce=\017:cl=\014:cm=\027%+ %+ :cr=^M:do=^J:\ - :ho=^K:kd=^J:kl=^H:kr=^I:ku=^N:le=^H:nd=^I:sf=^J:sr=^N:up=^N: -# (mdl110: removed obsolete ":ma=^Z^P:" and overridden ":cd=145^NA^W:" -- esr) -cyb110|mdl110|cybernex mdl-110:\ - :am:bs:\ - :co#80:li#24:\ - :al=\016A\016\035:bl=^G:cd=\016@\026:ce=\016@\026:\ - :cl=\030:cm=\020%+ %+ :cr=^M:dc=\016A\036:\ - :dl=\016A\016\036:do=^J:ei=:ho=^Y:ic=\016A\035:im=:le=^H:\ - :nd=^U:se=^NG:sf=^J:so=^NF:ta=\011:up=^Z: - -#### Datapoint -# -# Datapoint is gone. They used to be headquartered in Texas. -# They created ARCnet, an Ethernet competitor that flourished for a while -# in the early 1980s before 3COM got wise and cut its prices. The service -# side of Datapoint still lives (1995) in the form of Intelogic Trace. -# - -dp3360|datapoint|datapoint 3360:\ - :am:bs:\ - :co#82:li#25:\ - :bl=^G:cd=^_:ce=^^:cl=^]^_:cr=^M:do=^J:ho=^]:le=^H:nd=^X:\ - :sf=^J:up=^Z: - -# From: Jan Willem Stumpel , 11 May 1997 -# The Datapoint 8242 Workstation was sold at least between 1985 -# and 1989. To make the terminal work with this entry, press -# CONTROL-INT-INT to take the terminal off-line, and type (opt). -# Set the options AUTO ROLL, ROLL DN, and ESC KBD on, and AUTO -# CR/LF off. Use control-shift-[] as escape key, control-I as tab, -# shift-F1 to shift-F5 as F6 to F10 (unshifted F1 to F5 are in -# fact unusable because the strings sent by the terminal conflict -# with other keys). -# The terminal is capable of displaying "box draw" characters. -# For each graphic character you must send 2 ESC's (\E\E) followed -# by a control character as follows: -# character meaning -# ========= ======= -# ctrl-E top tee -# ctrl-F right tee -# ctrl-G bottom tee -# ctrl-H left tee -# ctrl-I cross -# ctrl-J top left corner -# ctrl-K top right corner -# ctrl-L bottom left corner -# ctrl-M bottom right corner -# ctrl-N horizontal line -# ctrl-O vertical line -# Unfortunately this cannot be fitted into the termcap/terminfo -# description scheme. -dp8242|datapoint 8242:\ - :ms:\ - :co#80:li#25:\ - :al=\E^T:bl=^G:cd=^W:ce=^V:cl=\025\E\004\027\030:\ - :cm=\011%r%+\\%+\\:cr=^M:dl=\E^Z:do=^J:ho=^U:\ - :i1=\E\014\E\016\200\230\200\317\025\027\030\E\004:\ - :k1=^G\Ee:k2=^I\Ed:k3=^J\Ec:k4=^J\Eb:k5=^S\Ea:k6=\EO\Ee:\ - :k7=\EN\Ed:k8=\EM\Ec:k9=\EL\Eb:k;=\EK\Ea:kb=^H:kd=^B:kl=^D:\ - :kr=^F:ku=^E:le=^H:nw=^M^J:\ - :r1=\E\014\E\016\200\230\200\317\025\027\030\E\004:\ - :rp=\E\023%.%.:se=\E^D:sf=^C:so=\E^E:sr=^K:ta=^I:ue=\E^D:\ - :us=\E^F:ve=^X:vi=^Y: - -#### DEC terminals (Obsolete types: DECwriter and vt40/42/50) -# -# These entries are DEC's official terminfos for its older terminals. -# Contact Bill Hedberg of Terminal Support -# Engineering for more information. Updated terminfos and termcaps -# are kept available at ftp://gatekeeper.dec.com/pub/DEC/termcaps. -# - -gt40|dec gt40:\ - :bs:os:\ - :co#72:li#30:\ - :bl=^G:cr=^M:do=^J:le=^H: -gt42|dec gt42:\ - :bs:os:\ - :co#72:li#40:\ - :bl=^G:cr=^M:do=^J:le=^H: -vt50|dec vt50:\ - :bs:\ - :co#80:li#12:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cr=^M:do=^J:le=^H:nd=\EC:\ - :sf=^J:ta=^I:up=\EA: -vt50h|dec vt50h:\ - :bs:\ - :co#80:li#12:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:do=^J:\ - :le=^H:nd=\EC:sf=^J:sr=\EI:ta=^I:up=\EA: -# (vt61: there's a BSD termcap that claims :dl=\EPd:, :al=\EPf.: :kb=^H:) -vt61|vt-61|vt61.5|dec vt61:\ - :co#80:li#24:\ - :bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=\r:do=^J:\ - :kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:sf=\n:sr=\EI:ta=^I:\ - :up=\EA: - -# The gigi does standout with red! -# (gigi: I added / based on the init string, corrected cub1 -- esr) -gigi|vk100|dec gigi graphics terminal:\ - :am:bs:xn:\ - :co#84:li#24:\ - :DO=\E[%dB:LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:\ - :UP=\E[%dA:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:do=^J:\ - :is=\E>\E[?3l\E[?4l\E[?5l\E[?20l\E[?7h\E[?8h:k1=\EOP:\ - :k2=\EOQ:k3=\EOR:k4=\EOS:kd=\EOB:ke=\E[?1l\E>:kh=\E[H:\ - :kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:me=\E[m:\ - :nd=\E[C:se=\E[m:sf=^J:so=\E[7;31m:sr=\EM:ta=^I:ue=\E[m:\ - :up=\E[A:us=\E[4m: - -# DEC PRO-350 console (VT220-style). The 350 was DEC's attempt to produce -# a PC differentiated from the IBM clones. It was a total, ludicrous, -# grossly-overpriced failure (among other things, DEC's OS didn't include -# a format program, so you had to buy pre-formatted floppies from DEC at -# a hefty premium!). -pro350|decpro|dec pro console:\ - :bs:\ - :co#80:it#8:li#24:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\EG:as=\EF:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :do=\EB:\ - :ho=\EH:k0=\EE:k1=\EF:k2=\EG:k3=\EH:k4=\EI:k5=\EJ:k6=\Ei:\ - :k7=\Ej:kd=\EB:kh=\EH:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:\ - :se=\E^N:so=\E^H:sr=\EI:ta=^I:ue=\E^C:up=\EA:us=\E^D: - -dw1|decwriter I:\ - :bs:hc:os:\ - :co#72:\ - :bl=^G:cr=^M:do=^J:le=^H:sf=^J: -dw2|decwriter|dw|decwriter II:\ - :bs:hc:os:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:kb=^H:le=^H:sf=^J: -# \E(B Use U.S. character set (otherwise # => british pound !) -# \E[20l Disable "linefeed newline" mode (else puts \r after \n,\f,\v) -# \E[w 10 char/in pitch -# \E[1;132 full width horizontal margins -# \E[2g clear all tab stops -# \E[z 6 lines/in -# \E[66t 66 lines/page (for \f) -# \E[1;66r full vertical page can be printed -# \E[4g clear vertical tab stops -# \E> disable alternate keypad mode (so it transmits numbers!) -# \E[%i%p1%du set tab stop at column %d (origin == 1) -# (Full syntax is \E[n;n;n;n;n;...;nu where each 'n' is -# a tab stop) -# -# The dw3 does standout with wide characters. -# -dw3|la120|decwriter III:\ - :bs:hc:os:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:\ - :i1=\E(B\E[20l\E[w\E[0;132s\E[2g\E[z\E[66t\E[1;66r\E[4g\E>:\ - :is=\E[9;17;25;33;41;49;57;65;73;81;89;97;105;113;121;129u\r:\ - :kb=^H:le=^H:me=\E[w:se=\E[w:sf=^J:so=\E[6w:ta=^I: -dw4|decwriter IV:\ - :am:bs:hc:os:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:is=\Ec:k0=\EOP:k1=\EOQ:k2=\EOR:k3=\EOS:\ - :kb=^H:le=^H:sf=^J:ta=^I: - -# These aren't official -ln03|dec ln03 laser printer:\ - :hc:\ - :co#80:li#66:\ - :bl=^G:cr=^M:do=^J:hd=\EK:hu=\EL:me=\E[m:nw=^M^J:se=\E[22m:\ - :sf=^J:so=\E[1m:ta=^I:ue=\E[24m:us=\E[4m: -ln03-w|dec ln03 laser printer 132 cols:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:kb=^H:kd=^J:kl=^H:nw=^M^J:sf=^J:ta=^I:tc=ln03: - -#### Delta Data (dd) -# - -# Untested. The cup sequence is hairy enough that it probably needs work. -# The idea is ctrl(O), dd(row), dd(col), where dd(x) is x - 2*(x%16) + '9'. -# There are BSD-derived termcap entries floating around for this puppy -# that are *certainly* wrong. -delta|dd5000|delta data 5000:\ - :am:bs:\ - :co#80:li#27:\ - :bl=^G:ce=^NU:cl=^NR:cm=\017%+^P%+^P:dc=^NV:do=^J:ho=^NQ:\ - :le=^H:nd=^Y:sf=^J:up=^Z: - -#### Digital Data Research (ddr) -# - -# (ddr: I added / based on the init string -- esr) -ddr|rebus3180|ddr3180|Rebus/DDR 3180 vt100 emulator:\ - :am:bs:xn:\ - :co#80:it#8:li#24:vt#3:\ - :RA=\E[7l:SA=\E[7l:cd=50\E[J:ce=3\E[K:cl=50\E[H\E[2J:\ - :cm=5\E[%i%d;%dH:cs=\E[%i%d;%dr:do=^J:ho=\E[H:\ - :is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :kb=^H:kd=\E[B:ke=\E[?1l\E>:kl=\E[D:kr=\E[C:ks=\E[?1h\E=:\ - :ku=\E[A:le=^H:mb=2\E[5m:md=2\E[1m:me=2\E[m:mr=2\E[7m:\ - :nd=2\E[C:r1=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:\ - :rf=/usr/share/tabset/vt100:sc=\E7:se=\E[m:sf=5\ED:\ - :so=\E[7m:sr=5\EM:ta=^I:ue=2\E[m:up=2\E[A:us=2\E[4m: - -#### Evans & Sutherland -# - -# Jon Leech tells us: -# The ps300 was the Evans & Sutherland Picture System 300, a high -# performance 3D vector graphics system with a bunch of specialized hardware. -# Approximate date of release was 1982 (early 80s, anyway), and it had several -# evolutions including (limited) color versions such as the PS330C. PS300s -# were effectively obsolete by the late 80s, replaced by raster graphics -# systems, although specialized applications like molecular modelling -# hung onto them for a while longer. AFAIK all E&S vector graphics systems -# are out of production, though of course E&S is very much alive (in 1996). -# (ps300: changed ":pt@:" to "it@" -- esr) -# -ps300|Picture System 300:\ - :xt:\ - :it@:\ - :se@:so@:ue@:us@:tc=vt100: - -#### General Electric (ge) -# - -terminet1200|terminet300|tn1200|tn300|terminet|GE terminet 1200:\ - :bs:hc:os:\ - :co#120:\ - :bl=^G:cr=^M:do=^J:sf=^J: - -#### Heathkit/Zenith -# - -# Here is a description of the H19 DIP switches: -# -# S401 -# 0-3 = baud rate as follows: -# -# 3 2 1 0 -# --- --- --- --- -# 0 0 1 1 300 baud -# 0 1 0 1 1200 baud -# 1 0 0 0 2400 baud -# 1 0 1 0 4800 baud -# 1 1 0 0 9600 baud -# 1 1 0 1 19.2K baud -# -# 4 = parity (0 = no parity) -# 5 = even parity (0 = odd parity) -# 6 = stick parity (0 = normal parity) -# 7 = full duplex (0 = half duplex) -# -# S402 -# 0 = block cursor (0 = underscore cursor) -# 1 = no key click (0 = keyclick) -# 2 = wrap at end of line (0 = no wrap) -# 3 = auto LF on CR (0 = no LF on CR) -# 4 = auto CR on LF (0 = no CR on LF) -# 5 = ANSI mode (0 = VT52 mode) -# 6 = keypad shifted (0 = keypad unshifted) -# 7 = 50Hz refresh (1 = 60Hz refresh) -# -# Factory Default settings are as follows: -# 7 6 5 4 3 2 1 0 -# S401 1 0 0 0 1 1 0 0 -# S402 0 0 0 0 0 0 0 0 -# (h19: I added / based on the init string; -# also added empty to suppress a tic warning -- esr) -h19-a|h19a|heath-ansi|heathkit-a|heathkit h19 ansi mode:\ - :am:bs:mi:ms:\ - :co#80:it#8:li#24:\ - :RA=\E[?7l:SA=\E[?7h:ac=:ae=\E[11m:al=\E[1L:as=\E[10m:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :dc=\E[1P:dl=\E[1M:do=\E[1B:ei=\E[4l:ho=\E[H:im=\E[4h:\ - :is=\E<\E[>1;2;3;4;5;6;7;8;9l\E[m\E[11m\E[?7h:k1=\EOS:\ - :k2=\EOT:k3=\EOU:k4=\EOV:k5=\EOW:k6=\EOP:k7=\EOQ:k8=\EOR:\ - :kb=^H:kd=\E[1B:kh=\E[H:kl=\E[1D:kr=\E[1C:ku=\E[1A:l6=blue:\ - :l7=red:l8=white:le=^H:nd=\E[1C:se=\E[m:sf=^J:so=\E[7m:\ - :sr=\EM:ta=^I:up=\E[1A:ve=\E[>4l:vs=\E[>4h: -h19-bs|heathkit w/keypad shifted:\ - :ke=\Eu:ks=\Et:tc=h19-b: -h19-smul|heathkit w/keypad shifted/underscore cursor:\ - :ke=\Eu:ks=\Et:\ - :tc=h19-u: -# (h19: merged in :ip: from BSDI hp19-e entry>; -# also added empty to suppress a tic warning --esr) -h19|heath|h19-b|heathkit|heath-19|z19|zenith|heathkit h19:\ - :am:bs:es:hs:mi:ms:\ - :co#80:it#8:li#24:\ - :ac=:ae=\EG:al=\EL:as=\EF:bl=^G:cd=\EJ:ce=\EK:cl=\EE:\ - :cm=\EY%+ %+ :cr=^M:dc=\EN:dl=\EM:do=\EB:ei=\EO:fs=\Ek\Ey5:\ - :ho=\EH:im=\E@:ip=1.5<1.5/>:k1=\ES:k2=\ET:k3=\EU:k4=\EV:\ - :k5=\EW:k6=\EP:k7=\EQ:k8=\ER:kb=^H:kd=\EB:kh=\EH:kl=\ED:\ - :kr=\EC:ku=\EA:l6=blue:l7=red:l8=white:le=^H:nd=\EC:se=\Eq:\ - :sf=^J:so=\Ep:sr=\EI:ta=^I:\ - :ts=\Ej\Ex5\EY8%+ \Eo\Eo:up=\EA:ve=\Ey4:\ - :vs=\Ex4: -h19-u|heathkit with underscore cursor:\ - :ve@:vs@:tc=h19-b: -h19-us|h19us|heathkit w/keypad shifted/underscore cursor:\ - :ke=\Eu:ks=\Et:\ - :tc=h19-u: -h19-g|h19g|heathkit w/block cursor:\ - :ve=\Ex4:tc=h19-b: -alto-h19|altoh19|altoheath|alto-heath|alto emulating heathkit h19:\ - :li#60:\ - :al=\EL:dl=\EM:tc=h19: - -# The major problem with the Z29 is that it requires more padding than the Z19. -# -# The problem with declaring an H19 to be synonymous with a Z29 is that -# it needs more padding. It especially loses if a program attempts -# to put the Z29 into insert mode and insert text at 9600 baud. It -# even loses worse if the program attempts to insert tabs at 9600 -# baud. Adding padding to text that is inserted loses because in -# order to make the Z29 not die, one must add so much padding that -# whenever the program tries to use insert mode, the effective -# rate is about 110 baud. -# -# What program would want to put the terminal into insert mode -# and shove stuff at it at 9600 baud you ask? -# -# Emacs. Emacs seems to want to do the mathematically optimal -# thing in doing a redisplay rather than the practical thing. -# When it is about to output a line on top of a line that is -# already on the screen, instead of just killing to the end of -# the line and outputting the new line, it compares the old line -# and the new line and if there are any similarities, it -# constructs the new line by deleting the text on the old line -# on the terminal that is already there and then inserting new -# text into the line to transform it into the new line that is -# to be displayed. The Z29 does not react kindly to this. -# -# But don't cry for too long.... There is a solution. You can make -# a termcap entry for the Z29 that says the Z29 has no insert mode. -# Then Emacs cannot use it. "Oh, no, but now inserting into a -# line will be really slow", you say. Well there is a sort of a -# solution to that too. There is an insert character option on -# the Z29 that will insert one character. Unfortunately, it -# involves putting the terminal into ansi mode, inserting the -# character, and changing it back to H19 mode. All this takes 12 -# characters. Pretty expensive to insert one character, but it -# works. Either Emacs doesn't try to use its inserting hack when -# it's only given an insert character ability or the Z29 doesn't -# require padding with this (the former is probably more likely, -# but I haven't checked it out). -# (z29: added empty to suppress a tic warning, merged in -# status line capabilities from BRL entry --esr) -z29|zenith29|z29b|zenith z29b:\ - :am:bs:es:hs:mi:ms:pt:\ - :co#80:kn#10:li#24:\ - :ac=:ae=\EF:al=1\EL:as=\EG:bc=\ED:bl=^G:bt=\E-:cd=\EJ:ce=\EK:\ - :cl=\EE:cm=\EY%+ %+ :cr=^M:dc=\EN:dl=1\EM:do=\EB:ds=\Ey1:\ - :ei=\EO:fs=\Ek\Ey5:ho=\EH:ic=\E<\E[1@\E[?2h:im=\E@:\ - :is=\E<\E[?2h\Ev:k0=\E~:k1=\ES:k2=\ET:k3=\EU:k4=\EV:k5=\EW:\ - :k6=\EP:k7=\EQ:k8=\ER:k9=\E0I:kb=^H:kd=\EB:kh=\EH:kl=\ED:\ - :kr=\EC:ku=\EA:l0=home:le=^H:nd=\EC:se=\Eq:sf=\n:so=\Ep:\ - :sr=2\EI:ta=^I:ts=\Ej\Ex5\Ex1\EY8%+ \Eo:ue=\Es0:up=\EA:\ - :us=\Es8:ve=\Ey4:vs=\Ex4: -# z29 in ansi mode. Assumes that the cursor is in the correct state, and that -# the world is stable. causes the terminal to be reset to the state -# indicated by the name. kc -> key click, nkc -> no key click, uc -> underscore -# cursor, bc -> block cursor. -# From: Mike Meyers -# (z29a: replaced nonexistent :if=/usr/share/tabset/zenith29: befause :st: -# looks vt100-compatible -- esr) -z29a|z29a-kc-bc|h29a-kc-bc|heath/zenith 29 in ansi mode:\ - :am:bs:es:hs:mi:ms:pt:\ - :co#80:it#8:kn#10:li#24:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:bc=\ED:bl=^G:cd=\E[J:ce=\E[K:cl=\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[1P:\ - :do=^J:ds=\E[>1l:fs=\E[u\E[>5l:ho=\E[H:\ - :if=/usr/share/tabset/vt100:k0=\E[~:k1=\EOS:k2=\EOT:\ - :k3=\EOU:k4=\EOV:k5=\EOW:k6=\EOP:k7=\EOQ:k8=\EOR:k9=\EOX:\ - :kC=\E[J:kS=\E[J:kb=^H:kd=\EOB:kh=\E[H:kl=\EOD:kr=\EOC:\ - :ku=\EOA:l0=help:le=^H:mb=\E[5m:md=\E[2m:me=\E[m:mh=\E[2m:\ - :mr=\E[7m:nd=\E[C:nw=^M\ED:ps=\E#7:\ - :r1=\E<\E[1;24r\E[24;1H\E[?7h\E[>4h\E[>1;2;3;5;6;7;8;9l\E[m\E[11m:\ - :rc=\E[r:sc=\E[s:se=\E[m:sf=\ED:so=\E[7;2m:sr=\EM:st=\EH:\ - :ta=^I:te=\E[?7h:ti=\E[?7l:\ - :ts=\E[s\E[>5;1h\E[25;%i%dH\E[1K:ue=\E[m:up=\E[A:\ - :us=\E[4m: -z29a-kc-uc|h29a-kc-uc|z29 ansi mode with keyckick and underscore cursor:\ - :r1=\E<\E[1;24r\E[24;1H\E[?7h\E[>1;2;3;4;5;6;7;8;9l\E[m\E[11m:\ - :tc=z29a: -z29a-nkc-bc|h29a-nkc-bc|z29 ansi mode with block cursor and no keyclick:\ - :r1=\E<\E[1;24r\E[24;1H\E[?7h\E[>2;4h\E[>1;3;5;6;7;8;9l\E[m\E[11m:\ - :tc=z29a: -z29a-nkc-uc|h29a-nkc-uc|z29 ansi mode with underscore cursor and no keyclick:\ - :r1=\E<\E[1;24r\E[24;1H\E[?7h\E[>2h\E[>1;3;4;5;6;7;8;9l\E[m\E[11m:\ - :tc=z29a: -# From: Jeff Bartig 31 Mar 1995 -z39-a|z39a|zenith39-a|zenith39-ansi|Zenith 39 in ANSI mode:\ - :5i:am:es:hs:mi:ms:xo:\ - :co#80:li#24:\ - :%1=\E[~:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:K1=\EOw:\ - :K2=\EOy:K3=\EOu:K4=\EOq:K5=\EOs:LE=\E[%dD:RI=\E[%dC:\ - :UP=\E[%dA:ac=``aaffggjjkkllmmnnooqqssttuuvvwwxx~~0a:\ - :ae=\E(B:al=\E[1L:as=\E(0:bl=^G:bt=\E[1Z:cb=\E[1K:cd=\E[0J:\ - :ce=\E[0K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:dc=\E[1P:dl=\E[1M:do=\E[B:\ - :ds=\E[>1l:ei=\E[4l:fs=\E[u:ho=\E[H:im=\E[4h:\ - :is=\E<\E[>1;3;5;6;7l\E[0m\E[2J:k1=\EOS:k2=\EOT:k3=\EOU:\ - :k4=\EOV:k5=\EOW:k6=\EOP:k7=\EOQ:k8=\EOR:k9=\EOX:kS=\E[J:\ - :kb=^H:kd=\E[B:ke=\E[>7l:kh=\E[H:kl=\E[D:kr=\E[C:ks=\E[>7h:\ - :ku=\E[A:le=^H:ll=\E[24;1H:mb=\E[5m:md=\E[1m:me=\E[0m:\ - :mh=\E[2m:mr=\E[7m:nd=\E[C:pf=\E[4i:po=\E[5i:\ - :ps=\E[?19h\E[i:r2=\E<\Ec\200:rc=\E[u:sc=\E[s:se=\E[0m:\ - :sf=^J:so=\E[7m:st=\EH:ta=^I:ts=\E[s\E[>1h\E[25;%i%dH:\ - :ue=\E[0m:up=\E[A:us=\E[4m:ve=\E[>5l:vi=\E[>5h: - -# From: Brad Brahms -z100|h100|z110|z-100|h-100|heath/zenith z-100 pc with color monitor:\ - :ve=\Ey4\Em70:vs=\Ex4\Em71:\ - :tc=z100bw: -# (z100bw: removed obsolete ":kn#10:", added empty -- esr) -z100bw|h100bw|z110bw|z-100bw|h-100bw|heath/zenith z-100 pc:\ - :bs:mi:ms:pt:\ - :co#80:it#8:kn#10:li#24:\ - :ac=:ae=\EG:al=5*\EL:as=\EF:cd=\EJ:ce=\EK:cl=5*\EE:\ - :cm=1*\EY%+ %+ :dc=1*\EN:dl=5*\EM:do=\EB:ei=\EO:ho=\EH:\ - :im=\E@:k0=\EJ:k1=\ES:k2=\ET:k3=\EU:k4=\EV:k5=\EW:k6=\EP:\ - :k7=\EQ:k8=\ER:k9=\EOI:kb=^H:kd=\EB:kh=\EH:kl=\ED:kr=\EC:\ - :ku=\EA:le=^H:nd=\EC:se=\Eq:so=\Ep:sr=\EI:ta=^I:up=\EA:\ - :ve=\Ey4:vs=\Ex4: -p19|h19-b with il1/dl1:\ - :al=2*\EL:dl=2*\EM:tc=h19-b: -# From: -# (ztx: removed duplicate :sr: -- esr) -ztx|ztx11|zt-1|htx11|ztx-1-a|ztx-10 or 11:\ - :am:bs:es:hs:\ - :co#80:it#8:li#24:\ - :al=\EL:cd=\EJ:ce=\EK:cl=\EE:cm=\EY%+ %+ :dl=\EM:do=^J:\ - :ds=\Ey1:fs=\Ek\Ey5:ho=\EH:\ - :is=\Ej\EH\Eq\Ek\Ev\Ey1\Ey5\EG\Ey8\Ey9\Ey>:k0=\ES:\ - :k1=\EB:k2=\EU:k3=\EV:k4=\EW:k5=\EP:k6=\EQ:k7=\ER:kb=^H:\ - :kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=^H:nd=\EC:se=\Eq:so=\Es5:\ - :sr=\EI:ta=^I:ts=\Ej\Ex5\Ex1\EY8%+ \Eo:ue=\Eq:up=\EA:\ - :us=\Es2: - -#### IMS International (ims) -# -# There was a company called IMS International located in Carson City, -# Nevada, that flourished from the mid-70s to mid-80s. They made S-100 -# bus/Z80 hardware and a line of terminals called Ultimas. -# - -# From: Erik Fair Sun Oct 27 07:21:05 1985 -ims950-b|bare ims950 no init string:\ - :is@:tc=ims950: -# (ims950: removed obsolete ":ko@:" -- esr) -ims950|ims televideo 950 emulation:\ - :xn@:\ - :k0@:k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:k9@:kb@:kd@:kh@:kl@:kr@:ku@:vb@:tc=tvi950: -# (ims950-rv: removed obsolete ":ko@:" -- esr) -ims950-rv|ims tvi950 rev video:\ - :xn@:\ - :k0@:k1@:k2@:k3@:k4@:k5@:k6@:k7@:k8@:k9@:kb@:kd@:kh@:kl@:kr@:ku@:vb@:tc=tvi950-rv: -ims-ansi|ultima2|ultimaII|IMS Ultima II:\ - :am:bs:\ - :co#80:it#8:li#24:\ - :cd=\E[0J:ce=\E[0K:cl=\E[H\E[2J:cm=\E[%i%2;%2H:do=\ED:\ - :if=/usr/share/tabset/vt100:\ - :is=\E[m\E[>14l\E[?1;?5;20l\E>\E[1m\r:kd=\E[B:kh=\E[H:\ - :kl=\E[D:kr=\E[C:ku=\E[A:le=^H:me=\E[m:se=\E[m\E[1m:\ - :so=\E[7m:sr=\EM:ta=^I:ue=\E[m\E[1m:up=\EM:us=\E[4m: - -#### Intertec Data Systems -# -# I think this company is long dead as of 1995. They made an early CP/M -# micro called the "Intertec Superbrain" that was moderately popular, -# then sank out of sight. -# - -superbrain|intertec superbrain:\ - :am:bs:bw:\ - :co#80:li#24:\ - :bc=^U:bl=^G:cd=\E~k<10*>:ce=\E~K:cl=\014:cm=\EY%+ %+ :\ - :cr=^M:do=^J:kd=^J:kl=^U:kr=^F:ku=^K:le=^H:nd=^F:sf=^J:ta=^I:\ - :te=^L:ti=^L:up=^K: -# (intertube: a Gould entry via BRL asserted smul=\E0@$<200/>, -# rmul=\E0A$<200/>; my guess is the highlight letter is bit-coded like an ADM, -# and the reverse is actually true. Try it. -- esr) -intertube|intertec|Intertec InterTube:\ - :am:bs:\ - :co#80:li#25:\ - :bl=^G:cl=^L:cm=\EY%+ %+ :cr=^M:do=^J:ho=^A:le=^H:nd=^F:\ - :se=\E0@:sf=^J:so=\E0P:up=^Z: -# The intertube 2 has the "full duplex" problem like the tek 4025: if you -# are typing and a command comes in, the keystrokes you type get interspersed -# with the command and it messes up -intertube2|intertec data systems intertube 2:\ - :bs:\ - :ce=\EK:ch=\020%+^J:cm=\016%.\020%+^J:cv=\013%.:\ - :ll=^K^X\r:\ - :tc=intertube: - -#### Ithaca Intersystems -# -# This company made S100-bus personal computers long ago in the pre-IBM-PC -# past. They used to be reachable at: -# -# Ithaca Intersystems -# 1650 Hanshaw Road -# Ithaca, New York 14850 -# -# However, the outfit went bankrupt years ago. -# - -# The Graphos III was a color graphics terminal from Ithaca Intersystems. -# These entries were written (originally in termcap syntax) by Brian Yandell -# and Mike Meyer at the -# University of Wisconsin. - -# (graphos: removed obsolete and syntactically incorrect :kn=4:, -# removed :if=/usr/share/tabset/init.graphos: and -# no such file & no :st: -- esr) -graphos|graphos III:\ - :am:mi:\ - :co#80:it#8:li#24:\ - :AL=\E[%dL:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:\ - :UP=\E[%dA:al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:dm=\E[4h:do=\E[B:\ - :ed=\E[4l:ei=\E[4l:ho=\E[H:im=\E[4h:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ku=\E[A:le=^H:me=\E[m:nd=\E[C:nw=^M\ED:rc=\E8:sc=\E7:\ - :se=\E[m:sf=\ED:so=\E[7m:sr=\EM:ta=^I:up=\E[A:\ - :ve=\Ez56;2;0;0z\Ez73z\Ez4;1;1z:\ - :vs=\Ez4;2;1z\Ez56;2;80;24z: -graphos-30|graphos III with 30 lines:\ - :li#30:\ - :vs=\Ez4;2;1z\Ez56;2;80;30z:tc=graphos: - -#### Modgraph -# -# These people used to be reachable at: -# -# Modgraph, Inc -# 1393 Main Street, -# Waltham, MA 02154 -# Vox: (617)-890-5796. -# -# However, if you call that number today you'll get an insurance company. -# I have mail from "Michael Berman, V.P. Sales, Modgraph" dated -# 26 Feb 1997 that says: -# -# Modgraph GX-1000, replaced by GX-2000. Both are out of production, have been -# for ~7 years. Modgraph still in business. Products are rugged laptop and -# portable PC's and specialized CRT and LCD monitors (rugged, rack-mount -# panel-mount etc). I can be emailed at sonfour@aol.com -# - -modgraph|mod24|modgraph terminal emulating vt100:\ - :xn@:\ - :co#80:li#24:\ - :is=\E\1369;0s\E\1367;1s\E[3g\E\13611;9s\E\13611;17s\E\13611;25s\E\13611;33s\E\13611;41s\E\13611;49s\E\13611;57s\E\13611;65s\E\13611;73s\E\13611;81s\E\13611;89s:\ - :rf@:sr=5\EM\E[K:vs=\E\1369;0s\E\1367;1s:\ - :tc=vt100: -# The GX-1000 manual is dated 1984. This looks rather like a VT-52. -modgraph2|modgraph gx-1000 80x24 with keypad not enabled:\ - :am:da:db:\ - :co#80:it#8:li#24:\ - :cd=50\EJ:ce=3\EK:cl=50\EH\EJ:cm=5\EY%+ %+ :\ - :is=\E<\E\1365;2s\E\1367;1s\E[3g\E\13611;9s\E\13611;17s\E\13611;25s\E\13611;33s\E\13611;41s\E\13611;49s\E\13611;57s\E\13611;65s\E\13611;73s\E\13611;81s\E\13611;89s\E\13612;0s\E\13614;2s\E\13615;9s\E\13625;1s\E\1369;1s\E\13627;1:\ - :le=^H:nd=2\EC:sr=5\EI:ta=^I:up=2\EA: -# -# Modgraph from Nancy L. Cider -# BUG NOTE from Barbara E. Ringers : -# If we set TERM=vt100, and set the Modgraph screen to 24 lines, setting a -# mark and using delete-to-killbuffer work correctly. However, we would -# like normal mode of operation to be using a Modgraph with 48 line setting. -# If we set TERM=mod (which is a valid entry in termcap with 48 lines) -# the setting mark and delete-to-killbuffer results in the deletion of only -# the line the mark is set on. -# We've discovered that the delete-to-killbuffer works correctly -# with TERM=mod and screen set to 80x48 but it's not obvious. Only -# the first line disappears but a ctrl-l shows that it did work -# correctly. -modgraph48|mod|Modgraph w/48 lines:\ - :am:bs:pt:xn:\ - :co#80:it#8:li#48:vt#3:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[;H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:do=^J:ho=\E[H:\ - :is=\E<\E[1;48r\E[0q\E[3;4q\E=\E[?1h:k1=\EOP:k2=\EOQ:\ - :k3=\EOR:k4=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:\ - :me=\E[m:mr=\E[7m:nd=\E[C:nl=^J:r1=\E=\E[0q\E>:rc=\E8:\ - :sc=\E7:se=\E[m:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:\ - :us=\E[4m:vb=\E[?5h\E[0q\E[1;2q\E[?5l\E[0q\E[4;3q: - -#### Morrow Designs -# -# This was George Morrow's company. They started in the late 1970s making -# S100-bus machines. They used to be reachable at: -# -# Morrow -# 600 McCormick St. -# San Leandro, CA 94577 -# -# but they're long gone now (1995). -# - -# The mt70 terminal was shipped with the Morrow MD-3 microcomputer. -# Jeff's specimen was dated June 1984. -# From: Jeff Wieland 24 Feb 1995 -mt70|mt-70|Morrow MD-70; native Morrow mode:\ - :am:mi:ms:xo:\ - :co#80:it#8:li#24:\ - :%1=^AO\r:F1=^A`\r:F2=^Aa\r:F3=^Ab\r:F4=^Ac\r:F5=^Ad\r:\ - :F6=^Ae\r:F7=^Af\r:F8=^Ag\r:F9=^Ah\r:FA=^Ai\r:\ - :ac=+z\054{.yOi-x`|jGkFlEmDnHtLuKvNwMxIqJ:ae=\E%:\ - :al=\EE:as=\E$:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=^Z:\ - :cm=\E=%+ %+ :cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ei=:ho=^^:\ - :i1=\E"2\EG0\E]:ic=\EQ:im=:k1=^A@\r:k2=^AA\r:k3=^AB\r:\ - :k4=^AC\r:k5=^AD\r:k6=^AE\r:k7=^AF\r:k8=^AG\r:k9=^AH\r:\ - :k;=^AI\r:kB=^A^Z\r:kC=^An\r:kD=\177:kb=^H:kd=^AK\r:\ - :kh=^AN\r:kl=^AL\r:kr=^AM\r:ku=^AJ\r:le=^H:mh=\EG2:mk@:\ - :nd=^L:nw=^_:sf=^J:ta=^I:te=:ti=\E"2\EG0\E]:up=^K:us=\EG1:\ - :vb=\EK1\EK0:ve=\E"2:vi=\E"0:\ - :tc=adm+sgr: - -#### Motorola -# - -# Motorola EXORterm 155 from {decvax, ihnp4}!philabs!sbcs!megad!seth via BRL -# (Seth H Zirin) -ex155|Motorola Exorterm 155:\ - :am:bs:bw:\ - :co#80:kn#5:li#24:ug#1:\ - :bt=\E[:cd=\ET:ce=\EU:cl=\EX:cm=\EE%+ %+ :do=\EB:ho=\E@:\ - :kB=\E[:kC=\EX:kE=\EU:kS=\ET:kb=^H:kd=^J:kh=\E@:kl=^H:kr=^L:\ - :ku=^K:nd=\ED:se=\Ec\ED:so=\Eb\ED:ta=\EZ:ue=\Eg\ED:\ - :us=\Ef\ED: - -#### Omron -# -# This company is still around in 1995, manufacturing point-of-sale systems. - -omron|Omron 8025AG:\ - :am:bs:da:db:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=\ER:ce=\EK:cl=\EJ:cr=^M:dc=\EP:dl=\EM:do=^J:\ - :ho=\EH:le=^H:nd=\EC:se=\E4:sf=\ES:so=\Ef:sr=\ET:up=\EA:\ - :vs=\EN: - -#### Ramtek -# -# Ramtek was a vendor of high-end graphics terminals around 1979-1983; they -# were competition for things like the Tektronics 4025. -# - -# Ramtek 6221 from BRL, probably by Doug Gwyn -# The following SET-UP modes are assumed for normal operation: -# UNDERLINE_CURSOR ANSI_MODE AUTO_XON/XOFF_ON -# NEWLINE_OFF 80_COLUMNS -# Other SET-UP modes may be set for operator convenience or communication -# requirements; I recommend -# SMOOTH_SCROLL AUTO_REPEAT_ON 3_#_SHIFTED WRAP_AROUND_ON -# Hardware tabs are assumed to be every 8 columns; they can be set up by the -# "reset", "tset", or "tabs" utilities (use rt6221-w, 160 columns, for this). -# Note that the Control-E key is useless on this brain-damaged terminal. No -# delays are specified; use "stty ixon -ixany" to enable DC3/DC1 flow control! -rt6221|Ramtek 6221, 80x24:\ - :bs:ms:pt:xo:\ - :co#80:it#8:kn#4:li#24:vt#3:\ - :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ac=:ae=\E(B:as=\E(0:\ - :bl=^G:cd=\E[J:ce=\E[K:cl=\E[1;1H\E[J:cm=\E[%i%d;%dH:\ - :cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:do=^K:ho=\E[1;1H:is=:\ - :k0=\EOP:k1=\EOQ:k2=\EOR:k3=\EOS:kb=^H:kd=\E[B:ke=\E>:\ - :kl=\E[D:kr=\E[C:ks=\E=:ku=\E[A:l0=PF1:l1=PF2:l2=PF3:l3=PF4:\ - :le=^H:ll=\E[24;1H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:\ - :nd=\E[C:nw=\EE:\ - :r1=\E[1w\E[>37m\E[>39m\E[1v\E[20l\E[?3l\E[?6l\E[>5h\E[>6h\E[>7h\E[>8l\E[>9h\E[>10l\E[1;24r\E[m\E[q\E(B\017\E#5\E>:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :ue=\E[m:up=\EM:us=\E[4m:ve=\E[>5h\E[>9h:vi=\E[>5l:\ - :vs=\E[>7h\E[>9l: -# [TO DO: Check out: short forms of ho/cl and ll; reset (\Ec)]. -rt6221-w|Ramtek 6221, 160x48:\ - :co#160:li#48:\ - :ll=\E[48;1H:tc=rt6221: - -#### RCA -# - -# RCA VP3301 or VP3501 -rca|rca vp3301/vp3501:\ - :bs:\ - :co#40:li#24:\ - :cl=^L:cm=\EY%+ %+ :ho=^Z:nd=^U:se=\E\ES0:so=\E\ES1:up=^K: - - -#### Selanar -# - -# Selanar HiREZ-100 from BRL, probably by Doug Gwyn -# The following SET-UP modes are assumed for normal operation: -# SET_DEFAULT_TABS 48_LINES 80_COLUMNS -# ONLINE ANSI CURSOR_VISIBLE -# VT102_AUTO_WRAP_ON VT102_NEWLINE_OFF VT102_MONITOR_MODE_OFF -# LOCAL_ECHO_OFF US_CHAR_SET WPS_TERMINAL_DISABLED -# CPU_AUTO_XON/XOFF_ENABLED PRINT_FULL_SCREEN -# For use with graphics software, all graphics modes should be set to factory -# default. Other SET-UP modes may be set for operator convenience or -# communication requirements. No delays are specified; use "stty ixon -ixany" -# to enable DC3/DC1 flow control! -# I commented out the scrolling capabilities since they are too slow. -hirez100|Selanar HiREZ-100:\ - :bs:mi:ms:pt:xo:\ - :co#80:it#8:kn#4:li#48:vt#3:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ac=:ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:\ - :ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:\ - :dc=\E[P:dl=\E[M:do=^J:ho=\E[H:is=\E<:k0=\EOP:k1=\EOQ:\ - :k2=\EOR:k3=\EOS:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\ - :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:l0=PF1:l1=PF2:l2=PF3:l3=PF4:\ - :le=^H:ll=\E[48H:mb=\E[5m:md=\E[1m:me=\E[m:mr=\E[7m:\ - :nd=\E[C:nw=\EE:pf=\E[4i\E[?4i:po=\E[?5i\E[5i:ps=\E[i:\ - :r1=\030\E2\E<\E[4i\E[?4i\E[12h\E[2;4;20l\E[?0;7h\E[?1;3;6;19l\E[r\E[m\E(B\017\E>:\ - :rc=\E8:sc=\E7:se=\E[m:so=\E[7m:st=\EH:ta=^I:ue=\E[m:up=\EM:\ - :us=\E[4m: -hirez100-w|Selanar HiREZ-100 in 132-column mode:\ - :co#132:tc=hirez100: - -#### Signetics -# - -# From University of Wisconsin -vsc|Signetics Vsc Video driver by RMC:\ - :am:ms:\ - :co#80:it#8:li#26:\ - :ce=\E[K:cl=50\E[;H\E[2J:cm=\E[%i%d;%dH:cr=^M:do=^J:\ - :ho=\E[H:kb=^H:kd=^J:kl=^H:le=^H:me=^_\041:mr=^_ :nd=\E[C:\ - :nw=^M^J:se=^_\041:sf=^J:so=^_ :ta=^I:ue=^_#:up=\E[A:us=^_": - -#### Soroc -# -# Alan Frisbie writes: -# -# As you may recall, the Soroc logo consisted of their name, -# with the letter "S" superimposed over an odd design. This -# consisted of a circle with a slightly smaller 15 degree (approx.) -# wedge with rounded corners inside it. The color was sort of -# a metallic gold/yellow. -# -# If I had been more of a beer drinker it might have been obvious -# to me, but it took a clue from their service department to make -# me exclaim, "Of course!" The circular object was the top of -# a beer can (the old removable pop-top style) and "Soroc" was an -# anagram for "Coors". -# -# I can just imagine the founders of the company sitting around -# one evening, tossing back a few and trying to decide what to -# call their new company and what to use for a logo. -# - -# (soroc120: removed obsolete ":ma=^K^P^R^L^L :" -- esr) -soroc120|iq120|soroc|soroc iq120:\ - :cd=\EY:ce=\ET:cl=\E*:do=^J:kd=^J:kl=^H:kr=^L:ku=^K:tc=adm3a: -soroc140|iq140|soroc iq140:\ - :am:bs:mi:\ - :co#80:li#24:\ - :al=\Ee:bl=^G:bt=\EI:cd=\Ey:ce=\Et:cl=\E+:cm=\E=%+ %+ :\ - :cr=^M:dc=\Ew:dl=\Er:do=^J:ei=\E8:ho=^^:im=\E9:k0=^A0\r:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kb=^H:kh=^^:kr=^L:ku=^K:le=^H:\ - :ll=^^^K:nd=^L:se=\E\177:sf=^J:so=\E\177:ue=\E^A:up=^K:\ - :us=\E^A: - -#### Southwest Technical Products -# -# These guys made an early personal micro called the M6800. -# The ct82 was probably its console terminal. -# - -# (swtp: removed obsolete ":bc=^D:" -- esr) -swtp|ct82|southwest technical products ct82:\ - :am:\ - :co#82:li#20:\ - :al=^^Y:bl=^G:cd=^V:ce=^F:cl=^L:cm=\013%r%.%.:cr=^M:dc=^^H:\ - :dl=^Z:do=^J:ei=:ho=^P:ic=^^X:im=:\ - :is=\034\022\036\023\036\004\035\027\011\023\036\035\036\017\035\027\022\011:\ - :le=^D:ll=^C:nd=^S:se=^^^F:sf=^N:so=^^^V:sr=^O:up=^A: - -#### Synertek -# -# Bob Manson writes (28 Apr 1995): -# -# Synertek used to make ICs, various 6502-based single-board process -# control and hobbyist computers, and assorted peripherals including a -# series of small inexpensive terminals (I think they were one of the -# first to have a "terminal-on-a-keyboard", where the terminal itself -# was only slightly larger than the keyboard). -# -# They apparently had a KTM-1 model, which I've never seen. The KTM-2/40 -# was a 40x24 terminal that could connect to a standard TV through a -# video modulator. The KTM-2/80 was the 80-column version (the 2/40 -# could be upgraded to the 2/80 by adding 2 2114 SRAMs and a new ROM). -# I have a KTM-2/80 still in working order. The KTM-2s had fully -# socketed parts, used 2 6507s, a 6532 as keyboard scanner, a program -# ROM and 2 ROMs as character generators. They were incredibly simple, -# and I've never had any problems with mine (witness the fact that mine -# was made in 1981 and is still working great... I've blown the video -# output transistor a couple of times, but it's a 2N2222 :-) -# -# The KTM-3 (which is what is listed in the terminfo file) was their -# attempt at putting a KTM-2 in a box (and some models came with a -# CRT). It wasn't much different from the KTM-2 hardware-wise, but the -# control and escape sequences are very different. The KTM-3 was always -# real broken, at least according to the folks I've talked to about it. -# -# The padding in the entry is probably off--these terminals were very -# slow (it takes like 100ms for the KTM-2 to clear the screen...) And -# anyone with any sanity replaced the ROMs with something that provided -# a reasonable subset of VT100 functionality, since the usual ROMs were -# obviously very primitive... oh, you could get an upgraded ROM from -# Synertek for some incredible amount of money, but what hacker with an -# EPROM burner would do that? :) -# -# Sorry I don't have any contact info; I believe they were located in -# Sunnyvale, and I'm fairly sure they are still manufacturing ICs -# (they've gone to ASICs and FPGAs), but I doubt they're in the computer -# business these days. -# - -# Tested, seems to work fine with vi. -synertek|ktm|synertek380|synertek ktm 3/80 tubeless terminal:\ - :am:\ - :co#80:li#24:\ - :cd=\EJ:ce=\EK:cl=^Z:cm=\E=%+ %+ :le=^H:nd=^L:up=^K: - -#### Tab Office Products -# -# TAB Products Co. - Palo Alto, California -# Electronic Office Products, -# 1451 California Avenue 94304 -# -# I think they're out of business. -# - -# The tab 132 uses xon/xoff, so no padding needed. -# :ks:/:ke: have nothing to do with arrow keys. -# :is: sets 80 col mode, normal video, autowrap on (for :am:). -# Seems to be no way to get rid of status line. -# The manual for this puppy was dated June 1981. It claims to be VT52- -# compatible but looks more vt100-like. -tab132|tab|tab132-15|tab 132/15:\ - :da:db:\ - :co#80:dN@:li#24:lm#96:\ - :al=\E[L:cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:do=^J:ei=\E[4l:\ - :im=\E[4h:is=\E[?7h\E[?3l\E[?5l:kd=\E[B:ke@:kl=\E[D:ks@:\ - :ku=\E[A:\ - :tc=vt100: -tab132-w|tab132 in wide mode:\ - :co#132:\ - :is=\E[?7h\E[?3h\E[?5l:tc=tab132: -tab132-rv|tab132 in reverse-video mode:\ - :is=\E[?7h\E[?3l\E[?5h:tc=tab132: -tab132-w-rv|tab132 in reverse-video/wide mode:\ - :is=\E[?7h\E[?3h\E[?5h:tc=tab132-w: - - -#### Teleray -# -# Research Incorporated -# 6425 Flying Cloud Drive -# Eden Prairie, MN 55344 -# Vox: (612)-941-3300 -# -# The Teleray terminals were all discontinued in 1992-93. RI still services -# and repairs these beasts, but no longer manufactures them. The Teleray -# people believe that all the types listed below are very rare now (1995). -# There was a newer line of Telerays (Model 7, Model 20, Model 30, and -# Model 100) that were ANSI-compatible. -# -# Note two things called "teleray". Reorder should move the common one -# to the front if you have either. A dumb teleray with the cursor stuck -# on the bottom and no obvious model number is probably a 3700. -# - -t3700|dumb teleray 3700:\ - :bs:\ - :co#80:li#24:\ - :bl=^G:cl=^L:cr=^M:do=^J:le=^H:sf=^J: -t3800|teleray 3800 series:\ - :bs:\ - :co#80:it#8:li#24:\ - :bl=^G:cd=\EJ:ce=\EK:cl=^L:cm=\EY%+ %+ :cr=^M:do=^J:ho=\EH:\ - :le=^H:ll=\EY7 :nd=\EC:sf=^J:ta=^I:up=^K: -t1061|teleray|teleray 1061:\ - :am:bs:km:xs:xt:\ - :co#80:it#8:li#24:sg#1:ug#1:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:cl=\014:cm=\EY%+ %+ :cr=^M:\ - :ct=\EG:dc=\EQ:dl=\EM:do=^J:ei=:ho=\EH:ic=\EP:im=:ip=:\ - :is=\Ee\EU01^Z1\EV\EU02^Z2\EV\EU03^Z3\EV\EU04^Z4\EV\EU05^Z5\EV\EU06^Z6\EV\EU07^Z7\EV\EU08^Z8\EV\Ef:\ - :k1=^Z1:k2=^Z2:k3=^Z3:k4=^Z4:k5=^Z5:k6=^Z6:k7=^Z7:k8=^Z8:\ - :le=^H:nd=\EC:se=\ER@:sf=^J:so= \ERD:st=\EF:ta=^I:ue=\ER@:\ - :up=\EA:us=\ERH: -t1061f|teleray 1061 with fast PROMs:\ - :al=\EL:dl=\EM:ip@:tc=t1061: -# "Teleray Arpa Special", officially designated as -# "Teleray Arpa network model 10" with "Special feature 720". -# This is the new (1981) fast microcode updating the older "arpa" proms -# (which gave meta-key and programmable-fxn keys). 720 is much much faster, -# converts the keypad to programmable function keys, and has other goodies. -# Standout mode is still broken (magic cookie, etc) so is suppressed as no -# programs handle such lossage properly. -# Note: this is NOT the old termcap's "t1061f with fast proms." -# From: J. Lepreau Tue Feb 1 06:39:37 1983, Univ of Utah -# (t10: removed overridden ":so@:se@:us@:ue@:" -- esr) -t10|teleray 10 special:\ - :bs:km:xs:xt:\ - :co#80:it#8:li#24:sg#2:ug#2:\ - :al=\EL:cd=\EJ:ce=\EK:cl=30\Ej:cm=\EY%+ %+ :dc=\EQ:dl=\EM:\ - :ei=:ho=\EH:ic=\EP:im=:le=^H:nd=\EC:pc=\200:se=\ER@:sf=\Eq:\ - :so=\ERD:sr=\Ep:ta=^I:ue=\ER@:up=\EA:us=\ERH: -# teleray 16 - map the arrow keys for vi/rogue, shifted to up/down page, and -# back/forth words. Put the function keys (f1-f10) where they can be -# found, and turn off the other magic keys along the top row, except -# for line/local. Do the magic appropriate to make the page shifts work. -# Also toggle ^S/^Q for those of us who use Emacs. -t16|teleray 16:\ - :am:da:db:mi:xs:xt:\ - :co#80:li#24:\ - :al=\E[L:bl=^G:cd=\E[0J:ce=\E[0K:cl=\E[H\E[2J:\ - :cm=%i\E[%d;%df:cr=^M:dc=\E[P:dl=\E[M:do=\E[B:ei=\E[4l:\ - :ho=\E[H:im=\E[4h:k1=^Z1:k2=^Z2:k3=^Z3:k4=^Z4:k5=^Z5:k6=^Z6:\ - :k7=^Z7:k8=^Z8:k9=^Z9:k;=^Z0:le=^H:me=\E[m:nd=\E[C:se=\E[m:\ - :sf=^J:so=\E[7m:sr=\E[T:ta=^I:te=\E[V\E[24;1f\E[?38h:\ - :ti=\E[U\E[?38l:ue=\E[m:up=\E[A:us=\E[4m: - -#### Texas Instruments (ti) -# - -# The Silent 700 was so called because it was built around a quiet thermal -# printer. It was portable, equipped with an acoustic coupler, and pretty -# neat for its day. -ti700|ti733|ti735|ti745|ti800|ti silent 700/733/735/745 or omni 800:\ - :bs:hc:os:\ - :co#80:\ - :bl=^G:cr=\r:do=^J:le=^H:sf=^J: - -# -# Texas Instruments 916 VDT 7 bit control mode -# -ti916|ti916-220-7|Texas Instruments 916 VDT 8859/1 vt220 mode 7 bit CTRL:\ - :da:db:in:ms:\ - :%9=^X:@4=\E[29~:@8=^J:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ - :DO=\E[%dB:F1=\E[29~:F2=\E[31~:IC=\E[%d@:LE=\E[%dD:\ - :RI=\E[%dC:UP=\E[%dA:ae=\E(B:as=\E(0:bt=\E[Z:cb=\E[1K:\ - :cd=\E[J:ce=\E[0K:ch=\E[%+^AG:cl=\E[H\E[2J:\ - :cm=\E[%i%d;%dH:ct=\E[3g:cv=\E[%+^Ad:dc=\E[P:eA=\E(B:\ - :ec=\E[%dX:ei=:ff=^L:im=:ip=:is=\E[1;24r\E[24;1H:k1=\E[17~:\ - :k2=\E[18~:k3=\E[19~:k4=\E[20~:k5=\E[21~:k6=\E[23~:\ - :k7=\E[24~:k8=\E[25~:k9=\E[26~:k;=\E[28~:kD=\E[P:kI=\E[@:\ - :kN=\E[S:kP=\E[T:kh=\E[H:mp=\E&:r2=\E[\041p:st=\E[0W:\ - :vb=\E[?5h\E[?5l:ve=\E[?25h:vi=\E[?25l:vs=\E[?25h:\ - :tc=vt220: -# -# Texas Instruments 916 VDT 8 bit control mode -# -ti916-8|ti916-220-8|Texas Instruments 916 VDT 8859/1 8 vt220 mode bit CTRL:\ - :%9=^X:@4=\23329~:@8=^J:F1=\23329~:F2=\23331~:k1=\23317~:\ - :k2=\23318~:k3=\23319~:k4=\23320~:k5=\23321~:k6=\23323~:\ - :k7=\23324~:k8=\23325~:k9=\23326~:k;=\23328~:kD=\233P:\ - :kI=\233@:kN=\233S:kP=\233T:kd=\233B:kh=\233H:kl=\233D:\ - :kr=\233C:ku=\233A:\ - :tc=ti916: -# -# Texas Instruments 916 VDT 8859/1 7 bit control 132 column mode -# -ti916-132|Texas Instruments 916 VDT vt220 132 column:\ - :co#132:tc=ti916: -# -# Texas Instruments 916 VDT 8859/1 8 bit control 132 column mode -# -ti916-8-132|Texas Instruments 916 VDT vt220 132 column:\ - :co#132:tc=ti916-8: -ti924|Texas Instruments 924 VDT 8859/1 7 bit CTRL:\ - :am:bs:xo:\ - :co#80:it#8:li#24:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[2J\E[H:\ - :cm=%i\E[%d;%dH:cr=^M:cs=%i\E[%d;%dr:ct=\E[3g:dl=\E[M:\ - :do=\E[B:ho=\E[H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[16~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kD=\E[P:kI=\E[@:\ - :kb=^H:kd=\E[B:kl=\E[D:kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:\ - :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[m:\ - :sf=\ED:so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:up=\E[A:\ - :us=\E[4m:ve=\E[?25h:vi=\E[?25l:vs=\E[?31h: -ti924-8|Texas Instruments 924 VDT 8859/1 8 bit CTRL:\ - :am:xo:\ - :co#80:it#8:li#24:\ - :al=\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[2J\E[H:\ - :cm=%i\E[%d;%dH:cr=^M:cs=%i\E[%d;%dr:ct=\E[3g:dl=\E[M:\ - :do=\E[B:ho=\E[H:k1=P\217>:k2=Q\217>:k3=R\217>:k4=S\217>:\ - :k5=~\23316>:k6=~\23317>:k7=~\23318>:k8=~\23319>:\ - :k9=~\23320>:kD=P\233>:kI=@\233>:kb=^H:kd=\E[B:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=\E[D:mb=\E[5m:md=\E[1m:me=\E[m:\ - :mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[7m:\ - :sr=\EM:st=\EH:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[?25h:\ - :vi=\E[?25l:vs=\E[?31h: -ti924w|Texas Instruments 924 VDT 7 bit - 132 column mode:\ - :co#132:tc=ti924: -ti924-8w|Texas Instruments 924 VDT 8 bit - 132 column mode:\ - :co#132:tc=ti924-8: -ti931|Texas Instruments 931 VDT:\ - :am:bs:xo:\ - :co#80:li#24:\ - :al=\EN:bl=^G:cd=\EJ:ce=\EI:cl=\EL:cm=\EY%+ %+ :cr=^M:\ - :dc=\EQ:dl=\EO:do=\EB:ei=:ho=\EH:ic=\ER\EP\EM:im=:\ - :is=\EGB\E(@B@@\E):k1=\Ei1:k2=\Ei2:k3=\Ei3:k4=\Ei4:\ - :k5=\Ei5:k6=\Ei6:k7=\Ei7:k8=\Ei8:k9=\Ei9:kA=\EN:kD=\EQ:\ - :kI=\EP:kL=\EO:kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=\ED:mb=\E4P:\ - :me=\E4@:mk=\E4H:mr=\E4B:nd=\EC:se=\E4@:sf=\Ea:so=\E4A:\ - :sr=\Eb:ue=\E4@:up=\EA:us=\E4D:ve=\E4@: -ti926|Texas Instruments 926 VDT 8859/1 7 bit CTRL:\ - :cs@:sf=\E[1S:sr=\E[1T:tc=ti924: -# (ti926-8: I corrected this from the broken SCO entry -- esr) -ti926-8|Texas Instruments 926 VDT 8859/1 8 bit CTRL:\ - :cs@:sf=\2331S:sr=\2331T:\ - :tc=ti924-8: -ti_ansi|basic entry for ti928:\ - :am:eo:ut:xn:xo:\ - :Co#8:co#80:it#8:li#25:pa#64:\ - :@7=\E[F:Sb=\E[4%dm:Sf=\E[3%dm:al=\E[L:bl=^G:bt=\E[Z:\ - :cd=\E[J:ce=\E[K:cl=\E[2J\E[H:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:dc=\E[P:dl=\E[M:do=\E[B:ei=:ho=\E[H:\ - :ic=\E[@:im=:k0=\E[V:k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:\ - :k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:k9=\E[U:kN=\E[G:kP=\E[I:\ - :kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\ - :mb=\E[5m:md=\E[1m:me=\E[m:nd=\E[C:op=\E[37;40m:se=\E[m:\ - :sf=\E[S:so=\E[7m:sr=\E[T:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -# -# 928 VDT 7 bit control mode -# -ti928|Texas Instruments 928 VDT 8859/1 7 bit CTRL:\ - :%9=\E[35~:@7=\E_1\E\:@8=\E[8~:F1=\E[29~:F2=\E[31~:\ - :F3=\E[32~:F5=\E[34~:k1=\E[17~:k2=\E[18~:k3=\E[19~:\ - :k4=\E[20~:k5=\E[21~:k6=\E[23~:k7=\E[24~:k8=\E[25~:\ - :k9=\E[26~:k;=\E[28~:kD=\E[P:kI=\E[@:kN=\E[S:kP=\E[T:\ - :tc=ti_ansi: -# -# 928 VDT 8 bit control mode -# -ti928-8|Texas Instruments 928 VDT 8859/1 8 bit CTRL:\ - :%9=\23335~:@7=\2371\234:@8=\2338~:F1=\23329~:F2=\23331~:\ - :F3=\23332~:F5=\23334~:k1=\23317~:k2=\23318~:k3=\23319~:\ - :k4=\23320~:k5=\23321~:k6=\23323~:k7=\23324~:k8=\23325~:\ - :k9=\23326~:k;=\23328~:kD=\233P:kI=\233@:kN=\233S:\ - :kP=\233T:kh=\233H:\ - :tc=ti_ansi: - -#### Zentec (zen) -# - -# (zen30: removed obsolete :ma=^L ^R^L^K^P:. This entry originally -# had just :so:=\EG6 which I think means standout was supposed to be -# dim-reverse using ADM12-style attributes. ADM12 :us:/:ue: and -# might work-- esr) -zen30|z30|zentec 30:\ - :am:bs:mi:ul:\ - :co#80:li#24:\ - :al=\EE:bl=^G:cd=\EY:ce=\ET:cl=\E*:cm=\E=%+ %+ :cr=^M:\ - :dc=\EW:dl=\ER:do=^J:ei=\Er:ho=^^:im=\Eq:le=^H:mh=\EG2:nd=^L:\ - :sf=^J:so=\EG6:ue@:up=^K:us@:\ - :tc=adm+sgr: -# (zen50: this had extension capabilities -# :BS=^U:CL=^V:CR=^B: -# UK/DK/RK/LK/HM were someone's aliases for ku/kd/kl/kr/kh, -# which were also in the original entry -- esr) -# (zen50: removed obsolete ":ma=^Hh^Ll^Jj^Kk:" -- esr) -zen50|z50|zentec zephyr:\ - :am:bs:\ - :co#80:li#24:sg#1:\ - :al=\EE:cd=\EY:ce=\ET:cl=\E+:cm=\E=%+ %+ :dc=\EW:dl=\ER:ei=:\ - :ic=\EQ:im=:kd=^J:kh=^^:kl=^H:kr=^L:ku=^K:le=^H:mk@:ue@:up=^K:\ - :us@:\ - :tc=adm+sgr: - -# CCI 4574 (Office Power) from Will Martin via BRL -cci|cci1|z8001|zen8001|CCI Custom Zentec 8001:\ - :am:bs:bw:\ - :co#80:li#24:\ - :cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cs=\ER%+ %+ :do=^J:\ - :ho=\EH:is=\EM \EF\ET\EP\ER 7:kb=^H:kd=\EB:kh=\EH:kl=\ED:\ - :kr=\EC:ku=\EA:le=^H:mb=\EM":me=\EM :mh=\EM\041:mk=\EM(:\ - :mr=\EM$:nd=\EC:pf=^T:po=^R:se=\EM :so=\EM$:sr=\EI:ue=\EM :\ - :up=\EA:us=\EM0:ve=\EP:vs=\EF\EQ\EM \ER 7: - -######## OBSOLETE UNIX CONSOLES -# - -#### Apollo consoles -# -# Apollo got bought by Hewlett-Packard. The Apollo workstations are -# labeled HP700s now. -# - -# From: Gary Darland -apollo|apollo console:\ - :am:bs:mi:\ - :co#88:li#53:\ - :al=\EI:cd=\EJ:ce=\EK:ch=\EN%d:cl=^L:cm=\EM%+ %d):cv=\EO+ :\ - :dc=\EP:dl=\EL:do=\EB:ei=\ER:im=\EQ:le=^H:nd=\EC:se=\ET:\ - :sf=\EE:so=\ES:sr=\ED:te=\EX:ti=\EW:ue=\EV:up=\EA:us=\EU: - -# We don't know whether or not the apollo guys replicated DEC's firmware bug -# in the VT132 that reversed :ei:/:im:. To be on the safe side, disable -# both these capabilities. -apollo_15P|apollo 15 inch display:\ - :ei@:im@:tc=vt132: -apollo_19L|apollo 19 inch display:\ - :ei@:im@:tc=vt132: -apollo_color|apollo color display:\ - :ei@:im@:tc=vt132: - -#### Convergent Technology -# -# Burroughs bought Convergent shortly before it merged with Univac. -# CTOS is (I believe) dead. Probably the aws is too (this entry dates -# from 1991 or earlier). -# - -# Convergent AWS workstation from Gould/SEL UTX/32 via BRL -# (aws: removed unknown :dn=^K: -- esr) -aws|Convergent Technologies AWS workstation under UTX,Xenix:\ - :am:\ - :co#80:li#28:sg#0:ug#0:\ - :ac=:ae=\EAAF:al=\EIL:as=\EAAN:bc=^H:cd=\EEF:ce=\EEL:\ - :ch=\EH%.:cl=^L:cm=\EC%r%.%.:cv=\EV%.:dc=\EDC:dl=\EDL:\ - :do=^K:ei=:ic=\EIC:im=:kb=^H:kd=^K:kl=^N:kr=^R:ku=^A:\ - :ma=\016h\013j\001k\022l\002m:nd=^R:nl=^J:se=\EARF:\ - :sf=\ESU:so=\EARN:sr=\ESD:ue=\EAUF:up=^A:us=\EAUN: -awsc|Convergent Technologies AWS workstation under CTOS:\ - :am:\ - :co#80:li#24:sg#0:ug#0:\ - :ac=:ae=\EAAF:as=\EAAN:bc=^N:cd=\EEF:ce=\EEL:cl=^L:\ - :cm=\EC%r%.%.:do=^K:kb=^H:kd=^K:kl=^N:kr=^R:ku=^A:\ - :ma=\016h\013j\001k\022l\002m:nd=^R:se=\EAA:so=\EAE:\ - :ue=\EAA:up=^A:us=\EAC: - -#### DEC consoles -# - -# The MicroVax console. Tim Theisen writes: -# The digital uVax II's had a graphic display called a qdss. It was -# supposed to be a high performance graphic accelerator, but it was -# late to market and barely appeared before faster dumb frame buffers -# appeared. I have only used this display while running X11. However, -# during bootup, it was in text mode, and probably had a terminal emulator -# within it. And that is what your termcap entry is for. In graphics -# mode the screen size is 1024x864 pixels. -qdss|qdcons|qdss glass tty:\ - :am:bs:\ - :co#128:li#57:\ - :cl=1\032:cm=\E=%.%.:do=^J:le=^H:nd=^L:up=^K: - -#### Fortune Systems consoles -# -# Fortune made a line of 68K-based UNIX boxes that were pretty nifty -# in their day; I (esr) used one myself for a year or so around 1984. -# They had no graphics, though, and couldn't compete against Suns and -# the like. R.I.P. -# - -# From: Robert Nathanson via tut Wed Oct 5, 1983 -# (This had extension capabilities -# :rv=\EH:re=\EI:rg=0:GG=0:\ -# :CO=\E\\:WL=^Aa\r:WR=^Ab\r:CL=^Ac\r:CR=^Ad\r:DL=^Ae\r:RF=^Af\r:\ -# :RC=^Ag\r:CW=^Ah\r:NU=^Aj\r:EN=^Ak\r:HM=^Al:PL=^Am\r:\ -# :PU=^An\r:PD=^Ao\r:PR=^Ap\r:HP=^A@\r:RT=^Aq\r:TB=\r:CN=\177:MP=\E+F: -# It had both ":bs:" and ":bs=^H:"; I removed the latter. Also, it had -# ":sg=0:" and ":ug=0:"; evidently the composer was trying (unnecessarily) -# to force both magic cookie glitches off. Once upon a time, I -# used a Fortune myself, so I know the capabilities of the form ^A[a-z]\r are -# function keys; thus the "Al" value for HM was certainly an error. I renamed -# EN/PD/PU/CO/CF/RT according to the XENIX/TC mappings, but not HM/DL/RF/RC. -# I think :rv: and :re: are start/end reverse video and :rg: is a nonexistent -# "reverse-video-glitch" capability; I have put :rv: and :re: in with standard -# names below. I've removed obsolete ":nl=5^J:" as there is a :do: -- esr) -fos|fortune|Fortune system:\ - :am:bs:bw:\ - :co#80:li#25:\ - :@7=^Ak\r:@8=^Aq:ac=l m"k(j*v%w#q&x-:ae=^O:al=\034E:\ - :as=\Eo:bl=^G:cd=\034Y:ce=^\Z:cl=\014:cm=\034C%+ %+ :cr=^M:\ - :dc=\034W:dl=\034R:do=\n:ei=:ho=\036:ic=\034Q:im=:is=^_..:\ - :k1=^Aa\r:k2=^Ab\r:k3=^Ac\r:k4=^Ad\r:k5=^Ae\r:k6=^Af\r:\ - :k7=^Ag\r:k8=^Ah\r:kN=^Ao\r:kP=^An\r:kb=^H:kd=^Ay\r:\ - :kh=^A?\r:kl=^Aw\r:kr=^Az\r:ku=^Ax\r:le=^H:mb=\EN:me=\EI:\ - :mr=\EH:nw=^M^J:se=^\I`:sf=^J:so=^\H`:ta=^Z:ue=^\IP:up=\013:\ - :us=^\HP:ve=\E\:vi=\E]:vs=\E\072: - -#### Masscomp consoles -# -# Masscomp has gone out of business. Their product line was purchased by -# comany in Georgia (US) called "XS International", parts and service may -# still be available through them. -# - -# (masscomp: ":MT:" changed to ":km:"; -- esr) -masscomp|masscomp workstation console:\ - :bs:km:mi:\ - :co#80:it#8:li#24:\ - :al=\E[L:cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:dc=\E[P:\ - :dl=\E[M:do=\E[B:ei=\E[4l:im=\E[4h:is=\EGc\EGb\EGw:kb=^H:\ - :kd=\EOB:kl=\EOD:kr=\EOC:ku=\EOA:le=^H:nd=\E[C:se=\E[m:\ - :so=\E[7m:ta=^I:ue=\EGau:up=\E[A:us=\EGu: -masscomp1|masscomp large screen version 1:\ - :co#104:li#36:tc=masscomp: -masscomp2|masscomp large screen version 2:\ - :co#64:li#21:tc=masscomp: - -######## OTHER OBSOLETE TYPES -# -# These terminals are *long* dead -- these entries are retained for -# historical interest only. -# - -#### Obsolete non-ANSI software emulations -# - -# CTRM terminal emulator -# 1. underlining is not allowed with colors: first, is is simulated by -# black on white, second, it disables background color manipulations. -# 2. BLINKING, REVERSE and BOLD are allowed with colors, -# so we have to save their status in the static registers A, B and H -# respectively, to be able to restore them when color changes -# (because any color change turns off ALL attributes) -# 3. :md: and :mr: sequences alternate modes, -# rather than simply entering them. Thus we have to check the -# static register B and H to determine the status, before sending the -# escape sequence. -# 4. :me: now must set the status of all 3 register (A,B,H) to zero -# and then reset colors -# 5. implementation of the protect mode would badly penalize the performance. -# we would have to use \E&bn sequence to turn off colors (as well as all -# other attributes), and keep the status of protect mode in yet another -# static variable. If someone really needs this mode, they would have to -# create another terminfo entry. -# 6. original color-pair is white on black. -# store the information about colors into static registers -# 7. set foreground color. it performs the following steps. -# 1) turn off all attributes -# 2) turn on the background and video attributes that have been turned -# on before (this information is stored in static registers X,Y,Z,A,B,H,D). -# 3) turn on foreground attributes -# 4) store information about foreground into U,V,W static registers -# 8. turn on background: similar to turn on foreground above -# (untranslatable capabilities removed to fit entry within 1023 bytes) -ctrm|C terminal emulator:\ - :am:ut:xo:\ - :Co#8:NC#2:Nl#0:co#80:lh#0:li#24:lm#0:lw#0:pa#63:pb#19200:vt#6:\ - :al=\EL:bl=^G:bt=\Ei:cd=\EJ:ce=\EK:ch=\E&a%dC:cl=\EH\EJ:\ - :cm=\E&a%r%dc%dY:cr=^M:ct=\E3:cv=\E&a%dY:dc=\EP:dl=\EM:\ - :do=^J:ei=\ER:im=\EQ:ip=:is=\E&jA\r:k1=\Ep\r:k2=\Eq\r:\ - :k3=\Er\r:k4=\Es\r:k5=\Et\r:k6=\Eu\r:k7=\Ev\r:k8=\Ew\r:\ - :kb=^H:kd=\Ew\r:ke=\E&jA:kh=\Ep\r:kl=\Eu\r:kr=\Ev\r:\ - :ks=\E&jB:ku=\Et\r:le=^H:mb=\E&dA%{1}%PA:\ - :md=%?%gH%{0}%=%t\E&dH%{1}%PH%;:\ - :me=\E&d@%{0}%PA%{0}%PB%{0}%PH:\ - :mr=%?%gB%{0}%=%t\E&dB%{1}%PB%;:nd=\EC:\ - :op=\E&bn\E&bB\E&bG\E&bR\n%{0}%PX%{0}%PY%{0}%PZ\n%{1}%PW%{1}%PV%{1}%PU:\ - :sf=^J:so=\E&dD:st=\E1:ta=\011:up=\EA:us=\E&dD: - -# gs6300 - can't use blue foreground, it clashes with underline; -# it's simulated with cyan -# Bug: The capability probably resets attributes. -# (gs6300: commented out (no ) --esr) -gs6300|emots|AT&T PC6300 with EMOTS terminal emulator:\ - :am:ms:ut:xo:\ - :Co#8:co#80:it#8:li#24:pa#63:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ - :LE=\E[%dD:RI=\E[%dC:Sb=\E[?;%dm:\ - :UP=\E[%dA:\ - :ac=\054\054..--++``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E[10m:al=\E[L:as=\E[11m:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:dc=\E[P:dl=\E[M:do=^J:\ - :ei=:ho=\E[H:ic=\E[@:im=:is=\E[m:k1=\E[0s:k2=\E[24s:\ - :k3=\E[1s:k4=\E[23s:k5=\E[2s:k6=\E[22s:k7=\E[3s:k8=\E[21s:\ - :kB=^R^I:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:\ - :le=^H:mb=\E[5m:md=\E[1m:me=\E[m\E[10m:mr=\E[7m:nd=\E[C:\ - :op=\E[?;m:pf=\E[4i:po=\E[5i:r1=\Ec:sf=^J:so=\E[1m:sr=\E[L:\ - :ta=^I:up=\E[A:us=\E[4m: - -# From: 29 Oct 85 05:40:18 GMT -# MS-Kermit with Heath-19 emulation mode enabled -# (h19k: changed ":pt@:" to ":it@" -h19k|h19kermit|heathkit emulation provided by Kermit (no auto margin):\ - :am@:da:db:xt:\ - :it@:\ - :ta@:tc=h19-u: - -# Apple Macintosh with Versaterm, a terminal emulator distributed by Synergy -# Software (formerly Peripherals Computers & Supplies, Inc) of -# 2457 Perkiomen Ave., Reading, PA 19606, 1-800-876-8376. They can -# also be reached at support@synergy.com. -versaterm|versaterm vt100 emulator for the macintosh:\ - :am:xn:\ - :co#80:it#8:li#24:\ - :al=9\E[1L:bl=^G:cd=50\E[J:ce=3\E[K:cl=50\E[;H\E[2J:\ - :cm=5\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=7\E[1P:\ - :dl=9\E[1M:do=^J:ei=:ho=\E[H:ic=7\E[1@:im=:\ - :is=\E[1;24r\E[24;1H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ - :kb=^H:kd=\EOB:ke=\E>\E[?1l:kl=\EOD:kr=\EOC:ks=\E=\E[?1h:\ - :ku=\EOA:le=^H:mb=2\E[5m:md=2\E[1m:me=2\E[m:mr=2\E[7m:\ - :nd=2\E[C:nw=^M^J:r1=\E>:rc=\E8:\ - :rf=/usr/share/tabset/vt100:sc=\E7:se=2\E[m:so=2\E[7m:\ - :sr=5\EM:ta=^I:ue=2\E[m:up=2\E[A:us=2\E[4m: - -# From: Rick Thomas -# (xtalk: I added / based on the init string. -# I also removed :sg#1: and the trailing \s characters from the highlight -# changers, I don't believe these on a VT100-emulating PC display -- esr) -xtalk|IBM PC with xtalk communication program (versions up to 3.4):\ - :am:mi:ms:xo:\ - :co#80:it#8:li#24:vt#3:\ - :@8=\EOM:DO=\E[%dB:K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:\ - :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ - :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:ct=\E[3g:dl=\E[M:do=^J:\ - :eA=\E(B:ho=\E[H:k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:\ - :kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:\ - :ku=\EOA:le=^H:me=\E[m:nd=\E[C:\ - :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:se=\E[m:sf=^J:\ - :so=\E[7m:sr=\EM:st=\EH:ta=^I:up=\E[A: - -# The official PC terminal emulator program of the AT&T Product Centers. -# Note - insert mode commented out - doesn't seem to work on AT&T PC. -simterm|attpc running simterm:\ - :am:\ - :co#80:li#24:\ - :al=\EL:bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\E=%+ %+ :cr=^M:\ - :dc=\ER:dl=\EM:do=\EB:ho=\EH:le=^H:me=\E&d@:nd=\EC:se=\E&d@:\ - :sf=^J:so=\E&dB:te=\EVE:ti=\EVS:up=\EA: - -#### Daisy wheel printers -# -# This section collects Diablo, DTC, Xerox, Qume, and other daisy -# wheel terminals. These are now largely obsolete. -# - -# (diablo1620: removed :if=/usr/share/tabset/xerox1720:, no such file -- esr) -diablo1620|diablo1720|diablo450|ipsi|diablo 1620:\ - :bs:hc:os:\ - :co#132:it#8:\ - :ch=\E\011%i%.:ct=\E2:do=^J:hd=\ED:hu=\EU:kb=^H:le=^H:\ - :st=\E1:ta=^I:up=\E^J: -diablo1620-m8|diablo1640-m8|diablo 1620 w/8 column left margin:\ - :co#124:\ - :is=\r \E9:tc=diablo1620: -# (diablo1640: removed :if=/usr/share/tabset/xerox1730:, no such file -- esr) -diablo1640|diablo1730|diablo1740|diablo630|x1700|diablo|xerox|diablo 1640:\ - :bl=^G:se=\E&:so=\EW:ue=\ER:us=\EE:\ - :tc=diablo1620: -# (diablo1640-lm: removed :if=/usr/share/tabset/xerox1730-lm:, no such -# file -- esr) -diablo1640-lm|diablo-lm|xerox-lm|diablo 1640 with indented left margin:\ - :co#124:\ - :se=\E&:so=\EW:ue=\ER:us=\EE:tc=diablo1620: -diablo1740-lm|630-lm|1730-lm|x1700-lm|diablo 1740 printer:\ - :tc=diablo1640-lm: -# DTC 382 with VDU. Has no :cd: so we fake it with :ce:. Standout -# :so=^P\s\002^PF: works but won't go away without dynamite :se=^P\s\200:. -# The terminal has tabs, but I'm getting tired of fighting the braindamage. -# If no tab is set or the terminal's in a bad mood, it glitches the screen -# around all of memory. Note that return puts a blank ("a return character") -# in the space the cursor was at, so we use ^P return (and thus ^P newline for -# newline). Note also that if you turn off :pt: and let Unix expand tabs, -# curses won't work (some old BSD versions) because it doesn't clear this bit, -# and cursor addressing sends a tab for row/column 9. What a losing terminal! -# I have been unable to get tabs set in all 96 lines - it always leaves at -# least one line with no tabs in it, and once you tab through that line, -# it completely weirds out. -# (dtc382: change :te: to :ti: -- it just does a clear --esr) -dtc382|DTC 382:\ - :am:bs:da:db:xs:\ - :co#80:li#24:lm#96:\ - :al=^P^Z:bl=^G:cd=\020\025\020\023\020\023:ce=^P^U:\ - :cl=\020\035:cm=\020\021%r%.%.:cr=^P^M:dc=^X:dl=^P^S:\ - :ei=^Pi:ho=^P^R:im=^PI:le=^H:nd=^PR:pc=\177:sf=^J:te=:\ - :ti=\020\035:ue=^P \200:up=^P^L:us=^P ^P:ve=^Pb:vs=^PB: -dtc300s|DTC 300s:\ - :bs:hc:os:\ - :co#132:\ - :bl=^G:cr=^M:ct=\E3:do=^J:ff=^L:hd=\Eh:hu=\EH:kb=^H:le=^H:\ - :sf=^J:st=\E1:ta=^I:up=^Z: -gsi|mystery gsi terminal:\ - :bs:hc:os:\ - :co#132:\ - :bl=^G:cr=^M:do=^J:hd=\Eh:hu=\EH:le=^H:sf=^J:ta=^I:up=^Z: -aj830|aj832|aj|anderson jacobson:\ - :bs:hc:os:\ - :bl=^G:cr=^M:do=^J:hd=\E9:hu=\E8:le=^H:sf=^J:up=\E7: -# From: Chris Torek Thu, 7 Nov 85 18:21:58 EST -aj510|Anderson-Jacobson model 510:\ - :am:bs:mi:\ - :co#80:li#24:\ - :al=2*\E&I:cd=\E'P:ce=\E'L:cl=^L:cm=\E#%+ %+ :dc=.1*\E'D:\ - :dl=2*\E&D:ei=\E'J:ic=:im=\E'I:ip=.1*:kd=\EZ:kl=\EW:kr=\EX:\ - :ku=\EY:le=^H:nd=\EX:pc=\177:se=\E"I:so=\E"I:te=\E"N:\ - :ti=\E"N:ue=\E"U:up=\EY:us=\E"U: -# From: Thu Aug 20 09:09:18 1981 -# This is incomplete, but it's a start. -nec5520|nec|spinwriter|nec 5520:\ - :bs:hc:os:\ - :co#132:it#8:\ - :bl=^G:cr=^M:ct=\E3:do=^J:ff=^L:hd=\E]s\n\E]W:\ - :hu=\E]s\E9\E]W:kb=^H:le=^H:sf=^J:st=\E1:ta=^I:up=\E9: -qume5|qume|Qume Sprint 5:\ - :bs:hc:os:\ - :co#80:it#8:\ - :bl=^G:cr=^M:ct=\E3:do=^J:ff=^L:hd=\Eh:hu=\EH:kb=^H:le=^H:\ - :sf=^J:st=\E1:ta=^I:up=^Z: -# I suspect the xerox 1720 is the same as the diablo 1620. -xerox1720|x1720|x1750|xerox 1720:\ - :bs:hc:os:\ - :co#132:it#8:\ - :bl=^G:cr=^M:ct=\E2:do=^J:ff=^L:le=^H:sf=^J:st=\E1:ta=^I: - -#### Miscellaneous obsolete terminals, manufacturers unknown -# -# If you have any information about these (like, a manufacturer's name, -# and a date on the serial-number plate) please send it! - -cad68-3|cgc3|cad68 basic monitor transparent mode size 3 chars:\ - :am:bs:\ - :co#73:li#36:\ - :cl=^Z:ho=^^:le=^H:nd=^L:up=^K: -cad68-2|cgc2|cad68 basic monitor transparent mode size 2 chars:\ - :am:bs:\ - :co#85:li#39:\ - :cl=^Z:ho=^^:k1=\E5:k2=\E6:k3=\E7:k4=\E8:kd=\E2:kl=\E3:\ - :kr=\E4:ku=\E1:le=^H:nd=^L:se=\Em^C:so=\Em^L:up=^K: -cops10|cops|cops-10|cops 10:\ - :am:bw:\ - :co#80:li#24:\ - :bl=^G:cd=^W:ce=^V:cl=30\030:cm=\020%+ %+ :cr=^M:do=^J:\ - :kb=^H:kd=^J:kh=^Y:kl=^H:kr=^L:ku=^K:le=^H:nd=^L:sf=^J:up=^K: -# (d132: removed duplicate :ic=\E5:, -# merged in capabilities from a BRL entry -- esr) -d132|datagraphix|datagraphix 132a:\ - :da:db:in:\ - :co#80:li#30:\ - :al=\E3:bl=^G:cl=^L:cm=\E8%i%3%3:cr=^M:dc=\E6:do=^J:ei=:\ - :ho=\ET:ic=\E5:im=:kb=^H:kd=^J:kl=^H:le=^H:nd=\EL:nw=^M^J:\ - :sf=^J:sr=\Ew:ta=^I:up=\EK:ve=\Em\En:vs=\Ex: -# The d800 was an early portable terminal from c.1984-85 that looked a lot -# like the original Compaq `lunchbox' portable (but no handle). It had a vt220 -# mode (which is what this entry looks like) and several other lesser-known -# emulations. -d800|Direct 800/A:\ - :am:bs:da:db:ms:xs:\ - :co#80:it#8:li#24:\ - :ac=``a1fxgqh0jYk?lZm@nEooppqDrrsstCu4vAwBx3yyzz{{||}}~~:\ - :ae=\E[m:as=\E[1m:bl=^G:cd=\E[J:ce=\E[K:cl=\E[1;1H\E[2J:\ - :cm=\E[%i%d;%dH:cr=^M:do=^J:k1=\EOP:k2=\EOQ:k3=\EOR:\ - :k4=\EOS:k5=\EOT:k6=\EOU:k7=\EOV:k8=\EOW:kd=\E[B:kl=\E[D:\ - :kr=\E[C:ku=\E[A:le=^H:me=\E[m:nd=\E[C:se=\E[m:sf=\ED:\ - :so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:ve=\E[>12h:\ - :vs=\E[>12l: -digilog|digilog 333:\ - :bs:\ - :co#80:li#16:\ - :bl=^G:ce=^X:cr=^M:do=^J:ho=^N:le=^H:nd=^I:sf=^J:up=^O: -# The DWK was a terminal manufactured in the Soviet Union c.1986 -dwk|dwk-vt|dwk terminal:\ - :am:\ - :co#80:it#8:li#24:\ - :ac=lJmFkCjXtEuPv\\wKqUxWnNo~s_`+a\072f'g#~_\\054Q+\136.M-Sh#I#0\177:\ - :ae=\EG:as=\EF:bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :\ - :cr=^M:dc=\EP:do=^J:ei=:ho=\EH:ic=\EQ:im=:k1=\Ef1:k2=\Ef2:\ - :k3=\Ef3:k4=\Ef4:k5=\Ef5:k6=\Ef6:k7=\Ef7:k8=\Ef8:k9=\Ef9:\ - :k;=\Ef0:kD=\Ee:kI=\Ed:kN=\Eh:kP=\Eg:kb=\177:kd=\EB:kl=\ED:\ - :kr=\EC:ku=\EA:le=^H:me=\EX:mr=\ET:nd=\EC:nw=^M^J:se=\EX:\ - :sf=^J:so=\ET:sr=\ES:ta=^I:up=\EA: -env230|envision230|envision 230 graphics terminal:\ - :xn@:\ - :pf=\E[4i:po=\E[5i:ps=\E[0i:\ - :tc=vt100: -# These execuports were impact-printer ttys with a 30- or maybe 15-cps acoustic -# coupler attached, the whole rig fitting in a suitcase and more or less -# portable. Hot stuff for c.1977 :-) -- esr -ep48|ep4080|execuport 4080:\ - :am:bs:os:\ - :co#80:\ - :bl=^G:cr=^M:do=^J:hd=^\:hu=^^:le=^H:sf=^J: -ep40|ep4000|execuport 4000:\ - :co#136:tc=ep4080: -# Adam Thompson tells us: -# Informer series - these are all portable units, resembling older -# automatic bread-baking machines. The terminal looks like a `clamshell' -# design, but isn't. The structure is similar to the Direct terminals, -# but only half the width. The entire unit is only about 10" wide. -# It features an 8" screen (6" or 7" if you have color!), and an 9"x6" -# keyboard. All the keys are crammed together, much like some laptop -# PCs today, but perhaps less well organized...all these units have a -# bewildering array of plugs on the back, including a built-in modem. -# The 305 was a color version of the 304; the 306 and 307 were mono and -# color terminals built for IBM bisync protocols. -# From: Paul Leondis -ifmr|Informer D304:\ - :am:bs:\ - :co#80:li#24:\ - :cd=\E/:ce=\EQ:cl=\EZ:cm=\EY%r%+ %+ :dc=\E\:do=^J:ei=:\ - :ho=\EH:ic=\E[:im=:le=^H:me=\EK:nd=\EC:se=\EK:so=\EJ:sr=\En:\ - :up=\EA: -# Entry largely based on wy60 and has the features of wy60ak. -# (untranslatable capabilities removed to fit entry within 1023 bytes) -# (sgr removed to fit entry within 1023 bytes) -# (terminfo-only capabilities suppressed to fit entry within 1023 bytes) -opus3n1+|Esprit Opus3n1+ in wy60 mode with ANSI arrow keys:\ - :am:bw:hs:km:mi:ms:ul:xo:\ - :co#80:li#24:ws#80:\ - :ae=\EH^C:al=\EE:as=\EH^B:bl=^G:bt=\EI:cd=\EY:ce=\ET:cl=\E*:\ - :cm=\Ea%i%dR%dC:cr=^M:ct=\E0:dc=\EW:dl=\ER:do=^J:ds=\Ez(\r:\ - :ei=\Er:fs=^M:ho=\036:if=/usr/share/tabset/std:im=\Eq:ip=:\ - :is=\E`\072\Ee(\EO\Ee6\Ec41\E~4\Ec21\Ed/\Ezz&\E[A\177\Ezz'\E[B\177\Ezz(\E[D\177\Ezz)\E[C\177\Ezz<\E[Q\177\Ezz`\E[F\177\EA1*\EZH12:\ - :k1=^A@\r:k2=^AA\r:k3=^AB\r:k4=^AC\r:k5=^AD\r:k6=^AE\r:\ - :k7=^AF\r:k8=^AG\r:k9=^AH\r:kD=\EW:kI=\EQ:kN=\EK:kP=\EJ:\ - :kb=^H:kd=\E[B:kh=^^:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\EG2:\ - :me=\E(\EH\003\EG0\EcD:mh=\EGp:nd=^L:nw=\r\n:sf=^J:sr=\Ej:\ - :st=\E1:ta=\011:te=:\ - :ti=\Ezz&\E[A\177\Ezz'\E[B\177\Ezz(\E[D\177\Ezz)\E[C\177\Ezz<\E[Q\177:\ - :ts=\Ez(:uc=\EG8%p1%c\EG0:up=^K:ve=\E`1:vi=\E`0:\ - :tc=adm+sgr: -teletec|Teletec Datascreen:\ - :am:bs:\ - :co#80:li#24:\ - :bl=^G:cl=^L:cr=^M:do=^J:ho=^^:le=^H:nd=^_:sf=^J:up=^K: -# From: Mark Dornfeld -# This termcap is for the LANPAR Technologies VISION 3220 -# terminal. The function key definitions k0-k5 represent the -# edit keypad: FIND, INSERT HERE, REMOVE, SELECT, PREV SCREEN, -# NEXT SCREEN. The key definitions k6-k9 represent the PF1 to -# PF4 keys. -# (v3220: removed obsolete ":kn#10:", -# I added / based on the init string -- esr) -v3220|LANPAR Vision II model 3220/3221/3222:\ - :am:bs:mi:xn:\ - :co#80:it#8:li#24:\ - :RA=\E[?7l:SA=\E[?7h:al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ - :cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:ei=\E[4l:im=\E[4h:\ - :is=\E>\E[?3l\E[?7h\E[?8h\E[p:k0=\E[1~:k1=\E[2~:\ - :k2=\E[3~:k3=\E[4~:k4=\E[5~:k5=\E[6~:k6=\E[OP:k7=\E[OQ:\ - :k8=\E[OR:k9=\E[OS:kd=\E[B:ke=\E>:kh=\E[H:kl=\E[D:kr=\E[C:\ - :ks=\E=:ku=\E[A:le=^H:me=\E[m:nd=\E[C:se=\E[m:so=\E[7m:\ - :sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m: -# `rasterconsole' provided by 4.4BSD, NetBSD and OpenBSD on SPARC, and -# DECstation/pmax. -rcons|BSD rasterconsole:\ - :tc=sun-il: -# Color version of above. Color currenly only provided by NetBSD. -rcons-color|BSD rasterconsole with ANSI color:\ - :AF=\E[3%dm:AB=\E[4%dm:Co#8:pa#64:op=\E[m:ut:tc=rcons: - -# bebox -- an ansi style termcap entry without all the tc= fields which -# gnu termcap doesn't grok properly. -beterm|ANSI BeOS Terminal:\ - :am:eo:mi:ms:xn:xo:\ - :Co#8:co#80:it#8:li#25:pa#64:\ - :&7=^Z:@7=\E[4~:AB=\E[4%dm:AF=\E[3%dm:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:F1=\E[21~:F2=\E[22~:\ - :IC=\E[%d@:\ - :K2=\E[G:Sb=\E[%+(m:Sf=\E[%+^^m:\ - :al=\E[L::bl=^G:cd=\E[J:ce=\E[K:\ - :ch=\E[%i%dG:cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:\ - :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ - :do=^J:ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:k1=\E[11~:\ - :k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:k6=\E[16~:\ - :k7=\E[17~:k8=\E[18~:k9=\E[19~:k;=\E[20~:\ - :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^h:kd=\E[B:\ - :kh=\E[1~:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:mb=\E[5m:\ - :md=\E[1m:me=\E[0;10m:mh=\E[2m:mk=\E[8m:mr=\E[7m:\ - :nd=\E[C:nw=^M^J:op=\E[m:r1=\Ec:rc=\E8:\ - :sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ - :u6=\E[%i%d;%dR:u7=\E[6n:u8=\E[?6c:u9=\E[c:ue=\E[24m:\ - :up=\E[A:us=\E[4m:vb=200\E[?5h\E[?5l:ve=\E[?25h:\ - :vi=\E[?25l: -# mgterm -- MGL/MGL2, MobileGear Graphic Library -# for PocketBSD,PocketLinux,NetBSD/{hpcmips,mac68k} -mgterm:\ - :al=\E[L:am:bs:NP:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:co#80:\ - :dc=\E[P:dl=\E[M:do=\E[B:bt=\E[Z:ho=\E[H:ic=\E[@:li#18:cb=\E[1K:\ - :ms:nd=\E[C:pt:rs=\E[x\E[m\Ec:so=\E[7m:se=\E[m:up=\E[A:\ - :pa#64:Co#8:Sf=\E[3%dm:Sb=\E[4%dm:op=\E[x:\ - :k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:\ - :k9=\E[U:k;=\E[V:F1=\E[W:F2=\E[X:K2=\E[E:nw=\E[E:ec=\E[%dX:\ - :kb=^H:kh=\E[H:ku=\E[A:kd=\E[B:kl=\E[D:kr=\E[C:le=^H:eo:\ - :sf=\E[S:sr=\E[T:\ - :kN=\E[G:kP=\E[I:@7=\E[F:kI=\E[L:kD=\177:kB=\E[Z:\ - :IC=\E[%d@:DC=\E[%dP:SF=\E[%dS:SR=\E[%dT:AL=\E[%dL:DL=\E[%dM:\ - :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:cv=\E[%i%dd:ch=\E[%i%d`:bw:\ - :mb=\E[5m:md=\E[1m:mh=\E[30;1m:mr=\E[7m:me=\E[m:bl=^G:ut:it#8:km:\ - :sc=\E7:rc=\E8:cs=\E[%i%d;%dr: - -######## ICH/ICH1 VERSUS RMIR/SMIR -# -# Some non-curses applications get confused if both ich/ich1 and rmir/smir -# are present; the symptom is doubled characters in an update using insert. -# These applications are technically correct; in both 4.3BSD termcap and -# terminfo, you're not actually supposed to specify both ich/ich1 and rmir/smir -# unless the terminal needs both. This requirement is now rare; most ich -# sequences do not require previous smir, and most smir insert modes do not -# require ich1 before each character. -# -# For ncurses-based applications this is not a problem, as ncurses uses -# one or the other as appropriate but never mixes the two. Therefore we -# have not corrected entries like `linux' and `xterm' that specify both. -# If you see doubled characters from these, use the linux-nic and xterm-nic -# entries that suppress ich/ich1. And upgrade to ncurses! -# - -######## VT100/ANSI/ISO 6429/ECMA-48/PC-TERM TERMINAL STANDARDS -# -# ANSI X3.64 has been withdrawn and replaced by ECMA-48. The ISO 6429 and -# ECMA-48 standards are said to be almost identical, but are not the same -# as X3.64 (though for practical purposes they are close supersets of it). -# -# You can obtain ECMA-48 for free by sending email to helpdesk@ecma.ch -# requesting the standard(s) you want (i.e. ECMA-48, "Control Functions for -# Coded Character Sets"), include your snail-mail address, and you should -# receive the document in due course. Don't expect an email acknowledgement. -# -# Related standards include "X3.4-1977: American National Standard Code for -# Information Interchange" (the ASCII standard) and "X3.41.1974: -# Code-Extension Techniques for Use with the 7-Bit Coded Character Set of -# American National Standard for Information Interchange." I believe (but -# am not certain) that these are effectively identical to ECMA-6 and ECMA-35 -# respectively. -# - -#### VT100/ANSI/ECMA-48 -# -# ANSI Standard (X3.64) Control Sequences for Video Terminals and Peripherals -# and ECMA-48 Control Functions for Coded Character Sets. -# -# Much of the content of this comment is adapted from a table prepared by -# Richard Shuford, based on a 1984 Byte article. Terminfo correspondences, -# discussion of some terminfo-related issues, and updates to capture ECMA-48 -# have been added. Control functions described in ECMA-48 only are tagged -# with * after their names. -# -# The table is a complete list of the defined ANSI X3.64/ECMA-48 control -# sequences. In the main table, \E stands for an escape (\033) character, -# SPC for space. Pn stands for a single numeric parameter to be inserted -# in decimal ASCII. Ps stands for a list of such parameters separated by -# semicolons. Parameter meanings for most parametrized sequences are -# decribed in the notes. -# -# Sequence Sequence Parameter or -# Mnemonic Name Sequence Value Mode terminfo -# ----------------------------------------------------------------------------- -# APC Applicatn Program Command \E _ - Delim - -# BEL Bell * ^G - - bel -# BPH Break Permitted Here * \E B - * - -# BS Backpace * ^H - EF - -# CAN Cancel * ^X - - - (A) -# CBT Cursor Backward Tab \E [ Pn Z 1 eF cbt -# CCH Cancel Previous Character \E T - - - -# CHA Cursor Horizntal Absolute \E [ Pn G 1 eF hpa (B) -# CHT Cursor Horizontal Tab \E [ Pn I 1 eF tab (C) -# CMD Coding Method Delimiter * \E -# CNL Cursor Next Line \E [ Pn E 1 eF nel (D) -# CPL Cursor Preceding Line \E [ Pn F 1 eF - -# CPR Cursor Position Report \E [ Pn ; Pn R 1, 1 - - (E) -# CSI Control Sequence Intro \E [ - Intro - -# CTC Cursor Tabulation Control \E [ Ps W 0 eF - (F) -# CUB Cursor Backward \E [ Pn D 1 eF cub -# CUD Cursor Down \E [ Pn B 1 eF cud -# CUF Cursor Forward \E [ Pn C 1 eF cuf -# CUP Cursor Position \E [ Pn ; Pn H 1, 1 eF cup (G) -# CUU Cursor Up \E [ Pn A 1 eF cuu -# CVT Cursor Vertical Tab \E [ Pn Y - eF - (H) -# DA Device Attributes \E [ Pn c 0 - - -# DAQ Define Area Qualification \E [ Ps o 0 - - -# DCH Delete Character \E [ Pn P 1 eF dch -# DCS Device Control String \E P - Delim - -# DL Delete Line \E [ Pn M 1 eF dl -# DLE Data Link Escape * ^P - - - -# DMI Disable Manual Input \E \ - Fs - -# DSR Device Status Report \E [ Ps n 0 - - (I) -# DTA Dimension Text Area * \E [ Pn ; Pn SPC T - PC - -# EA Erase in Area \E [ Ps O 0 eF - (J) -# ECH Erase Character \E [ Pn X 1 eF ech -# ED Erase in Display \E [ Ps J 0 eF ed (J) -# EF Erase in Field \E [ Ps N 0 eF - -# EL Erase in Line \E [ Ps K 0 eF el (J) -# EM End of Medium * ^Y - - - -# EMI Enable Manual Input \E b Fs - -# ENQ Enquire ^E - - - -# EOT End Of Transmission ^D - * - -# EPA End of Protected Area \E W - - - (K) -# ESA End of Selected Area \E G - - - -# ESC Escape ^[ - - - -# ETB End Transmission Block ^W - - - -# ETX End of Text ^C - - - -# FF Form Feed ^L - - - -# FNK Function Key * \E [ Pn SPC W - - - -# GCC Graphic Char Combination* \E [ Pn ; Pn SPC B - - - -# FNT Font Selection \E [ Pn ; Pn SPC D 0, 0 FE - -# GSM Graphic Size Modify \E [ Pn ; Pn SPC B 100, 100 FE - (L) -# GSS Graphic Size Selection \E [ Pn SPC C none FE - -# HPA Horz Position Absolute \E [ Pn ` 1 FE - (B) -# HPB Char Position Backward \E [ j 1 FE - -# HPR Horz Position Relative \E [ Pn a 1 FE - (M) -# HT Horizontal Tab * ^I - FE - (N) -# HTJ Horz Tab w/Justification \E I - FE - -# HTS Horizontal Tab Set \E H - FE hts -# HVP Horz & Vertical Position \E [ Pn ; Pn f 1, 1 FE - (G) -# ICH Insert Character \E [ Pn @ 1 eF ich -# IDCS ID Device Control String \E [ SPC O - * - -# IGS ID Graphic Subrepertoire \E [ SPC M - * - -# IL Insert Line \E [ Pn L 1 eF il -# IND Index \E D - FE - -# INT Interrupt \E a - Fs - -# JFY Justify \E [ Ps SPC F 0 FE - -# IS1 Info Separator #1 * ^_ - * - -# IS2 Info Separator #1 * ^^ - * - -# IS3 Info Separator #1 * ^] - * - -# IS4 Info Separator #1 * ^\ - * - -# LF Line Feed ^J - - - -# LS1R Locking Shift Right 1 * \E ~ - - - -# LS2 Locking Shift 2 * \E n - - - -# LS2R Locking Shift Right 2 * \E } - - - -# LS3 Locking Shift 3 * \E o - - - -# LS3R Locking Shift Right 3 * \E | - - - -# MC Media Copy \E [ Ps i 0 - - (S) -# MW Message Waiting \E U - - - -# NAK Negative Acknowledge * ^U - * - -# NBH No Break Here * \E C - - - -# NEL Next Line \E E - FE nel (D) -# NP Next Page \E [ Pn U 1 eF - -# NUL Null * ^@ - - - -# OSC Operating System Command \E ] - Delim - -# PEC Pres. Expand/Contract * \E Pn SPC Z 0 - - -# PFS Page Format Selection * \E Pn SPC J 0 - - -# PLD Partial Line Down \E K - FE - (T) -# PLU Partial Line Up \E L - FE - (U) -# PM Privacy Message \E ^ - Delim - -# PP Preceding Page \E [ Pn V 1 eF - -# PPA Page Position Absolute * \E [ Pn SPC P 1 FE - -# PPB Page Position Backward * \E [ Pn SPC R 1 FE - -# PPR Page Position Forward * \E [ Pn SPC Q 1 FE - -# PTX Parallel Texts * \E [ \ - - - -# PU1 Private Use 1 \E Q - - - -# PU2 Private Use 2 \E R - - - -# QUAD Typographic Quadding \E [ Ps SPC H 0 FE - -# REP Repeat Char or Control \E [ Pn b 1 - rep -# RI Reverse Index \E M - FE - (V) -# RIS Reset to Initial State \E c - Fs - -# RM Reset Mode * \E [ Ps l - - - (W) -# SACS Set Add. Char. Sep. * \E [ Pn SPC / 0 - - -# SAPV Sel. Alt. Present. Var. * \E [ Ps SPC ] 0 - - (X) -# SCI Single-Char Introducer \E Z - - - -# SCO Sel. Char. Orientation * \E [ Pn ; Pn SPC k - - - -# SCS Set Char. Spacing * \E [ Pn SPC g - - - -# SD Scroll Down \E [ Pn T 1 eF rin -# SDS Start Directed String * \E [ Pn ] 1 - - -# SEE Select Editing Extent \E [ Ps Q 0 - - (Y) -# SEF Sheet Eject & Feed * \E [ Ps ; Ps SPC Y 0,0 - - -# SGR Select Graphic Rendition \E [ Ps m 0 FE sgr (O) -# SHS Select Char. Spacing * \E [ Ps SPC K 0 - - -# SI Shift In ^O - - - (P) -# SIMD Sel. Imp. Move Direct. * \E [ Ps ^ - - - -# SL Scroll Left \E [ Pn SPC @ 1 eF - -# SLH Set Line Home * \E [ Pn SPC U - - - -# SLL Set Line Limit * \E [ Pn SPC V - - - -# SLS Set Line Spacing * \E [ Pn SPC h - - - -# SM Select Mode \E [ Ps h none - - (W) -# SO Shift Out ^N - - - (Q) -# SOH Start Of Heading * ^A - - - -# SOS Start of String * \E X - - - -# SPA Start of Protected Area \E V - - - (Z) -# SPD Select Pres. Direction * \E [ Ps ; Ps SPC S 0,0 - - -# SPH Set Page Home * \E [ Ps SPC G - - - -# SPI Spacing Increment \E [ Pn ; Pn SPC G none FE - -# SPL Set Page Limit * \E [ Ps SPC j - - - -# SPQR Set Pr. Qual. & Rapid. * \E [ Ps SPC X 0 - - -# SR Scroll Right \E [ Pn SPC A 1 eF - -# SRCS Set Reduced Char. Sep. * \E [ Pn SPC f 0 - - -# SRS Start Reversed String * \E [ Ps [ 0 - - -# SSA Start of Selected Area \E F - - - -# SSU Select Size Unit * \E [ Pn SPC I 0 - - -# SSW Set Space Width * \E [ Pn SPC [ none - - -# SS2 Single Shift 2 (G2 set) \E N - Intro - -# SS3 Single Shift 3 (G3 set) \E O - Intro - -# ST String Terminator \E \ - Delim - -# STAB Selective Tabulation * \E [ Pn SPC ^ - - - -# STS Set Transmit State \E S - - - -# STX Start pf Text * ^B - - - -# SU Scroll Up \E [ Pn S 1 eF indn -# SUB Substitute * ^Z - - - -# SVS Select Line Spacing * \E [ Pn SPC \ 1 - - -# SYN Synchronous Idle * ^F - - - -# TAC Tabul. Aligned Centered * \E [ Pn SPC b - - - -# TALE Tabul. Al. Leading Edge * \E [ Pn SPC a - - - -# TATE Tabul. Al. Trailing Edge* \E [ Pn SPC ` - - - -# TBC Tab Clear \E [ Ps g 0 FE tbc -# TCC Tabul. Centered on Char * \E [ Pn SPC c - - - -# TSR Tabulation Stop Remove * \E [ Pn SPC d - FE - -# TSS Thin Space Specification \E [ Pn SC E none FE - -# VPA Vert. Position Absolute \E [ Pn d 1 FE vpa -# VPB Line Position Backward * \E [ Pn k 1 FE - -# VPR Vert. Position Relative \E [ Pn e 1 FE - (R) -# VT Vertical Tabulation * ^K - FE - -# VTS Vertical Tabulation Set \E J - FE - -# -# --------------------------------------------------------------------------- -# -# Notes: -# -# Some control characters are listed in the ECMA-48 standard without -# being assigned functions relevant to terminal control there (they -# referred to other standards such as ISO 1745 or ECMA-35). They are listed -# here anyway for completeness. -# -# (A) ECMA-48 calls this "CancelCharacter" but retains the CCH abbreviation. -# -# (B) There seems to be some confusion abroad between CHA and HPA. Most -# `ANSI' terminals accept the CHA sequence, not the HPA. but terminfo calls -# the capability (hpa). ECMA-48 calls this "Cursor Character Absolute" but -# preserved the CHA abbreviation. -# -# (C) CHT corresponds to terminfo (tab). Usually it has the value ^I. -# Occasionally (as on, for example, certain HP terminals) this has the HTJ -# value. ECMA-48 calls this "Cursor Forward Tabulation" but preserved the -# CHT abbreviation. -# -# (D) terminfo (nel) is usually \r\n rather than ANSI \EE. -# -# (E) ECMA-48 calls this "Active Position Report" but preserves the CPR -# abbreviation. -# -# (F) CTC parameter values: 0 = set char tab, 1 = set line tab, 2 = clear -# char tab, 3 = clear line tab, 4 = clear all char tabs on current line, -# 5 = clear all char tabs, 6 = clear all line tabs. -# -# (G) CUP and HVP are identical in effect. Some ANSI.SYS versions accept -# HVP, but always allow CUP as an alternate. ECMA-48 calls HVP "Character -# Position Absolute" but retains the HVP abbreviation. -# -# (H) ECMA calls this "Cursor Line Tabulation" but preserves the CVT -# abbreviation. -# -# (I) DSR parameter values: 0 = ready, 1 = busy, 2 = busy, will send DSR -# later, 3 = malfunction, 4 = malfunction, will send DSR later, 5 = request -# DSR, 6 = request CPR response. -# -# (J) ECMA calls ED "Erase In Page". EA/ED/EL parameters: 0 = clear to end, -# 1 = clear from beginning, 2 = clear. -# -# (K) ECMA calls this "End of Guarded Area" but preserves the EPA abbreviation. -# -# (L) The GSM parameters are vertical and horizontal parameters to scale by. -# -# (M) Some ANSI.SYS versions accept HPR, but more commonly `ANSI' terminals -# use CUF for this function and ignore HPR. ECMA-48 calls this "Character -# Position Relative" but retains the HPR abbreviation. -# -# (N) ECMA-48 calls this "Character Tabulation" but retains the HT -# abbreviation. -# -# (O) SGR parameter values: 0 = default mode (attributes off), 1 = bold, -# 2 = dim, 3 = italicized, 4 = underlined, 5 = slow blink, 6 = fast blink, -# 7 = reverse video, 8 = invisible, 9 = crossed-out (marked for deletion), -# 10 = primary font, 10 + n (n in 1..9) = nth alternative font, 20 = Fraktur, -# 21 = double underline, 22 = turn off 2, 23 = turn off 3, 24 = turn off 4, -# 25 = turn off 5, 26 = proportional spacing, 27 = turn off 7, 28 = turn off -# 8, 29 = turn off 9, 30 = black fg, 31 = red fg, 32 = green fg, 33 = yellow -# fg, 34 = blue fg, 35 = magenta fg, 36 = cyan fg, 37 = white fg, 38 = set -# fg color as in CCIT T.416, 39 = set default fg color, 40 = black bg -# 41 = red bg, 42 = green bg, 43 = yellow bg, 44 = blue bg, 45 = magenta bg, -# 46 = cyan bg, 47 = white bg, 48 = set bg color as in CCIT T.416, 39 = set -# default bg color, 50 = turn off 26, 51 = framed, 52 = encircled, 53 = -# overlined, 54 = turn off 51 & 52, 55 = not overlined, 56-59 = reserved, -# 61-65 = variable highlights for ideograms. -# -# (P) SI is also called LSO, Locking Shift Zero. -# -# (Q) SI is also called LS1, Locking Shift One. -# -# (R) Some ANSI.SYS versions accept VPR, but more commonly `ANSI' terminals -# use CUD for this function and ignore VPR. ECMA calls it `Line Position -# Absolute' but retains the VPA abbreviation. -# -# (S) MC parameters: 0 = start xfer to primary aux device, 1 = start xfer from -# primary aux device, 2 = start xfer to secondary aux device, 3 = start xfer -# from secondary aux device, 4 = stop relay to primary aux device, 5 = -# start relay to primary aux device, 6 = stop relay to secondary aux device, -# 7 = start relay to secondary aux device. -# -# (T) ECMA-48 calls this "Partial Line Forward" but retains the PLD -# abbreviation. -# -# (U) ECMA-48 calls this "Partial Line Backward" but retains the PLD -# abbreviation. -# -# (V) ECMA-48 calls this "Reverse Line Feed" but retains the RI abbreviation. -# -# (W) RM/SM modes are as follows: 1 = Guarder Area Transfer Mode (GATM), -# 2 = Keyboard Action Mode (KAM), 3 = Control Representation Mode (CRM), -# 4 = Insertion Replacement Mode, 5 = Status Report Transfer Mode (SRTM), -# 6 = Erasure Mode (ERM), 7 = Line Editing Mode (LEM), 8 = Bi-Directional -# Support Mode (BDSM), 9 = Device Component Select Mode (DCSM), -# 10 = Character Editing Mode (HEM), 11 = Positioning Unit Mode (PUM), -# 12 = Send/Receive Mode, 13 = Format Effector Action Mode (FEAM), -# 14 = Format Effector Transfer Mode (FETM), 15 = Multiple Area Transfer -# Mode (MATM), 16 = Transfer Termination Mode, 17 = Selected Area Transfer -# Mode, 18 = Tabulation Stop Mode, 19 = Editing Boundary Mode, 20 = Line Feed -# New Line Mode (LF/NL), Graphic Rendition Combination Mode (GRCM), 22 = -# Zero Default Mode (ZDM). The EBM and LF/NL modes have actually been removed -# from ECMA-48's 5th edition but are listed here for reference. -# -# (X) Select Alternate Presentation Variants is used only for non-Latin -# alphabets. -# -# (Y) "Select Editing Extent" (SEE) was ANSI "Select Edit Extent Mode" (SEM). -# -# (Z) ECMA-48 calls this "Start of Guarded Area" but retains the SPA -# abbreviation. -# -# --------------------------------------------------------------------------- -# -# Abbreviations: -# -# Intro an Introducer of some kind of defined sequence; the normal 7-bit -# X3.64 Control Sequence Introducer is the two characters "Escape [" -# -# Delim a Delimiter -# -# x/y identifies a character by position in the ASCII table (column/row) -# -# eF editor function (see explanation) -# -# FE format effector (see explanation) -# -# F is a Final character in -# an Escape sequence (F from 3/0 to 7/14 in the ASCII table) -# a control sequence (F from 4/0 to 7/14) -# -# Gs is a graphic character appearing in strings (Gs ranges from -# 2/0 to 7/14) in the ASCII table -# -# Ce is a control represented as a single bit combination in the C1 set -# of controls in an 8-bit character set -# -# C0 the familiar set of 7-bit ASCII control characters -# -# C1 roughly, the set of control chars available only in 8-bit systems. -# This is too complicated to explain fully here, so read Jim Fleming's -# article in the February 1983 BYTE, especially pages 214 through 224. -# -# Fe is a Final character of a 2-character Escape sequence that has an -# equivalent representation in an 8-bit environment as a Ce-type -# (Fe ranges from 4/0 to 5/15) -# -# Fs is a Final character of a 2-character Escape sequence that is -# standardized internationally with identical representation in 7-bit -# and 8-bit environments and is independent of the currently -# designated C0 and C1 control sets (Fs ranges from 6/0 to 7/14) -# -# I is an Intermediate character from 2/0 to 2/15 (inclusive) in the -# ASCII table -# -# P is a parameter character from 3/0 to 3/15 (inclusive) in the ASCII -# table -# -# Pn is a numeric parameter in a control sequence, a string of zero or -# more characters ranging from 3/0 to 3/9 in the ASCII table -# -# Ps is a variable number of selective parameters in a control sequence -# with each selective parameter separated from the other by the code -# 3/11 (which usually represents a semicolon); Ps ranges from -# 3/0 to 3/9 and includes 3/11 -# -# * Not relevant to terminal control, listed for completeness only. -# -# Format Effectors versus Editor Functions -# -# A format effector specifies how following output is to be displayed. -# An editor function allows you to modify the display. Informally -# format effectors may be destructive; format effectors should not be. -# -# For instance, a format effector that moves the "active position" (the -# cursor or equivalent) one space to the left would be useful when you want to -# create an overstrike, a compound character made of two standard characters -# overlaid. Control-H, the Backspace character, is actually supposed to be a -# format effector, so you can do this. But many systems use it in a -# nonstandard fashion, as an editor function, deleting the character to the -# left of the cursor and moving the cursor left. When Control-H is assumed to -# be an editor function, you cannot predict whether its use will create an -# overstrike unless you also know whether the output device is in an "insert -# mode" or an "overwrite mode". When Control-H is used as a format effector, -# its effect can always be predicted. The familiar characters carriage -# return, linefeed, formfeed, etc., are defined as format effectors. -# -# NOTES ON THE DEC VT100 IMPLEMENTATION -# -# Control sequences implemented in the VT100 are as follows: -# -# CPR, CUB, CUD, CUF, CUP, CUU, DA, DSR, ED, EL, HTS, HVP, IND, -# LNM, NEL, RI, RIS, RM, SGR, SM, TBC -# -# plus several private DEC commands. -# -# Erasing parts of the display (EL and ED) in the VT100 is performed thus: -# -# Erase from cursor to end of line Esc [ 0 K or Esc [ K -# Erase from beginning of line to cursor Esc [ 1 K -# Erase line containing cursor Esc [ 2 K -# Erase from cursor to end of screen Esc [ 0 J or Esc [ J -# Erase from beginning of screen to cursor Esc [ 1 J -# Erase entire screen Esc [ 2 J -# -# Some brain-damaged terminal/emulators respond to Esc [ J as if it were -# Esc [ 2 J, but this is wrong; the default is 0. -# -# The VT100 responds to receiving the DA (Device Attributes) control -# -# Esc [ c (or Esc [ 0 c) -# -# by transmitting the sequence -# -# Esc [ ? l ; Ps c -# -# where Ps is a character that describes installed options. -# -# The VT100's cursor location can be read with the DSR (Device Status -# Report) control -# -# Esc [ 6 n -# -# The VT100 reports by transmitting the CPR sequence -# -# Esc [ Pl ; Pc R -# -# where Pl is the line number and Pc is the column number (in decimal). -# -# The specification for the DEC VT100 is document EK-VT100-UG-003. - -#### ANSI.SYS -# -# Here is a description of the color and attribute controls supported in the -# the ANSI.SYS driver under MS-DOS. Most console drivers and ANSI -# terminal emulators for Intel boxes obey these. They are a proper subset -# of the ECMA-48 escapes. -# -# 0 all attributes off -# 1 foreground bright -# 4 underscore on -# 5 blink on/background bright (not reliable with brown) -# 7 reverse-video -# 8 set blank (non-display) -# 10 set primary font -# 11 set first alternate font (on PCs, display ROM characters 1-31) -# 12 set second alternate font (on PCs, display IBM high-half chars) -# -# Color attribute sets -# 3n set foreground color / 0=black, 1=red, 2=green, 3=brown, -# 4n set background color \ 4=blue, 5=magenta, 6=cyan, 7=white -# Bright black becomes gray. Bright brown becomes yellow, -# These coincide with the prescriptions of the ISO 6429/ECMA-48 standard. -# -# * If the 5 attribute is on and you set a background color (40-47) it is -# supposed to enable bright background. -# -# * Many VGA cards (such as the Paradise and compatibles) do the wrong thing -# when you try to set a "bright brown" (yellow) background with attribute -# 5 (you get a blinking yellow foreground instead). A few displays -# (including the System V console) support an attribute 6 that undoes this -# braindamage (this is required by iBCS2). -# -# * Some older versions of ANSI.SYS have a bug that causes thems to require -# ESC [ Pn k as EL rather than the ANSI ESC [ Pn K. (This is not ECMA-48 -# compatible.) - -#### Intel Binary Compatibility Standard -# -# For comparison, here are the capabilities implied by the Intel Binary -# Compatibility Standard for UNIX systems (Intel order number 468366-001). -# These recommendations are optional. IBCS2 allows the leading escape to -# be either the 7-bit \E[ or 8-bit \0233 introducer, in accordance with -# the ANSI X.364/ISO 6429/ECMA-48 standard. Here are the iBCS2 capabilities -# (as described in figure 9-3 of the standard). Those expressed in the ibcs2 -# terminfo entry are followed with the corresponding capability in parens: -# -# CSI k disable (n=0) or enable (n=1) keyclick -# CSI 2h lock keyboard -# CSI 2i send screen as input -# CSI 2l unlock keyboard -# CSI 6m enable background color intensity -# CSI <0-2>c reserved -# CSI <0-59>m select graphic rendition -# CSI ;H (cup) cursor to line n and column m -# CSI ;f cursor to line n and column m -# CSI @ (ich) insert characters -# CSI A (cuu) cursor up n lines -# CSI B (cud) cursor down n lines -# CSI C (cuu) cursor right n characters -# CSI D (cud) cursor left n characters -# CSI E cursor down n lines and in first column -# CSI F cursor up n lines and in first column -# CSI G (hpa) position cursor at column n-1 -# CSI J (ed) erase in display -# CSI K (el) erase in line -# CSI L (il) insert line(s) -# CSI P (dch) delete characters -# CSI S (indn) scroll up n lines -# CSI T (rin) scroll down n lines -# CSI X (ech) erase characters -# CSI Z (cbt) back up n tab stops -# CSI ` cursor to column n on line -# CSI a (cuu) cursor right n characters -# CSI d (vpa) cursor to line n -# CSI e cursor down n lines and in first column -# CSI g (cbt) clear all tabs -# CSI z make virtual terminal n active -# CSI ?7h (smam) turn automargin on -# CSI ?7l (rmam) turn automargin off -# CSI s save cursor position -# CSI u restore cursor position to saved value -# CSI =A set overscan color -# CSI =F set normal foreground color -# CSI =G set normal background color -# CSI =H set reverse foreground color -# CSI =I set reverse foreground color -# CSI =J set graphic foreground color -# CSI =K set graphic foreground color -# CSI =g (dispc) display n from alternate graphics character set -# CSI =

;B set bell parameters -# CSI =;C set cursor parameters -# CSI =D enable/disable intensity of background color -# CSI =E set/clear blink vs. bold background -# CSI 7 (sc) (sc) save cursor position -# CSI 8 (rc) (rc) restore cursor position to saved value -# CSI H (hts) (hts) set tab stop -# CSI Q define function key string -# (string must begin and end with delimiter char) -# CSI c (clear) clear screen -# -# The lack of any specification for attributes in SGR (among other things) -# makes this a wretchedly weak standard. The table above is literally -# everything iBSC2 has to say about terminal escape sequences; there is -# no further discussion of their meaning or how to set the parameters -# in these sequences at all. -# - -######## NONSTANDARD CAPABILITY TRANSLATIONS USED IN THIS FILE -# -# The historical termcap file entries were written primarily in 4.4BSD termcap. -# The 4.4BSD termcap set was substantially larger than the original 4.1BSD set, -# with the extension names chosen for compatibility with the termcap names -# assigned in System V terminfo. There are some variant extension sets out -# there. We try to describe them here. -# -# XENIX extensions: -# -# The XENIX extensions include a set of function-key capabilities as follows: -# -# code XENIX variable name terminfo name name clashes? -# ---- ------------------- ------------- ----------------------- -# CL key_char_left -# CR key_char_right -# CW key_change_window create_window -# EN key_end kend -# HM key_home khome -# HP ?? -# LD key_delete_line kdl1 -# LF key_linefeed label_off -# NU key_next_unlocked_cell -# PD key_page_down knp -# PL ?? -# PN start_print mc5 -# PR ?? -# PS stop_print mc4 -# PU key_page_up kpp pulse -# RC key_recalc remove_clock -# RF key_toggle_ref req_for_input -# RT key_return kent -# UP key_up_arrow kcuu1 parm_up_cursor -# WL key_word_left -# WR key_word_right -# -# The XENIX extensions also include the following character-set and highlight -# capabilities: -# -# XENIX terminfo function -# ----- -------- ------------------------------ -# GS smacs start alternate character set -# GE rmacs end alternate character set -# GG :as:/:ae: glitch (analogous to :sg:/:ug:) -# bo blink begin blink (not used in /etc/termcap) -# be end blink (not used in /etc/termcap) -# bb blink glitch (not used in /etc/termcap) -# it dim begin dim (not used in /etc/termcap) -# ie end dim (not used in /etc/termcap) -# ig dim glitch (not used in /etc/termcap) -# -# Finally, XENIX also used the following forms-drawing capabilities: -# -# single double type ASCII approximation -# ------ ------ ------------- ------------------- -# GV Gv vertical line | -# GH Gv horizontal line - _ -# G1 G5 top right corner _ | -# G2 G6 top left corner | -# G3 G7 bottom left corner |_ -# G4 G8 bottom right corner _| -# GD Gd down-tick character T -# GL Gl left-tick character -| -# GR Gr right-tick character |- -# GC Gc middle intersection -|- -# GU Gu up-tick character _|_ -# -# These were invented to take advantage of the IBM PC ROM character set. One -# can compose an acsc string from the single-width characters as follows -# "j{G4}k{G1}l{G2}m{G3}q{GH}x{GV}t{GR}u{GL}v{GU}w{GD}n{GC}" -# When translating a termcap file, ncurses tic will do this automatically. -# The double forms characters don't fit the SVr4 terminfo model. -# -# AT&T Extensions: -# -# The old AT&T 5410, 5420, 5425, pc6300plus, 610, and s4 entries used a set of -# nonstandard capabilities. Its signature is the KM capability, used to name -# some sort of keymap file. EE, BO, CI, CV, XS, DS, FL and FE are in this -# set. Comments in the original, and a little cross-checking with other AT&T -# documentation, seem to establish that BO=:mr: (start reverse video), DS=:mh: -# (start dim), XS=:mk: (secure/invisible mode), EE=:me: (end highlights), -# FL=:LO: (enable soft labels), FE=:LF: (disable soft labels), CI=:vi: (make -# cursor invisible), and CV=:ve: (make cursor normal). -# -# HP Extensions -# -# The HP library (as of mid-1995, their term.h file version 70.1) appears to -# have the System V capabilities up to SVr1 level. After that, it supports -# two nonstandard caps meml and memu corresponding to the old termcap :ml:, -# :mu: capabilities. After that, it supports caps plab_norm, label_on, -# label_off, and key_f11..key_f63 capabilities like SVr4's. This makes the -# HP binary format incompatible with SVr4's. -# -# IBM Extensions -# -# There is a set of nonstandard terminfos used by IBM's AIX operating system. -# The AIX terminfo library diverged from SVr1 terminfo, and replaces all -# capabilities following prtr_non with the following special capabilties: -# box[12], batt[12], colb[0123456789], colf[0123456789], f[01234567], kbtab, -# kdo, kcmd, kcpn, kend, khlp, knl, knpn, kppn, kppn, kquit, ksel, kscl, kscr, -# ktab, kmpf[123456789], apstr, ksf1..ksf10, kf11...kf63, kact, topl, btml, -# rvert, lvert. Some of these are identical to XPG4/SVr4 equivalents: -# kcmd, kend, khlp, and kf11...kf63. Two others (kbtab and ksel) can be -# renamed (to kcbt and kslt). The places in the box[12] capabilities -# correspond to acsc chars, here is the mapping: -# -# box1[0] = ACS_ULCORNER -# box1[1] = ACS_HLINE -# box1[2] = ACS_URCORNER -# box1[3] = ACS_VLINE -# box1[4] = ACS_LRCORNER -# box1[5] = ACS_LLCORNER -# box1[6] = ACS_TTEE -# box1[7] = ACS_RTEE -# box1[8] = ACS_BTEE -# box1[9] = ACS_LTEE -# box1[10] = ACS_PLUS -# -# The box2 characters are the double-line versions of these forms graphics. -# The AIX binary terminfo format is incompatible with SVr4's. -# -# Iris console extensions: -# -# HS is half-intensity start; HE is half-intensity end -# CT is color terminal type (for Curses & rogue) -# CP is color change escape sequence -# CZ are color names (for Curses & rogue) -# -# The ncurses tic utility recognizes HS as an alias for mh . -# -# TC Extensions: -# -# There is a set of extended termcaps associated with something -# called the "Terminal Control" or TC package created by MainStream Systems, -# Winfield Kansas. This one also uses GS/GE for as/ae, and also uses -# CF for civis and CO for cvvis. Finally, they define a boolean :ct: -# that flags color terminals. -# -######## CHANGE HISTORY -# -# The last /etc/termcap version maintained by John Kunze was 8.3, dated 8/5/94. -# Releases 9 and up are maintained by Eric S. Raymond as part of the ncurses -# project. -# -# This file contains all the capability information present in John Kunze's -# last version of the termcap master file, except as noted in the change -# comments at end of file. Some information about very ancient obsolete -# capabilities has been moved to comments. Some all-numeric names of older -# terminals have been retired. -# -# I changed :MT: to :km: (the 4.4BSD name) everywhere. I commented out some -# capabilities (EP, dF, dT, dV, kn, ma, ml, mu, xr, xx) that are no longer -# used by BSD curses. -# -# The 9.1.0 version of this file was translated from my lightly-edited copy of -# 8.3, then mechanically checked against 8.3 using Emacs Lisp code written for -# the purpose. Unless the ncurses tic implementation and the Lisp code were -# making perfectly synchronized mistakes which I then failed to catch by -# eyeball, the translation was correct and perfectly information-preserving. -# -# Major version number bumps correspond to major version changes in ncurses. -# -# Here is a log of the changes since then: -# -# 9.1.0 (Wed Feb 1 04:50:32 EST 1995): -# * First terminfo master translated from 8.3. -# 9.2.0 (Wed Feb 1 12:21:45 EST 1995): -# * Replaced Wyse entries with updated entries supplied by vendor. -# -# 9.3.0 (Mon Feb 6 19:14:40 EST 1995): -# * Added contact & status info from G. Clark Brown . -# 9.3.1 (Tue Feb 7 12:00:24 EST 1995): -# * Better XENIX keycap translation. Describe TC termcaps. -# * Contact and history info supplied by Qume. -# 9.3.2 (Sat Feb 11 23:40:02 EST 1995): -# * Raided the Shuford FTP site for recent termcaps/terminfos. -# * Added information on X3.64 and VT100 standard escape sequences. -# 9.3.3 (Mon Feb 13 12:26:15 EST 1995): -# * Added a correct X11R6 xterm entry. -# * Fixed terminfo translations of padding. -# 9.3.4 (Wed Feb 22 19:27:34 EST 1995): -# * Added correct acsc/smacs/rmacs strings for vt100 and xterm. -# * Added u6/u7/u8/u9 capabilities. -# * Added PCVT entry. -# 9.3.5 (Thu Feb 23 09:37:12 EST 1995): -# * Emacs uses :so:, not :mr:, for its mode line. Fix linux entry -# to use reverse-video standout so Emacs will look right. -# * Added el1 capability to ansi. -# * Added smacs/rmacs to ansi.sys. -# -# 9.4.0 (Sat Feb 25 16:43:25 EST 1995): -# * New mt70 entry. -# * Added COPYRIGHTS AND OTHER DELUSIONS. -# * Added AT&T 23xx & 500/513, vt220 and vt420, opus3n1+, netronics -# smartvid & smarterm, ampex 175 & 219 & 232, -# env230, falco ts100, fluke, intertube, superbrain, ncr7901, vic20, -# ozzie, trs200, tr600, Tandy & Texas Instruments VDTs, intext2, -# screwpoint, fviewpoint, Contel Business Systems, Datamedia Colorscan, -# adm36, mime314, ergo4000, ca22851. Replaced att7300, esprit, dd5500. -# * Replaced the Perkin-Elmer entries with vendor's official ones. -# * Restored the old minimal-ansi entry, luna needs it. -# * Fixed some incorrect ip and proportional-padding translations. -# 9.4.1 (Mon Feb 27 14:18:33 EST 1995): -# * Fix linux & AT386 sgr strings to do A_ALTCHARSET turnoff correctly. -# * Make the xterm entry 65 lines again; create xterm25 and xterm24 -# to force a particular height. -# * Added beehive4 and reorganized other Harris entries. -# 9.4.2 (Thu Mar 9 01:45:44 EST 1995): -# * Merged in DEC's official entries for its terminals. The only old -# entry I kept was Doug Gwyn's alternate vt100 (as vt100-avo). -# * Replaced the translated BBN Bitgraph entries with purpose-built -# ones from AT&T's SVr3. -# * Replaced the AT&T entries with AT&T's official terminfos. -# * Added teleray 16, vc415, cops10. -# * Merged in many individual capabilities from SCO terminfo files. -# 9.4.3 (Mon Mar 13 02:37:53 EST 1995): -# * Typo fixes. -# * Change linux entry so A_PROTECT enables IBM-PC ROM characters. -# 9.4.4 (Mon Mar 27 12:32:35 EST 1995): -# * Added tty35, Ann Arbor Guru series. vi300 and 550, cg7900, tvi803, -# pt210, ibm3164, IBM System 1, ctrm, Tymshare scanset, dt200, adm21, -# simterm, citoh and variants. -# * Replaced sol entry with sol1 and sol2. -# * Replaced Qume QVT and Freedom-series entries with purpose-built -# terminfo entries. -# * Enhanced vt220, tvi910, tvi924, hpterm, hp2645, adm42, tek -# and dg200 entries using caps from from SCO. -# * Added the usual set of function-key mappings to ANSI entry. -# * Corrected xterm's function-key capabilities. -# 9.4.5 (Tue Mar 28 14:27:49 EST 1995): -# * Fix in xterm entry, cub and cud are not reliable under X11R6. -# 9.4.6 (Thu Mar 30 14:52:15 EST 1995): -# * Fix in xterm entry, get the arrow keys right. -# * Change some \0 escapes to \200. -# 9.4.7 (Tue Apr 4 11:27:11 EDT 1995) -# * Added apple (Videx card), adm1a, oadm31. -# * Fixed malformed ampex csr. -# * Fixed act4, cyb110; they had old-style prefix padding left in. -# * Changed mandatory to advisory padding in many entries. -# * Replaced HP entries up to hpsub with purpose-built ones. -# * Blank rmir/smir/rmdc/smdc capabilities removed. -# * Small fixes merged in from SCO entries for lpr, fos, tvi910+, tvi924. -# 9.4.8 (Fri Apr 7 09:36:34 EDT 199): -# * Replaced the Ann Arbor entries with SCO's, the init strings are -# more efficient (but the entries otherwise identical). -# * Added dg211 from Shuford archive. -# * Added synertek, apple-soroc, ibmpc, pc-venix, pc-coherent, xtalk, -# adm42-nl, pc52, gs6300, xerox820, uts30. -# * Pull SCO's padding into vi200 entry. -# * Improved capabilities for tvi4107 and other Televideo and Viewpoint -# entries merged in from SCO's descriptions. -# * Fixed old-style prefix padding on zen50, h1500. -# * Moved old superbee entry to superbee-xsb, pulled in new superbee -# entry from SCO's description. -# * Reorganized the special entries. -# * Added lm#0 to cbunix and virtual entries. -# -# 9.5.0 (Mon Apr 10 11:30:00 EDT 1995): -# * Restored cdc456tst. -# * Fixed sb1 entry, SCO erroneously left out the xsb glitch. -# * Added megatek, beacon, microkit. -# * Freeze for ncurses-1.9 release. -# 9.5.1 (Fri Apr 21 12:46:42 EDT 1995): -# * Added historical data for TAB. -# * Comment fixes from David MacKenzie. -# * Added the new BSDI pc3 entry. -# 9.5.2 (Tue Apr 25 17:27:52 EDT 1995) -# * A change in the tic -C logic now ensures that all entries in -# the termcap translation will fit in < 1024 bytes. -# * Added `bobcat' and `gator' HP consoles and the Nu machine entries -# from GNU termcap file. This merges in all their local information. -# 9.5.3 (Tue Apr 25 22:28:13 EDT 1995) -# * Changed tic -C logic to dump all capabilities used by GNU termcap. -# * Added warnings about entries with long translations (restoring -# all the GNU termcaps pushes a few over the edge). -# 9.5.4 (Wed Apr 26 15:35:09 EDT 1995) -# * Yet another tic change, and a couple of entry tweaks, to reduce the -# number of long (> 1024) termcap translations back to 0. -# -# 9.6.0 (Mon May 1 10:35:54 EDT 1995) -# * Added kf13-kf20 to Linux entry. -# * Regularize Prime terminal names. -# * Historical data on Synertek. -# * Freeze for ncurses-1.9.1. -# 9.6.1 (Sat May 6 02:00:52 EDT 1995): -# * Added true xterm-color entry, renamed djm's pseudo-color entry. -# * Eliminate whitespace in short name fields, this tanks some scripts. -# * Name field changes to shorten some long entries. -# * Termcap translation now automatically generates empty rmir/smir -# when ich1/ich is present (copes with an ancient vi bug). -# * Added `screen' entries from FSF's screen-3.6.2. -# * Added linux-nic and xterm-nic entries. -# 9.6.2 (Sat May 6 17:00:55 EDT 1995): -# * Change linux entry to use smacs=\E[11m and have an explicit acsc, -# eliminating some special-case code in ncurses. -# -# 9.7.0 (Tue May 9 18:03:12 EDT 1995): -# * Added vt320-k3, rsvidtx from the Emacs termcap.dat file. I think -# that captures everything unique from it. -# * Added reorder script generator. -# * Freeze for ncurses 1.9.2 release. -# 9.7.1 (Thu Jun 29 09:35:22 EDT 1995): -# * Added Sean Farley's kspd, flash, rs1 capabilities for linux. -# * Added Olaf Siebert's corrections for adm12. -# * ansi-pc-color now includes the colors and pairs caps, so that -# entries which use it will inherit them automatically. -# * The linux entry can now recognize the center (keypad 5) key. -# * Removed some junk that found its way into Linux acsc. -# -# 9.8.0 (Fri Jul 7 04:46:57 EDT 1995): -# * Add 50% cut mark as a desperate hack to reduce tic's core usage. -# * xterm doesn't try to use application keypad mode any more. -# * Freeze for ncurses-1.9.3 release. -# 9.8.1 (Thu Jul 19 17:02:12 EDT 1995): -# * Added corrected sun entry from vendor. -# * Added csr capability to linux entry. -# * Peter Wemm says the at386 hpa should be \E[%i%p1%dG, not \E[%p1%dG. -# * Added vt102-nsgr to cope with stupid IBM PC `VT100' emulators. -# * Some commented-out caps in long entries come back in, my code -# for computing string-table lengths had a bug in it. -# * pcansi series modified to fit comm-program reality better. -# 9.8.2 (Sat Sep 9 23:35:00 EDT 1995): -# * BSD/OS actually ships the ibmpc3 bold entry as its console. -# * Correct some bad aliases in the pcansi series -# * Added entry for QNX console. -# * Clean up duplicate long names for use with 4.4 library. -# * Change vt100 standout to be normal reverse vide, not bright reverse; -# this makes the Emacs status line look better. -# 9.8.3 (Sun Sep 10 13:07:34 EDT 1995): -# * Added Adam Thompson's VT320 entries, also his dtx-sas and z340. -# * Minor surgery, mostly on name strings, to shorten termcap version. -# -# 9.9.0 (Sat Sep 16 23:03:48 EDT 1995): -# * Added dec-vt100 for use with the EWAN emulator. -# * Added kmous to xterm for use with xterm's mouse-tracking facility. -# * Freeze for 1.9.5 alpha release. -# 9.9.1 (Wed Sep 20 13:46:09 EDT 1995): -# * Changed xterm lines to 24, the X11R6 default. -# 9.9.2 (Sat Sep 23 21:29:21 EDT 1995): -# * Added 7 newly discovered, undocumented acsc characters to linux -# entry (the pryz{|} characters). -# * ncurses no longer steals A_PROTECT. Simplify linux sgr accordingly. -# * Correct two typos in the xterm entries introduced in 9.9.1. -# * I finally figured out how to translate ko capabilities. Done. -# * Added tvi921 entries from Tim Theisen. -# * Cleanup: dgd211 -> dg211, adm42-nl -> adm42-nsl. -# * Removed mystery tec entry, it was neither interesting nor useful. -# * shortened altos3, qvt203, tvi910+, tvi92D, tvi921-g, tvi955, vi200-f, -# vi300-ss, att505-24, contel301, dm3045, f200vi, pe7000c, vc303a, -# trs200, wind26, wind40, wind50, cdc456tst, dku7003, f110, dg211, -# by making them relative to use capabilities -# * Added cuf1=^L to tvi925 from deleted variant tvi925a. -# * fixed cup in adm22 entry and parametrized strings in vt320-k3. -# * added it#8 to entries that used to have :pt: -- tvi912, vi200, -# ampex80, -# * Translate all home=\E[;H capabilities to home=\E[H, they're -# equivalent. -# * Translate \E[0m -> \E[m in [rs]mso, [rs]mul, and init strings of -# vt100 and ANSI-like terminals. -# 9.9.3 (Tue Sep 26 20:11:15 EDT 1995): -# * Added it#8 and ht=\t to *all* entries with :pt:; the ncurses tic -# does this now, too. -# * fviewpoint is gone, it duplicated screwpoint. -# * Added hp2627, graphos, graphos-30, hpex, ibmega, ibm8514, ibm8514-c, -# ibmvga, ibmvga-c, minix, mm340, mt4520-rv, screen2, screen3, -# versaterm, vi500, vsc, vt131, vt340, vt400 entries from UW. -# The UW vi50 replaces the old one, which becomes vi50adm, -# * No more embedded commas in name fields. -# -# 9.10.0 (Wed Oct 4 15:39:37 EDT 1995): -# * XENIX forms characters in fos, trs16, scoansi become acsc strings, -# * Introduced klone+* entries for describing Intel-console behavior. -# * Linux kbs is default-mapped to delete for some brain-dead reason. -# * -nsl -> -ns. The -pp syntax is obsolete. -# * Eliminate [A-Z]* primaries in accordance with SVr4 terminfo docs. -# * Make xterm entry do application-keypad mode again. I got complaints -# that it was messing up someone's 3270 emulator. -# * Added some longname fields in order to avoid warning messages from -# older tic implementations. -# * According to ctrlseqs.ms, xterm has a full vt100 graphics set. Use -# it! (This gives us pi, greater than, less than, and a few more.) -# * Freeze for ncurses-1.9.6 release. -# 9.10.1 (Sat Oct 21 22:18:09 EDT 1995): -# * Add xon to a number of console entries, they're memory-mapped and -# don't need padding. -# * Correct the use dependencies in the ansi series. -# * Hand-translate more XENIX capabilities. -# * Added hpterm entry for HP's X terminal emulator. -# * Added aixterm entries. -# * Shortened four names so everything fits in 14 chars. -# -# 9.11.0 (Thu Nov 2 17:29:35 EST 1995): -# * Added ibcs2 entry and info on iBCS2 standard. -# * Corrected hpa/vpa in linux entry. They still fail the worm test. -# * We can handle the HP meml/memu capability now. -# * Added smacs to klone entries, just as documentation. -# * Carrected ansi.sys and cit-500 entries. -# * Added z39, vt320-k311, v220c, and avatar entries. -# * Make pcansi use the ansi.sys invis capability. -# * Added DIP switch descriptions for vt100, adm31, tvi910, tvi920c, -# tvi925, tvi950, dt80, ncr7900i, h19. -# * X3.64 has been withdrawn, change some references. -# * Removed function keys from ansi-m entry. -# * Corrected ansi.sys entry. -# * Freeze for ncurses-1.9.7 release. -# 9.11.1 (Tue Nov 6 18:18:38 EST 1995): -# * Added rmam/smam capabilities to many entries based on init strings. -# * Added correct hpa/vpa to linux. -# * Reduced several entries relative to vt52. -# 9.11.2 (Tue Nov 7 00:21:06 EST 1995): -# * Exiled some utterly unidentifiable custom and homebrew types to the -# UFO file; also, obsolete small-screen hardware; also, entries which -# look flat-out incorrect, garbled, or redundant. These include the -# following entries: carlock, cdc456tst, microkit, qdss, ramtek, tec, -# tec400, tec500, ubell, wind, wind16, wind40, wind50, plasma, agile, -# apple, bch, daleblit, nucterm, ttywilliams, nuterminal, nu24, bnu, -# fnu, nunix-30, nunix-61, exidy, ex3000, sexidy, pc52, sanyo55, -# yterm10, yterm11, yterm10nat, aed, aed-ucb, compucolor, compucolor2, -# vic20, dg1, act5s, netx, smartvid, smarterm, sol, sol2, dt200, -# trs80, trs100, trs200, trs600, xitex, rsvidtx, vid, att2300-x40, -# att2350-x40, att4410-nfk, att5410-ns, otty5410, att5425-nl-w, -# tty5425-fk, tty5425-w-fk, cita, c108-na, c108-rv-na, c100-rv-na, -# c108-na-acs, c108-rv-na-acs, ims950-ns, infotonKAS, ncr7900i-na, -# regent60na, scanset-n, tvi921-g, tvi925n, tvi925vbn, tvi925vb, -# vc404-na, vc404-s-na, vt420nam, vt420f-nam, vt420pc-nam, vt510nam, -# vt510pc-nam, vt520nam, vt525nam, xterm25, xterm50, xterm65, xterms. -# * Corrected pcvt25h as suggested by Brian C. Grayson -# . -# 9.11.3 (Thu Nov 9 12:14:40 EST 1995): -# * Added kspd=\E[P, kcbt=\E[Z, to linux entry, changed kbs back to ^H. -# * Added kent=\EOM to xterm entry. -# -# 9.11.4 (Fri Nov 10 08:31:35 EST 1995): -# * Corrected gigi entry. -# * Restored cuf/cud1 to xterm, their apparent bugginess was due to -# bad hpa/vpa capabilities. -# * Corrected flash strings to have a uniform delay of .2 sec. No -# more speed-dependent NUL-padding! -# * terminfo capabilities in comments bracketed with <>. -# 9.11.5 (Fri Nov 10 15:35:02 EST 1995): -# * Replaced pcvt with the 3.31 pcvt entries. -# * Freeze for 1.9.7a. -# 9.11.6 (Mon Nov 13 10:20:24 EST 1995): -# * Added emu entry from the X11R6 contrib tape sources. -# -# 9.12.0 (Wed Nov 29 04:22:25 EST 1995): -# * Improved iris-ansi and sun entries. -# * More flash string improvements. -# * Corrected wy160 & wy160 as suggested by Robert Dunn -# * Added dim to at386. -# * Reconciled pc3 and ibmpc3 with the BSDI termcap file. Keith says -# he's ready to start using the termcap generated from this one. -# * Added vt102-w, vt220-w, xterm-bold, wyse-vp, wy75ap, att4424m, -# ln03, lno3-w, h19-g, z29a*, qdss. Made vt200 an alias of vt220. -# * Improved hpterm, apollo consoles, fos, qvt101, tvi924. tvi925, -# att610, att620, att630, -# * Changed hazeltine name prefix from h to hz. -# * Sent t500 to the UFI file. -# * I think we've sucked all the juice out of BSDI's termcap file now. -# * Freeze for ncurses 1.9.8 release -# 9.12.1 (Thu Nov 30 03:14:06 EST 1995) -# * Unfreeze, linux kbs needed to be fixed. -# * Tim Theisen pinned down a bug in the DMD firmware. -# 9.12.2 (Thu Nov 30 19:08:55 EST 1995): -# * Fixes to ansi and klone capabilities (thank you, Aaron Ucko). -# (The broken ones had been shadowed by sgr.) -# 9.12.3 (Thu Dec 7 17:47:22 EST 1995): -# * Added documentation on ECMA-48 standard. -# * New Amiga entry. -# 9.12.4 (Thu Dec 14 04:16:39 EST 1995): -# * More ECMA-48 stuff -# * Corrected typo in minix entry, added pc-minix. -# * Corrected khome/kend in xterm (thank you again, Aaron Ucko). -# * Added rxvt entry. -# * Added 1.3.x color-change capabilities to linux entry. -# 9.12.5 (Tue Dec 19 00:22:10 EST 1995): -# * Corrected rxvt entry khome/kend. -# * Corrected linux color change capabilities. -# * NeXT entries from Dave Wetzel. -# * Cleaned up if and rf file names (all in /usr/share now). -# * Changed linux op capability to avoid screwing up a background color -# pair set by setterm. -# 9.12.6 (Wed Feb 7 16:14:35 EST 1996): -# * Added xterm-sun. -# 9.12.7 (Fri Feb 9 13:27:35 EST 1996): -# * Added visa50. -# -# 9.13.0 (Sun Mar 10 00:13:08 EST 1996): -# * Another sweep through the Shuford archive looking for new info. -# * Added dg100 alias to dg6053 based on a comp.terminals posting. -# * Added st52 from Per Persson. -# * Added eterm from the GNU Emacs 19.30 distribution. -# * Freeze for 1.9.9. -# 9.13.1 (Fri Mar 29 14:06:46 EST 1996): -# * FreeBSD console entries from Andrew Chernov. -# * Removed duplicate Atari st52 name. -# 9.13.2 (Tue May 7 16:10:06 EDT 1996) -# * xterm doesn't actually have ACS_BLOCK. -# * Change klone+color setf/setb to simpler forms that can be -# translated into termcap. -# * Added xterm1. -# * Removed mechanically-generated junk capabilities from cons* entries. -# * Added color support to bsdos. -# 9.13.3 (Thu May 9 10:35:51 EDT 1996): -# * Added Wyse 520 entries from Wm. Randolph Franklin . -# * Created ecma+color, linux can use it. Also added ech to linux. -# * Teach xterm about more keys. Add Thomas Dickey's 3.1.2E updates. -# * Add descriptions to FreeBSD console entries. Also shorten -# some aliases to <= 14 chars for portability. -# * Added x68k console -# * Added OTbs to several VT-series entries. -# 9.13.4 (Wed May 22 10:54:09 EDT 1996): -# * screen entry update for 3.7.1 from Michael Alan Dorfman. -# 9.13.5 (Wed Jun 5 11:22:41 EDT 1996): -# * kterm correction due to Kenji Rikitake. -# * ACS correction in vt320-kll due to Phillippe De Muyter. -# 9.13.6 (Sun Jun 16 15:01:07 EDT 1996): -# * Sun console entry correction from J.T. Conklin. -# * Changed all DEC VT300 and up terminals to use VT300 tab set -# 9.13.7 (Mon Jul 8 20:14:32 EDT 1996): -# * Added smul to linux entry (we never noticed it was missing -# because of sgr!). -# * Added rmln to hp+labels (deduced from other HP entries). -# * Added vt100 acsc capability to vt220, vt340, vt400, d800, dt80-sas, -# pro350, att7300, 5420_2, att4418, att4424, att4426, att505, vt320-k3. -# * Corrected vt220 acsc. -# * The klone+sgr and klone+sgr-dumb entries now use klone+acs; -# this corresponds to reality and helps prevent some tic warnings. -# * Added sgr0 to c101, pcix, vt100-nav, screen2, oldsun, next, altos2, -# hpgeneric, hpansi, hpsub, hp236, hp700-wy, bobcat, dku7003, adm11, -# adm12, adm20, adm21, adm22, adm31, adm36, adm42, pt100, pt200, -# qvt101, tvi910, tvi921, tvi92B, tvi925, tvi950, tvi970, wy30-mc, -# wy50-mc, wy100, wyse-vp, ampex232, regent100, viewpoint, vp90, -# adds980, cit101, cit500, contel300, cs10, dm80, falco, falco-p, -# f1720a, go140, sb1, superbeeic, microb, ibm8512, kt7, ergo4000, -# owl, uts30, dmterm, dt100, dt100, dt110, appleII, apple-videx, -# lisa, trsII, atari, st52, pc-coherent, basis, m2-man, bg2.0, bg1.25, -# dw3, ln03, ims-ansi, graphos, t16, zen30, xtalk, simterm, d800, -# ifmr, v3220, wy100q, tandem653, ibmaed. -# * Added DWK terminal description. -# 9.13.8 (Wed Jul 10 11:45:21 EDT 1996): -# * Many entries now have highlights inherited from adm+sgr. -# * xterm entry now corresponds to XFree86 3.1.2E, with color. -# * xtitle and xtitle-twm enable access to the X status line. -# * Added linux-1.3.6 color palette caps in conventional format. -# * Added adm1178 terminal. -# * Move fos and apollo terminals to obsolete category. -# * Aha! The BRL terminals file told us what the Iris extensions mean. -# * Added, from the BRL termcap file: rt6221, rt6221-w, northstar, -# commodore, cdc721-esc, excel62, osexec. Replaced from the BRL file: -# cit500, adm11. -# 9.13.9 (Mon Jul 15 00:32:51 EDT 1996): -# * Added, from the BRL termcap file: cdc721, cdc721l, cdc752, cdc756, -# aws, awsc, zentec8001, modgraph48, rca vp3301/vp3501, ex155. -# * Corrected, from BRL termcap file: vi50. -# * Better rxvt entry & corrected xterm entries from Thomas Dickey. -# 9.13.10 (Mon Jul 15 12:20:13 EDT 1996): -# * Added from BRL: cit101e & variants, hmod1, vi200, ansi77, att5620-1, -# att5620-s, att5620-s, dg210, aas1901, hz1520, hp9845, osborne -# (old osborne moved to osborne-w), tvi970-vb, tvi970-2p, tvi925-hi, -# tek4105brl, tek4106brl, tek4107brl,tek4109brl, hazel, aepro, -# apple40p, apple80p, appleIIgs, apple2e, apple2e-p, apple-ae. -# * Paired-attribute fixes to various terminals. -# * Sun entry corrections from A. Lukyanov & Gert-Jan Vons. -# * xterm entry corrections from Thomas Dickey. -# 9.13.11 (Tue Jul 30 16:42:58 EDT 1996): -# * Added t916 entry, translated from a termcap in SCO's support area. -# * New qnx entry from Michael Hunter. -# 9.13.12 (Mon Aug 5 14:31:11 EDT 1996): -# * Added hpex2 from Ville Sulko. -# * Fixed a bug that ran the qnx and pcvtXX together. -# 9.13.13 (Fri Aug 9 01:16:17 EDT 1996): -# * Added dtterm entry from Solaris CDE. -# 9.13.14 (Tue Sep 10 15:31:56 EDT 1996): -# * corrected pairs#8 typo in dtterm entry. -# * added tvi9065. -# 9.13.15 (Sun Sep 15 02:47:05 EDT 1996): -# * updated xterm entry to cover 3.1.2E's new features. -# 9.13.16 (Tue Sep 24 12:47:43 EDT 1996): -# * Added new minix entry -# * Removed aliases of the form ^[0-9]* for obsolete terminals. -# * Commented out linux-old, nobody's using pre-1.2 kernels now. -# 9.13.17 (Fri Sep 27 13:25:38 EDT 1996): -# * Added Prism entries and kt7ix. -# * Caution notes about EWAN and tabset files. -# * Changed /usr/lib/tabset -> /usr/share/tabset. -# * Added acsc/rmacs/smacs to vt52. -# 9.13.18 (Mon Oct 28 13:24:59 EST 1996): -# * Merged in Thomas Dickey's reorganization of the xterm entries; -# added technical corrections to avoid warning messages. -# 9.13.19 (Sat Nov 16 16:05:49 EST 1996): -# * Added rmso=\E[27m in Linux entry. -# * Added koi8-r support for Linux console. -# * Replace xterm entries with canonical ones from XFree86 3.2. -# 9.13.20 (Sun Nov 17 23:02:51 EST 1996): -# * Added color_xterm from Jacob Mandelson -# 9.13.21 (Mon Nov 18 12:43:42 EST 1996): -# * Back off the xterm entry to use r6 as a base. -# 9.13.22 (Sat Nov 30 11:51:31 EST 1996): -# * Added dec-vt220 at Adrian Garside's request. -# 9.13.23 (Fri Feb 21 16:36:06 EST 1997): -# * Replaced minitel-2 entry. -# * Added MGR, ansi-nt. -# * Minor corrections to xterm entries. -# * Replaced EWAN telnet entry. -# * Dropped the reorder script generator. It was a fossil. -# 9.13.24 (Sun Feb 23 20:55:23 EST 1997): -# * Thorsten Lockert added termcap `bs' to a lot of types, working from -# the 4.4BSD Lite2 file. -# 9.13.25 (Fri Jun 20 12:33:36 EDT 1997): -# * Added Datapoint 8242, pilot, ansi_psx, rbcomm, vt220js. -# * Updated iris-ansi; corrected vt102-w. -# * Switch base xterm entry to 3.3 level. -# -# The following sets edit modes for GNU EMACS -# Local Variables: -# fill-prefix:"\t" -# fill-column:75 -# End: -######## SHANTIH! SHANTIH! SHANTIH! diff --git a/src/libtermio/termcap.c b/src/libtermio/termcap.c deleted file mode 100644 index b92dd7c688b..00000000000 --- a/src/libtermio/termcap.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * This code contains changes by - * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - * - * The conditions and no-warranty notice below apply to these changes. - * - * - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "common.h" - -/* from termcap.c 5.1 (Berkeley) 6/5/85 */ - -#if 0 /* GR */ -#define TCBUFSIZE 1024 -#else -#include "termcap.h" -#endif - -#define E_TERMCAP "/etc/termcap" - -#define MAXHOP 32 /* max number of tc= indirections */ - -#include -#include -#include -#include -#include -#include -#include - -#include "bu/log.h" -#include "bu/str.h" - -/* - * termcap - routines for dealing with the terminal capability data base - * - * BUG: Should use a "last" pointer in tbuf, so that searching - * for capabilities alphabetically would not be a n**2/2 - * process when large numbers of capabilities are given. - * Note: If we add a last pointer now we will screw up the - * tc capability. We really should compile termcap. - * - * Essentially all the work here is scanning and decoding escapes - * in string capabilities. We don't use stdio because the editor - * doesn't, and because living w/o it is not hard. - */ - -static char *tbuf; -static int hopcount; /* detect infinite loops in termcap, init 0 */ - -static int tnamatch(const char *); -static int tnchktc(void); -static char *tskip(register const char *); -static char *tdecode(register char *, char **); - -/* - * Tnamatch deals with name matching. The first field of the termcap - * entry is a sequence of names separated by |'s, so we compare - * against each such name. The normal : terminator after the last - * name (before the first field) stops us. - */ -static int -tnamatch(const char *np) -{ - register const char *Np; - register char *Bp; - - Bp = tbuf; - if (*Bp == '#') - return(0); - for (;;) { - for (Np = np; *Np && *Bp == *Np; Bp++, Np++) - continue; - if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) - return (1); - while (*Bp && *Bp != ':' && *Bp != '|') - Bp++; - if (*Bp == 0 || *Bp == ':') - return (0); - Bp++; - } -} - -/* - * tnchktc: check the last entry, see if it's tc=xxx. If so, - * recursively find xxx and append that entry (minus the names) - * to take the place of the tc=xxx entry. This allows termcap - * entries to say "like an HP2621 but doesn't turn on the labels". - * Note that this works because of the left to right scan. - */ -static int -tnchktc(void) -{ - register char *p, *q; - char tcname[16]; /* name of similar terminal */ - char tcbuf[TCBUFSIZE] = {0}; - char rmbuf[TCBUFSIZE] = {0}; - char *holdtbuf = tbuf, *holdtc; - int l; - - p = tbuf; - while (*p) { - holdtc = p = tskip(p); - if (!p) - return (0); - if (!*p) - break; - if (*p++ != 't' || *p == 0 || *p++ != 'c') - continue; - if (*p++ != '=') { - bad: bu_log("Bad termcap entry\n"); - return (0); - } - for (q = tcname; *p && *p != ':'; p++) { - if (q >= &tcname[sizeof tcname - 1]) - goto bad; - *q++ = *p; - } - *q = '\0'; - if (++hopcount > MAXHOP) { - bu_log("Infinite tc= loop\n"); - return (0); - } - if (tgetent(tcbuf, tcname) != 1) { - hopcount = 0; /* unwind recursion */ - tbuf = NULL; // Clear reference to stack address - return(0); - } - hopcount--; - tbuf = holdtbuf; - bu_strlcpy(rmbuf, &p[1], TCBUFSIZE); - for (q=tcbuf; *q != ':'; q++) - ; - l = holdtc - holdtbuf + strlen(rmbuf) + strlen(q); - if (l > TCBUFSIZE) { - bu_log("Termcap entry too long\n"); - break; - } - q++; - for (p = holdtc; *q; q++) - *p++ = *q; - bu_strlcpy(p, rmbuf, TCBUFSIZE); - p = holdtc; - } - return(1); -} - -/* - * Get an entry for terminal name in buffer bp, - * from the termcap file. Parse is very rudimentary; - * we just notice escaped newlines. - */ -int -tgetent(char *bp, const char *name) -{ - register char *cp; - register int c; - register int i = 0, cnt = 0; - char ibuf[TCBUFSIZE]; - int tf = -1; - - tbuf = bp; - - cp = getenv("TERMCAP"); - /* - * TERMCAP can have one of two things in it. It can be the - * name of a file to use instead of /etc/termcap. In this - * case it better start with a "/". Or it can be an entry to - * use so we don't have to read the file. In this case it - * has to already have the newlines crunched out. - */ - if (cp && *cp) { - if (*cp == '/') { - tf = open(cp, 0); - } else { - tbuf = cp; - c = tnamatch(name); - tbuf = bp; - if (c) { - bu_strlcpy(bp, cp, TCBUFSIZE); - return(tnchktc()); - } - } - } - -#ifdef B_TERMCAP - if (tf < 0) - tf = open(B_TERMCAP, 0); -#endif - -#ifdef E_TERMCAP - if (tf < 0) - tf = open(E_TERMCAP, 0); -#endif - - if (tf < 0) - return (-1); - for (;;) { - cp = bp; - for (;;) { - if (i == cnt) { - cnt = read(tf, ibuf, TCBUFSIZE); - if (cnt <= 0) { - close(tf); - return (0); - } - i = 0; - } - c = ibuf[i++]; - if (c == '\n') { - if (cp > bp && cp[-1] == '\\'){ - cp--; - continue; - } - break; - } - if (cp >= bp+TCBUFSIZE) { - bu_log("Termcap entry too long\n"); - break; - } else - *cp++ = c; - } - *cp = 0; - - /* - * The real work for the match. - */ - if (tnamatch(name)) { - close(tf); - return(tnchktc()); - } - } -} - -/* - * Skip to the next field. Notice that this is very dumb, not - * knowing about \: escapes or any such. If necessary, :'s can be put - * into the termcap file in octal. - */ -static char * -tskip(register const char *bp) -{ - if (!bp) { - return NULL; - } - - while (*bp && *bp != ':') - bp++; - if (*bp == ':') - bp++; - return (char *)bp; -} - -/* - * Return the (numeric) option id. - * Numeric options look like - * li#80 - * i.e. the option string is separated from the numeric value by - * a # character. If the option is not found we return -1. - * Note that we handle octal numbers beginning with 0. - */ -int -tgetnum(char *id) -{ - register int i, base; - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (!bp) - return -1; - if (*bp == 0) - return (-1); - if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) - continue; - if (*bp == '@') - return(-1); - if (*bp != '#') - continue; - bp++; - base = 10; - if (*bp == '0') - base = 8; - i = 0; - while (isdigit((*bp & 0377))) - i *= base, i += *bp++ - '0'; - return (i); - } -} - -/* - * Handle a flag option. - * Flag options are given "naked", i.e. followed by a : or the end - * of the buffer. Return 1 if we find the option, or 0 if it is - * not given. - */ -int -tgetflag(char *id) -{ - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (!bp) - return 0; - if (!*bp) - return (0); - if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { - if (!*bp || *bp == ':') - return (1); - else if (*bp == '@') - return(0); - } - } -} - -/* - * Get a string valued option. - * These are given as - * cl=^Z - * Much decoding is done on the strings, and the strings are - * placed in area, which is a ref parameter which is updated. - * No checking on area overflow. - */ -char * -tgetstr(char *id, char **area) -{ - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (!bp) - return 0; - if (!*bp) - return (0); - if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) - continue; - if (*bp == '@') - return(0); - if (*bp != '=') - continue; - bp++; - return (tdecode(bp, area)); - } -} - -/* - * Tdecode does the grung work to decode the - * string capability escapes. - */ -static char * -tdecode(register char *str, char **area) -{ - register char *cp; - register int c; - register char *dp; - int i; - - cp = *area; - while ((c = *str++) && c != ':') { - switch (c) { - - case '^': - c = *str++ & 037; - break; - - case '\\': - dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; - c = *str++; -nextc: - if (*dp++ == c) { - c = *dp++; - break; - } - dp++; - if (*dp) - goto nextc; - if (isdigit(c)) { - c -= '0', i = 2; - do - c <<= 3, c |= *str++ - '0'; - while (--i && isdigit(*str & 0377)); - } - break; - } - *cp++ = c; - } - *cp++ = 0; - str = *area; - *area = cp; - return (str); -} - diff --git a/src/libtermio/termcap.h b/src/libtermio/termcap.h deleted file mode 100644 index 99a81a7cb21..00000000000 --- a/src/libtermio/termcap.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This code contains changes by - * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - * - * The conditions and no-warranty notice below apply to these changes. - * - * - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * Header for termcap routines derived from 2.11 BSD. - */ - -#ifndef __LIBTERM_H__ -#define __LIBTERM_H__ - -#include "common.h" - -/* - * Size of the capability buffer string. - */ -#define TCBUFSIZE 2048 - -int tgetent(char *, const char *); -int tgetnum(char *); -int tgetflag(char *); -char *tgetstr(char *, char **); -char *tgoto(char *, int, int); -int tputs(const char *, int, int (*)(int)); - -#endif /* __LIBTERM_H__ */ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * c-basic-offset: 4 - * indent-tabs-mode: t - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libtermio/termio.c b/src/libtermio/termio.c deleted file mode 100644 index bd8d14f5800..00000000000 --- a/src/libtermio/termio.c +++ /dev/null @@ -1,527 +0,0 @@ -/* T E R M I O . C - * BRL-CAD - * - * Copyright (c) 2007-2023 United States Government as represented by - * the U.S. Army Research Laboratory. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this file; see the file named COPYING for more - * information. - */ -/** @file libtermio/termio.c - * - */ - -#include "common.h" - -#ifdef HAVE_SYS_FILE_H -# include -#endif - -#ifdef HAVE_SYS_IOCTL_COMPAT_H -# if defined(__FreeBSD__) && !defined(COMPAT_43TTY) /* TODO: figure out a better way, mebbe 43bsd tty semantics isn't right anymore? */ -# define COMPAT_43TTY 1 -# endif -# include -# if !defined(OCRNL) -# define OCRNL 0000010 -# endif - -#endif - -#include "bio.h" - -/* - * This file will work IFF one of these three flags is set: - * HAVE_TERMIOS_H use POXIX termios and tcsetattr() call with XOPEN flags - * SYSV use SysV Rel3 termio and TCSETA ioctl - * BSD use Version 7 / BSD sgttyb and TIOCSETP ioctl - */ - -#if defined(HAVE_MEMORY_H) -# include -#endif - - -/* - * Figure out the maximum number of files that can simultaneously be open - * by a process. - */ - -#if !defined(FOPEN_MAX) && defined(_NFILE) -# define FOPEN_MAX _NFILE -#endif -#if !defined(FOPEN_MAX) && defined(NOFILE) -# define FOPEN_MAX NOFILE -#endif -#if !defined(FOPEN_MAX) && defined(OPEN_MAX) -# define FOPEN_MAX OPEN_MAX -#endif -#if !defined(FOPEN_MAX) && defined(_SYS_OPEN) -# define FOPEN_MAX _SYS_OPEN -#endif -#if !defined(FOPEN_MAX) -# define FOPEN_MAX 32 -#endif - - -/* figure out how to do tab-expansion */ -#if !defined(TAB_EXPANSION) && defined(TAB3) -# define TAB_EXPANSION TAB3 -#endif -#if !defined(TAB_EXPANSION) && defined(XTABS) -# define TAB_EXPANSION XTABS -#endif -#if !defined(TAB_EXPANSION) && defined(OXTABS) -# define TAB_EXPANSION OXTABS -#endif -#if !defined(TAB_EXPANSION) && defined(TAB1) && defined(TAB2) -# define TAB_EXPANSION (TAB1 | TAB2) /* obsolete */ -#endif -#ifndef TAB_EXPANSION -# define TAB_EXPANSION 0 /* punt */ -#endif - - -#if defined(HAVE_TERMIOS_H) -# undef SYSV -# undef BSD -# include - -static struct termios save_tio[FOPEN_MAX], curr_tio[FOPEN_MAX]; - -#else /* !defined(HAVE_TERMIOS_H) */ - -# ifdef SYSV -# undef BSD -# include -# include -static struct termio save_tio[FOPEN_MAX], curr_tio[FOPEN_MAX]; -# endif /* SYSV */ - -# ifdef BSD -# undef SYSV -# include - -static struct sgttyb save_tio[FOPEN_MAX], curr_tio[FOPEN_MAX]; -# endif /* BSD */ - -#endif /* HAVE_TERMIOS_H */ - -#include "libtermio.h" - - -static int fileStatus[FOPEN_MAX]; - - -/* - Clear CBREAK mode, for file descriptor 'fd'. -*/ -void -clr_Cbreak(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags &= ~CBREAK; /* CBREAK mode OFF. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */ - curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */ - curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */ - curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */ - curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */ - (void)tcsetattr(fd, TCSAFLUSH, &curr_tio[fd]); -#endif - return; -} - -/* - Set CBREAK mode, 'fd'. -*/ -void -set_Cbreak(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags |= CBREAK; /* CBREAK mode ON. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ - curr_tio[fd].c_cc[VMIN] = 1; - curr_tio[fd].c_cc[VTIME] = 0; - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ - curr_tio[fd].c_cc[VMIN] = 1; - curr_tio[fd].c_cc[VTIME] = 0; - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Set cooked mode, 'fd'. -*/ -void -clr_Raw(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags &= ~RAW; /* Raw mode OFF. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */ - curr_tio[fd].c_lflag |= ISIG; /* Signals ON. */ - curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */ - curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */ - curr_tio[fd].c_lflag |= ISIG; /* Signals ON. */ - curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */ - curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */ - (void)tcsetattr(fd, TCSAFLUSH, &curr_tio[fd]); -#endif - return; -} - -/* - Set raw mode, 'fd'. -*/ -void -set_Raw(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags |= RAW; /* Raw mode ON. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ - curr_tio[fd].c_lflag &= ~ISIG; /* Signals OFF. */ - curr_tio[fd].c_cc[VMIN] = 1; - curr_tio[fd].c_cc[VTIME] = 0; - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */ - curr_tio[fd].c_lflag &= ~ISIG; /* Signals OFF. */ - curr_tio[fd].c_cc[VMIN] = 1; - curr_tio[fd].c_cc[VTIME] = 0; - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Set echo mode, 'fd'. -*/ -void -set_Echo(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags |= ECHO; /* Echo mode ON. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag |= ECHO; /* Echo mode ON. */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag |= ECHO; /* Echo mode ON. */ - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Clear echo mode, 'fd'. -*/ -void -clr_Echo(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags &= ~ECHO; /* Echo mode OFF. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_lflag &= ~ECHO; /* Echo mode OFF. */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_lflag &= ~ECHO; /* Echo mode OFF. */ - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Turn on tab expansion, 'fd'. -*/ -void -set_Tabs(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags |= TAB_EXPANSION; /* Tab expansion ON. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif - -#ifdef SYSV - curr_tio[fd].c_oflag |= TAB_EXPANSION; /* Tab expansion ON. */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif - -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_oflag |= TAB_EXPANSION; /* Tab expansion ON. */ - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Turn off tab expansion, 'fd'. -*/ -void -clr_Tabs(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags &= ~TAB_EXPANSION; /* Tab expans. OFF. */ - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV - curr_tio[fd].c_oflag &= ~TAB_EXPANSION; /* Tab expans. OFF. */ - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_oflag &= ~TAB_EXPANSION; /* Tab expans. OFF. */ - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Turn on "Hang up on last close", 'fd'. -*/ -void -set_HUPCL(int fd) -{ -#ifdef BSD - (void) ioctl(fd, TIOCHPCL, NULL); -#endif - -#ifdef SYSV - curr_tio[fd].c_cflag |= HUPCL; - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif - -#ifdef HAVE_TERMIOS_H - curr_tio[fd].c_cflag |= HUPCL; - (void)tcsetattr(fd, TCSANOW, &curr_tio[fd]); -#endif - return; -} - -/* - Turn off CR/LF mapping, fd. -*/ -void -clr_CRNL(int fd) -{ -#ifdef BSD - curr_tio[fd].sg_flags &= ~CRMOD; - (void) ioctl(fd, TIOCSETP, &curr_tio[fd]); -#endif -#ifdef SYSV -# if !defined(__FreeBSD__) - curr_tio[fd].c_oflag &= ~(ONLCR|OCRNL); -# endif - curr_tio[fd].c_iflag &= ~(ICRNL|INLCR); - (void) ioctl(fd, TCSETA, &curr_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H -# if !defined(__FreeBSD__) - curr_tio[fd].c_oflag &= ~(ONLCR|OCRNL); -# endif - curr_tio[fd].c_iflag &= ~(ICRNL|INLCR); - (void)tcsetattr(fd, TCSAFLUSH, &curr_tio[fd]); -#endif -} - -/* - Get the terminals output speed, 'fd'. -*/ -unsigned short -get_O_Speed(int fd) -{ -#ifdef BSD - return (unsigned short) save_tio[fd].sg_ospeed; -#endif -#ifdef SYSV - return save_tio[fd].c_cflag & CBAUD; -#endif -#ifdef HAVE_TERMIOS_H - return cfgetospeed(&save_tio[fd]); -#endif -} - -static void -copy_Tio( -#if defined(BSD) - struct sgttyb *to, struct sgttyb *from -#elif defined(SYSV) - struct termio *to, struct termio *from -#elif defined(HAVE_TERMIOS_H) - struct termios *to, struct termios*from -#endif -) -{ - (void)memcpy((char *) to, (char *) from, sizeof(*from)); - return; -} - -/* - Get and save terminal parameters, 'fd'. -*/ -void -save_Tty(int fd) -{ -#ifdef BSD - (void) ioctl(fd, TIOCGETP, &save_tio[fd]); -#endif -#ifdef SYSV - (void) ioctl(fd, TCGETA, &save_tio[fd]); -#endif -#ifdef HAVE_TERMIOS_H - (void)tcgetattr(fd, &save_tio[fd]); -#endif - copy_Tio(&curr_tio[fd], &save_tio[fd]); - return; -} - -/* - Set the terminal back to the mode that the user had last time - save_Tty() was called for 'fd'. -*/ -void -reset_Tty(int fd) -{ -#ifdef BSD - (void) ioctl(fd, TIOCSETP, &save_tio[fd]); /* Write setting. */ -#endif -#ifdef SYSV - (void) ioctl(fd, TCSETA, &save_tio[fd]); /* Write setting. */ -#endif -#ifdef HAVE_TERMIOS_H - (void)tcsetattr(fd, TCSAFLUSH, &save_tio[fd]); -#endif - return; -} - -/* - Save file status flags for 'fd'. -*/ -int -save_Fil_Stat(int fd) -{ - return fileStatus[fd] = fcntl(fd, F_GETFL, 0); -} - -/* - Restore file status flags for file desc. 'fd' to what they were the - last time saveFilStat(fd) was called. -*/ -int -reset_Fil_Stat(int fd) -{ - return fcntl(fd, F_SETFL, fileStatus[fd]); -} - -/* - Set non-blocking read on 'fd'. -*/ -int -set_O_NDELAY(int fd) -{ -#if defined(O_NDELAY) - return fcntl(fd, F_SETFL, O_NDELAY); -#elif defined(O_NONBLOCK) - return fcntl(fd, F_SETFL, O_NONBLOCK); -#elif defined(HAVE_TERMIOS_H) && defined(FNDELAY) - return fcntl(fd, F_SETFL, FNDELAY); -#endif -} - -void -prnt_Tio( - char *msg, -#if defined(BSD) - struct sgttyb *tio_ptr -#elif defined(SYSV) - struct termio *tio_ptr -#elif defined(HAVE_TERMIOS_H) - struct termios *tio_ptr -#else - void *tio_ptr -#endif -) -{ - register int i; - (void) fprintf(stderr, "%s :\n\r", msg); -#if defined(BSD) - (void) fprintf(stderr, "\tsg_ispeed=%d\n\r", (int) tio_ptr->sg_ispeed); - (void) fprintf(stderr, "\tsg_ospeed=%d\n\r", (int) tio_ptr->sg_ospeed); - (void) fprintf(stderr, "\tsg_erase='%c'\n\r", tio_ptr->sg_erase); - (void) fprintf(stderr, "\tsg_kill='%c'\n\r", tio_ptr->sg_kill); - (void) fprintf(stderr, "\tsg_flags=0x%x\n\r", tio_ptr->sg_flags); -#elif defined(SYSV) - (void) fprintf(stderr, "\tc_iflag=0x%x\n\r", tio_ptr->c_iflag); - (void) fprintf(stderr, "\tc_oflag=0x%x\n\r", tio_ptr->c_oflag); - (void) fprintf(stderr, "\tc_cflag=0x%x\n\r", tio_ptr->c_cflag); - (void) fprintf(stderr, "\tc_lflag=0x%x\n\r", tio_ptr->c_lflag); - (void) fprintf(stderr, "\tc_line=%c\n\r", tio_ptr->c_line); - for (i = 0; i < NCC; ++i) { - (void) fprintf(stderr, - "\tc_cc[%d]=0%o\n\r", - i, - tio_ptr->c_cc[i] - ); - } -#elif defined(HAVE_TERMIOS_H) - (void) fprintf(stderr, "\tc_iflag=0x%x\n\r", (unsigned int)tio_ptr->c_iflag); - (void) fprintf(stderr, "\tc_oflag=0x%x\n\r", (unsigned int)tio_ptr->c_oflag); - (void) fprintf(stderr, "\tc_cflag=0x%x\n\r", (unsigned int)tio_ptr->c_cflag); - (void) fprintf(stderr, "\tc_lflag=0x%x\n\r", (unsigned int)tio_ptr->c_lflag); - for (i = 0; i < NCCS; ++i) { - (void) fprintf(stderr, - "\tc_cc[%d]=0%o\n\r", - i, - tio_ptr->c_cc[i] - ); - } -#endif - return; -} - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/libtermio/tgoto.c b/src/libtermio/tgoto.c deleted file mode 100644 index 997921305fe..00000000000 --- a/src/libtermio/tgoto.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * This code contains changes by - * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - * - * The conditions and no-warranty notice below apply to these changes. - * - * - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "common.h" - -/* from tgoto.c 5.1 (Berkeley) 6/5/85 */ - -#include "termcap.h" - -#include "bu/str.h" - -#define CTRL(c) (c & 037) - -#define MAXRETURNSIZE 64 - -#ifdef __STDC__ -#include -#endif - -char *UP; -char *BC; - -/* - * Routine to perform cursor addressing. - * CM is a string containing printf type escapes to allow - * cursor addressing. We start out ready to print the destination - * line, and switch each time we print row or column. - * The following escapes are defined for substituting row/column: - * - * %d as in printf - * %2 like %2d - * %3 like %3d - * %. gives %c hacking special case characters - * %+x like %c but adding x first - * - * The codes below affect the state but don't use up a value. - * - * %>xy if value > x add y - * %r reverses row/column - * %i increments row/column (for one origin indexing) - * %% gives % - * %B BCD (2 decimal digits encoded in one byte) - * %D Delta Data (backwards bcd) - * - * all other characters are ``self-inserting''. - */ -char * -tgoto(char *CM, int destcol, int destline) -{ - static char result[MAXRETURNSIZE]; - static char added[10]; - char *cp = CM; - register char *dp = result; - register int c; - int oncol = 0; - register int which = destline; - - if (cp == 0) { -toohard: - /* - * ``We don't do that under BOZO's big top'' - */ - return ("OOPS"); - } - added[0] = 0; - while ((c = *cp++)) { - if (c != '%') { - *dp++ = c; - continue; - } - switch (c = *cp++) { - -#ifdef CM_N - case 'n': - destcol ^= 0140; - destline ^= 0140; - goto setwhich; -#endif - - case 'd': - if (which < 10) - goto one; - if (which < 100) - goto two; - /* fall into... */ - goto three; - case '3': -three: - *dp++ = (which / 100) | '0'; - which %= 100; - /* fall into... */ - goto two; - case '2': -two: - *dp++ = which / 10 | '0'; -one: - *dp++ = which % 10 | '0'; -swap: - oncol = 1 - oncol; -setwhich: - which = oncol ? destcol : destline; - continue; - -#ifdef CM_GT - case '>': - if (which > *cp++) - which += *cp++; - else - cp++; - continue; -#endif - - case '+': - which += *cp++; - /* fall into... */ - goto casedot; - - case '.': -casedot: - /* - * This code is worth scratching your head at for a - * while. The idea is that various weird things can - * happen to nulls, EOT's, tabs, and newlines by the - * tty driver, arpanet, and so on, so we don't send - * them if we can help it. - * - * Tab is taken out to get Ann Arbors to work, otherwise - * when they go to column 9 we increment which is wrong - * because bcd isn't continuous. We should take out - * the rest too, or run the thing through more than - * once until it doesn't make any of these, but that - * would make termlib (and hence pdp-11 ex) bigger, - * and also somewhat slower. This requires all - * programs which use termlib to stty tabs so they - * don't get expanded. They should do this anyway - * because some terminals use ^I for other things, - * like nondestructive space. - */ - if (which == 0 || which == CTRL('d') || /* which == '\t' || */ which == '\n') { - if (oncol || UP) /* Assumption: backspace works */ - /* - * Loop needed because newline happens - * to be the successor of tab. - */ - do { - const char *cstr = oncol ? (BC ? BC : "\b") : UP; - bu_strlcat(added, cstr, strlen(cstr)); - which++; - } while (which == '\n'); - } - *dp++ = which; - goto swap; - - case 'r': - oncol = 1; - goto setwhich; - - case 'i': - destcol++; - destline++; - which++; - continue; - - case '%': - *dp++ = c; - continue; - -#ifdef CM_B - case 'B': - which = (which/10 << 4) + which%10; - continue; -#endif - -#ifdef CM_D - case 'D': - which = which - 2 * (which%16); - continue; -#endif - - default: - goto toohard; - } - } - bu_strlcpy(dp, added, MAXRETURNSIZE); - return (result); -} diff --git a/src/libtermio/tputs.c b/src/libtermio/tputs.c deleted file mode 100644 index b39ea113f70..00000000000 --- a/src/libtermio/tputs.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This code contains changes by - * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - * - * The conditions and no-warranty notice below apply to these changes. - * - * - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "common.h" - -/* from tputs.c 5.1 (Berkeley) 6/5/85 */ - -#include - -#include "termcap.h" - -/* - * The following array gives the number of tens of milliseconds per - * character for each speed as returned by gtty. Thus since 300 - * baud returns a 7, there are 33.3 milliseconds per char at 300 baud. - */ -static -short tmspc10[] = { - 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 -}; - -short ospeed; -char PC; - -/* - * Put the character string cp out, with padding. - * The number of affected lines is affcnt, and the routine - * used to output one character is outc. - */ -int -tputs(const char *cp, int affcnt, int (*outc)(int)) -{ - register int i = 0; - register int mspc10; - - if (cp == 0) - return 1; - - /* - * Convert the number representing the delay. - */ - if (isdigit(*cp & 0377)) { - do - i = i * 10 + *cp++ - '0'; - while (isdigit(*cp & 0377)); - } - i *= 10; - if (*cp == '.') { - cp++; - if (isdigit(*cp & 0377)) - i += *cp - '0'; - /* - * Only one digit to the right of the decimal point. - */ - while (isdigit(*cp & 0377)) - cp++; - } - - /* - * If the delay is followed by a `*', then - * multiply by the affected lines count. - */ - if (*cp == '*') - cp++, i *= affcnt; - - /* - * The guts of the string. - */ - while (*cp) - (*outc)(*cp++); - - /* - * If no delay needed, or output speed is - * not comprehensible, then don't try to delay. - */ - if (i == 0) - return 1; - if (ospeed <= 0 || ospeed >= (short int)(sizeof tmspc10 / sizeof tmspc10[0])) - return 1; - - /* - * Round up by a half a character frame, - * and then do the delay. - * Too bad there are no user program accessible programmed delays. - * Transmitting pad characters slows many - * terminals down and also loads the system. - */ - mspc10 = tmspc10[ospeed]; - i += mspc10 / 2; - for (i /= mspc10; i > 0; i--) - (*outc)(PC); - return 1; -} diff --git a/src/libwdb/CMakeLists.txt b/src/libwdb/CMakeLists.txt index b426899cb21..5503147e565 100644 --- a/src/libwdb/CMakeLists.txt +++ b/src/libwdb/CMakeLists.txt @@ -41,7 +41,7 @@ set(LIBWDB_SOURCES wdb.c ) -BRLCAD_ADDLIB(libwdb "${LIBWDB_SOURCES}" "librt;libnmg;libbn;libbu;${OPENNURBS_LIBRARIES}") +BRLCAD_ADDLIB(libwdb "${LIBWDB_SOURCES}" "${libwdb_deps};${OPENNURBS_LIBRARIES}") set_target_properties(libwdb PROPERTIES VERSION 20.0.1 SOVERSION 20) CMAKEFILES(CMakeLists.txt) diff --git a/src/mged/CMakeLists.txt b/src/mged/CMakeLists.txt index ac91e5e7ed3..862cbca5c38 100644 --- a/src/mged/CMakeLists.txt +++ b/src/mged/CMakeLists.txt @@ -19,6 +19,7 @@ set(MGED_SOURCES edars.c edpipe.c edsol.c + f_db.c facedef.c fbserv.c grid.c @@ -55,9 +56,6 @@ endif (HAVE_WINDOWS_H) set(mged_libs libtclcad libged libwdb libdm libnmg ${WS2_32_LIBRARY} ${OPENGL32_LIBRARY}) -if(TARGET libtermio) - set(mged_libs ${mged_libs} libtermio) -endif(TARGET libtermio) # Ideally we'd build as GUI for Windows to avoid the command window popping up, # but I'm not sure if that would be a problem for scripting with mged.exe on @@ -76,6 +74,7 @@ if (BRLCAD_ENABLE_TCL) ${TCL_INCLUDE_PATH} ${TERMIO_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../libtermio ) if (TK_INCLUDE_PATH) set(MGED_INCLUDE_DIRS ${MGED_INCLUDE_DIRS} ${TK_INCLUDE_PATH}) diff --git a/src/mged/cmd.c b/src/mged/cmd.c index 2ca32574ace..0b61001578d 100644 --- a/src/mged/cmd.c +++ b/src/mged/cmd.c @@ -77,16 +77,44 @@ static int output_as_return = 1; Tk_Window tkwin = NULL; -/* The following is for GUI output hooks: contains name of function to - * run with output. - */ -static struct bu_vls tcl_output_hook = BU_VLS_INIT_ZERO; +/* GUI output hooks use this variable to store the Tcl function used to run to + * produce output. */ +static struct bu_vls tcl_output_cmd = BU_VLS_INIT_ZERO; + +/* Container to store up bu_log strings for eventual Tcl printing. This is + * done to ensure only one thread attempts to print to the Tcl output - bu_log + * may be called from multiple threads, and if the hook itself tries to print + * to Tcl Bad Things can happen. */ +static struct bu_vls tcl_log_str = BU_VLS_INIT_ZERO; /** * Used as a hook for bu_log output. Sends output to the Tcl * procedure whose name is contained in the vls "tcl_output_hook". - * Useful for user interface building. + * + * NOTE: There is a problem with this code - per Tcl's documentation + * (https://www.tcl.tk/doc/howto/thread_model.html) "errors will occur if you + * let more than one thread call into the same interpreter (e.g., with + * Tcl_Eval)" However, gui_output may be called from multiple threads + * during (say) a parallel raytrace, when lower level routines encounter + * problems and bu_log about them. + * + * On some platforms we seem to get away with this despite the Tcl + * documentation warning, but on Windows we've frequently seen the MGED command + * prompt locking up - usually when we have heavy bu_log output from librt. + * Since we're going to freeze up anyway, in that situation we accumulate + * the output in a vls buffer rather than trying to force it to the Tcl + * prompt - this avoids putting the Tcl interp in a problematic state. + * Unfortunately, this comes at the expense of intermediate feedback reaching + * the end user - because ged_exec calls are made from the main thread, + * they are blocking as far as the refresh() call is concerned and we don't + * see any bu_log output until the command completes. + * + * The correct fix here is to set up a separate thread for ged_exec calls + * that doesn't block the main GUI thread. That way, the intermediate + * results being accumulated into the tcl_log_str buffer can be flushed + * to the Tcl command prompt by refresh() while the GED command is still + * running. Not clear yet how much effort that will take to implement. */ int gui_output(void *clientData, void *str) @@ -104,7 +132,7 @@ gui_output(void *clientData, void *str) } Tcl_DStringInit(&tclcommand); - (void)Tcl_DStringAppendElement(&tclcommand, bu_vls_addr(&tcl_output_hook)); + (void)Tcl_DStringAppendElement(&tclcommand, bu_vls_addr(&tcl_output_cmd)); (void)Tcl_DStringAppendElement(&tclcommand, (const char *)str); save_result = Tcl_GetObjResult(INTERP); @@ -120,6 +148,49 @@ gui_output(void *clientData, void *str) len = (int)strlen((const char *)str); return len; } +#if 0 +// Version of the above callback that just accumulates output in a buffer +// rather than writing it immediately to the interp - should be a starting +// point when we work on mulithreading ged_exec calls +int +gui_output(void *UNUSED(clientData), void *str) +{ + bu_semaphore_acquire(BU_SEM_SYSCALL); + bu_vls_printf(&tcl_log_str, "%s", (const char *)str); + bu_semaphore_release(BU_SEM_SYSCALL); + int len = (int)strlen((const char *)str); + return len; +} +#endif + +void +mged_pr_output(Tcl_Interp *interp) +{ + bu_semaphore_acquire(BU_SEM_SYSCALL); + if (!bu_vls_strlen(&tcl_output_cmd)) + bu_vls_sprintf(&tcl_output_cmd, "output_callback"); + + if (bu_vls_strlen(&tcl_log_str)) { + Tcl_DString tclcommand; + Tcl_DStringInit(&tclcommand); + (void)Tcl_DStringAppendElement(&tclcommand, bu_vls_cstr(&tcl_output_cmd)); + (void)Tcl_DStringAppendElement(&tclcommand, bu_vls_cstr(&tcl_log_str)); + Tcl_Obj *save_result = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(save_result); + Tcl_Eval(interp, Tcl_DStringValue(&tclcommand)); + Tcl_SetObjResult(interp, save_result); + Tcl_DecrRefCount(save_result); + Tcl_DStringFree(&tclcommand); + bu_vls_trunc(&tcl_log_str, 0); + } + + bu_semaphore_release(BU_SEM_SYSCALL); +} + +#define GED_OUTPUT do { \ + mged_pr_output(interpreter);\ + Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); \ +} while (0) int @@ -167,7 +238,7 @@ cmd_ged_edit_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, c return TCL_OK; ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret & GED_HELP) return TCL_OK; @@ -200,7 +271,7 @@ cmd_ged_simulate_wrapper(ClientData clientData, Tcl_Interp *interpreter, int arg ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret & GED_HELP) return TCL_OK; @@ -230,7 +301,7 @@ cmd_ged_info_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, c if (argc >= 2) { (void)(*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; } else { if ((argc == 1) && (STATE == ST_S_EDIT)) { argc = 2; @@ -242,13 +313,13 @@ cmd_ged_info_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, c av[1] = (const char *)LAST_SOLID(bdata)->d_namep; av[argc] = (const char *)NULL; (void)(*ctp->ged_func)(GEDP, argc, (const char **)av); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; } } bu_free((void *)av, "cmd_ged_info_wrapper: av"); } else { (void)(*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; } } @@ -266,7 +337,7 @@ cmd_ged_erase_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, return TCL_OK; ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -333,7 +404,7 @@ cmd_ged_gqa(ClientData clientData, Tcl_Interp *interpreter, int argc, const char } ret = (*ctp->ged_func)(GEDP, GEDP->ged_gdp->gd_rt_cmd_len, (const char **)GEDP->ged_gdp->gd_rt_cmd); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; bu_free(GEDP->ged_gdp->gd_rt_cmd, "free gd_rt_cmd"); GEDP->ged_gdp->gd_rt_cmd = NULL; @@ -404,9 +475,12 @@ cmd_ged_in(ClientData clientData, Tcl_Interp *interpreter, int argc, const char } ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - if (ret & GED_MORE) + if (ret & GED_MORE) { Tcl_AppendResult(interpreter, MORE_ARGS_STR, NULL); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + } else { + GED_OUTPUT; + } if (dont_draw) { if (ret & GED_HELP || ret == BRLCAD_OK) @@ -518,9 +592,12 @@ cmd_ged_inside(ClientData clientData, Tcl_Interp *interpreter, int argc, const c ret = ged_exec(GEDP, argc, (const char **)argv); } - if (ret & GED_MORE) + if (ret & GED_MORE) { Tcl_AppendResult(interpreter, MORE_ARGS_STR, NULL); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + } else { + GED_OUTPUT; + } if (ret & GED_HELP) { (void)signal(SIGINT, SIG_IGN); @@ -560,9 +637,12 @@ cmd_ged_more_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, c return TCL_OK; ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - if (ret & GED_MORE) + if (ret & GED_MORE) { Tcl_AppendResult(interpreter, MORE_ARGS_STR, NULL); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + } else { + GED_OUTPUT; + } if (ret & GED_HELP) return TCL_OK; @@ -620,9 +700,12 @@ cmd_ged_plain_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, } #endif - if (ret & GED_MORE) + if (ret & GED_MORE) { Tcl_AppendResult(interpreter, MORE_ARGS_STR, NULL); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + } else { + GED_OUTPUT; + } /* redraw any objects specified that are already drawn */ if (argc > 1) { @@ -689,7 +772,7 @@ cmd_ged_view_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, c GEDP->ged_gvp = view_state->vs_gvp; ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret & GED_HELP) return TCL_OK; @@ -723,7 +806,7 @@ cmd_ged_dm_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, con GEDP->ged_gvp->dmp = (void *)mged_curr_dm->dm_dmp; ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; (void)signal(SIGINT, SIG_IGN); @@ -803,13 +886,14 @@ cmd_output_hook(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc /* Also, don't allow silly infinite loops. */ if (BU_STR_EQUAL(argv[1], argv[0])) { - Tcl_AppendResult(interpreter, "Don't be silly.", (char *)NULL); + Tcl_AppendResult(interpreter, "Detected potential infinite loop in cmd_output_hook.", (char *)NULL); return TCL_ERROR; } - /* Set up the hook! */ - bu_vls_init(&tcl_output_hook); - bu_vls_strcpy(&tcl_output_hook, argv[1]); + /* Set up the command */ + bu_vls_sprintf(&tcl_output_cmd, "%s", argv[1]); + + /* Set up the libbu hook */ bu_log_add_hook(gui_output, (void *)interpreter); Tcl_ResetResult(interpreter); @@ -1739,7 +1823,7 @@ cmd_nmg_collapse(ClientData clientData, Tcl_Interp *interpreter, int argc, const return TCL_OK; ret = ged_exec(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -1773,7 +1857,7 @@ cmd_units(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, cons sf = DBIP->dbi_base2local; ret = ged_exec(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -1801,7 +1885,7 @@ cmd_search(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, con return TCL_OK; ret = ged_exec(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -1827,7 +1911,7 @@ cmd_tol(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, const return TCL_OK; ret = ged_exec(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -1992,7 +2076,7 @@ cmd_shaded_mode(ClientData UNUSED(clientData), } ret = ged_exec(GEDP, argc, (const char **)argv); - Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); + GED_OUTPUT; if (ret) return TCL_ERROR; @@ -2027,6 +2111,7 @@ cmd_ps(ClientData UNUSED(clientData), av[2] = NULL; ret = ged_exec(GEDP, 2, (const char **)av); /* For the next couple releases, print a rename notice */ + mged_pr_output(interpreter); Tcl_AppendResult(interpreter, "(Note: former 'ps' command has been renamed to 'postscript')\n", NULL); Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL); return (ret) ? TCL_ERROR : TCL_OK; diff --git a/src/mged/f_db.c b/src/mged/f_db.c new file mode 100644 index 00000000000..f341665dbc5 --- /dev/null +++ b/src/mged/f_db.c @@ -0,0 +1,473 @@ +/* F _ D B . C + * BRL-CAD + * + * Copyright (c) 1993-2023 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file mged/f_db.c + * + * Multiple-display Graphics EDitor (MGED) specific wrappers around + * opendb/closedb commands. + * + */ + +#include "common.h" +#include +#include "bu/getopt.h" +#include "bu/units.h" +#include "ged.h" +#include "tclcad.h" + +/* private */ +#include "./cmd.h" +#include "./mged.h" + +/* defined in chgmodel.c */ +extern void set_localunit_TclVar(void); + +/* Shorthand for open/close db callback function pointer type */ +typedef void (*db_clbk_t )(struct ged *, void *); + +void +mged_output_handler(struct ged *UNUSED(gp), char *line) +{ + if (line) + bu_log("%s", line); +} + +void +mged_refresh_handler(void *UNUSED(clientdata)) +{ + view_state->vs_flag = 1; + refresh(); +} + +static void +_post_opendb_failed(struct ged *gedp, struct mged_opendb_ctx *ctx) +{ + char line[128]; + int argc = ctx->argc; + const char **argv = ctx->argv; + const char *fname = argv[argc-1]; + /* + * Check to see if we can access the database + */ + if (bu_file_exists(fname, NULL)) { + if (!bu_file_readable(fname)) { + bu_log("ERROR: Unable to read from %s\n", fname); + ctx->ret = TCL_ERROR; + return; + } + + bu_log("ERROR: Unable to open %s as geometry database file\n", fname); + ctx->ret = TCL_ERROR; + return; + } + + /* Did the caller specify not creating a new database? If so, + * we're done */ + if (ctx->no_create) { + ctx->ret = TCL_ERROR; + return; + } + + /* File does not exist, but nobody told us one way or the other + * about creation - ask */ + if (interactive && !ctx->force_create) { + if (mged_init_flag) { + if (classic_mged) { + bu_log("Create new database (y|n)[n]? "); + (void)bu_fgets(line, sizeof(line), stdin); + if (bu_str_false(line)) { + bu_log("Warning: no database is currently open!\n"); + ctx->ret = TCL_ERROR; + return; + } + } else { + struct bu_vls vls = BU_VLS_INIT_ZERO; + int status; + + if (dpy_string != (char *)NULL) + bu_vls_printf(&vls, "cad_dialog .createdb %s \"Create New Database?\" \"Create new database named %s?\" \"\" 0 Yes No Quit", + dpy_string, fname); + else + bu_vls_printf(&vls, "cad_dialog .createdb :0 \"Create New Database?\" \"Create new database named %s?\" \"\" 0 Yes No Quit", + fname); + + status = Tcl_Eval(ctx->interpreter, bu_vls_addr(&vls)); + + bu_vls_free(&vls); + + if (status != TCL_OK || Tcl_GetStringResult(ctx->interpreter)[0] == '2') { + ctx->ret = TCL_ERROR; + return; + } + + if (Tcl_GetStringResult(ctx->interpreter)[0] == '1') { + bu_log("opendb: no database is currently opened!\n"); + ctx->ret = TCL_OK; + return; + } + } /* classic */ + } else { + /* not initializing mged */ + if (argc == 2) { + /* need to reset this before returning */ + Tcl_AppendResult(ctx->interpreter, MORE_ARGS_STR, "Create new database (y|n)[n]? ", + (char *)NULL); + bu_vls_printf(&curr_cmd_list->cl_more_default, "n"); + ctx->ret = TCL_ERROR; + return; + } + } + } + + if (ctx->post_open_cnt < 2) { + const char *av[3]; + av[0] = "opendb"; + av[1] = "-c"; + av[2] = fname; + ctx->ged_ret = ged_exec(gedp, 3, (const char **)av); + } + + if (gedp->dbip == DBI_NULL) { + ctx->ret = TCL_ERROR; + + if (mged_init_flag) { + /* we need to use bu_log here */ + bu_log("opendb: failed to create %s\n", fname); + bu_log("opendb: no database is currently opened!\n"); + return; + } + + Tcl_AppendResult(ctx->interpreter, "opendb: failed to create ", fname, "\n", (char *)NULL); + if (DBIP == DBI_NULL) + Tcl_AppendResult(ctx->interpreter, "opendb: no database is currently opened!", (char *)NULL); + + return; + } + + ctx->created_new_db = 1; + bu_vls_printf(gedp->ged_result_str, "The new database %s was successfully created.\n", fname); +} + +void +mged_pre_opendb_clbk(struct ged *UNUSED(gedp), void *ctx) +{ + struct mged_opendb_ctx *mctx = (struct mged_opendb_ctx *)ctx; + mctx->force_create = 0; + mctx->no_create = 1; + mctx->created_new_db = 0; + mctx->ret = 0; + mctx->ged_ret = 0; +} + +void +mged_post_opendb_clbk(struct ged *gedp, void *ctx) +{ + struct mged_opendb_ctx *mctx = (struct mged_opendb_ctx *)ctx; + mctx->post_open_cnt++; + + /* Sync global to GED results */ + DBIP = gedp->dbip; + + if (DBIP == DBI_NULL || mctx->old_dbip == gedp->dbip) { + _post_opendb_failed(gedp, mctx); + mctx->post_open_cnt--; + return; + } + + /* Opened database file */ + mctx->old_dbip = gedp->dbip; + if (DBIP->dbi_read_only) + bu_vls_printf(gedp->ged_result_str, "%s: READ ONLY\n", DBIP->dbi_filename); + + /* increment use count for gedp db instance */ + (void)db_clone_dbi(DBIP, NULL); + + /* Provide LIBWDB C access to the on-disk database */ + if ((WDBP = wdb_dbopen(DBIP, RT_WDB_TYPE_DB_DISK)) == RT_WDB_NULL) { + Tcl_AppendResult(mctx->interpreter, "wdb_dbopen() failed?\n", (char *)NULL); + mctx->ret = TCL_ERROR; + mctx->post_open_cnt--; + return; + } + + /* increment use count for tcl db instance */ + (void)db_clone_dbi(DBIP, NULL); + + /* Establish LIBWDB TCL access to both disk and in-memory databases */ + + /* initialize rt_wdb */ + bu_vls_init(&WDBP->wdb_name); + bu_vls_strcpy(&WDBP->wdb_name, MGED_DB_NAME); + + WDBP->wdb_interp = mctx->interpreter; + + /* append to list of rt_wdb's */ + BU_LIST_APPEND(&RTG.rtg_headwdb.l, &WDBP->l); + + /* This creates a "db" command object */ + + /* Beware, returns a "token", not TCL_OK. */ + (void)Tcl_CreateCommand((Tcl_Interp *)WDBP->wdb_interp, MGED_DB_NAME, (Tcl_CmdProc *)wdb_cmd, (ClientData)WDBP, wdb_deleteProc); + + /* Return new function name as result */ + Tcl_AppendResult((Tcl_Interp *)WDBP->wdb_interp, MGED_DB_NAME, (char *)NULL); + + /* This creates the ".inmem" in-memory geometry container and sets + * up the GUI. + */ + { + struct bu_vls cmd = BU_VLS_INIT_ZERO; + + // Stash the result string state prior to doing the following Tcl commands. + // get_dbip in particular uses it... + struct bu_vls tmp_gedr = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&tmp_gedr, "%s", bu_vls_cstr(gedp->ged_result_str)); + + bu_vls_printf(&cmd, "wdb_open %s inmem [get_dbip]", MGED_INMEM_NAME); + if (Tcl_Eval(mctx->interpreter, bu_vls_addr(&cmd)) != TCL_OK) { + bu_vls_sprintf(gedp->ged_result_str, "%s\n%s\n", Tcl_GetStringResult(mctx->interpreter), Tcl_GetVar(mctx->interpreter, "errorInfo", TCL_GLOBAL_ONLY)); + Tcl_AppendResult(mctx->interpreter, bu_vls_addr(gedp->ged_result_str), (char *)NULL); + bu_vls_free(&cmd); + mctx->ret = TCL_ERROR; + return; + } + + /* Perhaps do something special with the GUI */ + bu_vls_trunc(&cmd, 0); + bu_vls_printf(&cmd, "opendb_callback {%s}", DBIP->dbi_filename); + (void)Tcl_Eval(mctx->interpreter, bu_vls_addr(&cmd)); + + bu_vls_strcpy(&cmd, "local2base"); + Tcl_UnlinkVar(mctx->interpreter, bu_vls_addr(&cmd)); + Tcl_LinkVar(mctx->interpreter, bu_vls_addr(&cmd), (char *)&local2base, TCL_LINK_DOUBLE|TCL_LINK_READ_ONLY); + + bu_vls_strcpy(&cmd, "base2local"); + Tcl_UnlinkVar(mctx->interpreter, bu_vls_addr(&cmd)); + Tcl_LinkVar(mctx->interpreter, bu_vls_addr(&cmd), (char *)&base2local, TCL_LINK_DOUBLE|TCL_LINK_READ_ONLY); + + // Restore the pre Tcl ged_result_str + bu_vls_sprintf(gedp->ged_result_str, "%s", bu_vls_cstr(&tmp_gedr)); + bu_vls_free(&tmp_gedr); + + bu_vls_free(&cmd); + } + + set_localunit_TclVar(); + + /* Print title/units information */ + if (interactive) { + bu_vls_printf(gedp->ged_result_str, "%s (units=%s)\n", DBIP->dbi_title, + bu_units_string(DBIP->dbi_local2base)); + } + + /* + * We have an old database version AND we're not in the process of + * creating a new database. + */ + if (db_version(DBIP) < 5 && !mctx->created_new_db) { + if (mged_db_upgrade) { + if (mged_db_warn) + bu_vls_printf(gedp->ged_result_str, "Warning:\n\tDatabase version is old.\n\tConverting to the new format.\n"); + + (void)Tcl_Eval(mctx->interpreter, "after idle dbupgrade -f y"); + } else { + if (mged_db_warn) { + if (classic_mged) + bu_vls_printf(gedp->ged_result_str, "Warning:\n\tDatabase version is old.\n\tSee the dbupgrade command."); + else + bu_vls_printf(gedp->ged_result_str, "Warning:\n\tDatabase version is old.\n\tSelect Tools-->Upgrade Database for info."); + } + } + } + + Tcl_ResetResult(mctx->interpreter); + Tcl_AppendResult(mctx->interpreter, bu_vls_addr(gedp->ged_result_str), (char *)NULL); + + /* Update the background colors now that we have a file open */ + cs_set_bg(NULL, NULL, NULL, NULL, NULL); + + mctx->post_open_cnt--; + mctx->ret = TCL_OK; +} + +void +mged_pre_closedb_clbk(struct ged *UNUSED(gedp), void *ctx) +{ + struct mged_opendb_ctx *mctx = (struct mged_opendb_ctx *)ctx; + + /* Close the Tcl database objects */ + Tcl_Eval(mctx->interpreter, "rename " MGED_DB_NAME " \"\"; rename .inmem \"\""); +} + +void +mged_post_closedb_clbk(struct ged *UNUSED(gedp), void *ctx) +{ + struct mged_opendb_ctx *mctx = (struct mged_opendb_ctx *)ctx; + mctx->old_dbip = NULL; + WDBP = RT_WDB_NULL; + DBIP = DBI_NULL; +} + + +/** + * Close the current database, if open, and then open a new database. May also + * open a display manager, if interactive and none selected yet. + * + * Syntax is that of opendb from libged, with one addition - the last argument + * can be an optional 'y' or 'n' indicating whether to create the database if + * it does not exist. This is used to avoid triggering MGED's interactive + * prompting if presented with a filename that doesn't exist. + * + * Returns TCL_OK if database was opened, TCL_ERROR if database was + * NOT opened (and the user didn't abort). + */ +int +f_opendb(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, const char *argv[]) +{ + struct mged_opendb_ctx ctx; + + if (argc <= 1) { + /* Invoked without args, return name of current database */ + + if (DBIP != DBI_NULL) { + Tcl_AppendResult(interpreter, DBIP->dbi_filename, (char *)NULL); + return TCL_OK; + } + + Tcl_AppendResult(interpreter, "", (char *)NULL); + return TCL_OK; + } + + argc--; argv++; + + /* For the most part GED handles the options, but there is one + * exception - the y/n option at the end of the command. If + * present, we replace that with a -c creation flag */ + ctx.post_open_cnt = 0; + ctx.force_create = 0; + ctx.no_create = 0; + ctx.created_new_db = 0; + ctx.interpreter = interpreter; + ctx.ret = TCL_OK; + if (BU_STR_EQUIV("y", argv[argc-1]) || BU_STR_EQUIV("n", argv[argc-1])) { + if (BU_STR_EQUIV("y", argv[argc-1])) + ctx.force_create = 1; + if (BU_STR_EQUIV("n", argv[argc-1])) + ctx.no_create = 1; + + argv[argc-1] = NULL; + argc--; + } + + // In order for MGED to work with GED calls that aren't prompted by + // f_opendb or f_closedb, we must have a default data container available, + // and callbacks to manage a default ctx. However, if we're going the + // f_opendb route, our options are handled a bit differently - use a local + // data container for this call and stash the default. + void (*pre_opendb_clbk)(struct ged *, void *) = GEDP->ged_pre_opendb_callback; + void (*post_opendb_clbk)(struct ged *, void *) = GEDP->ged_post_opendb_callback; + void (*pre_closedb_clbk)(struct ged *, void *) = GEDP->ged_pre_closedb_callback; + void (*post_closedb_clbk)(struct ged *, void *) = GEDP->ged_post_closedb_callback; + void *gctx = GEDP->ged_db_callback_udata; + + // Assign the local values + GEDP->ged_pre_opendb_callback = NULL; + GEDP->ged_post_opendb_callback = &mged_post_opendb_clbk; + GEDP->ged_pre_closedb_callback = &mged_pre_closedb_clbk; + GEDP->ged_post_closedb_callback = &mged_post_closedb_clbk; + GEDP->ged_db_callback_udata = (void *)&ctx; + + const char **av = (const char **)bu_calloc(argc+2, sizeof(const char *), "av"); + int ind = 0; + av[ind] = "opendb"; + ind++; + if (ctx.force_create) { + av[ind] = "-c"; + ind++; + } + for (int i = 0; i < argc; i++) + av[i+ind] = argv[i]; + + ctx.argv = av; + ctx.argc = argc+ind; + + ctx.ged_ret = ged_exec(GEDP, argc+ind, (const char **)av); + + // Done - restore standard values + GEDP->ged_pre_opendb_callback = pre_opendb_clbk; + GEDP->ged_post_opendb_callback = post_opendb_clbk; + GEDP->ged_pre_closedb_callback = pre_closedb_clbk; + GEDP->ged_post_closedb_callback = post_closedb_clbk; + GEDP->ged_db_callback_udata = gctx; + + if (ctx.ged_ret == GED_HELP) { + Tcl_Eval(interpreter, "help opendb"); + } + + return ctx.ret; +} + + +/** + * Close the current database, if open. + */ +int +f_closedb(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, const char *argv[]) +{ + // For the most part when it comes to close, the default + // callbacks should be fine, but since f_closedb potentially + // specifies a Tcl_Interp prepare a context to be sure + // we're using the one expected. + struct mged_opendb_ctx ctx; + ctx.interpreter = interpreter; + ctx.ret = TCL_OK; + + if (argc != 1) { + Tcl_AppendResult(interpreter, "Unexpected argument [%s]\n", (const char *)argv[1], NULL); + Tcl_Eval(interpreter, "help closedb"); + return TCL_ERROR; + } + + if (DBIP == DBI_NULL) { + Tcl_AppendResult(interpreter, "No database is open\n", NULL); + return TCL_OK; + } + + void *gctx = GEDP->ged_db_callback_udata; + GEDP->ged_db_callback_udata = (void *)&ctx; + + const char *av[2]; + av[0] = "closedb"; + av[1] = NULL; + ged_exec(GEDP, 1, (const char **)av); + + GEDP->ged_db_callback_udata = gctx; + + return ctx.ret; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/mged/grid.c b/src/mged/grid.c index a9745296f57..22384a87597 100644 --- a/src/mged/grid.c +++ b/src/mged/grid.c @@ -47,6 +47,7 @@ static void set_grid_res(const struct bu_structparse *, const char *, void *, co struct bv_grid_state default_grid_state = { /* rc */ 1, /* draw */ 0, + /* non-adaptive*/ 0, /* snap */ 0, /* anchor */ VINIT_ZERO, /* res_h */ 1.0, diff --git a/src/mged/mged.c b/src/mged/mged.c index 4c849c87bee..6c60c587de3 100644 --- a/src/mged/mged.c +++ b/src/mged/mged.c @@ -67,8 +67,10 @@ #include "vmath.h" #include "bn.h" #include "raytrace.h" -#include "libtermio.h" -#include "rt/db4.h" +#ifndef HAVE_WINDOWS_H +# define LIBTERMIO_IMPLEMENTATION +# include "libtermio.h" +#endif #include "bv/util.h" #include "ged.h" #include "tclcad.h" @@ -157,7 +159,7 @@ int cbreak_mode = 0; /* >0 means in cbreak_mode */ /* The old mged gui is temporarily the default. */ int old_mged_gui=1; -static int mged_init_flag = 1; /* >0 means in initialization stage */ +int mged_init_flag = 1; /* >0 means in initialization stage */ size_t input_str_index = 0; @@ -181,7 +183,7 @@ int mged_db_warn = 0; int mged_db_upgrade = 0; /* force creation of specific database versions */ -int mged_db_version = 5; +int mged_db_version = BRLCAD_DB_FORMAT_LATEST; struct bn_tol mged_tol; /* calculation tolerance */ struct bg_tess_tol mged_ttol; /* XXX needs to replace mged_abs_tol, et.al. */ @@ -2265,6 +2267,13 @@ refresh(void) int64_t elapsed_time, start_time = bu_gettime(); int do_time = 0; + /* Print any text output that has accumulated to the command prompt + * TODO - this is currently a no-op because the gui_output callback + * is still in the old form of trying to immediately print the bu_log + * output to the interp. */ + mged_pr_output(INTERP); + + /* Display Manager / Views */ for (size_t di = 0; di < BU_PTBL_LEN(&active_dm_set); di++) { struct mged_dm *p = (struct mged_dm *)BU_PTBL_GET(&active_dm_set, di); if (!p->dm_view_state) @@ -2541,414 +2550,6 @@ mged_finish(int exitcode) } -static void -mged_output_handler(struct ged *UNUSED(gp), char *line) -{ - if (line) - bu_log("%s", line); -} - - -static void -mged_refresh_handler(void *UNUSED(clientdata)) -{ - view_state->vs_flag = 1; - refresh(); -} - - -/** - * Close the current database, if open, and then open a new database. - * May also open a display manager, if interactive and none selected - * yet. - * - * argv[1] is the filename. - * - * argv[2] is optional 'y' or 'n' indicating whether to create the - * database if it does not exist. - * - * Returns TCL_OK if database was opened, TCL_ERROR if database was - * NOT opened (and the user didn't abort). - */ -int -f_opendb(ClientData clientData, Tcl_Interp *interpreter, int argc, const char *argv[]) -{ - struct db_i *save_dbip = DBI_NULL; - struct mater *save_materp = MATER_NULL; - struct bu_vls msg = BU_VLS_INIT_ZERO; /* use this to hold returned message */ - int created_new_db = 0; - int c; - int flip_v4 = 0; - - if (argc <= 1) { - /* Invoked without args, return name of current database */ - - if (DBIP != DBI_NULL) { - Tcl_AppendResult(interpreter, DBIP->dbi_filename, (char *)NULL); - return TCL_OK; - } - - Tcl_AppendResult(interpreter, "", (char *)NULL); - return TCL_OK; - } - - /* handle getopt arguments */ - bu_optind = 1; - while ((c = bu_getopt(argc, (char * const *)argv, "f")) != -1) { - switch (c) { - case 'f': - flip_v4=1; - break; - } - } - argc -= (bu_optind - 1); - argv += (bu_optind - 1); - - /* validate arguments */ - if (argc > 3 - || (argc == 2 - && strlen(argv[1]) == 0) - || (argc == 3 - && !BU_STR_EQUAL("y", argv[2]) - && !BU_STR_EQUAL("Y", argv[2]) - && !BU_STR_EQUAL("n", argv[2]) - && !BU_STR_EQUAL("N", argv[2]))) - { - Tcl_Eval(interpreter, "help opendb"); - return TCL_ERROR; - } - - save_dbip = DBIP; - DBIP = DBI_NULL; - save_materp = rt_material_head(); - rt_new_material_head(MATER_NULL); - - /* Get input file */ - if (((DBIP = db_open(argv[1], DB_OPEN_READWRITE)) == DBI_NULL) && - ((DBIP = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL)) { - char line[128]; - - /* - * Check to see if we can access the database - */ - if (bu_file_exists(argv[1], NULL)) { - /* need to reset things before returning */ - DBIP = save_dbip; - rt_new_material_head(save_materp); - - if (!bu_file_readable(argv[1])) { - bu_log("ERROR: Unable to read from %s\n", argv[1]); - bu_vls_free(&msg); - return TCL_ERROR; - } - - bu_log("ERROR: Unable to open %s as geometry database file\n", argv[1]); - bu_vls_free(&msg); - return TCL_ERROR; - } - - /* File does not exist */ - if (interactive && argc < 3) { - if (mged_init_flag) { - if (classic_mged) { - bu_log("Create new database (y|n)[n]? "); - (void)bu_fgets(line, sizeof(line), stdin); - if (bu_str_false(line)) { - bu_log("Warning: no database is currently open!\n"); - bu_vls_free(&msg); - return TCL_OK; - } - } else { - struct bu_vls vls = BU_VLS_INIT_ZERO; - int status; - - if (dpy_string != (char *)NULL) - bu_vls_printf(&vls, "cad_dialog .createdb %s \"Create New Database?\" \"Create new database named %s?\" \"\" 0 Yes No Quit", - dpy_string, argv[1]); - else - bu_vls_printf(&vls, "cad_dialog .createdb :0 \"Create New Database?\" \"Create new database named %s?\" \"\" 0 Yes No Quit", - argv[1]); - - status = Tcl_Eval(interpreter, bu_vls_addr(&vls)); - - bu_vls_free(&vls); - - if (status != TCL_OK || Tcl_GetStringResult(interpreter)[0] == '2') { - bu_vls_free(&msg); - return TCL_ERROR; - } - - if (Tcl_GetStringResult(interpreter)[0] == '1') { - bu_log("opendb: no database is currently opened!\n"); - bu_vls_free(&msg); - return TCL_OK; - } - } /* classic */ - } else { - /* not initializing mged */ - if (argc == 2) { - /* need to reset this before returning */ - DBIP = save_dbip; - rt_new_material_head(save_materp); - Tcl_AppendResult(interpreter, MORE_ARGS_STR, "Create new database (y|n)[n]? ", - (char *)NULL); - bu_vls_printf(&curr_cmd_list->cl_more_default, "n"); - bu_vls_free(&msg); - return TCL_ERROR; - } - - } - } - - /* did the caller specify not creating a new database? */ - if (argc >= 3 && bu_str_false(argv[2])) { - DBIP = save_dbip; /* restore previous database */ - rt_new_material_head(save_materp); - bu_vls_free(&msg); - return TCL_OK; - } - - /* File does not exist, and should be created */ - if ((DBIP = db_create(argv[1], mged_db_version)) == DBI_NULL) { - DBIP = save_dbip; /* restore previous database */ - rt_new_material_head(save_materp); - bu_vls_free(&msg); - - if (mged_init_flag) { - /* we need to use bu_log here */ - bu_log("opendb: failed to create %s\n", argv[1]); - bu_log("opendb: no database is currently opened!\n"); - return TCL_OK; - } - - Tcl_AppendResult(interpreter, "opendb: failed to create ", argv[1], "\n", (char *)NULL); - if (DBIP == DBI_NULL) - Tcl_AppendResult(interpreter, "opendb: no database is currently opened!", (char *)NULL); - - return TCL_ERROR; - } - /* New database has already had db_dirbuild() by here */ - - created_new_db = 1; - bu_vls_printf(&msg, "The new database %s was successfully created.\n", argv[1]); - } else { - /* Opened existing database file */ - - /* Version indicates whether we have a valid .g file */ - if (db_version(DBIP) < 0) { - bu_free(DBIP->dbi_filename, "free filename"); - DBIP = DBI_NULL; - Tcl_AppendResult(interpreter, "opendb: ", argv[1], " is not a valid database\n", (char *)NULL); - return TCL_ERROR; - } - - /* Scan geometry database and build in-memory directory */ - (void)db_dirbuild(DBIP); - } - - /* close out the old dbip */ - if (save_dbip) { - struct db_i *new_dbip; - struct mater *new_materp; - - new_dbip = DBIP; - new_materp = rt_material_head(); - - /* activate the 'saved' values so we can cleanly close the previous db */ - DBIP = save_dbip; - rt_new_material_head(save_materp); - - /* bye bye db */ - f_closedb(clientData, interpreter, 1, NULL); - - /* restore to the new db just opened */ - DBIP = new_dbip; - rt_new_material_head(new_materp); - } - - if (flip_v4) { - if (db_version(DBIP) != 4) { - bu_log("WARNING: [%s] is not a v4 database. The -f option will be ignored.\n", DBIP->dbi_filename); - } else { - if (DBIP->dbi_version < 0) { - bu_log("Database [%s] was already (perhaps automatically) flipped, -f is redundant.\n", DBIP->dbi_filename); - } else { - bu_log("Treating [%s] as a binary-incompatible v4 geometry database.\n", DBIP->dbi_filename); - bu_log("Endianness flipped. Converting to READ ONLY.\n"); - - /* flip the version number to indicate a flipped database. */ - DBIP->dbi_version *= -1; - - /* do NOT write to a flipped database */ - DBIP->dbi_read_only = 1; - } - } - } - - if (DBIP->dbi_read_only) { - bu_vls_printf(&msg, "%s: READ ONLY\n", DBIP->dbi_filename); - } - - /* This must occur before the call to [get_dbip] since - * that hooks into a libged callback. - */ - GEDP->dbip = DBIP; - GEDP->ged_output_handler = mged_output_handler; - GEDP->ged_refresh_handler = mged_refresh_handler; - GEDP->ged_create_vlist_scene_obj_callback = createDListSolid; - GEDP->ged_create_vlist_display_list_callback = createDListAll; - GEDP->ged_destroy_vlist_callback = freeDListsAll; - GEDP->ged_create_io_handler = &tclcad_create_io_handler; - GEDP->ged_delete_io_handler = &tclcad_delete_io_handler; - GEDP->ged_interp = (void *)interpreter; - GEDP->ged_interp_eval = &mged_db_search_callback; - struct tclcad_io_data *t_iod = tclcad_create_io_data(); - t_iod->io_mode = TCL_READABLE; - t_iod->interp = interpreter; - GEDP->ged_io_data = t_iod; - - /* increment use count for gedp db instance */ - (void)db_clone_dbi(DBIP, NULL); - - /* Provide LIBWDB C access to the on-disk database */ - if ((WDBP = wdb_dbopen(DBIP, RT_WDB_TYPE_DB_DISK)) == RT_WDB_NULL) { - Tcl_AppendResult(interpreter, "wdb_dbopen() failed?\n", (char *)NULL); - return TCL_ERROR; - } - - /* increment use count for tcl db instance */ - (void)db_clone_dbi(DBIP, NULL); - - /* Establish LIBWDB TCL access to both disk and in-memory databases */ - - /* initialize rt_wdb */ - bu_vls_init(&WDBP->wdb_name); - bu_vls_strcpy(&WDBP->wdb_name, MGED_DB_NAME); - - WDBP->wdb_interp = interpreter; - - /* append to list of rt_wdb's */ - BU_LIST_APPEND(&RTG.rtg_headwdb.l, &WDBP->l); - - /* This creates a "db" command object */ - - /* Beware, returns a "token", not TCL_OK. */ - (void)Tcl_CreateCommand((Tcl_Interp *)WDBP->wdb_interp, MGED_DB_NAME, (Tcl_CmdProc *)wdb_cmd, (ClientData)WDBP, wdb_deleteProc); - - /* Return new function name as result */ - Tcl_AppendResult((Tcl_Interp *)WDBP->wdb_interp, MGED_DB_NAME, (char *)NULL); - - /* This creates the ".inmem" in-memory geometry container and sets - * up the GUI. - */ - { - struct bu_vls cmd = BU_VLS_INIT_ZERO; - - bu_vls_printf(&cmd, "wdb_open %s inmem [get_dbip]", MGED_INMEM_NAME); - if (Tcl_Eval(interpreter, bu_vls_addr(&cmd)) != TCL_OK) { - bu_vls_printf(&msg, "%s\n%s\n", Tcl_GetStringResult(interpreter), Tcl_GetVar(interpreter, "errorInfo", TCL_GLOBAL_ONLY)); - Tcl_AppendResult(interpreter, bu_vls_addr(&msg), (char *)NULL); - bu_vls_free(&msg); - bu_vls_free(&cmd); - return TCL_ERROR; - } - - /* Perhaps do something special with the GUI */ - bu_vls_trunc(&cmd, 0); - bu_vls_printf(&cmd, "opendb_callback {%s}", DBIP->dbi_filename); - (void)Tcl_Eval(interpreter, bu_vls_addr(&cmd)); - - bu_vls_strcpy(&cmd, "local2base"); - Tcl_UnlinkVar(interpreter, bu_vls_addr(&cmd)); - Tcl_LinkVar(interpreter, bu_vls_addr(&cmd), (char *)&local2base, TCL_LINK_DOUBLE|TCL_LINK_READ_ONLY); - - bu_vls_strcpy(&cmd, "base2local"); - Tcl_UnlinkVar(interpreter, bu_vls_addr(&cmd)); - Tcl_LinkVar(interpreter, bu_vls_addr(&cmd), (char *)&base2local, TCL_LINK_DOUBLE|TCL_LINK_READ_ONLY); - - bu_vls_free(&cmd); - } - - set_localunit_TclVar(); - - /* Print title/units information */ - if (interactive) { - bu_vls_printf(&msg, "%s (units=%s)\n", DBIP->dbi_title, - bu_units_string(DBIP->dbi_local2base)); - } - - /* - * We have an old database version AND we're not in the process of - * creating a new database. - */ - if (db_version(DBIP) < 5 && !created_new_db) { - if (mged_db_upgrade) { - if (mged_db_warn) - bu_vls_printf(&msg, "Warning:\n\tDatabase version is old.\n\tConverting to the new format.\n"); - - (void)Tcl_Eval(interpreter, "after idle dbupgrade -f y"); - } else { - if (mged_db_warn) { - if (classic_mged) - bu_vls_printf(&msg, "Warning:\n\tDatabase version is old.\n\tSee the dbupgrade command."); - else - bu_vls_printf(&msg, "Warning:\n\tDatabase version is old.\n\tSelect Tools-->Upgrade Database for info."); - } - } - } - - Tcl_ResetResult(interpreter); - Tcl_AppendResult(interpreter, bu_vls_addr(&msg), (char *)NULL); - bu_vls_free(&msg); - - /* Update the background colors now that we have a file open */ - cs_set_bg(NULL, NULL, NULL, NULL, NULL); - - return TCL_OK; -} - - -/** - * Close the current database, if open. - */ -int -f_closedb(ClientData clientData, Tcl_Interp *interpreter, int argc, const char *argv[]) -{ - const char *av[2]; - - if (argc != 1) { - Tcl_AppendResult(interpreter, "Unexpected argument [%s]\n", (const char *)argv[1], NULL); - Tcl_Eval(interpreter, "help closedb"); - return TCL_ERROR; - } - - if (DBIP == DBI_NULL) { - Tcl_AppendResult(interpreter, "No database is open\n", NULL); - return TCL_OK; - } - - /* Clear out anything in the display */ - av[0] = "zap"; - av[1] = NULL; - cmd_zap(clientData, interpreter, 1, av); - - /* Close the Tcl database objects */ - Tcl_Eval(interpreter, "rename " MGED_DB_NAME " \"\"; rename .inmem \"\""); - - /* close the geometry instance */ - db_close(GEDP->dbip); - GEDP->dbip = NULL; - - WDBP = RT_WDB_NULL; - DBIP = DBI_NULL; - - /* wipe out the material list */ - rt_new_material_head(MATER_NULL); - - return TCL_OK; -} - - /* * Local Variables: * mode: C diff --git a/src/mged/mged.h b/src/mged/mged.h index a618fcda5ba..78c2eb64a1e 100644 --- a/src/mged/mged.h +++ b/src/mged/mged.h @@ -90,6 +90,15 @@ extern struct ged *GEDP; /* defined in mged.c */ extern struct db_i *DBIP; /* defined in mged.c */ extern struct rt_wdb *WDBP; /* defined in mged.c */ +/* initialization states */ +extern int mged_init_flag; /* >0 means in initialization stage */ +extern int classic_mged; /* >0 means interactive. gets set to 0 if + * there's libdm graphics support, and forced + * with -c option. */ +extern char *dpy_string; +extern int mged_db_upgrade; +extern int mged_db_version; +extern int mged_db_warn; /* * All GED files are stored in a fixed base unit (MM). These factors @@ -436,7 +445,6 @@ int mged_attach(const char *wp_name, int argc, const char *argv[]); void mged_link_vars(struct mged_dm *p); void mged_slider_free_vls(struct mged_dm *p); int gui_setup(const char *dstr); -int gui_output(void *clientData, void *str); /* buttons.c */ @@ -466,6 +474,8 @@ extern void view_ring_destroy(struct mged_dm *dlp); int cmdline(struct bu_vls *vp, int record); int mged_cmd(int argc, const char *argv[], struct funtab in_functions[]); void mged_print_result(int status); +int gui_output(void *clientData, void *str); +void mged_pr_output(Tcl_Interp *interp); /* color_scheme.c */ void cs_set_bg(const struct bu_structparse *, const char *, void *, const char *, void *); @@ -515,6 +525,29 @@ extern int newedge; /* new edge for arb editing */ /* edars.c */ void find_ars_nearest_pnt(int *crv, int *col, struct rt_ars_internal *ars, point_t pick_pt, vect_t dir); +/* f_db.c */ +struct mged_opendb_ctx { + int argc; + const char **argv; + int force_create; + int no_create; + int created_new_db; + int ret; + int ged_ret; + Tcl_Interp *interpreter; + struct db_i *old_dbip; + int post_open_cnt; +}; +extern struct mged_opendb_ctx mged_global_db_ctx; +int f_opendb(ClientData clientData, Tcl_Interp *interpreter, int argc, const char *argv[]); +int f_closedb(ClientData clientData, Tcl_Interp *interpreter, int argc, const char *argv[]); +void mged_output_handler(struct ged *, char *line); +void mged_refresh_handler(void *clientdata); +void mged_pre_opendb_clbk(struct ged *gedp, void *ctx); +void mged_post_opendb_clbk(struct ged *gedp, void *ctx); +void mged_pre_closedb_clbk(struct ged *gedp, void *ctx); +void mged_post_closedb_clbk(struct ged *gedp, void *ctx); + /* mged.c */ int event_check(int non_blocking); void new_edit_mats(void); diff --git a/src/mged/setup.c b/src/mged/setup.c index 10b748943f5..8216f2e8d81 100644 --- a/src/mged/setup.c +++ b/src/mged/setup.c @@ -56,6 +56,16 @@ extern void mged_global_variable_setup(Tcl_Interp *interpreter); const char cmd3525[] = {'3', '5', COMMA, '2', '5', '\0'}; const char cmd4545[] = {'4', '5', COMMA, '4', '5', '\0'}; +// We need to trigger MGED operations when opening and closing +// database files. However, some commands like garbage_collect +// also need to do these operations, and they have no awareness +// of the extra steps MGED takes with f_opendb/f_closedb. To +// allow both MGED and GED to do what they need, we define +// default callbacks in GEDP with MGED functions and data that +// will do the necessary work if the opendb/closedb functions +// are called at lower levels. +struct mged_opendb_ctx mged_global_db_ctx; + static struct cmdtab mged_cmdtab[] = { {"%", f_comm, GED_FUNC_PTR_NULL}, {cmd3525, f_bv_35_25, GED_FUNC_PTR_NULL}, /* 35,25 */ @@ -462,6 +472,36 @@ mged_setup(Tcl_Interp **interpreter) BU_GET(GEDP, struct ged); GED_INIT(GEDP, NULL); + GEDP->ged_output_handler = mged_output_handler; + GEDP->ged_refresh_handler = mged_refresh_handler; + GEDP->ged_create_vlist_scene_obj_callback = createDListSolid; + GEDP->ged_create_vlist_display_list_callback = createDListAll; + GEDP->ged_destroy_vlist_callback = freeDListsAll; + GEDP->ged_create_io_handler = &tclcad_create_io_handler; + GEDP->ged_delete_io_handler = &tclcad_delete_io_handler; + GEDP->ged_pre_opendb_callback = &mged_pre_opendb_clbk; + GEDP->ged_post_opendb_callback = &mged_post_opendb_clbk; + GEDP->ged_pre_closedb_callback = &mged_pre_closedb_clbk; + GEDP->ged_post_closedb_callback = &mged_post_closedb_clbk; + GEDP->ged_db_callback_udata = &mged_global_db_ctx; + GEDP->ged_interp = (void *)interpreter; + GEDP->ged_interp_eval = &mged_db_search_callback; + struct tclcad_io_data *t_iod = tclcad_create_io_data(); + t_iod->io_mode = TCL_READABLE; + t_iod->interp = *interpreter; + GEDP->ged_io_data = t_iod; + + /* Set up the default state of the standard open/close db container */ + mged_global_db_ctx.argc = 0; + mged_global_db_ctx.argv = NULL; + mged_global_db_ctx.force_create = 0; + mged_global_db_ctx.no_create = 0; + mged_global_db_ctx.created_new_db = 0; + mged_global_db_ctx.ret = 0; + mged_global_db_ctx.ged_ret = 0; + mged_global_db_ctx.interpreter = *interpreter; + mged_global_db_ctx.old_dbip = NULL; + mged_global_db_ctx.post_open_cnt = 0; BU_ALLOC(view_state->vs_gvp, struct bview); bv_init(view_state->vs_gvp, NULL); @@ -475,6 +515,7 @@ mged_setup(Tcl_Interp **interpreter) view_state->vs_gvp->vset = &GEDP->ged_views; bv_set_add_view(&GEDP->ged_views, view_state->vs_gvp); + bu_ptbl_ins(&GEDP->ged_free_views, (long *)view_state->vs_gvp); GEDP->ged_gvp = view_state->vs_gvp; /* register commands */ diff --git a/src/mged/utility1.c b/src/mged/utility1.c index cc6937cf0e8..82bd1d1713f 100644 --- a/src/mged/utility1.c +++ b/src/mged/utility1.c @@ -237,8 +237,10 @@ f_red(ClientData UNUSED(clientData), Tcl_Interp *interpreter, int argc, const ch av[3] = argv[1]; if ( ged_exec(GEDP, 4, (const char **)av) & BRLCAD_ERROR ) { + mged_pr_output(interpreter); Tcl_AppendResult(interpreter, "Error: ", bu_vls_addr(GEDP->ged_result_str), (char *)NULL); } else { + mged_pr_output(interpreter); Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), (char *)NULL); } diff --git a/src/mged/wdb_obj.c b/src/mged/wdb_obj.c index 4b0b06794a4..79ff3556adf 100644 --- a/src/mged/wdb_obj.c +++ b/src/mged/wdb_obj.c @@ -121,7 +121,7 @@ wdb_prep_dbip(const char *filename) } /* db_create does a db_dirbuild */ - if ((dbip = db_create(filename, 5)) == DBI_NULL) { + if ((dbip = db_create(filename, BRLCAD_DB_FORMAT_LATEST)) == DBI_NULL) { bu_log("wdb_prep_dbip: failed to create %s\n", filename); if (dbip == DBI_NULL) @@ -320,7 +320,7 @@ wdb_make_bb_cmd(struct rt_wdb *wdbp, return TCL_ERROR; } - /*XXX Temporary */ + /*XXX Temporary. TODO - why are we not using the applications GEDP here? */ GED_INIT(&ged, wdbp); i = 1; @@ -1957,6 +1957,7 @@ wdb_cmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) int ret; /* look for the new libged commands before trying one of the old ones */ + /* TODO - why are we not using the applications GEDP here? */ GED_INIT(&ged, wdbp); bu_log_hook_save_all(&save_hook_list); diff --git a/src/nirt/CMakeLists.txt b/src/nirt/CMakeLists.txt index 25ee81781f9..c62e7245aea 100644 --- a/src/nirt/CMakeLists.txt +++ b/src/nirt/CMakeLists.txt @@ -1,22 +1,14 @@ -set(LDIR "${BRLCAD_SOURCE_DIR}/src/other/ext/linenoise") - set(NIRT_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${BU_INCLUDE_DIRS} ${RT_INCLUDE_DIRS} ${ANALYZE_INCLUDE_DIRS} - ${LDIR} + ${LINENOISE_INCLUDE_DIRS} ) BRLCAD_INCLUDE_DIRS(NIRT_INCLUDE_DIRS) -set(NIRT_SRCS - main.cpp - ${LDIR}/utf8.c - ${LDIR}/linenoise.c - ${LDIR}/stringbuf.c - ) - -BRLCAD_ADDEXEC(nirt "${NIRT_SRCS}" "libanalyze;librt;libbu;${M_LIBRARY}") +BRLCAD_ADDEXEC(nirt main.cpp "libanalyze;librt;libbu;${LINENOISE_LIBRARIES};${M_LIBRARY}") +set_property(TARGET nirt APPEND PROPERTY COMPILE_DEFINITIONS "LINENOISE_DLL_IMPORTS") BRLCAD_ADDEXEC(showshot showshot.c libbn) diff --git a/src/other/CMakeLists.txt b/src/other/CMakeLists.txt index 9c5df17a3d7..a305a1825b7 100644 --- a/src/other/CMakeLists.txt +++ b/src/other/CMakeLists.txt @@ -106,45 +106,53 @@ mark_as_advanced(SKIP_INSTALL_HEADERS) # libutahrle Library - The directory to perform ADD_SUBDIRECTORY on # and the include directory for utahrle are different, so override the # macro's setting of UTAHRLE_INCLUDE_DIRS here. -if (BRLCAD_LEVEL3) +if (BRLCAD_LEVEL3 AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libutahrle) add_subdirectory(libutahrle) set(UTAHRLE_LIBRARY utahrle CACHE STRING "directory with rle.h header" FORCE) set(UTAHRLE_LIBRARIES utahrle CACHE STRING "directory with rle.h header" FORCE) set(UTAHRLE_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/libutahrle/include" CACHE STRING "directory with rle.h header" FORCE) set(UTAHRLE_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/libutahrle/include" CACHE STRING "directory with rle.h header" FORCE) - mark_as_advanced(UTAHRLE_LIBRARY) - mark_as_advanced(UTAHRLE_LIBRARIES) - mark_as_advanced(UTAHRLE_INCLUDE_DIR) - mark_as_advanced(UTAHRLE_INCLUDE_DIRS) -endif (BRLCAD_LEVEL3) -include("${CMAKE_CURRENT_SOURCE_DIR}/libutahrle.dist") -CMAKEFILES_IN_DIR(libutahrle_ignore_files libutahrle) - +endif (BRLCAD_LEVEL3 AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libutahrle) +mark_as_advanced(UTAHRLE_LIBRARY) +mark_as_advanced(UTAHRLE_LIBRARIES) +mark_as_advanced(UTAHRLE_INCLUDE_DIR) +mark_as_advanced(UTAHRLE_INCLUDE_DIRS) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libutahrle) + include("${CMAKE_CURRENT_SOURCE_DIR}/libutahrle.dist") + CMAKEFILES_IN_DIR(libutahrle_ignore_files libutahrle) +endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libutahrle) + +# OpenCV library +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/opencv) + add_subdirectory(opencv) +endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/opencv) # OpenNURBS Library -add_subdirectory(openNURBS) -SetTargetFolder(openNURBS "Third Party Libraries") -SetTargetFolder(openNURBS-static "Third Party Libraries") -SetTargetFolder(openNURBS-obj "Third Party Libraries") -set(OPENNURBS_LIBRARY openNURBS CACHE STRING "Require opennurbs libraries" FORCE) -set(OPENNURBS_LIBRARIES openNURBS CACHE STRING "Require opennurbs libraries" FORCE) -set(OPENNURBS_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/openNURBS" CACHE STRING "Require opennurbs header includes" FORCE) -set(OPENNURBS_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/openNURBS" CACHE STRING "Require opennurbs header includes" FORCE) -# openNURBS headers trigger a number of warnings - treat them the same way we -# do the ext headers -set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} openNURBS CACHE STRING "Bundled system include dirs" FORCE) -mark_as_advanced(OPENNURBS_LIBRARY) -mark_as_advanced(OPENNURBS_LIBRARIES) -mark_as_advanced(OPENNURBS_INCLUDE_DIR) -mark_as_advanced(OPENNURBS_INCLUDE_DIRS) -get_directory_property(openNURBS_headers_orig DIRECTORY openNURBS DEFINITION OPENNURBS_HEADERS) -set(openNURBS_headers) -foreach(onhfile ${openNURBS_headers_orig}) - set(openNURBS_headers ${openNURBS_headers} openNURBS/${onhfile}) -endforeach(onhfile ${openNURBS_headers_orig}) -BRLCAD_MANAGE_FILES(openNURBS_headers ${INCLUDE_DIR}/openNURBS) -include("${CMAKE_CURRENT_SOURCE_DIR}/openNURBS.dist") -CMAKEFILES_IN_DIR(openNURBS_ignore_files openNURBS) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/openNURBS) + add_subdirectory(openNURBS) + SetTargetFolder(openNURBS "Third Party Libraries") + SetTargetFolder(openNURBS-static "Third Party Libraries") + SetTargetFolder(openNURBS-obj "Third Party Libraries") + set(OPENNURBS_LIBRARY openNURBS CACHE STRING "Require opennurbs libraries" FORCE) + set(OPENNURBS_LIBRARIES openNURBS CACHE STRING "Require opennurbs libraries" FORCE) + set(OPENNURBS_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/openNURBS" CACHE STRING "Require opennurbs header includes" FORCE) + set(OPENNURBS_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/openNURBS" CACHE STRING "Require opennurbs header includes" FORCE) + # openNURBS headers trigger a number of warnings - treat them the same way we + # do the ext headers + set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} openNURBS CACHE STRING "Bundled system include dirs" FORCE) + mark_as_advanced(OPENNURBS_LIBRARY) + mark_as_advanced(OPENNURBS_LIBRARIES) + mark_as_advanced(OPENNURBS_INCLUDE_DIR) + mark_as_advanced(OPENNURBS_INCLUDE_DIRS) + get_directory_property(openNURBS_headers_orig DIRECTORY openNURBS DEFINITION OPENNURBS_HEADERS) + set(openNURBS_headers) + foreach(onhfile ${openNURBS_headers_orig}) + set(openNURBS_headers ${openNURBS_headers} openNURBS/${onhfile}) + endforeach(onhfile ${openNURBS_headers_orig}) + BRLCAD_MANAGE_FILES(openNURBS_headers ${INCLUDE_DIR}/openNURBS) + include("${CMAKE_CURRENT_SOURCE_DIR}/openNURBS.dist") + CMAKEFILES_IN_DIR(openNURBS_ignore_files openNURBS) +endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/openNURBS) # Poly2Tri CDT library @@ -175,22 +183,42 @@ mark_as_advanced(POLY2TRI_LIBRARIES) mark_as_advanced(POLY2TRI_INCLUDE_DIR) mark_as_advanced(POLY2TRI_INCLUDE_DIRS) +# Manifold is a geometry library for operating on manifold triangle meshes: +# https://github.com/elalish/manifold +# (current configuration is from https://github.com/starseeker/manifold) +if ("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) + add_subdirectory(manifold) + include("${CMAKE_CURRENT_SOURCE_DIR}/manifold.dist") + CMAKEFILES_IN_DIR(manifold_ignore_files manifold) + DISTCLEAN("${CMAKE_CURRENT_SOURCE_DIR}/manifold/Makefile") + set(MANIFOLD_LIBRARY "manifold" CACHE STRING "Manifold library" FORCE) + set(MANIFOLD_LIBRARIES "manifold" CACHE STRING "Manifold library" FORCE) + set(MANIFOLD_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/manifold/include" CACHE STRING "Directory containing manifold headers" FORCE) + set(MANIFOLD_INCLUDE_DIRS "${MANIFOLD_INCLUDE_DIR}" CACHE STRING "Directory containing manifold headers" FORCE) + SetTargetFolder(manifold "Third Party Libraries") +endif("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) +mark_as_advanced(MANIFOLD_LIBRARY) +mark_as_advanced(MANIFOLD_LIBRARIES) +mark_as_advanced(MANIFOLD_INCLUDE_DIR) +mark_as_advanced(MANIFOLD_INCLUDE_DIRS) # Lightning Memory-Mapped Database (LMDB) # Fast key-value store database from OpenLDAP Project. -add_subdirectory(lmdb) -include("${CMAKE_CURRENT_SOURCE_DIR}/lmdb.dist") -CMAKEFILES_IN_DIR(lmdb_ignore_files lmdb) -DISTCLEAN("${CMAKE_CURRENT_SOURCE_DIR}/lmdb/Makefile") -set(LMDB_LIBRARY "lmdb" CACHE STRING "Lightning Memory-Mapped Database library" FORCE) -set(LMDB_LIBRARIES "lmdb" CACHE STRING "Lightning Memory-Mapped Database library" FORCE) -set(LMDB_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/lmdb" CACHE STRING "Directory containing lmdb header" FORCE) -set(LMDB_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/lmdb" CACHE STRING "Directory containing lmdb header" FORCE) -SetTargetFolder(lmdb "Third Party Libraries") -mark_as_advanced(LMDB_LIBRARY) -mark_as_advanced(LMDB_LIBRARIES) -mark_as_advanced(LMDB_INCLUDE_DIR) -mark_as_advanced(LMDB_INCLUDE_DIRS) +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lmdb") + add_subdirectory(lmdb) + include("${CMAKE_CURRENT_SOURCE_DIR}/lmdb.dist") + CMAKEFILES_IN_DIR(lmdb_ignore_files lmdb) + DISTCLEAN("${CMAKE_CURRENT_SOURCE_DIR}/lmdb/Makefile") + set(LMDB_LIBRARY "lmdb" CACHE STRING "Lightning Memory-Mapped Database library" FORCE) + set(LMDB_LIBRARIES "lmdb" CACHE STRING "Lightning Memory-Mapped Database library" FORCE) + set(LMDB_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/lmdb" CACHE STRING "Directory containing lmdb header" FORCE) + set(LMDB_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/lmdb" CACHE STRING "Directory containing lmdb header" FORCE) + SetTargetFolder(lmdb "Third Party Libraries") + mark_as_advanced(LMDB_LIBRARY) + mark_as_advanced(LMDB_LIBRARIES) + mark_as_advanced(LMDB_INCLUDE_DIR) + mark_as_advanced(LMDB_INCLUDE_DIRS) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lmdb") # Interactive Robust Mesh Booleans - slight modification of # https://github.com/gcherchi/InteractiveAndRobustMeshBooleans - to build, place libirmb @@ -214,51 +242,82 @@ mark_as_advanced(IRMB_LIBRARIES) mark_as_advanced(IRMB_INCLUDE_DIR) mark_as_advanced(IRMB_INCLUDE_DIRS) -# GCT is a collection of algorithms for geometry processing and conversion -#add_subdirectory(gct) -include("${CMAKE_CURRENT_SOURCE_DIR}/gct.dist") -CMAKEFILES_IN_DIR(gct_ignore_files gct) - # OSMesa Library -add_subdirectory(libosmesa) -SetTargetFolder(osmesa "Third Party Libraries") -set(OSMESA_LIBRARY osmesa CACHE STRING "Require opennurbs libraries" FORCE) -set(OSMESA_LIBRARIES osmesa CACHE STRING "Require opennurbs libraries" FORCE) -set(OSMESA_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/libosmesa/include" CACHE STRING "Require osmesa header includes" FORCE) -set(OSMESA_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/libosmesa/include" CACHE STRING "Require osmesa header includes" FORCE) -mark_as_advanced(OSMESA_LIBRARY) -mark_as_advanced(OSMESA_LIBRARIES) -mark_as_advanced(OSMESA_INCLUDE_DIR) -mark_as_advanced(OSMESA_INCLUDE_DIRS) -include("${CMAKE_CURRENT_SOURCE_DIR}/libosmesa.dist") -CMAKEFILES_IN_DIR(libosmesa_ignore_files libosmesa) +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libosmesa") + add_subdirectory(libosmesa) + SetTargetFolder(osmesa "Third Party Libraries") + set(OSMESA_LIBRARY osmesa CACHE STRING "Require osmesa libraries" FORCE) + set(OSMESA_LIBRARIES osmesa CACHE STRING "Require osmesa libraries" FORCE) + set(OSMESA_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/libosmesa/include" CACHE STRING "Require osmesa header includes" FORCE) + set(OSMESA_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/libosmesa/include" CACHE STRING "Require osmesa header includes" FORCE) + mark_as_advanced(OSMESA_LIBRARY) + mark_as_advanced(OSMESA_LIBRARIES) + mark_as_advanced(OSMESA_INCLUDE_DIR) + mark_as_advanced(OSMESA_INCLUDE_DIRS) + include("${CMAKE_CURRENT_SOURCE_DIR}/libosmesa.dist") + CMAKEFILES_IN_DIR(libosmesa_ignore_files libosmesa) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libosmesa") if (BRLCAD_ENABLE_TCL AND BRLCAD_ENABLE_TK) - # Tkhtml doesn't have an active upstream - add_subdirectory(tkhtml) - DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tkhtml/pkgIndex.tcl") - DISTCLEAN("${CMAKE_BINARY_DIR}/lib/Tkhtml3.0") - SetTargetFolder(Tkhtml "Third Party Libraries") - SetTargetFolder(tkhtml_n_gen "Compilation Utilities") - - # Tktable is a borderline case. It does exist and is used in the Tcl/Tk - # ecosystem, but it is has the same problem we have generally with "package - # require" Tk package testing and there is very little upstream activity... - add_subdirectory(tktable) - DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tktable/pkgIndex.tcl") - DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tktable/tktable_cfg.h") - DISTCLEAN("${CMAKE_BINARY_DIR}/lib/Tktable2.10") - SetTargetFolder(Tktable "Third Party Libraries") - SetTargetFolder(tktable_header_gen "Compilation Utilities") + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tkhtml") + # Tkhtml doesn't have an active upstream + add_subdirectory(tkhtml) + DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tkhtml/pkgIndex.tcl") + DISTCLEAN("${CMAKE_BINARY_DIR}/lib/Tkhtml3.0") + SetTargetFolder(Tkhtml "Third Party Libraries") + SetTargetFolder(tkhtml_n_gen "Compilation Utilities") + endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tkhtml") + + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tktable") + # Tktable is a borderline case. It does exist and is used in the Tcl/Tk + # ecosystem, but it is has the same problem we have generally with "package + # require" Tk package testing and there is very little upstream activity... + add_subdirectory(tktable) + DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tktable/pkgIndex.tcl") + DISTCLEAN("${CMAKE_CURRENT_BINARY_DIR}/tktable/tktable_cfg.h") + DISTCLEAN("${CMAKE_BINARY_DIR}/lib/Tktable2.10") + SetTargetFolder(Tktable "Third Party Libraries") + SetTargetFolder(tktable_header_gen "Compilation Utilities") + endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tktable") endif (BRLCAD_ENABLE_TCL AND BRLCAD_ENABLE_TK) -include("${CMAKE_CURRENT_SOURCE_DIR}/tkhtml.dist") -CMAKEFILES_IN_DIR(tkhtml_ignore_files tkhtml) - -include("${CMAKE_CURRENT_SOURCE_DIR}/tktable.dist") -CMAKEFILES_IN_DIR(tktable_ignore_files tktable) +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tkhtml") + include("${CMAKE_CURRENT_SOURCE_DIR}/tkhtml.dist") + CMAKEFILES_IN_DIR(tkhtml_ignore_files tkhtml) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tkhtml") + +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tktable") + include("${CMAKE_CURRENT_SOURCE_DIR}/tktable.dist") + CMAKEFILES_IN_DIR(tktable_ignore_files tktable) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tktable") + +# The above libraries are all compilation targets with libraries, and so have +# build outputs that must be distributed with BRL-CAD. The following are +# either header-only libraries or built directly into executables, and as such +# may remain in place - they are needed only for building. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Eigen") + include("${CMAKE_CURRENT_SOURCE_DIR}/Eigen.dist") + CMAKEFILES_IN_DIR(Eigen_ignore_files Eigen) + set(SYS_INCLUDE_PATTERNS ${SYS_INCLUDE_PATTERNS} Eigen CACHE STRING "Bundled system include dirs" FORCE) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Eigen") + +# linenoise is used by applications directly +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/linenoise") + add_subdirectory(linenoise) + SetTargetFolder(linenoise "Third Party Libraries") + set(LINENOISE_LIBRARY linenoise CACHE STRING "Require linenoise libraries" FORCE) + set(LINENOISE_LIBRARIES linenoise CACHE STRING "Require linenoise libraries" FORCE) + set(LINENOISE_INCLUDE_DIR "${BRLCAD_SOURCE_DIR}/src/other/linenoise" CACHE STRING "Require linenoise header includes" FORCE) + set(LINENOISE_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/linenoise" CACHE STRING "Require linenoise header includes" FORCE) + mark_as_advanced(LINENOISE_LIBRARY) + mark_as_advanced(LINENOISE_LIBRARIES) + mark_as_advanced(LINENOISE_INCLUDE_DIR) + mark_as_advanced(LINENOISE_INCLUDE_DIRS) + include(${CMAKE_CURRENT_SOURCE_DIR}/linenoise.dist) + CMAKEFILES_IN_DIR(linenoise_ignore_files linenoise) +endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/linenoise") CMAKEFILES( README diff --git a/src/other/ext/Eigen.dist b/src/other/Eigen.dist similarity index 100% rename from src/other/ext/Eigen.dist rename to src/other/Eigen.dist diff --git a/src/other/ext/Eigen/COPYING.APACHE b/src/other/Eigen/COPYING.APACHE similarity index 100% rename from src/other/ext/Eigen/COPYING.APACHE rename to src/other/Eigen/COPYING.APACHE diff --git a/src/other/ext/Eigen/COPYING.BSD b/src/other/Eigen/COPYING.BSD similarity index 100% rename from src/other/ext/Eigen/COPYING.BSD rename to src/other/Eigen/COPYING.BSD diff --git a/src/other/ext/Eigen/COPYING.GPL b/src/other/Eigen/COPYING.GPL similarity index 100% rename from src/other/ext/Eigen/COPYING.GPL rename to src/other/Eigen/COPYING.GPL diff --git a/src/other/ext/Eigen/COPYING.LGPL b/src/other/Eigen/COPYING.LGPL similarity index 100% rename from src/other/ext/Eigen/COPYING.LGPL rename to src/other/Eigen/COPYING.LGPL diff --git a/src/other/ext/Eigen/COPYING.MINPACK b/src/other/Eigen/COPYING.MINPACK similarity index 100% rename from src/other/ext/Eigen/COPYING.MINPACK rename to src/other/Eigen/COPYING.MINPACK diff --git a/src/other/ext/Eigen/COPYING.MPL2 b/src/other/Eigen/COPYING.MPL2 similarity index 100% rename from src/other/ext/Eigen/COPYING.MPL2 rename to src/other/Eigen/COPYING.MPL2 diff --git a/src/other/ext/Eigen/COPYING.README b/src/other/Eigen/COPYING.README similarity index 100% rename from src/other/ext/Eigen/COPYING.README rename to src/other/Eigen/COPYING.README diff --git a/src/other/ext/Eigen/Eigen/Cholesky b/src/other/Eigen/Eigen/Cholesky similarity index 100% rename from src/other/ext/Eigen/Eigen/Cholesky rename to src/other/Eigen/Eigen/Cholesky diff --git a/src/other/ext/Eigen/Eigen/CholmodSupport b/src/other/Eigen/Eigen/CholmodSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/CholmodSupport rename to src/other/Eigen/Eigen/CholmodSupport diff --git a/src/other/ext/Eigen/Eigen/Core b/src/other/Eigen/Eigen/Core similarity index 100% rename from src/other/ext/Eigen/Eigen/Core rename to src/other/Eigen/Eigen/Core diff --git a/src/other/ext/Eigen/Eigen/Dense b/src/other/Eigen/Eigen/Dense similarity index 100% rename from src/other/ext/Eigen/Eigen/Dense rename to src/other/Eigen/Eigen/Dense diff --git a/src/other/ext/Eigen/Eigen/Eigen b/src/other/Eigen/Eigen/Eigen similarity index 100% rename from src/other/ext/Eigen/Eigen/Eigen rename to src/other/Eigen/Eigen/Eigen diff --git a/src/other/ext/Eigen/Eigen/Eigenvalues b/src/other/Eigen/Eigen/Eigenvalues similarity index 100% rename from src/other/ext/Eigen/Eigen/Eigenvalues rename to src/other/Eigen/Eigen/Eigenvalues diff --git a/src/other/ext/Eigen/Eigen/Geometry b/src/other/Eigen/Eigen/Geometry similarity index 100% rename from src/other/ext/Eigen/Eigen/Geometry rename to src/other/Eigen/Eigen/Geometry diff --git a/src/other/ext/Eigen/Eigen/Householder b/src/other/Eigen/Eigen/Householder similarity index 100% rename from src/other/ext/Eigen/Eigen/Householder rename to src/other/Eigen/Eigen/Householder diff --git a/src/other/ext/Eigen/Eigen/IterativeLinearSolvers b/src/other/Eigen/Eigen/IterativeLinearSolvers similarity index 100% rename from src/other/ext/Eigen/Eigen/IterativeLinearSolvers rename to src/other/Eigen/Eigen/IterativeLinearSolvers diff --git a/src/other/ext/Eigen/Eigen/Jacobi b/src/other/Eigen/Eigen/Jacobi similarity index 100% rename from src/other/ext/Eigen/Eigen/Jacobi rename to src/other/Eigen/Eigen/Jacobi diff --git a/src/other/ext/Eigen/Eigen/KLUSupport b/src/other/Eigen/Eigen/KLUSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/KLUSupport rename to src/other/Eigen/Eigen/KLUSupport diff --git a/src/other/ext/Eigen/Eigen/LU b/src/other/Eigen/Eigen/LU similarity index 100% rename from src/other/ext/Eigen/Eigen/LU rename to src/other/Eigen/Eigen/LU diff --git a/src/other/ext/Eigen/Eigen/MetisSupport b/src/other/Eigen/Eigen/MetisSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/MetisSupport rename to src/other/Eigen/Eigen/MetisSupport diff --git a/src/other/ext/Eigen/Eigen/OrderingMethods b/src/other/Eigen/Eigen/OrderingMethods similarity index 100% rename from src/other/ext/Eigen/Eigen/OrderingMethods rename to src/other/Eigen/Eigen/OrderingMethods diff --git a/src/other/ext/Eigen/Eigen/PaStiXSupport b/src/other/Eigen/Eigen/PaStiXSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/PaStiXSupport rename to src/other/Eigen/Eigen/PaStiXSupport diff --git a/src/other/ext/Eigen/Eigen/PardisoSupport b/src/other/Eigen/Eigen/PardisoSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/PardisoSupport rename to src/other/Eigen/Eigen/PardisoSupport diff --git a/src/other/ext/Eigen/Eigen/QR b/src/other/Eigen/Eigen/QR similarity index 100% rename from src/other/ext/Eigen/Eigen/QR rename to src/other/Eigen/Eigen/QR diff --git a/src/other/ext/Eigen/Eigen/QtAlignedMalloc b/src/other/Eigen/Eigen/QtAlignedMalloc similarity index 100% rename from src/other/ext/Eigen/Eigen/QtAlignedMalloc rename to src/other/Eigen/Eigen/QtAlignedMalloc diff --git a/src/other/ext/Eigen/Eigen/SPQRSupport b/src/other/Eigen/Eigen/SPQRSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/SPQRSupport rename to src/other/Eigen/Eigen/SPQRSupport diff --git a/src/other/ext/Eigen/Eigen/SVD b/src/other/Eigen/Eigen/SVD similarity index 100% rename from src/other/ext/Eigen/Eigen/SVD rename to src/other/Eigen/Eigen/SVD diff --git a/src/other/ext/Eigen/Eigen/Sparse b/src/other/Eigen/Eigen/Sparse similarity index 100% rename from src/other/ext/Eigen/Eigen/Sparse rename to src/other/Eigen/Eigen/Sparse diff --git a/src/other/ext/Eigen/Eigen/SparseCholesky b/src/other/Eigen/Eigen/SparseCholesky similarity index 100% rename from src/other/ext/Eigen/Eigen/SparseCholesky rename to src/other/Eigen/Eigen/SparseCholesky diff --git a/src/other/ext/Eigen/Eigen/SparseCore b/src/other/Eigen/Eigen/SparseCore similarity index 100% rename from src/other/ext/Eigen/Eigen/SparseCore rename to src/other/Eigen/Eigen/SparseCore diff --git a/src/other/ext/Eigen/Eigen/SparseLU b/src/other/Eigen/Eigen/SparseLU similarity index 100% rename from src/other/ext/Eigen/Eigen/SparseLU rename to src/other/Eigen/Eigen/SparseLU diff --git a/src/other/ext/Eigen/Eigen/SparseQR b/src/other/Eigen/Eigen/SparseQR similarity index 100% rename from src/other/ext/Eigen/Eigen/SparseQR rename to src/other/Eigen/Eigen/SparseQR diff --git a/src/other/ext/Eigen/Eigen/StdDeque b/src/other/Eigen/Eigen/StdDeque similarity index 100% rename from src/other/ext/Eigen/Eigen/StdDeque rename to src/other/Eigen/Eigen/StdDeque diff --git a/src/other/ext/Eigen/Eigen/StdList b/src/other/Eigen/Eigen/StdList similarity index 100% rename from src/other/ext/Eigen/Eigen/StdList rename to src/other/Eigen/Eigen/StdList diff --git a/src/other/ext/Eigen/Eigen/StdVector b/src/other/Eigen/Eigen/StdVector similarity index 100% rename from src/other/ext/Eigen/Eigen/StdVector rename to src/other/Eigen/Eigen/StdVector diff --git a/src/other/ext/Eigen/Eigen/SuperLUSupport b/src/other/Eigen/Eigen/SuperLUSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/SuperLUSupport rename to src/other/Eigen/Eigen/SuperLUSupport diff --git a/src/other/ext/Eigen/Eigen/UmfPackSupport b/src/other/Eigen/Eigen/UmfPackSupport similarity index 100% rename from src/other/ext/Eigen/Eigen/UmfPackSupport rename to src/other/Eigen/Eigen/UmfPackSupport diff --git a/src/other/ext/Eigen/Eigen/src/Cholesky/LDLT.h b/src/other/Eigen/Eigen/src/Cholesky/LDLT.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Cholesky/LDLT.h rename to src/other/Eigen/Eigen/src/Cholesky/LDLT.h diff --git a/src/other/ext/Eigen/Eigen/src/Cholesky/LLT.h b/src/other/Eigen/Eigen/src/Cholesky/LLT.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Cholesky/LLT.h rename to src/other/Eigen/Eigen/src/Cholesky/LLT.h diff --git a/src/other/ext/Eigen/Eigen/src/Cholesky/LLT_LAPACKE.h b/src/other/Eigen/Eigen/src/Cholesky/LLT_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Cholesky/LLT_LAPACKE.h rename to src/other/Eigen/Eigen/src/Cholesky/LLT_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h b/src/other/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h rename to src/other/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ArithmeticSequence.h b/src/other/Eigen/Eigen/src/Core/ArithmeticSequence.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ArithmeticSequence.h rename to src/other/Eigen/Eigen/src/Core/ArithmeticSequence.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Array.h b/src/other/Eigen/Eigen/src/Core/Array.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Array.h rename to src/other/Eigen/Eigen/src/Core/Array.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ArrayBase.h b/src/other/Eigen/Eigen/src/Core/ArrayBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ArrayBase.h rename to src/other/Eigen/Eigen/src/Core/ArrayBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ArrayWrapper.h b/src/other/Eigen/Eigen/src/Core/ArrayWrapper.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ArrayWrapper.h rename to src/other/Eigen/Eigen/src/Core/ArrayWrapper.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Assign.h b/src/other/Eigen/Eigen/src/Core/Assign.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Assign.h rename to src/other/Eigen/Eigen/src/Core/Assign.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/AssignEvaluator.h b/src/other/Eigen/Eigen/src/Core/AssignEvaluator.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/AssignEvaluator.h rename to src/other/Eigen/Eigen/src/Core/AssignEvaluator.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Assign_MKL.h b/src/other/Eigen/Eigen/src/Core/Assign_MKL.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Assign_MKL.h rename to src/other/Eigen/Eigen/src/Core/Assign_MKL.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/BandMatrix.h b/src/other/Eigen/Eigen/src/Core/BandMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/BandMatrix.h rename to src/other/Eigen/Eigen/src/Core/BandMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Block.h b/src/other/Eigen/Eigen/src/Core/Block.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Block.h rename to src/other/Eigen/Eigen/src/Core/Block.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/BooleanRedux.h b/src/other/Eigen/Eigen/src/Core/BooleanRedux.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/BooleanRedux.h rename to src/other/Eigen/Eigen/src/Core/BooleanRedux.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CommaInitializer.h b/src/other/Eigen/Eigen/src/Core/CommaInitializer.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CommaInitializer.h rename to src/other/Eigen/Eigen/src/Core/CommaInitializer.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ConditionEstimator.h b/src/other/Eigen/Eigen/src/Core/ConditionEstimator.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ConditionEstimator.h rename to src/other/Eigen/Eigen/src/Core/ConditionEstimator.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CoreEvaluators.h b/src/other/Eigen/Eigen/src/Core/CoreEvaluators.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CoreEvaluators.h rename to src/other/Eigen/Eigen/src/Core/CoreEvaluators.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CoreIterators.h b/src/other/Eigen/Eigen/src/Core/CoreIterators.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CoreIterators.h rename to src/other/Eigen/Eigen/src/Core/CoreIterators.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CwiseBinaryOp.h b/src/other/Eigen/Eigen/src/Core/CwiseBinaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CwiseBinaryOp.h rename to src/other/Eigen/Eigen/src/Core/CwiseBinaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CwiseNullaryOp.h b/src/other/Eigen/Eigen/src/Core/CwiseNullaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CwiseNullaryOp.h rename to src/other/Eigen/Eigen/src/Core/CwiseNullaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CwiseTernaryOp.h b/src/other/Eigen/Eigen/src/Core/CwiseTernaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CwiseTernaryOp.h rename to src/other/Eigen/Eigen/src/Core/CwiseTernaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CwiseUnaryOp.h b/src/other/Eigen/Eigen/src/Core/CwiseUnaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CwiseUnaryOp.h rename to src/other/Eigen/Eigen/src/Core/CwiseUnaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/CwiseUnaryView.h b/src/other/Eigen/Eigen/src/Core/CwiseUnaryView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/CwiseUnaryView.h rename to src/other/Eigen/Eigen/src/Core/CwiseUnaryView.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/DenseBase.h b/src/other/Eigen/Eigen/src/Core/DenseBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/DenseBase.h rename to src/other/Eigen/Eigen/src/Core/DenseBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/DenseCoeffsBase.h b/src/other/Eigen/Eigen/src/Core/DenseCoeffsBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/DenseCoeffsBase.h rename to src/other/Eigen/Eigen/src/Core/DenseCoeffsBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/DenseStorage.h b/src/other/Eigen/Eigen/src/Core/DenseStorage.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/DenseStorage.h rename to src/other/Eigen/Eigen/src/Core/DenseStorage.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Diagonal.h b/src/other/Eigen/Eigen/src/Core/Diagonal.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Diagonal.h rename to src/other/Eigen/Eigen/src/Core/Diagonal.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/DiagonalMatrix.h b/src/other/Eigen/Eigen/src/Core/DiagonalMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/DiagonalMatrix.h rename to src/other/Eigen/Eigen/src/Core/DiagonalMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/DiagonalProduct.h b/src/other/Eigen/Eigen/src/Core/DiagonalProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/DiagonalProduct.h rename to src/other/Eigen/Eigen/src/Core/DiagonalProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Dot.h b/src/other/Eigen/Eigen/src/Core/Dot.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Dot.h rename to src/other/Eigen/Eigen/src/Core/Dot.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/EigenBase.h b/src/other/Eigen/Eigen/src/Core/EigenBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/EigenBase.h rename to src/other/Eigen/Eigen/src/Core/EigenBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ForceAlignedAccess.h b/src/other/Eigen/Eigen/src/Core/ForceAlignedAccess.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ForceAlignedAccess.h rename to src/other/Eigen/Eigen/src/Core/ForceAlignedAccess.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Fuzzy.h b/src/other/Eigen/Eigen/src/Core/Fuzzy.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Fuzzy.h rename to src/other/Eigen/Eigen/src/Core/Fuzzy.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/GeneralProduct.h b/src/other/Eigen/Eigen/src/Core/GeneralProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/GeneralProduct.h rename to src/other/Eigen/Eigen/src/Core/GeneralProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/GenericPacketMath.h b/src/other/Eigen/Eigen/src/Core/GenericPacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/GenericPacketMath.h rename to src/other/Eigen/Eigen/src/Core/GenericPacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/GlobalFunctions.h b/src/other/Eigen/Eigen/src/Core/GlobalFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/GlobalFunctions.h rename to src/other/Eigen/Eigen/src/Core/GlobalFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/IO.h b/src/other/Eigen/Eigen/src/Core/IO.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/IO.h rename to src/other/Eigen/Eigen/src/Core/IO.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/IndexedView.h b/src/other/Eigen/Eigen/src/Core/IndexedView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/IndexedView.h rename to src/other/Eigen/Eigen/src/Core/IndexedView.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Inverse.h b/src/other/Eigen/Eigen/src/Core/Inverse.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Inverse.h rename to src/other/Eigen/Eigen/src/Core/Inverse.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Map.h b/src/other/Eigen/Eigen/src/Core/Map.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Map.h rename to src/other/Eigen/Eigen/src/Core/Map.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/MapBase.h b/src/other/Eigen/Eigen/src/Core/MapBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/MapBase.h rename to src/other/Eigen/Eigen/src/Core/MapBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/MathFunctionsImpl.h b/src/other/Eigen/Eigen/src/Core/MathFunctionsImpl.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/MathFunctionsImpl.h rename to src/other/Eigen/Eigen/src/Core/MathFunctionsImpl.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Matrix.h b/src/other/Eigen/Eigen/src/Core/Matrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Matrix.h rename to src/other/Eigen/Eigen/src/Core/Matrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/MatrixBase.h b/src/other/Eigen/Eigen/src/Core/MatrixBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/MatrixBase.h rename to src/other/Eigen/Eigen/src/Core/MatrixBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/NestByValue.h b/src/other/Eigen/Eigen/src/Core/NestByValue.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/NestByValue.h rename to src/other/Eigen/Eigen/src/Core/NestByValue.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/NoAlias.h b/src/other/Eigen/Eigen/src/Core/NoAlias.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/NoAlias.h rename to src/other/Eigen/Eigen/src/Core/NoAlias.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/NumTraits.h b/src/other/Eigen/Eigen/src/Core/NumTraits.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/NumTraits.h rename to src/other/Eigen/Eigen/src/Core/NumTraits.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/PartialReduxEvaluator.h b/src/other/Eigen/Eigen/src/Core/PartialReduxEvaluator.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/PartialReduxEvaluator.h rename to src/other/Eigen/Eigen/src/Core/PartialReduxEvaluator.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/PermutationMatrix.h b/src/other/Eigen/Eigen/src/Core/PermutationMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/PermutationMatrix.h rename to src/other/Eigen/Eigen/src/Core/PermutationMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/PlainObjectBase.h b/src/other/Eigen/Eigen/src/Core/PlainObjectBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/PlainObjectBase.h rename to src/other/Eigen/Eigen/src/Core/PlainObjectBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Product.h b/src/other/Eigen/Eigen/src/Core/Product.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Product.h rename to src/other/Eigen/Eigen/src/Core/Product.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ProductEvaluators.h b/src/other/Eigen/Eigen/src/Core/ProductEvaluators.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ProductEvaluators.h rename to src/other/Eigen/Eigen/src/Core/ProductEvaluators.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Random.h b/src/other/Eigen/Eigen/src/Core/Random.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Random.h rename to src/other/Eigen/Eigen/src/Core/Random.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Redux.h b/src/other/Eigen/Eigen/src/Core/Redux.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Redux.h rename to src/other/Eigen/Eigen/src/Core/Redux.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Ref.h b/src/other/Eigen/Eigen/src/Core/Ref.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Ref.h rename to src/other/Eigen/Eigen/src/Core/Ref.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Replicate.h b/src/other/Eigen/Eigen/src/Core/Replicate.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Replicate.h rename to src/other/Eigen/Eigen/src/Core/Replicate.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Reshaped.h b/src/other/Eigen/Eigen/src/Core/Reshaped.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Reshaped.h rename to src/other/Eigen/Eigen/src/Core/Reshaped.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/ReturnByValue.h b/src/other/Eigen/Eigen/src/Core/ReturnByValue.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/ReturnByValue.h rename to src/other/Eigen/Eigen/src/Core/ReturnByValue.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Reverse.h b/src/other/Eigen/Eigen/src/Core/Reverse.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Reverse.h rename to src/other/Eigen/Eigen/src/Core/Reverse.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Select.h b/src/other/Eigen/Eigen/src/Core/Select.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Select.h rename to src/other/Eigen/Eigen/src/Core/Select.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/SelfAdjointView.h b/src/other/Eigen/Eigen/src/Core/SelfAdjointView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/SelfAdjointView.h rename to src/other/Eigen/Eigen/src/Core/SelfAdjointView.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h b/src/other/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h rename to src/other/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Solve.h b/src/other/Eigen/Eigen/src/Core/Solve.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Solve.h rename to src/other/Eigen/Eigen/src/Core/Solve.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/SolveTriangular.h b/src/other/Eigen/Eigen/src/Core/SolveTriangular.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/SolveTriangular.h rename to src/other/Eigen/Eigen/src/Core/SolveTriangular.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/SolverBase.h b/src/other/Eigen/Eigen/src/Core/SolverBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/SolverBase.h rename to src/other/Eigen/Eigen/src/Core/SolverBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/StableNorm.h b/src/other/Eigen/Eigen/src/Core/StableNorm.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/StableNorm.h rename to src/other/Eigen/Eigen/src/Core/StableNorm.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/StlIterators.h b/src/other/Eigen/Eigen/src/Core/StlIterators.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/StlIterators.h rename to src/other/Eigen/Eigen/src/Core/StlIterators.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Stride.h b/src/other/Eigen/Eigen/src/Core/Stride.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Stride.h rename to src/other/Eigen/Eigen/src/Core/Stride.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Swap.h b/src/other/Eigen/Eigen/src/Core/Swap.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Swap.h rename to src/other/Eigen/Eigen/src/Core/Swap.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Transpose.h b/src/other/Eigen/Eigen/src/Core/Transpose.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Transpose.h rename to src/other/Eigen/Eigen/src/Core/Transpose.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Transpositions.h b/src/other/Eigen/Eigen/src/Core/Transpositions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Transpositions.h rename to src/other/Eigen/Eigen/src/Core/Transpositions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/TriangularMatrix.h b/src/other/Eigen/Eigen/src/Core/TriangularMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/TriangularMatrix.h rename to src/other/Eigen/Eigen/src/Core/TriangularMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/VectorBlock.h b/src/other/Eigen/Eigen/src/Core/VectorBlock.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/VectorBlock.h rename to src/other/Eigen/Eigen/src/Core/VectorBlock.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/VectorwiseOp.h b/src/other/Eigen/Eigen/src/Core/VectorwiseOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/VectorwiseOp.h rename to src/other/Eigen/Eigen/src/Core/VectorwiseOp.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/Visitor.h b/src/other/Eigen/Eigen/src/Core/Visitor.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/Visitor.h rename to src/other/Eigen/Eigen/src/Core/Visitor.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/AVX/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/AVX/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/AVX/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/AVX/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/AVX512/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX512/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/AVX512/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX512/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/CUDA/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/CUDA/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/CUDA/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/CUDA/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/BFloat16.h b/src/other/Eigen/Eigen/src/Core/arch/Default/BFloat16.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/BFloat16.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/BFloat16.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/ConjHelper.h b/src/other/Eigen/Eigen/src/Core/arch/Default/ConjHelper.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/ConjHelper.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/ConjHelper.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h b/src/other/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/Half.h b/src/other/Eigen/Eigen/src/Core/arch/Default/Half.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/Half.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/Half.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/Settings.h b/src/other/Eigen/Eigen/src/Core/arch/Default/Settings.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/Settings.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/Settings.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/Default/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/Default/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/Default/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/Default/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/GPU/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/GPU/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/GPU/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/GPU/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/GPU/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/GPU/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/GPU/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/GPU/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/GPU/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/GPU/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/GPU/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/GPU/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h b/src/other/Eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h rename to src/other/Eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/MSA/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/MSA/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/MSA/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/MSA/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/MSA/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/MSA/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/MSA/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/MSA/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/MSA/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/MSA/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/MSA/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/MSA/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/NEON/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/NEON/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/NEON/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/NEON/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h b/src/other/Eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h rename to src/other/Eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/NEON/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/NEON/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/NEON/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/NEON/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/NEON/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/NEON/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/NEON/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/NEON/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SSE/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/SSE/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SSE/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/SSE/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SSE/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/SSE/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SSE/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/SSE/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SSE/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/SSE/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SSE/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/SSE/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SVE/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/SVE/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SVE/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/SVE/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SVE/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/SVE/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SVE/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/SVE/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SVE/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/SVE/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SVE/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/SVE/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h b/src/other/Eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h rename to src/other/Eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/SYCL/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/SYCL/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h b/src/other/Eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h rename to src/other/Eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h b/src/other/Eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h rename to src/other/Eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/Complex.h b/src/other/Eigen/Eigen/src/Core/arch/ZVector/Complex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/Complex.h rename to src/other/Eigen/Eigen/src/Core/arch/ZVector/Complex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h b/src/other/Eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h rename to src/other/Eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/PacketMath.h b/src/other/Eigen/Eigen/src/Core/arch/ZVector/PacketMath.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/arch/ZVector/PacketMath.h rename to src/other/Eigen/Eigen/src/Core/arch/ZVector/PacketMath.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/AssignmentFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/AssignmentFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/AssignmentFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/AssignmentFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/BinaryFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/BinaryFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/BinaryFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/BinaryFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/NullaryFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/NullaryFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/NullaryFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/NullaryFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/StlFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/StlFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/StlFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/StlFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/TernaryFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/TernaryFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/TernaryFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/TernaryFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/functors/UnaryFunctors.h b/src/other/Eigen/Eigen/src/Core/functors/UnaryFunctors.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/functors/UnaryFunctors.h rename to src/other/Eigen/Eigen/src/Core/functors/UnaryFunctors.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/src/other/Eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixVector.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixVector.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixVector.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/Parallelizer.h b/src/other/Eigen/Eigen/src/Core/products/Parallelizer.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/Parallelizer.h rename to src/other/Eigen/Eigen/src/Core/products/Parallelizer.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointProduct.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointProduct.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointRank2Update.h b/src/other/Eigen/Eigen/src/Core/products/SelfadjointRank2Update.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/SelfadjointRank2Update.h rename to src/other/Eigen/Eigen/src/Core/products/SelfadjointRank2Update.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h b/src/other/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixVector.h b/src/other/Eigen/Eigen/src/Core/products/TriangularMatrixVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixVector.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularMatrixVector.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverMatrix.h b/src/other/Eigen/Eigen/src/Core/products/TriangularSolverMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverMatrix.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularSolverMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h b/src/other/Eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverVector.h b/src/other/Eigen/Eigen/src/Core/products/TriangularSolverVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/products/TriangularSolverVector.h rename to src/other/Eigen/Eigen/src/Core/products/TriangularSolverVector.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/BlasUtil.h b/src/other/Eigen/Eigen/src/Core/util/BlasUtil.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/BlasUtil.h rename to src/other/Eigen/Eigen/src/Core/util/BlasUtil.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/ConfigureVectorization.h b/src/other/Eigen/Eigen/src/Core/util/ConfigureVectorization.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/ConfigureVectorization.h rename to src/other/Eigen/Eigen/src/Core/util/ConfigureVectorization.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/Constants.h b/src/other/Eigen/Eigen/src/Core/util/Constants.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/Constants.h rename to src/other/Eigen/Eigen/src/Core/util/Constants.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/DisableStupidWarnings.h b/src/other/Eigen/Eigen/src/Core/util/DisableStupidWarnings.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/DisableStupidWarnings.h rename to src/other/Eigen/Eigen/src/Core/util/DisableStupidWarnings.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/ForwardDeclarations.h b/src/other/Eigen/Eigen/src/Core/util/ForwardDeclarations.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/ForwardDeclarations.h rename to src/other/Eigen/Eigen/src/Core/util/ForwardDeclarations.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/IndexedViewHelper.h b/src/other/Eigen/Eigen/src/Core/util/IndexedViewHelper.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/IndexedViewHelper.h rename to src/other/Eigen/Eigen/src/Core/util/IndexedViewHelper.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/IntegralConstant.h b/src/other/Eigen/Eigen/src/Core/util/IntegralConstant.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/IntegralConstant.h rename to src/other/Eigen/Eigen/src/Core/util/IntegralConstant.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/MKL_support.h b/src/other/Eigen/Eigen/src/Core/util/MKL_support.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/MKL_support.h rename to src/other/Eigen/Eigen/src/Core/util/MKL_support.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/Macros.h b/src/other/Eigen/Eigen/src/Core/util/Macros.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/Macros.h rename to src/other/Eigen/Eigen/src/Core/util/Macros.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/Memory.h b/src/other/Eigen/Eigen/src/Core/util/Memory.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/Memory.h rename to src/other/Eigen/Eigen/src/Core/util/Memory.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/Meta.h b/src/other/Eigen/Eigen/src/Core/util/Meta.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/Meta.h rename to src/other/Eigen/Eigen/src/Core/util/Meta.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/NonMPL2.h b/src/other/Eigen/Eigen/src/Core/util/NonMPL2.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/NonMPL2.h rename to src/other/Eigen/Eigen/src/Core/util/NonMPL2.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/ReenableStupidWarnings.h b/src/other/Eigen/Eigen/src/Core/util/ReenableStupidWarnings.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/ReenableStupidWarnings.h rename to src/other/Eigen/Eigen/src/Core/util/ReenableStupidWarnings.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/ReshapedHelper.h b/src/other/Eigen/Eigen/src/Core/util/ReshapedHelper.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/ReshapedHelper.h rename to src/other/Eigen/Eigen/src/Core/util/ReshapedHelper.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/StaticAssert.h b/src/other/Eigen/Eigen/src/Core/util/StaticAssert.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/StaticAssert.h rename to src/other/Eigen/Eigen/src/Core/util/StaticAssert.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/SymbolicIndex.h b/src/other/Eigen/Eigen/src/Core/util/SymbolicIndex.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/SymbolicIndex.h rename to src/other/Eigen/Eigen/src/Core/util/SymbolicIndex.h diff --git a/src/other/ext/Eigen/Eigen/src/Core/util/XprHelper.h b/src/other/Eigen/Eigen/src/Core/util/XprHelper.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Core/util/XprHelper.h rename to src/other/Eigen/Eigen/src/Core/util/XprHelper.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/src/other/Eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h rename to src/other/Eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexSchur.h b/src/other/Eigen/Eigen/src/Eigenvalues/ComplexSchur.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexSchur.h rename to src/other/Eigen/Eigen/src/Eigenvalues/ComplexSchur.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h b/src/other/Eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h rename to src/other/Eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/EigenSolver.h b/src/other/Eigen/Eigen/src/Eigenvalues/EigenSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/EigenSolver.h rename to src/other/Eigen/Eigen/src/Eigenvalues/EigenSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/src/other/Eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h rename to src/other/Eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/src/other/Eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h rename to src/other/Eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/src/other/Eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h rename to src/other/Eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/src/other/Eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h rename to src/other/Eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/RealQZ.h b/src/other/Eigen/Eigen/src/Eigenvalues/RealQZ.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/RealQZ.h rename to src/other/Eigen/Eigen/src/Eigenvalues/RealQZ.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/RealSchur.h b/src/other/Eigen/Eigen/src/Eigenvalues/RealSchur.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/RealSchur.h rename to src/other/Eigen/Eigen/src/Eigenvalues/RealSchur.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h b/src/other/Eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h rename to src/other/Eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/src/other/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h rename to src/other/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h b/src/other/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h rename to src/other/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/Eigenvalues/Tridiagonalization.h b/src/other/Eigen/Eigen/src/Eigenvalues/Tridiagonalization.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Eigenvalues/Tridiagonalization.h rename to src/other/Eigen/Eigen/src/Eigenvalues/Tridiagonalization.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/AlignedBox.h b/src/other/Eigen/Eigen/src/Geometry/AlignedBox.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/AlignedBox.h rename to src/other/Eigen/Eigen/src/Geometry/AlignedBox.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/AngleAxis.h b/src/other/Eigen/Eigen/src/Geometry/AngleAxis.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/AngleAxis.h rename to src/other/Eigen/Eigen/src/Geometry/AngleAxis.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/EulerAngles.h b/src/other/Eigen/Eigen/src/Geometry/EulerAngles.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/EulerAngles.h rename to src/other/Eigen/Eigen/src/Geometry/EulerAngles.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Homogeneous.h b/src/other/Eigen/Eigen/src/Geometry/Homogeneous.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Homogeneous.h rename to src/other/Eigen/Eigen/src/Geometry/Homogeneous.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Hyperplane.h b/src/other/Eigen/Eigen/src/Geometry/Hyperplane.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Hyperplane.h rename to src/other/Eigen/Eigen/src/Geometry/Hyperplane.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/OrthoMethods.h b/src/other/Eigen/Eigen/src/Geometry/OrthoMethods.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/OrthoMethods.h rename to src/other/Eigen/Eigen/src/Geometry/OrthoMethods.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/ParametrizedLine.h b/src/other/Eigen/Eigen/src/Geometry/ParametrizedLine.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/ParametrizedLine.h rename to src/other/Eigen/Eigen/src/Geometry/ParametrizedLine.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Quaternion.h b/src/other/Eigen/Eigen/src/Geometry/Quaternion.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Quaternion.h rename to src/other/Eigen/Eigen/src/Geometry/Quaternion.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Rotation2D.h b/src/other/Eigen/Eigen/src/Geometry/Rotation2D.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Rotation2D.h rename to src/other/Eigen/Eigen/src/Geometry/Rotation2D.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/RotationBase.h b/src/other/Eigen/Eigen/src/Geometry/RotationBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/RotationBase.h rename to src/other/Eigen/Eigen/src/Geometry/RotationBase.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Scaling.h b/src/other/Eigen/Eigen/src/Geometry/Scaling.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Scaling.h rename to src/other/Eigen/Eigen/src/Geometry/Scaling.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Transform.h b/src/other/Eigen/Eigen/src/Geometry/Transform.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Transform.h rename to src/other/Eigen/Eigen/src/Geometry/Transform.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Translation.h b/src/other/Eigen/Eigen/src/Geometry/Translation.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Translation.h rename to src/other/Eigen/Eigen/src/Geometry/Translation.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/Umeyama.h b/src/other/Eigen/Eigen/src/Geometry/Umeyama.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/Umeyama.h rename to src/other/Eigen/Eigen/src/Geometry/Umeyama.h diff --git a/src/other/ext/Eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h b/src/other/Eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h rename to src/other/Eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h diff --git a/src/other/ext/Eigen/Eigen/src/Householder/BlockHouseholder.h b/src/other/Eigen/Eigen/src/Householder/BlockHouseholder.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Householder/BlockHouseholder.h rename to src/other/Eigen/Eigen/src/Householder/BlockHouseholder.h diff --git a/src/other/ext/Eigen/Eigen/src/Householder/Householder.h b/src/other/Eigen/Eigen/src/Householder/Householder.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Householder/Householder.h rename to src/other/Eigen/Eigen/src/Householder/Householder.h diff --git a/src/other/ext/Eigen/Eigen/src/Householder/HouseholderSequence.h b/src/other/Eigen/Eigen/src/Householder/HouseholderSequence.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Householder/HouseholderSequence.h rename to src/other/Eigen/Eigen/src/Householder/HouseholderSequence.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h diff --git a/src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h b/src/other/Eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h rename to src/other/Eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h diff --git a/src/other/ext/Eigen/Eigen/src/Jacobi/Jacobi.h b/src/other/Eigen/Eigen/src/Jacobi/Jacobi.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/Jacobi/Jacobi.h rename to src/other/Eigen/Eigen/src/Jacobi/Jacobi.h diff --git a/src/other/ext/Eigen/Eigen/src/KLUSupport/KLUSupport.h b/src/other/Eigen/Eigen/src/KLUSupport/KLUSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/KLUSupport/KLUSupport.h rename to src/other/Eigen/Eigen/src/KLUSupport/KLUSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/Determinant.h b/src/other/Eigen/Eigen/src/LU/Determinant.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/Determinant.h rename to src/other/Eigen/Eigen/src/LU/Determinant.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/FullPivLU.h b/src/other/Eigen/Eigen/src/LU/FullPivLU.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/FullPivLU.h rename to src/other/Eigen/Eigen/src/LU/FullPivLU.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/InverseImpl.h b/src/other/Eigen/Eigen/src/LU/InverseImpl.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/InverseImpl.h rename to src/other/Eigen/Eigen/src/LU/InverseImpl.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/PartialPivLU.h b/src/other/Eigen/Eigen/src/LU/PartialPivLU.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/PartialPivLU.h rename to src/other/Eigen/Eigen/src/LU/PartialPivLU.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h b/src/other/Eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h rename to src/other/Eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/LU/arch/InverseSize4.h b/src/other/Eigen/Eigen/src/LU/arch/InverseSize4.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/LU/arch/InverseSize4.h rename to src/other/Eigen/Eigen/src/LU/arch/InverseSize4.h diff --git a/src/other/ext/Eigen/Eigen/src/MetisSupport/MetisSupport.h b/src/other/Eigen/Eigen/src/MetisSupport/MetisSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/MetisSupport/MetisSupport.h rename to src/other/Eigen/Eigen/src/MetisSupport/MetisSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/OrderingMethods/Amd.h b/src/other/Eigen/Eigen/src/OrderingMethods/Amd.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/OrderingMethods/Amd.h rename to src/other/Eigen/Eigen/src/OrderingMethods/Amd.h diff --git a/src/other/ext/Eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h b/src/other/Eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h rename to src/other/Eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h diff --git a/src/other/ext/Eigen/Eigen/src/OrderingMethods/Ordering.h b/src/other/Eigen/Eigen/src/OrderingMethods/Ordering.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/OrderingMethods/Ordering.h rename to src/other/Eigen/Eigen/src/OrderingMethods/Ordering.h diff --git a/src/other/ext/Eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h b/src/other/Eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h rename to src/other/Eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/PardisoSupport/PardisoSupport.h b/src/other/Eigen/Eigen/src/PardisoSupport/PardisoSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/PardisoSupport/PardisoSupport.h rename to src/other/Eigen/Eigen/src/PardisoSupport/PardisoSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/ColPivHouseholderQR.h b/src/other/Eigen/Eigen/src/QR/ColPivHouseholderQR.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/ColPivHouseholderQR.h rename to src/other/Eigen/Eigen/src/QR/ColPivHouseholderQR.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h b/src/other/Eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h rename to src/other/Eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/src/other/Eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h rename to src/other/Eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/FullPivHouseholderQR.h b/src/other/Eigen/Eigen/src/QR/FullPivHouseholderQR.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/FullPivHouseholderQR.h rename to src/other/Eigen/Eigen/src/QR/FullPivHouseholderQR.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/HouseholderQR.h b/src/other/Eigen/Eigen/src/QR/HouseholderQR.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/HouseholderQR.h rename to src/other/Eigen/Eigen/src/QR/HouseholderQR.h diff --git a/src/other/ext/Eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h b/src/other/Eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h rename to src/other/Eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/src/other/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h rename to src/other/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/SVD/BDCSVD.h b/src/other/Eigen/Eigen/src/SVD/BDCSVD.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SVD/BDCSVD.h rename to src/other/Eigen/Eigen/src/SVD/BDCSVD.h diff --git a/src/other/ext/Eigen/Eigen/src/SVD/JacobiSVD.h b/src/other/Eigen/Eigen/src/SVD/JacobiSVD.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SVD/JacobiSVD.h rename to src/other/Eigen/Eigen/src/SVD/JacobiSVD.h diff --git a/src/other/ext/Eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h b/src/other/Eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h rename to src/other/Eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h diff --git a/src/other/ext/Eigen/Eigen/src/SVD/SVDBase.h b/src/other/Eigen/Eigen/src/SVD/SVDBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SVD/SVDBase.h rename to src/other/Eigen/Eigen/src/SVD/SVDBase.h diff --git a/src/other/ext/Eigen/Eigen/src/SVD/UpperBidiagonalization.h b/src/other/Eigen/Eigen/src/SVD/UpperBidiagonalization.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SVD/UpperBidiagonalization.h rename to src/other/Eigen/Eigen/src/SVD/UpperBidiagonalization.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h b/src/other/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h rename to src/other/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/src/other/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h rename to src/other/Eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/AmbiVector.h b/src/other/Eigen/Eigen/src/SparseCore/AmbiVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/AmbiVector.h rename to src/other/Eigen/Eigen/src/SparseCore/AmbiVector.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/CompressedStorage.h b/src/other/Eigen/Eigen/src/SparseCore/CompressedStorage.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/CompressedStorage.h rename to src/other/Eigen/Eigen/src/SparseCore/CompressedStorage.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/src/other/Eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h rename to src/other/Eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/MappedSparseMatrix.h b/src/other/Eigen/Eigen/src/SparseCore/MappedSparseMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/MappedSparseMatrix.h rename to src/other/Eigen/Eigen/src/SparseCore/MappedSparseMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseAssign.h b/src/other/Eigen/Eigen/src/SparseCore/SparseAssign.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseAssign.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseAssign.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseBlock.h b/src/other/Eigen/Eigen/src/SparseCore/SparseBlock.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseBlock.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseBlock.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseColEtree.h b/src/other/Eigen/Eigen/src/SparseCore/SparseColEtree.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseColEtree.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseColEtree.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseCompressedBase.h b/src/other/Eigen/Eigen/src/SparseCore/SparseCompressedBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseCompressedBase.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseCompressedBase.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/src/other/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/src/other/Eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseDenseProduct.h b/src/other/Eigen/Eigen/src/SparseCore/SparseDenseProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseDenseProduct.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseDenseProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h b/src/other/Eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseDot.h b/src/other/Eigen/Eigen/src/SparseCore/SparseDot.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseDot.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseDot.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseFuzzy.h b/src/other/Eigen/Eigen/src/SparseCore/SparseFuzzy.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseFuzzy.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseFuzzy.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseMap.h b/src/other/Eigen/Eigen/src/SparseCore/SparseMap.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseMap.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseMap.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseMatrix.h b/src/other/Eigen/Eigen/src/SparseCore/SparseMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseMatrix.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h b/src/other/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparsePermutation.h b/src/other/Eigen/Eigen/src/SparseCore/SparsePermutation.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparsePermutation.h rename to src/other/Eigen/Eigen/src/SparseCore/SparsePermutation.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseProduct.h b/src/other/Eigen/Eigen/src/SparseCore/SparseProduct.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseProduct.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseProduct.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseRedux.h b/src/other/Eigen/Eigen/src/SparseCore/SparseRedux.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseRedux.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseRedux.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseRef.h b/src/other/Eigen/Eigen/src/SparseCore/SparseRef.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseRef.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseRef.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h b/src/other/Eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseSolverBase.h b/src/other/Eigen/Eigen/src/SparseCore/SparseSolverBase.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseSolverBase.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseSolverBase.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/src/other/Eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseTranspose.h b/src/other/Eigen/Eigen/src/SparseCore/SparseTranspose.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseTranspose.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseTranspose.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseTriangularView.h b/src/other/Eigen/Eigen/src/SparseCore/SparseTriangularView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseTriangularView.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseTriangularView.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseUtil.h b/src/other/Eigen/Eigen/src/SparseCore/SparseUtil.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseUtil.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseUtil.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseVector.h b/src/other/Eigen/Eigen/src/SparseCore/SparseVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseVector.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseVector.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/SparseView.h b/src/other/Eigen/Eigen/src/SparseCore/SparseView.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/SparseView.h rename to src/other/Eigen/Eigen/src/SparseCore/SparseView.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseCore/TriangularSolver.h b/src/other/Eigen/Eigen/src/SparseCore/TriangularSolver.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseCore/TriangularSolver.h rename to src/other/Eigen/Eigen/src/SparseCore/TriangularSolver.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLUImpl.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLUImpl.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLUImpl.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLUImpl.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Structs.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_Structs.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Structs.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_Structs.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Utils.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_Utils.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_Utils.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_Utils.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_pruneL.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_pruneL.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_pruneL.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_pruneL.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h b/src/other/Eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h rename to src/other/Eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h diff --git a/src/other/ext/Eigen/Eigen/src/SparseQR/SparseQR.h b/src/other/Eigen/Eigen/src/SparseQR/SparseQR.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SparseQR/SparseQR.h rename to src/other/Eigen/Eigen/src/SparseQR/SparseQR.h diff --git a/src/other/ext/Eigen/Eigen/src/StlSupport/StdDeque.h b/src/other/Eigen/Eigen/src/StlSupport/StdDeque.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/StlSupport/StdDeque.h rename to src/other/Eigen/Eigen/src/StlSupport/StdDeque.h diff --git a/src/other/ext/Eigen/Eigen/src/StlSupport/StdList.h b/src/other/Eigen/Eigen/src/StlSupport/StdList.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/StlSupport/StdList.h rename to src/other/Eigen/Eigen/src/StlSupport/StdList.h diff --git a/src/other/ext/Eigen/Eigen/src/StlSupport/StdVector.h b/src/other/Eigen/Eigen/src/StlSupport/StdVector.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/StlSupport/StdVector.h rename to src/other/Eigen/Eigen/src/StlSupport/StdVector.h diff --git a/src/other/ext/Eigen/Eigen/src/StlSupport/details.h b/src/other/Eigen/Eigen/src/StlSupport/details.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/StlSupport/details.h rename to src/other/Eigen/Eigen/src/StlSupport/details.h diff --git a/src/other/ext/Eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h b/src/other/Eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h rename to src/other/Eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h b/src/other/Eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h rename to src/other/Eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/Image.h b/src/other/Eigen/Eigen/src/misc/Image.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/Image.h rename to src/other/Eigen/Eigen/src/misc/Image.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/Kernel.h b/src/other/Eigen/Eigen/src/misc/Kernel.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/Kernel.h rename to src/other/Eigen/Eigen/src/misc/Kernel.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/RealSvd2x2.h b/src/other/Eigen/Eigen/src/misc/RealSvd2x2.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/RealSvd2x2.h rename to src/other/Eigen/Eigen/src/misc/RealSvd2x2.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/blas.h b/src/other/Eigen/Eigen/src/misc/blas.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/blas.h rename to src/other/Eigen/Eigen/src/misc/blas.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/lapack.h b/src/other/Eigen/Eigen/src/misc/lapack.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/lapack.h rename to src/other/Eigen/Eigen/src/misc/lapack.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/lapacke.h b/src/other/Eigen/Eigen/src/misc/lapacke.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/lapacke.h rename to src/other/Eigen/Eigen/src/misc/lapacke.h diff --git a/src/other/ext/Eigen/Eigen/src/misc/lapacke_mangling.h b/src/other/Eigen/Eigen/src/misc/lapacke_mangling.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/misc/lapacke_mangling.h rename to src/other/Eigen/Eigen/src/misc/lapacke_mangling.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/src/other/Eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h rename to src/other/Eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/src/other/Eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h rename to src/other/Eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/BlockMethods.h b/src/other/Eigen/Eigen/src/plugins/BlockMethods.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/BlockMethods.h rename to src/other/Eigen/Eigen/src/plugins/BlockMethods.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h b/src/other/Eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h rename to src/other/Eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h b/src/other/Eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h rename to src/other/Eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/IndexedViewMethods.h b/src/other/Eigen/Eigen/src/plugins/IndexedViewMethods.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/IndexedViewMethods.h rename to src/other/Eigen/Eigen/src/plugins/IndexedViewMethods.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/src/other/Eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h rename to src/other/Eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/src/other/Eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h rename to src/other/Eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h diff --git a/src/other/ext/Eigen/Eigen/src/plugins/ReshapedMethods.h b/src/other/Eigen/Eigen/src/plugins/ReshapedMethods.h similarity index 100% rename from src/other/ext/Eigen/Eigen/src/plugins/ReshapedMethods.h rename to src/other/Eigen/Eigen/src/plugins/ReshapedMethods.h diff --git a/src/other/ext/Eigen/README.md b/src/other/Eigen/README.md similarity index 100% rename from src/other/ext/Eigen/README.md rename to src/other/Eigen/README.md diff --git a/src/other/ext/CMake/ExternalProject_Target.cmake b/src/other/ext/CMake/ExternalProject_Target.cmake index c45efe1366d..fe43faeedd6 100644 --- a/src/other/ext/CMake/ExternalProject_Target.cmake +++ b/src/other/ext/CMake/ExternalProject_Target.cmake @@ -20,6 +20,60 @@ # IMPORTED_RUNTIME_ARTIFACTS that may be useful for this work... see: # https://cmake.org/cmake/help/v3.21/command/install.html +# Wrap the platform specific naming conventions we must manage to copy +# build output from 3rd party build systems. +function(set_lib_vars RVAR root vmaj vmin vpatch) + + # OpenBSD has its own naming conventions. Set a platform variable based on + # the OS name so we can test for it succinctly. + if ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") + set(OPENBSD ON) + endif ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") + + unset(${RVAR}_BASENAME) + unset(${RVAR}_STATICNAME) + unset(${RVAR}_SUFFIX) + unset(${RVAR}_SYMLINK1) + unset(${RVAR}_SYMLINK2) + + if (NOT "${vpatch}" STREQUAL "") + set(vpatch_suffix ".${vpatch}") + else() + set(vpatch_suffix "") + endif() + + if (MSVC) + set(${RVAR}_BASENAME ${root}) + set(${RVAR}_STATICNAME ${root}-static) + set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}) + elseif (APPLE) + set(${RVAR}_BASENAME lib${root}) + set(${RVAR}_STATICNAME lib${root}) + set(${RVAR}_SUFFIX .${vmaj}.${vmin}${vpatch_suffix}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}.${vmaj}${CMAKE_SHARED_LIBRARY_SUFFIX}) + elseif (OPENBSD) + set(${RVAR}_BASENAME lib${root}) + set(${RVAR}_STATICNAME lib${root}) + set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}.${vmin}) + else (MSVC) + set(${RVAR}_BASENAME lib${root}) + set(${RVAR}_STATICNAME lib${root}) + set(${RVAR}_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}.${vmin}${vpatch_suffix}) + set(${RVAR}_SYMLINK_1 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(${RVAR}_SYMLINK_2 ${${RVAR}_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}.${vmaj}) + endif (MSVC) + + # Communicate the answers to the parent scope - these are the return values. + set(${RVAR}_BASENAME "${${RVAR}_BASENAME}" PARENT_SCOPE) + set(${RVAR}_STATICNAME "${${RVAR}_STATICNAME}" PARENT_SCOPE) + set(${RVAR}_SUFFIX "${${RVAR}_SUFFIX}" PARENT_SCOPE) + set(${RVAR}_SYMLINK_1 "${${RVAR}_SYMLINK_1}" PARENT_SCOPE) + set(${RVAR}_SYMLINK_2 "${${RVAR}_SYMLINK_2}" PARENT_SCOPE) + +endfunction(set_lib_vars RVAR root) # Be quite about tool outputs by default if(NOT DEFINED EXTPROJ_VERBOSE) diff --git a/src/other/ext/CMakeLists.txt b/src/other/ext/CMakeLists.txt index e9bf3ffa24d..4912b8f376b 100644 --- a/src/other/ext/CMakeLists.txt +++ b/src/other/ext/CMakeLists.txt @@ -341,19 +341,6 @@ if (COMMAND CONFIG_H_APPEND) CONFIG_H_APPEND(BRLCAD "#cmakedefine HAVE_TK\n") endif (COMMAND CONFIG_H_APPEND) - -# The above libraries are all compilation targets with libraries, and so have -# build outputs that must be distributed with BRL-CAD. The following are -# either header-only libraries or built directly into executables, and as such -# may remain in place - they are needed only for building. -include("${CMAKE_CURRENT_SOURCE_DIR}/Eigen.dist") -CMAKEFILES_IN_DIR(Eigen_ignore_files Eigen) - -# linenoise is used by applications directly -include(${CMAKE_CURRENT_SOURCE_DIR}/linenoise.dist) -CMAKEFILES_IN_DIR(linenoise_ignore_files linenoise) - - std_build_rpath() if (COMMAND CMAKEFILES) @@ -383,7 +370,6 @@ if (COMMAND CMAKEFILES) CMake/buildpath_replace.cxx.in CMake/rpath_replace.cxx.in CMake/tcl_replace.cxx.in - Eigen.dist assetimport.cmake assetimport.dist gdal.cmake @@ -394,7 +380,6 @@ if (COMMAND CMAKEFILES) itk3.dist iwidgets.cmake iwidgets.dist - linenoise.dist netpbm.cmake netpbm.dist openmesh.cmake diff --git a/src/other/ext/linenoise/linenoise.h b/src/other/ext/linenoise/linenoise.h deleted file mode 100644 index 8842de3a4e8..00000000000 --- a/src/other/ext/linenoise/linenoise.h +++ /dev/null @@ -1,149 +0,0 @@ -/* linenoise.h -- guerrilla line editing library against the idea that a - * line editing lib needs to be 20,000 lines of C code. - * - * See linenoise.c for more information. - * - * ------------------------------------------------------------------------ - * - * Copyright (c) 2010, Salvatore Sanfilippo - * Copyright (c) 2010, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __LINENOISE_H -#define __LINENOISE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef NO_COMPLETION -typedef struct linenoiseCompletions { - size_t len; - char **cvec; -} linenoiseCompletions; - -/* - * The callback type for tab completion handlers. - */ -typedef void(linenoiseCompletionCallback)(const char *prefix, linenoiseCompletions *comp, void *userdata); - -/* - * Sets the current tab completion handler and returns the previous one, or NULL - * if no prior one has been set. - */ -linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *comp, void *userdata); - -/* - * Adds a copy of the given string to the given completion list. The copy is owned - * by the linenoiseCompletions object. - */ -void linenoiseAddCompletion(linenoiseCompletions *comp, const char *str); - -typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold, void *userdata); -typedef void(linenoiseFreeHintsCallback)(void *hint, void *userdata); -void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata); -void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback); - -#endif - -/* - * Prompts for input using the given string as the input - * prompt. Returns when the user has tapped ENTER or (on an empty - * line) EOF (Ctrl-D on Unix, Ctrl-Z on Windows). Returns either - * a copy of the entered string (for ENTER) or NULL (on EOF). The - * caller owns the returned string and must eventually free() it. - */ -char *linenoise(const char *prompt); - -/** - * Like linenoise() but starts with an initial buffer. - */ -char *linenoiseWithInitial(const char *prompt, const char *initial); - -/** - * Clear the screen. - */ -void linenoiseClearScreen(void); - -/* - * Adds a copy of the given line of the command history. - */ -int linenoiseHistoryAdd(const char *line); - -/* - * Sets the maximum length of the command history, in lines. - * If the history is currently longer, it will be trimmed, - * retaining only the most recent entries. If len is 0 or less - * then this function does nothing. - */ -int linenoiseHistorySetMaxLen(int len); - -/* - * Returns the current maximum length of the history, in lines. - */ -int linenoiseHistoryGetMaxLen(void); - -/* - * Saves the current contents of the history to the given file. - * Returns 0 on success. - */ -int linenoiseHistorySave(const char *filename); - -/* - * Replaces the current history with the contents - * of the given file. Returns 0 on success. - */ -int linenoiseHistoryLoad(const char *filename); - -/* - * Frees all history entries, clearing the history. - */ -void linenoiseHistoryFree(void); - -/* - * Returns a pointer to the list of history entries, writing its - * length to *len if len is not NULL. The memory is owned by linenoise - * and must not be freed. - */ -char **linenoiseHistory(int *len); - -/* - * Returns the number of display columns in the current terminal. - */ -int linenoiseColumns(void); - -/** - * Enable or disable multiline mode (disabled by default) - */ -void linenoiseSetMultiLine(int enableml); - -#ifdef __cplusplus -} -#endif - -#endif /* __LINENOISE_H */ diff --git a/src/other/ext/png.cmake b/src/other/ext/png.cmake index 06fccabda2e..7b021dc7c2e 100644 --- a/src/other/ext/png.cmake +++ b/src/other/ext/png.cmake @@ -27,7 +27,7 @@ if (BRLCAD_PNG_BUILD) set(PNG_VERSION_MAJOR ${PNG_MAJOR_VERSION}${PNG_MINOR_VERSION}) set(PNG_VERSION_MINOR ${PNG_PATCH_VERSION}) - set(PNG_LIB_NAME png${PNG_VERSION_MAJOR}) + set(PNG_LIB_NAME png_brl${PNG_VERSION_MAJOR}) # NOTE: when we bump to libpng 1.6.40, they expose a PNG_DEBUG_POSTFIX which # we can supply empty at build time. For the current version we've added a @@ -127,9 +127,9 @@ if (BRLCAD_PNG_BUILD) png.h pngconf.h pnglibconf.h - libpng${PNG_VERSION_MAJOR}/png.h - libpng${PNG_VERSION_MAJOR}/pngconf.h - libpng${PNG_VERSION_MAJOR}/pnglibconf.h + libpng_brl${PNG_VERSION_MAJOR}/png.h + libpng_brl${PNG_VERSION_MAJOR}/pngconf.h + libpng_brl${PNG_VERSION_MAJOR}/pnglibconf.h ) set(PNG_LIBRARY_DEBUG png CACHE STRING "Building bundled libpng" FORCE) diff --git a/src/other/ext/png.dist b/src/other/ext/png.dist index ac46860ae22..3bad093cc70 100644 --- a/src/other/ext/png.dist +++ b/src/other/ext/png.dist @@ -3,6 +3,7 @@ ANNOUNCE AUTHORS CHANGES CMakeLists.txt +CMake/FindZLIB.cmake INSTALL LICENSE Makefile.am diff --git a/src/other/ext/png/CMake/FindZLIB.cmake b/src/other/ext/png/CMake/FindZLIB.cmake new file mode 100644 index 00000000000..e06dc8743c5 --- /dev/null +++ b/src/other/ext/png/CMake/FindZLIB.cmake @@ -0,0 +1,123 @@ +#.rst: +# FindZLIB +# -------- +# +# Find the native ZLIB includes and library. +# +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``ZLIB::ZLIB``, if +# ZLIB has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: +# +# :: +# +# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. +# ZLIB_LIBRARIES - List of libraries when using zlib. +# ZLIB_FOUND - True if zlib found. +# +# :: +# +# ZLIB_VERSION_STRING - The version of zlib found (x.y.z) +# ZLIB_VERSION_MAJOR - The major version of zlib +# ZLIB_VERSION_MINOR - The minor version of zlib +# ZLIB_VERSION_PATCH - The patch version of zlib +# ZLIB_VERSION_TWEAK - The tweak version of zlib +# +# Backward Compatibility +# ^^^^^^^^^^^^^^^^^^^^^^ +# +# The following variable are provided for backward compatibility +# +# :: +# +# ZLIB_MAJOR_VERSION - The major version of zlib +# ZLIB_MINOR_VERSION - The minor version of zlib +# ZLIB_PATCH_VERSION - The patch version of zlib +# +# Hints +# ^^^^^ +# +# A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this +# module where to look. + +#============================================================================= +# Copyright 2001-2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(_ZLIB_SEARCHES) + +# Search ZLIB_ROOT first if it is set. +if(ZLIB_ROOT) + set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH) + list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) +endif() + +# Normal search. +set(_ZLIB_SEARCH_NORMAL + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" + "$ENV{PROGRAMFILES}/zlib" + ) +list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) + +set(ZLIB_NAMES z_brl z zlib zdll zlib1 zlibd zlibd1) + +# Try each search configuration. +foreach(search ${_ZLIB_SEARCHES}) + find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include) + find_library(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib) +endforeach() + +mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR) + +if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") + file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(ZLIB_VERSION_TWEAK "") + if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}") + endif() + + set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") + set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") + set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") +endif() + +# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) + +if(ZLIB_FOUND) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + + if(NOT TARGET ZLIB::ZLIB) + add_library(ZLIB::ZLIB UNKNOWN IMPORTED) + set_target_properties(ZLIB::ZLIB PROPERTIES + IMPORTED_LOCATION "${ZLIB_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") + endif() +endif() diff --git a/src/other/ext/png/CMakeLists.txt b/src/other/ext/png/CMakeLists.txt index 8fbe2223fbb..8a5ab54fab3 100644 --- a/src/other/ext/png/CMakeLists.txt +++ b/src/other/ext/png/CMakeLists.txt @@ -27,8 +27,15 @@ cmake_minimum_required(VERSION 3.1) cmake_policy(VERSION 3.1) +if (POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif (POLICY CMP0074) project(libpng C ASM) + +# Location of CMake modules +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") + enable_testing() set(PNGLIB_MAJOR 1) @@ -36,7 +43,7 @@ set(PNGLIB_MINOR 6) set(PNGLIB_REVISION 39) set(PNGLIB_SUBREVISION 0) #set(PNGLIB_SUBREVISION "git") -set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR}) +set(PNGLIB_NAME libpng_brl${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION}) set(PNGLIB_SHARED_SOVERSION ${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNGLIB_SHARED_VERSION ${PNGLIB_SHARED_SOVERSION}.${PNGLIB_REVISION}.${PNGLIB_SUBREVISION}) @@ -221,7 +228,7 @@ endif() endif(PNG_HARDWARE_OPTIMIZATIONS) # Set PNG_LIB_NAME. -set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR}) +set(PNG_LIB_NAME png_brl${PNGLIB_MAJOR}${PNGLIB_MINOR}) # Distinguish between debug and release builds. if(NOT PNG_NO_DEBUG_POSTFIX) @@ -970,22 +977,22 @@ if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) if(PNG_SHARED) # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin if(CYGWIN OR MINGW) - create_symlink(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png) - install(FILES $/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} + create_symlink(libpng_brl${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png) + install(FILES $/libpng_brl${CMAKE_IMPORT_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if(NOT WIN32) - create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png) - install(FILES $/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} + create_symlink(libpng_brl${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png) + install(FILES $/libpng_brl${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endif() if(PNG_STATIC) if(NOT WIN32 OR CYGWIN OR MINGW) - create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static) - install(FILES $/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} + create_symlink(libpng_brl${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static) + install(FILES $/libpng_brl${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endif() diff --git a/src/other/ext/zlib.cmake b/src/other/ext/zlib.cmake index 09b64137241..9063ed6a501 100644 --- a/src/other/ext/zlib.cmake +++ b/src/other/ext/zlib.cmake @@ -68,6 +68,7 @@ if (BRLCAD_ZLIB_BUILD) zlib.h ) + set(ZLIB_LIBRARY zlib CACHE STRING "Building bundled zlib" FORCE) set(ZLIB_LIBRARY_DEBUG zlib CACHE STRING "Building bundled zlib" FORCE) set(ZLIB_LIBRARY_RELEASE zlib CACHE STRING "Building bundled zlib" FORCE) set(ZLIB_LIBRARIES zlib CACHE STRING "Building bundled zlib" FORCE) diff --git a/src/other/gct.dist b/src/other/gct.dist deleted file mode 100644 index e5e5a73f141..00000000000 --- a/src/other/gct.dist +++ /dev/null @@ -1,60 +0,0 @@ -set(gct_ignore_files -Auxiliary/CMakeLists.txt -Auxiliary/cc.c -Auxiliary/cc.h -Auxiliary/ccmergesort.h -Auxiliary/cpuconfig.h -Auxiliary/cpuinfo.c -Auxiliary/cpuinfo.h -Auxiliary/gctcommon.h -Auxiliary/math3d.h -Auxiliary/mm.c -Auxiliary/mm.h -Auxiliary/mmatomic.c -Auxiliary/mmatomic.h -Auxiliary/mmbinsort.c -Auxiliary/mmbinsort.h -Auxiliary/mmbitmap.c -Auxiliary/mmbitmap.h -Auxiliary/mmhash.c -Auxiliary/mmhash.h -Auxiliary/mmthread.h -BRLCAD/BrlcadAppWalker.cpp -BRLCAD/BrlcadAppWalker.h -BRLCAD/BrlcadLoader.cpp -BRLCAD/BrlcadLoader.h -BRLCAD/BrlcadTreeWalker.cpp -BRLCAD/BrlcadTreeWalker.h -BRLCAD/CMakeLists.txt -BRLCAD/DbGeometry.cpp -BRLCAD/DbGeometry.h -BRLCAD/DbTracer.cpp -BRLCAD/DbTracer.h -CMakeLists.txt -Interface/AppWalkerInterface.h -Interface/GLoaderInterface.h -Interface/IGeometryTracer.h -Interface/INativeGeometry.h -Interface/ISampler.h -MeshDecimation/CMakeLists.txt -MeshDecimation/meshcorrection.c -MeshDecimation/meshcorrection.h -MeshDecimation/meshdecimation.c -MeshDecimation/meshdecimation.h -MeshDecimation/meshdecimationSSE2.c -MeshDecimation/meshdecimationSSE3.c -MeshDecimation/meshdecimationSSE4p1.c -MeshDecimation/meshoptimization.cpp -MeshDecimation/meshoptimization.h -MeshDecimation/meshoptimizer.c -MeshDecimation/meshoptimizer.h -Sampler/CMakeLists.txt -Sampler/MarchingCubesSampler.cpp -Sampler/MarchingCubesSampler.h -Sampler/PointSampler.cpp -Sampler/PointSampler.h -dcmain/CMakeLists.txt -dcmain/main.cpp -psmain/CMakeLists.txt -psmain/main.cpp -) diff --git a/src/other/gct/Auxiliary/CMakeLists.txt b/src/other/gct/Auxiliary/CMakeLists.txt deleted file mode 100644 index 3cfa962076e..00000000000 --- a/src/other/gct/Auxiliary/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -set(AUX_SRCS - cc.c - cpuinfo.c - mmatomic.c - mmbinsort.c - mmbitmap.c - mm.c - mmhash.c - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} -) - -add_library(AUX SHARED ${AUX_SRCS}) -set_target_properties(AUX PROPERTIES VERSION 1.1.0 SOVERSION 1) - -install(TARGETS AUX - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR}) - -if(MSVC) - set_property(TARGET AUX APPEND PROPERTY COMPILE_DEFINITIONS "AUX_DLL_EXPORTS") -endif(MSVC) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/src/other/gct/Auxiliary/cc.c b/src/other/gct/Auxiliary/cc.c deleted file mode 100644 index 003078215cc..00000000000 --- a/src/other/gct/Auxiliary/cc.c +++ /dev/null @@ -1,1577 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cpuconfig.h" -#include "cc.h" - - - -//// - - - -#define CC_HASH_READ8(d,o) ((uint32_t)(((uint8_t *)d)[o])) -#define CC_HASH_AREAD16(d,o) ((uint32_t)(*((uint16_t *)ADDRESS(d,o)))) -#define CC_HASH_UREAD16(d,o) ((((uint32_t)(((uint8_t *)(d))[o+1]))<<8)+(uint32_t)(((uint8_t *)(d))[o])) - -uint32_t ccHash32Data( void *data, int size ) -{ - uint32_t hash; - int rem; - rem = size & 3; - size >>= 2; - hash = 0; - if( !( ( (uintptr_t)data ) & 0x1 ) ) - { - for( ; size ; size-- ) - { - hash += CC_HASH_AREAD16( data, 0 ); - hash = ( hash << 16 ) ^ ( ( CC_HASH_AREAD16( data, 2 ) << 11 ) ^ hash ); - hash += hash >> 11; - data = ADDRESS( data, 4 ); - } - } - else - { - for( ; size ; size-- ) - { - hash += CC_HASH_UREAD16( data, 0 ); - hash = ( hash << 16 ) ^ ( ( CC_HASH_UREAD16( data, 2 ) << 11 ) ^ hash ); - hash += hash >> 11; - data = ADDRESS( data, 4 ); - } - } - switch( rem ) - { - case 3: - hash += CC_HASH_UREAD16( data, 0 ); - hash ^= hash << 16; - hash ^= CC_HASH_READ8( data, 2 ) << 18; - hash += hash >> 11; - break; - case 2: - hash += CC_HASH_UREAD16( data, 0 ); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: - hash += CC_HASH_READ8( data, 0 ); - hash ^= hash << 10; - hash += hash >> 1; - break; - case 0: - break; - } - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -uint32_t ccHash32Data32( uint32_t i ) -{ - uint32_t hash; - hash = i & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( i & 0xFFFF0000 ) >> 5 ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -uint32_t ccHash32Data64( uint64_t i ) -{ - uint32_t hash; - hash = i & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( (uint32_t)( i >> 16 ) & 0xFFFF ) << 11 ); - hash += ( hash >> 11 ) + ( (uint32_t)( i >> 32 ) & 0xFFFF ); - hash = ( ( hash << 16 ) ^ hash ) ^ (uint32_t)( ( i & 0xFFFF000000000000LL ) >> 37 ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -uint32_t ccHash32Array32( uint32_t *data, int count ) -{ - uint32_t hash; - hash = 0; - for( ; count ; count-- ) - { - hash += *data & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( *data & 0xFFFF0000 ) >> 5 ); - hash += hash >> 11; - data = ADDRESS( data, 4 ); - } - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -uint32_t ccHash32Array64( uint64_t *data, int count ) -{ - uint32_t hash; - uint64_t v; - hash = 0; - for( ; count ; count-- ) - { - v = *data; - hash += v & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( (uint32_t)( v >> 16 ) & 0xFFFF ) << 11 ); - hash += ( hash >> 11 ) + ( (uint32_t)( v >> 32 ) & 0xFFFF ); - hash = ( ( hash << 16 ) ^ hash ) ^ (uint32_t)( ( v & 0xFFFF000000000000LL ) >> 37 ); - hash += hash >> 11; - data = ADDRESS( data, 8 ); - } - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - - -//// - - -int ccMemCmp( void *s0, void *s1, int size ) -{ - int i; - uint8_t *t0, *t1; - t0 = s0; - t1 = s1; - for( i = 0 ; i < size ; i++ ) - { - if( t0[i] != t1[i] ) - return 0; - } - return 1; -} - -int ccMemCmp32( uint32_t *s0, uint32_t *s1, int count ) -{ - int i; - for( i = 0 ; i < count ; i++ ) - { - if( s0[i] != s1[i] ) - return 0; - } - return 1; -} - -int ccMemCmp64( uint64_t *s0, uint64_t *s1, int count ) -{ - int i; - for( i = 0 ; i < count ; i++ ) - { - if( s0[i] != s1[i] ) - return 0; - } - return 1; -} - -int ccMemCmpSize( void *s0, void *s1, int size ) -{ - int i; - uint8_t *t0, *t1; - t0 = s0; - t1 = s1; - for( i = 0 ; i < size ; i++ ) - { - if( t0[i] != t1[i] ) - break; - } - return i; -} - - -//// - - -uint8_t ccLog2Int8( uint8_t v ) -{ - uint8_t r = 0; - if( v & 0xC ) - { - v >>= 2; - r |= 2; - } - if( v & 0x2 ) - { - v >>= 1; - r |= 1; - } - return r; -} - -uint16_t ccLog2Int16( uint16_t v ) -{ - uint16_t r = 0; - if( v & 0xFF00 ) - { - v >>= 8; - r |= 8; - } - if( v & 0xF0 ) - { - v >>= 4; - r |= 4; - } - if( v & 0xC ) - { - v >>= 2; - r |= 2; - } - if( v & 0x2 ) - { - v >>= 1; - r |= 1; - } - return r; -} - -uint32_t ccLog2Int32( uint32_t v ) -{ - uint32_t r = 0; - if( v & 0xFFFF0000 ) - { - v >>= 16; - r |= 16; - } - if( v & 0xFF00 ) - { - v >>= 8; - r |= 8; - } - if( v & 0xF0 ) - { - v >>= 4; - r |= 4; - } - if( v & 0xC ) - { - v >>= 2; - r |= 2; - } - if( v & 0x2 ) - { - v >>= 1; - r |= 1; - } - return r; -} - -uint64_t ccLog2Int64( uint64_t v ) -{ - uint64_t r = 0; - if( v & 0xFFFFFFFF00000000LL ) - { - v >>= 32; - r |= 32; - } - if( v & 0xFFFF0000 ) - { - v >>= 16; - r |= 16; - } - if( v & 0xFF00 ) - { - v >>= 8; - r |= 8; - } - if( v & 0xF0 ) - { - v >>= 4; - r |= 4; - } - if( v & 0xC ) - { - v >>= 2; - r |= 2; - } - if( v & 0x2 ) - { - v >>= 1; - r |= 1; - } - return r; -} - - -//// - - - - - - -//// - - -#define CC_CHAR_IS_CONTROL(c) ((c)<' ') -#define CC_CHAR_IS_DELIMITER(c) ((c)<=' ') - - -void ccStrLowCopy( char *dst, char *src, int length ) -{ - int i; - for( i = 0 ; i < length ; i++ ) - { - dst[i] = src[i]; - if( ( src[i] >= 'A' ) && ( src[i] <= 'Z' ) ) - dst[i] = src[i] + 'a' - 'A'; - } - dst[i] = 0; - return; -} - - -int ccStrCmpEqual( char *s0, char *s1 ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( s0[i] != s1[i] ) - return 0; - if( !( s0[i] ) ) - break; - } - return 1; -} - - -char *ccStrCmpWord( char *str, char *word ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( !( word[i] ) ) - return str + i; - if( str[i] != word[i] ) - break; - } - return 0; -} - - -char *ccStrCmpSeq( char *str, char *seq, int seqlength ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( i >= seqlength ) - return str + i; - if( str[i] != seq[i] ) - break; - } - return 0; -} - - -char *ccStrMatchSeq( char *str, char *seq, int seqlength ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( i >= seqlength ) - { - if( str[i] ) - break; - return str + i; - } - if( str[i] != seq[i] ) - break; - } - return 0; -} - - -char *ccStrSeqCmpSeq( char *s1, char *s2, int s1length, int s2length ) -{ - int i; - if( s1length != s2length ) - return 0; - for( i = 0 ; i < s1length ; i++ ) - { - if( s1[i] != s2[i] ) - break; - } - return s1 + i; -} - - -int ccStrWordCmpWord( char *s1, char *s2 ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( s1[i] != s2[i] ) - break; - if( CC_CHAR_IS_DELIMITER( s1[i] ) ) - { - if( CC_CHAR_IS_DELIMITER( s2[i] ) ) - return 1; - else - return 0; - } - } - if( ( CC_CHAR_IS_DELIMITER( s1[i] ) ) && ( CC_CHAR_IS_DELIMITER( s2[i] ) ) ) - return 1; - return 0; -} - - -char *ccStrLowCmpSeq( char *str, char *seq, int seqlength ) -{ - int i; - char c1, c2; - for( i = 0 ; ; i++ ) - { - if( i >= seqlength ) - return str + i; - c1 = str[i]; - if( ( c1 >= 'A' ) && ( c1 <= 'Z' ) ) - c1 += 'a' - 'A'; - c2 = seq[i]; - if( ( c2 >= 'A' ) && ( c2 <= 'Z' ) ) - c2 += 'a' - 'A'; - if( c1 != c2 ) - break; - } - return 0; -} - - -char *ccStrFind( char *str, char *seq, int seqlength ) -{ - int i; - for( ; *str ; str++ ) - { - for( i = 0 ; ; i++ ) - { - if( i >= seqlength ) - return str; - if( str[i] != seq[i] ) - break; - } - } - return 0; -} - - -char *ccStrFindWord( char *str, char *word, int wordlength ) -{ - int i, wordflag; - wordflag = 0; - for( ; *str ; str++ ) - { - if( CC_CHAR_IS_DELIMITER( *str ) ) - { - wordflag = 0; - continue; - } - else if( wordflag ) - continue; - for( i = 0 ; ; i++ ) - { - if( i >= wordlength ) - { - if( CC_CHAR_IS_DELIMITER( str[i] ) ) - return str; - return 0; - } - if( str[i] != word[i] ) - { - wordflag = 1; - str += i; - break; - } - } - } - return 0; -} - - -int ccStrWordLength( char *str ) -{ - int i; - for( i = 0 ; ; i++ ) - { - if( CC_CHAR_IS_DELIMITER( str[i] ) ) - break; - } - return i; -} - - -int ccSeqFindChar( char *seq, int seqlen, char c ) -{ - int i; - for( i = 0 ; i < seqlen ; i++ ) - { - if( seq[i] == c ) - return i; - } - return -1; -} - -char *ccSeqFindStr( char *seq, int seqlen, char *str ) -{ - int i; - for( ; seqlen ; seqlen--, seq++ ) - { - for( i = 0 ; ; i++ ) - { - if( !str[i] ) - return seq; - if( seq[i] != str[i] ) - break; - } - } - return 0; -} - - -char *ccStrParam( char *str, int *paramlen, int *skiplen ) -{ - int i; - if( str[0] == '"' ) - { - for( i = 1 ; ; i++ ) - { - if( str[i] == '"' ) - break; - if( CC_CHAR_IS_CONTROL( str[i] ) ) - return 0; - } - if( !( CC_CHAR_IS_DELIMITER( str[i+1] ) ) ) - return 0; - *paramlen = i-1; - *skiplen = i+1; - return str+1; - } - if( CC_CHAR_IS_DELIMITER( str[0] ) ) - return 0; - for( i = 1 ; ; i++ ) - { - if( CC_CHAR_IS_DELIMITER( str[i] ) ) - break; - } - *paramlen = i; - *skiplen = i; - return str; -} - - -int ccParseParameters( char *str, char **argv ) -{ - int argc, paramlen, skiplen; - char *param; - - argc = 0; - for( ; ; ) - { - if( !( str = ccStrNextWordSameLine( str ) ) ) - break; - param = ccStrParam( str, ¶mlen, &skiplen ); - if( argv ) - argv[argc] = param; - if( !( param ) ) - break; - str += skiplen; - argc++; - } - - return argc; -} - - -char *ccStrNextWord( char *str ) -{ - for( ; ; str++ ) - { - if( *str == 0 ) - return 0; - if( !( CC_CHAR_IS_DELIMITER( *str ) ) ) - break; - } - return str; -} - - - -char *ccStrSkipWord( char *str ) -{ - for( ; ; str++ ) - { - if( !( *str ) ) - return 0; - if( ( *str == ' ' ) || ( *str == '\t' ) || ( *str == '\n' ) || ( *str == '\r' ) ) - break; - } - return str; -} - - -char *ccStrNextWordSameLine( char *str ) -{ - for( ; ; str++ ) - { - if( *str == 0 ) - return 0; - if( *str == '\n' ) - return 0; - if( !( CC_CHAR_IS_DELIMITER( *str ) ) ) - break; - } - return str; -} - - -char *ccStrNextParam( char *str ) -{ - for( ; ; str++ ) - { - if( ( *str == 0 ) || ( *str != '\n' ) ) - return 0; - if( !( CC_CHAR_IS_DELIMITER( *str ) ) ) - break; - } - return str; -} - - -char *ccStrNextLine( char *str ) -{ - for( ; ; str++ ) - { - if( *str == 0 ) - return str; - if( *str == '\n' ) - break; - } - return str + 1; -} - - -char *ccStrPassLine( char *str ) -{ - for( ; ; str++ ) - { - if( ( *str == 0 ) || ( *str == '\n' ) ) - break; - if( !( CC_CHAR_IS_DELIMITER( *str ) ) ) - return 0; - } - return str; -} - - -int ccStrParseInt( char *str, int64_t *retint ) -{ - int negflag; - char c; - int64_t workint; - - negflag = 0; - if( *str == '-' ) - negflag = 1; - str += negflag; - - workint = 0; - for( ; ; str++ ) - { - c = *str; - if( CC_CHAR_IS_DELIMITER( c ) ) - break; - if( ( c < '0' ) || ( c > '9' ) ) - return 0; - workint = ( workint * 10 ) + ( c - '0' ); - } - - if( negflag ) - workint = -workint; - *retint = workint; - return 1; -} - - -int ccSeqParseInt( char *seq, int seqlength, int64_t *retint ) -{ - int i, negflag; - char c; - int64_t workint; - - if( !( seqlength ) ) - return 0; - negflag = 0; - i = 0; - if( *seq == '-' ) - { - negflag = 1; - i = 1; - } - - workint = 0; - for( ; i < seqlength ; i++ ) - { - c = seq[i]; - if( CC_CHAR_IS_DELIMITER( c ) ) - break; - if( ( c < '0' ) || ( c > '9' ) ) - return 0; - workint = ( workint * 10 ) + ( c - '0' ); - } - - if( negflag ) - workint = -workint; - *retint = workint; - return 1; -} - - -int ccStrParseFloat( char *str, float *retfloat ) -{ - char c; - int negflag; - double workfloat; - double decfactor; - - negflag = 0; - if( *str == '-' ) - negflag = 1; - str += negflag; - - workfloat = 0.0; - for( ; ; str++ ) - { - c = *str; - if( CC_CHAR_IS_DELIMITER( c ) ) - goto done; - if( c == '.' ) - break; - if( ( c < '0' ) || ( c > '9' ) ) - return 0; - workfloat = ( workfloat * 10.0 ) + (float)( c - '0' ); - } - - str++; - decfactor = 0.1; - for( ; ; str++ ) - { - c = *str; - if( CC_CHAR_IS_DELIMITER( c ) ) - break; - if( ( c < '0' ) || ( c > '9' ) ) - return 0; - workfloat += (float)( c - '0' ) * decfactor; - decfactor *= 0.1; - } - - done: - - if( negflag ) - workfloat = -workfloat; - *retfloat = (float)workfloat; - return 1; -} - - -//// - - -#define CC_SORT_SWAP(a,b) ({temp=table[b];table[b]=table[a];table[a]=temp;}) - -#define CC_SORT_STACK_DEPTH (512) - -#define CC_SORT_MIN_QSORT_COUNT (5) - -typedef struct -{ - void *table; - int count; -} ccQuickSortStack; - -static void ccQuickSortPart( void **table, int count, int (*sortfunc)( void *t0, void *t1 ) ) -{ - void *temp; - switch( count ) - { - case 4: - if( sortfunc( table[0], table[1] ) ) - CC_SORT_SWAP( 1, 0 ); - if( sortfunc( table[2], table[3] ) ) - CC_SORT_SWAP( 3, 2 ); - if( sortfunc( table[0], table[2] ) ) - { - temp = table[2]; - table[2] = table[1]; - table[1] = table[0]; - table[0] = temp; - if( sortfunc( table[2], table[3] ) ) - { - CC_SORT_SWAP( 3, 2 ); - if( sortfunc( table[1], table[2] ) ) - CC_SORT_SWAP( 2, 1 ); - } - } - else - { - if( sortfunc( table[1], table[2] ) ) - { - CC_SORT_SWAP( 2, 1 ); - if( sortfunc( table[2], table[3] ) ) - CC_SORT_SWAP( 3, 2 ); - } - } - break; - case 3: - if( sortfunc( table[0], table[1] ) ) - { - if( sortfunc( table[1], table[2] ) ) - { - /* [1]>[0], [2]>[1] = [2]>[1]>[0] */ - CC_SORT_SWAP( 2, 0 ); - } - else - { - if( sortfunc( table[0], table[2] ) ) - { - /* [1]>[0], [2]<[1], [2]>[0] = [1]>[2]>[0] */ - temp = table[0]; - table[0] = table[1]; - table[1] = table[2]; - table[2] = temp; - } - else - { - /* [1]>[0], [2]<[1], [2]<[0] = [1]>[0]>[2] */ - CC_SORT_SWAP( 1, 0 ); - } - } - } - else - { - if( sortfunc( table[1], table[2] ) ) - { - if( sortfunc( table[0], table[2] ) ) - { - /* [1]<[0], [2]>[1], [2]>[0] = [2]>[0]>[1] */ - temp = table[2]; - table[2] = table[1]; - table[1] = table[0]; - table[0] = temp; - } - else - { - /* [1]<[0], [2]>[1], [2]<[0] = [0]>[2]>[1] */ - CC_SORT_SWAP( 1, 2 ); - } - } - else - { - /* [1]<[0], [2]<[1] = [0]>[1]>[2] */ - } - } - break; - case 2: - if( sortfunc( table[0], table[1] ) ) - CC_SORT_SWAP( 1, 0 ); - break; - case 1: - case 0: - default: - break; - } - return; -} - - -void ccQuickSort( void **table, int count, int (*sortfunc)( void *t0, void *t1 ), uint32_t randmask ) -{ - ssize_t i, pivotindex, leftcount, rightcount, highindex, pivotstore; - void *temp; - void *pivot; - ccQuickSortStack stack[CC_SORT_STACK_DEPTH]; - ccQuickSortStack *sp; - - if( count < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortPart( table, count, sortfunc ); - return; - } - - sp = stack; - for( ; ; ) - { - /* Select pivot */ - randmask += count; - pivotindex = 1 + ( randmask % ( count-2 ) ); - - if( sortfunc( table[0], table[pivotindex] ) ) - CC_SORT_SWAP( pivotindex, 0 ); - if( sortfunc( table[pivotindex], table[count-1] ) ) - { - CC_SORT_SWAP( count-1, pivotindex ); - if( sortfunc( table[0], table[pivotindex] ) ) - CC_SORT_SWAP( pivotindex, 0 ); - } - - /* Quick sort on both sides of the pivot */ - pivot = table[pivotindex]; - highindex = count - 2; - pivotstore = highindex; - CC_SORT_SWAP( pivotstore, pivotindex ); - pivotindex = 1; - for( i = highindex ; --i ; ) - { - if( sortfunc( pivot, table[pivotindex] ) ) - pivotindex++; - else - { - highindex--; - CC_SORT_SWAP( highindex, pivotindex ); - } - } - CC_SORT_SWAP( pivotindex, pivotstore ); - - /* Count of entries on both sides of the pivot */ - leftcount = pivotindex; - pivotindex++; - rightcount = count - pivotindex; - - /* Fast sort small chunks, iterate */ - if( leftcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortPart( table, leftcount, sortfunc ); - table += pivotindex; - count = rightcount; - if( rightcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortPart( table, count, sortfunc ); - if( sp == stack ) - break; - sp--; - table = sp->table; - count = sp->count; - } - } - else if( rightcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortPart( &table[pivotindex], rightcount, sortfunc ); - count = leftcount; - } - else if( leftcount < rightcount ) - { - sp->table = &table[pivotindex]; - sp->count = rightcount; - sp++; - count = leftcount; - } - else - { - sp->table = table; - sp->count = leftcount; - sp++; - table += pivotindex; - count = rightcount; - } - } - - return; -} - -static void ccQuickSortContextPart( void **table, int count, int (*sortfunc)( void *context, void *t0, void *t1 ), void *context ) -{ - void *temp; - switch( count ) - { - case 4: - if( sortfunc( context, table[0], table[1] ) ) - CC_SORT_SWAP( 1, 0 ); - if( sortfunc( context, table[2], table[3] ) ) - CC_SORT_SWAP( 3, 2 ); - if( sortfunc( context, table[0], table[2] ) ) - { - temp = table[2]; - table[2] = table[1]; - table[1] = table[0]; - table[0] = temp; - if( sortfunc( context, table[2], table[3] ) ) - { - CC_SORT_SWAP( 3, 2 ); - if( sortfunc( context, table[1], table[2] ) ) - CC_SORT_SWAP( 2, 1 ); - } - } - else - { - if( sortfunc( context, table[1], table[2] ) ) - { - CC_SORT_SWAP( 2, 1 ); - if( sortfunc( context, table[2], table[3] ) ) - CC_SORT_SWAP( 3, 2 ); - } - } - break; - case 3: - if( sortfunc( context, table[0], table[1] ) ) - { - if( sortfunc( context, table[1], table[2] ) ) - { - /* [1]>[0], [2]>[1] = [2]>[1]>[0] */ - CC_SORT_SWAP( 2, 0 ); - } - else - { - if( sortfunc( context, table[0], table[2] ) ) - { - /* [1]>[0], [2]<[1], [2]>[0] = [1]>[2]>[0] */ - temp = table[0]; - table[0] = table[1]; - table[1] = table[2]; - table[2] = temp; - } - else - { - /* [1]>[0], [2]<[1], [2]<[0] = [1]>[0]>[2] */ - CC_SORT_SWAP( 1, 0 ); - } - } - } - else - { - if( sortfunc( context, table[1], table[2] ) ) - { - if( sortfunc( context, table[0], table[2] ) ) - { - /* [1]<[0], [2]>[1], [2]>[0] = [2]>[0]>[1] */ - temp = table[2]; - table[2] = table[1]; - table[1] = table[0]; - table[0] = temp; - } - else - { - /* [1]<[0], [2]>[1], [2]<[0] = [0]>[2]>[1] */ - CC_SORT_SWAP( 1, 2 ); - } - } - else - { - /* [1]<[0], [2]<[1] = [0]>[1]>[2] */ - } - } - break; - case 2: - if( sortfunc( context, table[0], table[1] ) ) - CC_SORT_SWAP( 1, 0 ); - break; - case 1: - case 0: - default: - break; - } - return; -} - -void ccQuickSortContext( void **table, int count, int (*sortfunc)( void *context, void *t0, void *t1 ), void *context, uint32_t randmask ) -{ - ssize_t i, pivotindex, leftcount, rightcount, highindex, pivotstore; - void *temp; - void *pivot; - ccQuickSortStack stack[CC_SORT_STACK_DEPTH]; - ccQuickSortStack *sp; - - if( count < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortContextPart( table, count, sortfunc, context ); - return; - } - - sp = stack; - for( ; ; ) - { - /* Select pivot */ - randmask += count; - pivotindex = 1 + ( randmask % ( count-2 ) ); - - if( sortfunc( context, table[0], table[pivotindex] ) ) - CC_SORT_SWAP( pivotindex, 0 ); - if( sortfunc( context, table[pivotindex], table[count-1] ) ) - { - CC_SORT_SWAP( count-1, pivotindex ); - if( sortfunc( context, table[0], table[pivotindex] ) ) - CC_SORT_SWAP( pivotindex, 0 ); - } - - /* Quick sort on both sides of the pivot */ - pivot = table[pivotindex]; - highindex = count - 2; - pivotstore = highindex; - CC_SORT_SWAP( pivotstore, pivotindex ); - pivotindex = 1; - for( i = highindex ; --i ; ) - { - if( sortfunc( context, pivot, table[pivotindex] ) ) - pivotindex++; - else - { - highindex--; - CC_SORT_SWAP( highindex, pivotindex ); - } - } - CC_SORT_SWAP( pivotindex, pivotstore ); - - /* Count of entries on both sides of the pivot */ - leftcount = pivotindex; - pivotindex++; - rightcount = count - pivotindex; - - /* Fast sort small chunks, iterate */ - if( leftcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortContextPart( table, leftcount, sortfunc, context ); - table += pivotindex; - count = rightcount; - if( rightcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortContextPart( table, count, sortfunc, context ); - if( sp == stack ) - break; - sp--; - table = sp->table; - count = sp->count; - } - } - else if( rightcount < CC_SORT_MIN_QSORT_COUNT ) - { - ccQuickSortContextPart( &table[pivotindex], rightcount, sortfunc, context ); - count = leftcount; - } - else if( leftcount < rightcount ) - { - sp->table = &table[pivotindex]; - sp->count = rightcount; - sp++; - count = leftcount; - } - else - { - sp->table = table; - sp->count = leftcount; - sp++; - table += pivotindex; - count = rightcount; - } - } - - return; -} - - - -//// - - -typedef struct -{ - void **src; - void **dst; - int count; - int mergeflag; - int depthbit; -} ccMergeSortStack; - -int ccMergeSort( void **src, void **tmp, int count, int (*sortfunc)( void *t0, void *t1 ) ) -{ - int swapflag, depthbit, maxdepthbit; - ssize_t i, leftcount, rightcount; - void **dst, **sl, **sr, *temp, **swap; - ccMergeSortStack stack[CC_SORT_STACK_DEPTH]; - ccMergeSortStack *sp; - - dst = tmp; - sp = stack; - swapflag = 0; - depthbit = 0; - - if( count <= 1 ) - return 0; - - leftcount = count; - for( maxdepthbit = 1 ; ; maxdepthbit ^= 1 ) - { - leftcount = leftcount - ( leftcount >> 1 ); - if( leftcount <= 4 ) - break; - } - - for( ; ; ) - { - if( count <= 4 ) - { - if( !( depthbit ^ maxdepthbit ) ) - { - if( ( count == 4 ) && sortfunc( src[2], src[3] ) ) - { - temp = src[2]; - src[2] = src[3]; - src[3] = temp; - } - if( sortfunc( src[0], src[1] ) ) - { - temp = src[0]; - src[0] = src[1]; - src[1] = temp; - } - swapflag = 0; - } - else - { - if( count == 4 ) - { - if( sortfunc( src[2], src[3] ) ) - { - dst[2] = src[3]; - dst[3] = src[2]; - } - else - { - dst[2] = src[2]; - dst[3] = src[3]; - } - } - else if( count == 3 ) - dst[2] = src[2]; - if( sortfunc( src[0], src[1] ) ) - { - dst[0] = src[1]; - dst[1] = src[0]; - } - else - { - dst[0] = src[0]; - dst[1] = src[1]; - } - swap = src; - src = dst; - dst = swap; - swapflag = 1; - } - } - else - { - rightcount = count >> 1; - leftcount = count - rightcount; - sp->src = src; - sp->dst = dst; - sp->count = count; - sp->mergeflag = 1; - sp->depthbit = depthbit; - depthbit ^= 1; - sp++; - sp->src = src + leftcount; - sp->dst = dst + leftcount; - sp->count = rightcount; - sp->mergeflag = 0; - sp->depthbit = depthbit; - sp++; - count = leftcount; - continue; - } - - for( ; ; ) - { - rightcount = count >> 1; - leftcount = count - rightcount; - sl = src; - sr = src + leftcount; - for( ; ; ) - { - if( sortfunc( *sl, *sr ) ) - { - *dst++ = *sr++; - if( --rightcount ) - continue; - for( i = 0 ; i < leftcount ; i++ ) - dst[i] = sl[i]; - break; - } - else - { - *dst++ = *sl++; - if( --leftcount ) - continue; - for( i = 0 ; i < rightcount ; i++ ) - dst[i] = sr[i]; - break; - } - } - - if( sp == stack ) - return swapflag ^ 1; - sp--; - src = sp->src; - dst = sp->dst; - count = sp->count; - depthbit = sp->depthbit; - if( !( sp->mergeflag ) ) - break; - swapflag ^= 1; - if( swapflag ) - { - src = sp->dst; - dst = sp->src; - } - } - } - - return 0; -} - -int ccMergeSortContext( void **src, void **tmp, int count, int (*sortfunc)( void *context, void *t0, void *t1 ), void *context ) -{ - int swapflag, depthbit, maxdepthbit; - ssize_t i, leftcount, rightcount; - void **dst, **sl, **sr, *temp, **swap; - ccMergeSortStack stack[CC_SORT_STACK_DEPTH]; - ccMergeSortStack *sp; - - dst = tmp; - sp = stack; - swapflag = 0; - depthbit = 0; - - if( count <= 1 ) - return 0; - - leftcount = count; - for( maxdepthbit = 1 ; ; maxdepthbit ^= 1 ) - { - leftcount = leftcount - ( leftcount >> 1 ); - if( leftcount <= 4 ) - break; - } - - for( ; ; ) - { - if( count <= 4 ) - { - if( !( depthbit ^ maxdepthbit ) ) - { - if( ( count == 4 ) && sortfunc( context, src[2], src[3] ) ) - { - temp = src[2]; - src[2] = src[3]; - src[3] = temp; - } - if( sortfunc( context, src[0], src[1] ) ) - { - temp = src[0]; - src[0] = src[1]; - src[1] = temp; - } - swapflag = 0; - } - else - { - if( count == 4 ) - { - if( sortfunc( context, src[2], src[3] ) ) - { - dst[2] = src[3]; - dst[3] = src[2]; - } - else - { - dst[2] = src[2]; - dst[3] = src[3]; - } - } - else if( count == 3 ) - dst[2] = src[2]; - if( sortfunc( context, src[0], src[1] ) ) - { - dst[0] = src[1]; - dst[1] = src[0]; - } - else - { - dst[0] = src[0]; - dst[1] = src[1]; - } - swap = src; - src = dst; - dst = swap; - swapflag = 1; - } - } - else - { - rightcount = count >> 1; - leftcount = count - rightcount; - sp->src = src; - sp->dst = dst; - sp->count = count; - sp->mergeflag = 1; - sp->depthbit = depthbit; - depthbit ^= 1; - sp++; - sp->src = src + leftcount; - sp->dst = dst + leftcount; - sp->count = rightcount; - sp->mergeflag = 0; - sp->depthbit = depthbit; - sp++; - count = leftcount; - continue; - } - - for( ; ; ) - { - rightcount = count >> 1; - leftcount = count - rightcount; - sl = src; - sr = src + leftcount; - for( ; ; ) - { - if( sortfunc( context, *sl, *sr ) ) - { - *dst++ = *sr++; - if( --rightcount ) - continue; - for( i = 0 ; i < leftcount ; i++ ) - dst[i] = sl[i]; - break; - } - else - { - *dst++ = *sl++; - if( --leftcount ) - continue; - for( i = 0 ; i < rightcount ; i++ ) - dst[i] = sr[i]; - break; - } - } - - if( sp == stack ) - return swapflag ^ 1; - sp--; - src = sp->src; - dst = sp->dst; - count = sp->count; - depthbit = sp->depthbit; - if( !( sp->mergeflag ) ) - break; - swapflag ^= 1; - if( swapflag ) - { - src = sp->dst; - dst = sp->src; - } - } - } - - return 0; -} - - - -//// - - - -#define CC_DEBUG_LOG_SIZE (4096) - -void ccDebugLog( char *filename, char *string, ... ) -{ - ssize_t slen; - char buffer[CC_DEBUG_LOG_SIZE]; - char *wbuf; - size_t bufsize; - va_list ap; - FILE *file; - - if( !( file = fopen( filename, "a" ) ) ) - return; - - wbuf = buffer; - bufsize = CC_DEBUG_LOG_SIZE; - for( ; ; ) - { - va_start( ap, string ); - slen = vsnprintf( wbuf, bufsize, string, ap ); - va_end( ap ); - if( slen < bufsize ) - break; - if( wbuf != buffer ) - free( wbuf ); - bufsize = slen + 1; - wbuf = malloc( bufsize ); - } - - fprintf( file, "%s", wbuf ); - - if( wbuf != buffer ) - free( wbuf ); - fclose( file ); - - return; -} - diff --git a/src/other/gct/Auxiliary/cc.h b/src/other/gct/Auxiliary/cc.h deleted file mode 100644 index 250fc654652..00000000000 --- a/src/other/gct/Auxiliary/cc.h +++ /dev/null @@ -1,1050 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -#ifndef ADDRESS - #define ADDRESS(p,o) ((void *)(((char *)p)+(o))) -#endif - -#ifndef ADDRESSDIFF - #define ADDRESSDIFF(a,b) (((char *)a)-((char *)b)) -#endif - - -#define CC_SIZEOF_ALIGN4(x) ((sizeof(x)+0x3)&~0x3) -#define CC_SIZEOF_ALIGN8(x) ((sizeof(x)+0x7)&~0x7) -#define CC_SIZEOF_ALIGN16(x) ((sizeof(x)+0xF)&~0xF) -#define CC_SIZEOF_ALIGN32(x) ((sizeof(x)+0x1F)&~0x1F) -#define CC_SIZEOF_ALIGN64(x) ((sizeof(x)+0x3F)&~0x3F) - - -#define CC_MIN(x,y) ((x)>(y)?(y):(x)) -#define CC_MAX(x,y) ((x)<(y)?(y):(x)) -#define CC_CLAMP(x,min,max) ((x)<(min)?(min):((x)>(max)?(max):(x))) - - -#define CC_MAX_INT8(x,y) (((int8_t)x)-((((int8_t)x)-((int8_t)y))&((((int8_t)x)-((int8_t)y))>>7))) -#define CC_MAX_INT16(x,y) (((int16_t)x)-((((int16_t)x)-((int16_t)y))&((((int16_t)x)-((int16_t)y))>>15))) -#define CC_MAX_INT32(x,y) (((int32_t)x)-((((int32_t)x)-((int32_t)y))&((((int32_t)x)-((int32_t)y))>>31))) -#define CC_MAX_INT64(x,y) (((int64_t)x)-((((int64_t)x)-((int64_t)y))&((((int64_t)x)-((int64_t)y))>>63))) - -#define CC_MIN_INT8(x,y) (((int8_t)y)+((((int8_t)x)-((int8_t)y))&((((int8_t)x)-((int8_t)y))>>7))) -#define CC_MIN_INT16(x,y) (((int16_t)y)+((((int16_t)x)-((int16_t)y))&((((int16_t)x)-((int16_t)y))>>15))) -#define CC_MIN_INT32(x,y) (((int32_t)y)+((((int32_t)x)-((int32_t)y))&((((int32_t)x)-((int32_t)y))>>31))) -#define CC_MIN_INT64(x,y) (((int64_t)y)+((((int64_t)x)-((int64_t)y))&((((int64_t)x)-((int64_t)y))>>63))) - -#define CC_SHIFTDIV_INT8(value,shift) ({uint8_t _s=((uint8_t)value)>>7;((int8_t)((value)+(_s<>shift;}) -#define CC_SHIFTDIV_INT16(value,shift) ({uint16_t _s=((uint16_t)value)>>15;((int16_t)((value)+(_s<>shift;}) -#define CC_SHIFTDIV_INT32(value,shift) ({uint32_t _s=((uint32_t)value)>>31;((int32_t)((value)+(_s<>shift;}) -#define CC_SHIFTDIV_INT64(value,shift) ({uint64_t _s=((uint64_t)value)>>63;((int64_t)((value)+(_s<>shift;}) - -#define CC_SHIFTDIVROUND(value,shift) ((value>>shift)+(((value&((1<=(1<>shift)+((((value&((1<>7))<<1)>=(1<>shift)+((((value&((1<>15))<<1)>=(1<>shift)+((((value&((1<>31))<<1)>=(1<>shift)+((((value&((1<>63))<<1)>=(1<> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Int32Inline( uint32_t i ) -{ - uint32_t hash; - hash = i & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( i & 0xFFFF0000 ) >> 5 ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Int64Inline( uint64_t i ) -{ - uint32_t hash; - hash = i & 0xFFFF; - hash = ( ( hash << 16 ) ^ hash ) ^ ( ( (uint32_t)( i >> 16 ) & 0xFFFF ) << 11 ); - hash += ( hash >> 11 ) + ( (uint32_t)( i >> 32 ) & 0xFFFF ); - hash = ( ( hash << 16 ) ^ hash ) ^ (uint32_t)( ( i & 0xFFFF000000000000LL ) >> 37 ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data3Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash ^= hash << 16; - hash ^= (uint32_t)data[2] << 18; - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data4Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[3] << 19 ) | ( (uint32_t)data[2] << 11 ) ) ^ hash ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data5Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[3] << 19 ) | ( (uint32_t)data[2] << 11 ) ) ^ hash ); - hash += hash >> 11; - hash += (uint32_t)data[4]; - hash ^= hash << 10; - hash += hash >> 1; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data6Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[3] << 19 ) | ( (uint32_t)data[2] << 11 ) ) ^ hash ); - hash += hash >> 11; - hash += ( (uint32_t)data[5] << 8 ) | (uint32_t)data[4]; - hash ^= hash << 11; - hash += hash >> 17; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data7Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[3] << 19 ) | ( (uint32_t)data[2] << 11 ) ) ^ hash ); - hash += hash >> 11; - data = ADDRESS( data, 4 ); - hash += ( (uint32_t)data[5] << 8 ) | (uint32_t)data[4]; - hash ^= hash << 16; - hash ^= (uint32_t)data[6] << 18; - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - -static inline uint32_t ccHash32Data8Inline( uint8_t *data ) -{ - uint32_t hash; - hash = 0; - hash += ( (uint32_t)data[1] << 8 ) | (uint32_t)data[0]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[3] << 19 ) | ( (uint32_t)data[2] << 11 ) ) ^ hash ); - hash += hash >> 11; - hash += ( (uint32_t)data[5] << 8 ) | (uint32_t)data[4]; - hash = ( hash << 16 ) ^ ( ( ( (uint32_t)data[7] << 19 ) | ( (uint32_t)data[6] << 11 ) ) ^ hash ); - hash += hash >> 11; - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; -} - - - -//// - - - -typedef struct -{ - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; -} ccQuickRandState32; - -static inline uint32_t ccQuickRand32( ccQuickRandState32 *randstate ) -{ - uint32_t e; - e = randstate->a - ( ( randstate->b << 27 ) | ( randstate->b >> (32-27) ) ); - randstate->a = randstate->b ^ ( ( randstate->c << 17 ) | ( randstate->c >> (32-17) ) ); - randstate->b = randstate->c + randstate->d; - randstate->c = randstate->d + e; - randstate->d = e + randstate->a; - return randstate->d; -} - -static inline void ccQuickRand32Seed( ccQuickRandState32 *randstate, uint32_t seed ) -{ - uint32_t i; - randstate->a = 0xf1ea5eed; - randstate->b = seed; - randstate->c = seed; - randstate->d = seed; - for( i = 0 ; i < 20 ; i++ ) - ccQuickRand32( randstate ); - return; -} - - -typedef struct -{ - uint64_t a; - uint64_t b; - uint64_t c; - uint64_t d; -} ccQuickRandState64; - -static inline uint64_t ccQuickRand64( ccQuickRandState64 *randstate ) -{ - uint64_t e; - e = randstate->a - ( ( randstate->b << 7 ) | ( randstate->b >> (64-7) ) ); - randstate->a = randstate->b ^ ( ( randstate->c << 13 ) | ( randstate->c >> (64-13) ) ); - randstate->b = randstate->c + ( ( randstate->d << 37 ) | ( randstate->d >> (64-37) ) ); - randstate->c = randstate->d + e; - randstate->d = e + randstate->a; - return randstate->d; -} - -static inline void ccQuickRand64Seed( ccQuickRandState64 *randstate, uint64_t seed ) -{ - uint64_t i; - randstate->a = 0xf1ea5eed; - randstate->b = seed; - randstate->c = seed; - randstate->d = seed; - for( i = 0 ; i < 20 ; i++ ) - ccQuickRand64( randstate ); - return; -} - - - -//// - - - -int ccMemCmp( void *s0, void *s1, int size ); -int ccMemCmp32( uint32_t *s0, uint32_t *s1, int count ); -int ccMemCmp64( uint64_t *s0, uint64_t *s1, int count ); -int ccMemCmpRetSize( void *s0, void *s1, int size ); - -static inline int ccMemCmpInline( void *s0, void *s1, int size ) -{ - int i; - uint8_t *t0, *t1; - t0 = s0; - t1 = s1; - for( i = 0 ; i < size ; i++ ) - { - if( t0[i] != t1[i] ) - return 0; - } - return 1; -} - -static inline int ccMemCmpSizeInline( void *s0, void *s1, int size ) -{ - int i; - uint8_t *t0, *t1; - t0 = s0; - t1 = s1; - for( i = 0 ; i < size ; i++ ) - { - if( t0[i] != t1[i] ) - break; - } - return i; -} - - - -//// - - -uint8_t ccLog2Int8( uint8_t i ); -uint16_t ccLog2Int16( uint16_t i ); -uint32_t ccLog2Int32( uint32_t i ); -uint64_t ccLog2Int64( uint64_t i ); -#if CPUCONF_LONG_SIZE == 8 - #define ccLog2IntL(v) ccLog2Int64(v) -#else - #define ccLog2IntL(v) ccLog2Int32(v) -#endif - - -//// - - -static inline uint8_t ccMergeIntMask8( uint8_t i0, uint8_t i1, uint8_t mask ) -{ - return i0 ^ ( ( i0 ^ i1 ) & mask ); -} - -static inline uint16_t ccMergeIntMask16( uint16_t i0, uint16_t i1, uint16_t mask ) -{ - return i0 ^ ( ( i0 ^ i1 ) & mask ); -} - -static inline uint32_t ccMergeIntMask32( uint32_t i0, uint32_t i1, uint32_t mask ) -{ - return i0 ^ ( ( i0 ^ i1 ) & mask ); -} - -static inline uint64_t ccMergeIntMask64( uint64_t i0, uint64_t i1, uint64_t mask ) -{ - return i0 ^ ( ( i0 ^ i1 ) & mask ); -} - -#if CPUCONF_LONG_SIZE == 8 - #define ccMergeIntMaskL(v) ccMergeIntMask64(v) -#else - #define ccMergeIntMaskL(v) ccMergeIntMask32(v) -#endif - - - -//// - - - -static inline int ccCountBits64( uint64_t i ) -{ - int r; - for( r = 0 ; i ; r++ ) - i &= i - 1; - return r; -} - - -static inline int ccCountBits32( uint32_t v ) -{ - int c; - v = v - ( ( v >> 1 ) & 0x55555555 ); - v = ( v & 0x33333333 ) + ( ( v >> 2 ) & 0x33333333 ); - c = ( ( ( v + ( v >> 4 ) ) & 0xF0F0F0F ) * 0x1010101 ) >> 24; - return c; -} - - - -//// - - -static inline uint8_t ccIsPow2Int8( uint8_t v ) -{ - return ( ( v & ( v - 1 ) ) == 0 ); -} - -static inline uint16_t ccIsPow2Int16( uint16_t v ) -{ - return ( ( v & ( v - 1 ) ) == 0 ); -} - -static inline uint32_t ccIsPow2Int32( uint32_t v ) -{ - return ( ( v & ( v - 1 ) ) == 0 ); -} - -static inline uint64_t ccIsPow2Int64( uint64_t v ) -{ - return ( ( v & ( v - 1 ) ) == 0 ); -} - - -static inline uint8_t ccPow2Round8( uint8_t v ) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v++; - return v; -} - -static inline uint16_t ccPow2Round16( uint16_t v ) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v++; - return v; -} - -static inline uint32_t ccPow2Round32( uint32_t v ) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} - -static inline uint64_t ccPow2Round64( uint64_t v ) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - v++; - return v; -} - -#if CPUCONF_LONG_SIZE == 8 - #define ccPow2RoundL(v) ccPow2Round64(v) -#else - #define ccPow2RoundL(v) ccPow2Round32(v) -#endif - - - -//// - - - -static inline uint32_t ccTestNullByte32( uint32_t v ) -{ - return ( v - 0x01010101 ) & ~v & 0x80808080; -} - -static inline uint64_t ccTestNullByte64( uint64_t v ) -{ - return ( v - 0x0101010101010101ULL ) & ~v & 0x8080808080808080ULL; -} - -static inline uint32_t ccSignBit32( uint32_t v ) -{ - return v >> 31; -} - -static inline uint64_t ccSignBit64( uint64_t v ) -{ - return v >> 63; -} - -static inline uint32_t ccAbs32( int32_t v ) -{ - int32_t mask; - mask = v >> 31; - return ( v ^ mask ) - mask; -} - -static inline uint64_t ccAbs64( int64_t v ) -{ - int32_t mask; - mask = v >> 63; - return ( v ^ mask ) - mask; -} - - - -//// - - - -static inline int ccIsAlphaNum( char c ) -{ - if( ( c >= 'a' ) && ( c <= 'z' ) ) - return 1; - if( ( c >= 'A' ) && ( c <= 'Z' ) ) - return 1; - if( ( c >= '0' ) && ( c <= '9' ) ) - return 1; - return 0; -} - - -void ccStrLowCopy( char *dst, char *src, int length ); - -int ccStrCmpEqual( char *s0, char *s1 ); - -char *ccStrCmpWord( char *str, char *word ); - -char *ccStrCmpSeq( char *str, char *seq, int seqlength ); - -char *ccStrMatchSeq( char *str, char *seq, int seqlength ); - -char *ccStrSeqCmpSeq( char *s1, char *s2, int s1length, int s2length ); - -int ccStrWordCmpWord( char *s1, char *s2 ); - -char *ccStrLowCmpSeq( char *str, char *seq, int seqlength ); - -char *ccStrFind( char *str, char *seq, int seqlength ); - -char *ccStrFindWord( char *str, char *word, int wordlength ); - -int ccStrWordLength( char *str ); - -int ccSeqFindChar( char *seq, int seqlen, char c ); - -char *ccSeqFindStr( char *seq, int seqlen, char *str ); - -char *ccStrParam( char *str, int *paramlen, int *skiplen ); - -int ccParseParameters( char *str, char **argv ); - -char *ccStrNextWord( char *str ); - -char *ccStrSkipWord( char *str ); - -char *ccStrNextWordSameLine( char *str ); - -char *ccStrNextParam( char *str ); - -char *ccStrNextLine( char *str ); - -char *ccStrPassLine( char *str ); - -int ccStrParseInt( char *str, int64_t *retint ); - -int ccSeqParseInt( char *seq, int seqlength, int64_t *retint ); - -int ccStrParseFloat( char *str, float *retfloat ); - - - -//// - - - -#define CC_FLT_INT_MAPPING - -#if CPUCONF_FLOAT_SIZE == 4 -typedef uint32_t ccuintf; -#elif CPUCONF_FLOAT_SIZE == 8 -typedef uint64_t ccuintf; -#else - #undef CC_FLT_INT_MAPPING -#endif - -#if CPUCONF_DOUBLE_SIZE == 4 -typedef uint32_t ccuintd; -#elif CPUCONF_DOUBLE_SIZE == 8 -typedef uint64_t ccuintd; -#else - #undef CC_FLT_INT_MAPPING -#endif - - -#ifdef CC_FLT_INT_MAPPING - -static inline ccuintf ccFloatToUint( float f ) -{ - void *p = &f; - return *((ccuintf *)p); -} - -static inline float ccUintToFloat( ccuintf f ) -{ - void *p = &f; - return *((float *)p); -} - - -static inline ccuintd ccDoubleToUint( double d ) -{ - void *p = &d; - return *((ccuintd *)p); -} - -static inline double ccUintToDouble( ccuintd d ) -{ - void *p = &d; - return *((double *)p); -} - -#endif - - - -//// - - - -#define CC_LOG2_E 1.4426950408889634073599246810018921 - -static inline float ccFastExpFloat( float x ) -{ - union - { - uint32_t i; - float f; - } u; - if( x > 88.0 ) - return expf( x ); - else if( x < -80.0 ) - return 0.0; - u.i = (int32_t)( x * ( (float)0x800000 * (float)CC_LOG2_E ) ) + ( 0x3f800000 - 486408 ); - return u.f; -} - -static inline float ccFastExpFloatNearZero( float x ) -{ - union - { - uint32_t i; - float f; - } u; - if( x > 88.0 ) - return expf( x ); - else if( x < -80.0 ) - return 0.0; - u.i = (int32_t)( x * ( (float)0x800000 * (float)CC_LOG2_E ) ) + 0x3f800000; - return u.f; -} - -static inline double ccFastExpDouble( double x ) -{ -#if CPUCONF_WORD_SIZE >= 64 - union - { - uint64_t i; - double d; - } u; - if( x > 88.0 ) - return exp( x ); - else if( x < -80.0 ) - return 0.0; - u.i = (int64_t)( x * ( (double)0x10000000000000 * CC_LOG2_E ) ) + ( (uint64_t)0x3ff0000000000000 - (uint64_t)261138306564096 ); - return u.d; -#else - union - { - uint32_t i[2]; - double d; - } u; - if( x > 88.0 ) - return expf( x ); - else if( x < -80.0 ) - return 0.0; - #ifdef CPUCONF_LITTLE_ENDIAN - u.i[1] = (int32_t)( x * ( (double)0x100000 * CC_LOG2_E ) ) + ( 0x3ff00000 - 60801 ); - u.i[0] = 0; - #else - u.i[0] = (int32_t)( x * ( (double)0x100000 * CC_LOG2_E ) ) + ( 0x3ff00000 - 60801 ); - u.i[1] = 0; - #endif - return u.d; -#endif -} - -static inline double ccFastExpDoubleNearZero( double x ) -{ -#if CPUCONF_WORD_SIZE >= 64 - union - { - uint64_t i; - double d; - } u; - if( x > 88.0 ) - return expf( x ); - else if( x < -80.0 ) - return 0.0; - u.i = (int64_t)( x * ( (double)0x10000000000000 * CC_LOG2_E ) ) + (uint64_t)0x3ff0000000000000; - return u.d; -#else - union - { - uint32_t i[2]; - double d; - } u; - if( x > 88.0 ) - return expf( x ); - else if( x < -80.0 ) - return 0.0; - #ifdef CPUCONF_LITTLE_ENDIAN - u.i[1] = (int32_t)( x * ( (double)0x100000 * CC_LOG2_E ) ) + 0x3ff00000; - u.i[0] = 0; - #else - u.i[0] = (int32_t)( x * ( (double)0x100000 * CC_LOG2_E ) ) + 0x3ff00000; - u.i[1] = 0; - #endif - return u.d; -#endif -} - - - -//// - - - -static inline float ccFastLog2Float( float x ) -{ - int base; - union - { - uint32_t i; - float f; - } u; - u.f = x; - base = ( ( u.i >> 23 ) & 0xff ) - 0x80; - u.i &= ~( (uint32_t)0xff << 23 ); - u.i += (uint32_t)0x7f << 23; - return (float)base + ( u.f * ( 2.0 + u.f * ( -1.0/3.0 ) ) ) - ( 2.0/3.0 ); -} - -static inline float ccFastLog2Double( double x ) -{ -#if CPUCONF_WORD_SIZE >= 64 - int base; - union - { - uint64_t i; - double f; - } u; - u.f = x; - base = ( ( u.i >> 52 ) & 0x7ff ) - 0x400; - u.i &= ~( (uint64_t)0x7ff << 52 ); - u.i += (uint64_t)0x3ff << 52; -#else - int base; - union - { - uint32_t i[2]; - double f; - } u; - u.f = x; - base = ( ( u.i[1] >> 20 ) & 0x7ff ) - 0x400; - u.i[1] &= ~( (uint32_t)0x7ff << 20 ); - u.i[1] += (uint32_t)0x3ff << 20; -#endif - return (double)base + ( u.f * ( 2.0 + u.f * ( -1.0/3.0 ) ) ) - ( 2.0/3.0 ); -} - - - -//// - - - -#define CC_INT16_BSWAP(i) ({uint16_t bsw=(i);(bsw<<8)|(bsw>>8);}) -#define CC_INT32_BSWAP(i) ({uint32_t bsw=(i);(bsw<<24)|((bsw&0xff00)<<8)|((bsw>>8)&0xff00)|(bsw>>24);}) -#define CC_INT64_BSWAP(i) ({uint64_t bsw=(i);(bsw>>56)|((bsw&0x00ff000000000000LL)>>40)|((bsw&0x0000ff0000000000LL)>>24)|((bsw&0x000000ff00000000LL)>>8)|((bsw&0x00000000ff000000LL)<<8)|((bsw&0x0000000000ff0000LL)<<24)|((bsw&0x000000000000ff00LL)<<40)|(bsw<<56);}) - - -static inline uint16_t ccByteSwap16( uint16_t i ) -{ - return CC_INT16_BSWAP( i ); -} - -#if defined(__GNUC__) && defined(__i386__) - -static inline uint32_t ccByteSwap32( uint32_t i ) -{ - __asm__( "bswap %0" : "=r" (i) : "0" (i) ); - return i; -} - -static inline uint64_t ccByteSwap64( uint64_t i ) -{ - union { - uint32_t s[2]; - uint64_t i; - } u; - u.i = i; - __asm__( "bswapl %0 ; bswapl %1 ; xchgl %0,%1" : "=r" (u.s[0]), "=r" (u.s[1]) : "0" (u.s[0]), "1" (u.s[1]) ); - return u.i; -} - -#elif defined(__GNUC__) && defined(__x86_64__) - -static inline uint32_t ccByteSwap32( uint32_t i ) -{ - __asm__( "bswapl %0" : "=r" (i) : "0" (i) ); - return i; -} - -static inline uint64_t ccByteSwap64( uint64_t i ) -{ - __asm__( "bswapq %0" : "=r" (i) : "0" (i) ); - return i; -} - -#else - -static inline uint32_t ccByteSwap32( uint32_t i ) -{ - return CC_INT32_BSWAP( i ); -} - -static inline uint64_t ccByteSwap64( uint64_t i ) -{ - return CC_INT64_BSWAP( i ); -} - -#endif - -static inline float ccByteSwapf( float f ) -{ - uint32_t i; - void *p; - p = &f; - i = ccByteSwap32( *((uint32_t *)p) ); - p = &i; - return *((float *)p); -} - -static inline double ccByteSwapd( double f ) -{ - uint64_t i; - void *p; - p = &f; - i = ccByteSwap64( *((uint64_t *)p) ); - p = &i; - return *((double *)p); -} - - -static inline uint32_t ccAlignInt32( uint32_t i ) -{ - i--; - i |= i >> 1; - i |= i >> 2; - i |= i >> 4; - i |= i >> 8; - i |= i >> 16; - return i + 1; -} - -static inline uint64_t ccAlignInt64( uint64_t i ) -{ - i--; - i |= i >> 1; - i |= i >> 2; - i |= i >> 4; - i |= i >> 8; - i |= i >> 16; - i |= i >> 32; - return i + 1; -} - -static inline uintptr_t ccAlignIntPtr( uintptr_t i ) -{ - i--; - i |= i >> 1; - i |= i >> 2; - i |= i >> 4; - i |= i >> 8; - i |= i >> 16; -#if CPUCONF_INTPTR_BITS > 32 - i |= i >> 32; -#endif - return i + 1; -} - - - -//// - - - -static inline uint8_t ccRotateLeft8( uint8_t x, int bits ) -{ - return ( x << bits ) | ( x >> ( 8 - bits ) ); -} - -static inline uint16_t ccRotateLeft16( uint16_t x, int bits ) -{ - return ( x << bits ) | ( x >> ( 16 - bits ) ); -} - -static inline uint32_t ccRotateLeft32( uint32_t x, int bits ) -{ - return ( x << bits ) | ( x >> ( 32 - bits ) ); -} - -static inline uint64_t ccRotateLeft64( uint64_t x, int bits ) -{ - return ( x << bits ) | ( x >> ( 64 - bits ) ); -} - - -static inline uint8_t ccRotateRight8( uint8_t x, int bits ) -{ - return ( x >> bits ) | ( x << ( 8 - bits ) ); -} - -static inline uint16_t ccRotateRight16( uint16_t x, int bits ) -{ - return ( x >> bits ) | ( x << ( 16 - bits ) ); -} - -static inline uint32_t ccRotateRight32( uint32_t x, int bits ) -{ - return ( x >> bits ) | ( x << ( 32 - bits ) ); -} - -static inline uint64_t ccRotateRight64( uint64_t x, int bits ) -{ - return ( x >> bits ) | ( x << ( 64 - bits ) ); -} - - -//// - - -#define CC_INT32_MAX ((((uint32_t)1)<<31)-1) - -static inline int32_t ccFloatToInt32Sat( float f ) -{ - if( f >= (float)CC_INT32_MAX ) - return CC_INT32_MAX; - else if( f <= -(float)CC_INT32_MAX ) - return -CC_INT32_MAX; - else - return (int32_t)f; -} - - -static inline int32_t ccDoubleToInt32Sat( double f ) -{ - if( f >= (double)CC_INT32_MAX ) - return CC_INT32_MAX; - else if( f <= -(double)CC_INT32_MAX ) - return -CC_INT32_MAX; - else - return (int32_t)f; -} - - -#define CC_INT64_MAX ((((uint64_t)1)<<63)-1) - -static inline int64_t ccFloatToInt64Sat( float f ) -{ - if( f >= (float)CC_INT64_MAX ) - return CC_INT64_MAX; - else if( f <= -(float)CC_INT64_MAX ) - return -CC_INT64_MAX; - else - return (int64_t)f; -} - - -static inline int64_t ccDoubleToInt64Sat( double f ) -{ - if( f >= (double)CC_INT64_MAX ) - return CC_INT64_MAX; - else if( f <= -(double)CC_INT64_MAX ) - return -CC_INT64_MAX; - else - return (int64_t)f; -} - - -//// - - - -void ccQuickSort( void **table, int count, int (*sortfunc)( void *t0, void *t1 ), uint32_t randmask ); -void ccQuickSortContext( void **table, int count, int (*sortfunc)( void *t0, void *t1, void *context ), void *context, uint32_t randmask ); - -int ccMergeSort( void **src, void **tmp, int count, int (*sortfunc)( void *t0, void *t1 ) ); -int ccMergeSortContext( void **src, void **tmp, int count, int (*sortfunc)( void *t0, void *t1, void *context ), void *context ); - - - -//// - - - -void ccDebugLog( char *filename, char *string, ... ); - diff --git a/src/other/gct/Auxiliary/ccmergesort.h b/src/other/gct/Auxiliary/ccmergesort.h deleted file mode 100644 index a0da529cb78..00000000000 --- a/src/other/gct/Auxiliary/ccmergesort.h +++ /dev/null @@ -1,215 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -/* - -Templates C style! - -#include this whole file with the following definitions set: - -#define MSORT_MAIN MyInlinedSortFunction -#define MSORT_CMP MyComparisonFunction -#define MSORT_TYPE int - -*/ - - -#ifndef CC_MSORT_INLINE - -typedef struct -{ - void *src; - void *dst; - int count; - int mergeflag; - int depthbit; -} ccMergeSortStack; - - #define CC_MSORT_INLINE - #define CC_MSORT_STACK_DEPTH (512) - -#endif - - -#ifndef MSORT_COPY - #define MSORT_COPY(d,s) (*(d)=*(s)) - #define CC_MSORT_COPY -#endif - - -static MSORT_TYPE *MSORT_MAIN( MSORT_TYPE *src, MSORT_TYPE *tmp, int count ) -{ - int swapflag, depthbit, maxdepthbit; - ssize_t leftcount, rightcount; - MSORT_TYPE *dst, *sl, *sr, *dstend, *dstbase, *swap, temp; - ccMergeSortStack stack[CC_MSORT_STACK_DEPTH]; - ccMergeSortStack *sp; - - dst = tmp; - sp = stack; - swapflag = 0; - depthbit = 0; - - if( count <= 1 ) - return src; - - leftcount = count; - for( maxdepthbit = 1 ; ; maxdepthbit ^= 1 ) - { - leftcount = leftcount - ( leftcount >> 1 ); - if( leftcount <= 4 ) - break; - } - - for( ; ; ) - { - if( count <= 4 ) - { - if( !( depthbit ^ maxdepthbit ) ) - { - if( ( count == 4 ) && MSORT_CMP( &src[2], &src[3] ) ) - { - MSORT_COPY( &temp, &src[2] ); - MSORT_COPY( &src[2], &src[3] ); - MSORT_COPY( &src[3], &temp ); - } - if( MSORT_CMP( &src[0], &src[1] ) ) - { - MSORT_COPY( &temp, &src[0] ); - MSORT_COPY( &src[0], &src[1] ); - MSORT_COPY( &src[1], &temp ); - } - swapflag = 0; - } - else - { - if( count == 4 ) - { - if( MSORT_CMP( &src[2], &src[3] ) ) - { - MSORT_COPY( &dst[2], &src[3] ); - MSORT_COPY( &dst[3], &src[2] ); - } - else - { - MSORT_COPY( &dst[2], &src[2] ); - MSORT_COPY( &dst[3], &src[3] ); - } - } - else if( count == 3 ) - MSORT_COPY( &dst[2], &src[2] ); - if( MSORT_CMP( &src[0], &src[1] ) ) - { - MSORT_COPY( &dst[0], &src[1] ); - MSORT_COPY( &dst[1], &src[0] ); - } - else - { - MSORT_COPY( &dst[0], &src[0] ); - MSORT_COPY( &dst[1], &src[1] ); - } - swap = src; - src = dst; - dst = swap; - swapflag = 1; - } - } - else - { - rightcount = count >> 1; - leftcount = count - rightcount; - sp->src = src; - sp->dst = dst; - sp->count = count; - sp->mergeflag = 1; - sp->depthbit = depthbit; - depthbit ^= 1; - sp++; - sp->src = src + leftcount; - sp->dst = dst + leftcount; - sp->count = rightcount; - sp->mergeflag = 0; - sp->depthbit = depthbit; - sp++; - count = leftcount; - continue; - } - - for( ; ; ) - { - rightcount = count >> 1; - leftcount = count - rightcount; - sl = src; - sr = src + leftcount; - dstbase = dst; - for( ; ; ) - { - if( MSORT_CMP( sl, sr ) ) - { - MSORT_COPY( dst++, sr++ ); - if( --rightcount ) - continue; - for( dstend = &dst[leftcount] ; dst < dstend ; ) - MSORT_COPY( dst++, sl++ ); - break; - } - else - { - MSORT_COPY( dst++, sl++ ); - if( --leftcount ) - continue; - for( dstend = &dst[rightcount] ; dst < dstend ; ) - MSORT_COPY( dst++, sr++ ); - break; - } - } - if( sp == stack ) - return dstbase; - sp--; - src = sp->src; - dst = sp->dst; - count = sp->count; - depthbit = sp->depthbit; - if( !( sp->mergeflag ) ) - break; - swapflag ^= 1; - if( swapflag ) - { - src = sp->dst; - dst = sp->src; - } - } - } - - return 0; -} - - -#ifndef CC_MSORT_COPY - #undef MSORT_COPY - #undef CC_MSORT_COPY -#endif diff --git a/src/other/gct/Auxiliary/cpuconfig.h b/src/other/gct/Auxiliary/cpuconfig.h deleted file mode 100644 index 7b7b351cf28..00000000000 --- a/src/other/gct/Auxiliary/cpuconfig.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Automatically generated CPU information header */ - -#define CPUCONF_CHAR_SIZE (1) -#define CPUCONF_SHORT_SIZE (2) -#define CPUCONF_INT_SIZE (4) -#define CPUCONF_LONG_SIZE (8) -#define CPUCONF_LONG_LONG_SIZE (8) -#define CPUCONF_INTPTR_SIZE (8) -#define CPUCONF_POINTER_SIZE (8) -#define CPUCONF_FLOAT_SIZE (4) -#define CPUCONF_DOUBLE_SIZE (8) -#define CPUCONF_LONG_DOUBLE_SIZE (16) - -#define CPUCONF_CHAR_BITS (8) -#define CPUCONF_SHORT_BITS (16) -#define CPUCONF_INT_BITS (32) -#define CPUCONF_LONG_BITS (64) -#define CPUCONF_LONG_LONG_BITS (64) -#define CPUCONF_INTPTR_BITS (64) -#define CPUCONF_POINTER_BITS (64) -#define CPUCONF_FLOAT_BITS (32) -#define CPUCONF_DOUBLE_BITS (64) -#define CPUCONF_LONG_DOUBLE_BITS (128) - -#define CPUCONF_CHAR_SIZESHIFT (0) -#define CPUCONF_SHORT_SIZESHIFT (1) -#define CPUCONF_INT_SIZESHIFT (2) -#define CPUCONF_LONG_SIZESHIFT (3) -#define CPUCONF_LONG_LONG_SIZESHIFT (3) -#define CPUCONF_INTPTR_SIZESHIFT (3) -#define CPUCONF_POINTER_SIZESHIFT (3) -#define CPUCONF_FLOAT_SIZESHIFT (2) -#define CPUCONF_DOUBLE_SIZESHIFT (3) -#define CPUCONF_LONG_DOUBLE_SIZESHIFT (4) - -#define CPUCONF_CHAR_BITSHIFT (3) -#define CPUCONF_SHORT_BITSHIFT (4) -#define CPUCONF_INT_BITSHIFT (5) -#define CPUCONF_LONG_BITSHIFT (6) -#define CPUCONF_LONG_LONG_BITSHIFT (6) -#define CPUCONF_INTPTR_BITSHIFT (6) -#define CPUCONF_POINTER_BITSHIFT (6) -#define CPUCONF_FLOAT_BITSHIFT (5) -#define CPUCONF_DOUBLE_BITSHIFT (6) -#define CPUCONF_LONG_DOUBLE_BITSHIFT (7) - -#define CPUCONF_LITTLE_ENDIAN -#define CPUCONF_ARCH_AMD64 -#define CPUCONF_VENDOR_INTEL -#define CPUCONF_IDENTIFIER "Intel(R) Core(TM) i7-2760QM CPU @ 2.40GHz" -#define CPUCONF_CLASS_CORE2 -#define CPUCONF_LOGICAL_CORES_COUNT (16) -#define CPUCONF_PHYSICAL_CORES_COUNT (8) -#define CPUCONF_CORES_COUNT (8) -#define CPUCONF_SYSTEM_MEMORY (8207917056LL) -#define CPUCONF_WORD_SIZE (64) -#define CPUCONF_CACHE_LINE_SIZE (64) -#define CPUCONF_CACHE_LOAD_SIZE (64) -#define CPUCONF_CACHE_L2_SIZE (262144) -#define CPUCONF_CAP_GPREGS (16) -#define CPUCONF_CAP_FPREGS (16) - -#define CPUCONF_CAP_CMOV -#define CPUCONF_CAP_MMX -#define CPUCONF_CAP_SSE -#define CPUCONF_CAP_SSE2 -#define CPUCONF_CAP_SSE3 -#define CPUCONF_CAP_SSSE3 -#define CPUCONF_CAP_SSE4_1 -#define CPUCONF_CAP_SSE4_2 -#define CPUCONF_CAP_HYPERTHREADING -#define CPUCONF_CAP_MWAIT - diff --git a/src/other/gct/Auxiliary/cpuinfo.c b/src/other/gct/Auxiliary/cpuinfo.c deleted file mode 100644 index 6b093ab4925..00000000000 --- a/src/other/gct/Auxiliary/cpuinfo.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuinfo.h" - - -#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) - #define ENV_ARCH_AMD64 -#elif defined(__i386__) || defined(__i386) || defined(i386) - #define ENV_ARCH_IA32 -#endif - -#if defined(__linux__) || defined(__gnu_linux__) || defined(__linux) || defined(__linux) - #include - #define ENV_OS_LINUX -#endif - -#if defined(__unix__) || defined(__unix) || defined(unix) - #include - #define ENV_OS_UNIX -#endif - -#if defined(_WIN32) || defined(WIN32) - #include - #include - #define ENV_OS_WINDOWS -#endif - -#if defined(_MSC_VER) - #include -#endif - - - -#define CAP001_ECX_SSE3 (1<<0) -#define CAP001_ECX_PCLMUL (1<<1) -#define CAP001_ECX_MWAIT (1<<3) -#define CAP001_ECX_SSSE3 (1<<9) -#define CAP001_ECX_FMA3 (1<<12) -#define CAP001_ECX_CMPXCHG16B (1<<13) -#define CAP001_ECX_SSE4_1 (1<<19) -#define CAP001_ECX_SSE4_2 (1<<20) -#define CAP001_ECX_POPCNT (1<<22) -#define CAP001_ECX_MOVBE (1<<23) -#define CAP001_ECX_AES (1<<25) -#define CAP001_ECX_AVX (1<<28) -#define CAP001_ECX_F16C (1<<29) -#define CAP001_ECX_RDRND (1<<30) - -#define CAP001_EDX_TSC (1<<4) -#define CAP001_EDX_CMOV (1<<15) -#define CAP001_EDX_CLFLUSH (1<<19) -#define CAP001_EDX_MMX (1<<23) -#define CAP001_EDX_SSE (1<<25) -#define CAP001_EDX_SSE2 (1<<26) -#define CAP001_EDX_HYPERTHREADING (1<<28) - -#define CAP006_EAX_THERMALSENSOR (1<<0) -#define CAP006_EAX_CLOCKMODULATION (1<<5) - -#define CAP007_EBX_BMI (1<<3) -#define CAP007_EBX_AVX2 (1<<5) -#define CAP007_EBX_BMI2 (1<<8) - -#define CAP801_ECX_NOHT (1<<1) -#define CAP801_ECX_LZCNT (1<<5) -#define CAP801_ECX_SSE4A (1<<6) -#define CAP801_ECX_MISALIGNSSE (1<<7) -#define CAP801_ECX_XOP (1<<11) -#define CAP801_ECX_FMA4 (1<<16) -#define CAP801_ECX_TBM (1<<21) - -#define CAP801_EDX_MMXEXT (1<<22) -#define CAP801_EDX_RDTSCP (1<<27) -#define CAP801_EDX_LONGMODE (1<<29) -#define CAP801_EDX_3DNOWEXT (1<<30) -#define CAP801_EDX_3DNOW (1<<31) - -#define CAP807_EDX_CONSTANTTSC (1<<8) - - -static void cpuInitInfo( cpuInfo *cpu ) -{ - memset( cpu, 0, sizeof(cpuInfo) ); - sprintf( cpu->identifier, "Unknown" ); - cpu->cachesizeL1code = -1; - cpu->cachesizeL1data = -1; - cpu->cachesizeL2 = -1; - cpu->cachesizeL3 = -1; -#if defined(ENV_ARCH_AMD64) - cpu->arch = CPUINFO_ARCH_AMD64; - cpu->wordsize = 64; - cpu->gpregs = 16; - cpu->fpregs = 16; -#elif defined(ENV_ARCH_IA32) - cpu->arch = CPUINFO_ARCH_IA32; - cpu->wordsize = 32; - cpu->gpregs = 8; - cpu->fpregs = 8; -#else - cpu->arch = CPUINFO_ARCH_UNKNOWN; - cpu->wordsize = sizeof(void *) * CHAR_BIT; -#endif - cpu->class = CPUINFO_CLASS_UNKNOWN; - return; -} - - -static void cpuGetEndian( cpuInfo *cpu ) -{ - static const uint32_t ref = 0x44332211; - if( ( ((char *)&ref)[0] == 0x11 ) && ( ((char *)&ref)[1] == 0x22 ) && ( ((char *)&ref)[2] == 0x33 ) && ( ((char *)&ref)[3] == 0x44 ) ) - cpu->endianness = CPUINFO_LITTLE_ENDIAN; - else if( ( ((char *)&ref)[0] == 0x44 ) && ( ((char *)&ref)[1] == 0x33 ) && ( ((char *)&ref)[2] == 0x22 ) && ( ((char *)&ref)[3] == 0x11 ) ) - cpu->endianness = CPUINFO_LITTLE_ENDIAN; - else - cpu->endianness = CPUINFO_MIXED_ENDIAN; - return; -} - - -#if defined(ENV_ARCH_IA32) || defined(ENV_ARCH_AMD64) - - -#ifdef ENV_ARCH_IA32 - - #define EFLAG_CPUID 0x00200000 - -static int cpuEflagCheck( uint32_t mask ) -{ - #if defined(__GNUC__) - uint32_t t0, t1; - asm("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0, %1\n\t" - "xorl %2, %1\n\t" - "pushl %1\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %1\n\t" - "popfl\n\t" - : "=&r" (t0), "=&r" (t1) - : "ri" (mask)); - return ( ( t0 ^ t1 ) & mask ); - #else - return 1; - #endif -} - -#endif - - -static void cpuCpuid( uint32_t level, uint32_t index, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) -{ -#if defined(__GNUC__) - #ifdef ENV_ARCH_AMD64 - asm("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (level), "c"(index) ); - #endif - #ifdef ENV_ARCH_IA32 - asm("movl %%ebx, %%esi\n\t" - "cpuid\n\t" - "movl %3, %%edi\n\t" - "movl %%ebx, (%%edi)\n\t" - "movl %%esi, %%ebx\n\t" - : "=a" (*eax), "=c" (*ecx), "=d" (*edx) - : "m" (ebx), "a" (level), "c"(index) : "edi", "esi", "memory" ); - #endif -#elif defined(_MSC_VER) - int regs[4]; - __cpuidex( regs, level, index ); - *eax = regs[0]; - *ebx = regs[1]; - *ecx = regs[2]; - *edx = regs[3]; -#else - #warning WARNING: Unknown compiler, we do not know how to execute CPUID instructions - *eax = 0; - *ebx = 0; - *ecx = 0; - *edx = 0; -#endif - return; -} - - -static int cpuGetGeneral( cpuInfo *cpu ) -{ - uint32_t eax, ebx, ecx, edx, vendorstring[3]; - -#ifdef ENV_ARCH_IA32 - if( !( cpuEflagCheck( EFLAG_CPUID ) ) ) - return 0; -#endif - - cpuCpuid( 0x00000000, 0, &cpu->intellevel, &vendorstring[0], &vendorstring[2], &vendorstring[1] ); - memcpy( cpu->vendorstring, vendorstring, 3*sizeof(uint32_t) ); - if( !( strcmp( cpu->vendorstring, "GenuineIntel" ) ) ) - cpu->vendor = CPUINFO_VENDOR_INTEL; - else if( !( strcmp( cpu->vendorstring, "AuthenticAMD" ) ) ) - cpu->vendor = CPUINFO_VENDOR_AMD; - else - cpu->vendor = CPUINFO_VENDOR_UNKNOWN; - - /* Intel flags */ - if( ( cpu->intellevel >= 0x00000001 ) && ( cpu->intellevel <= 0x0000ffff ) ) - { - cpuCpuid( 0x00000001, 0, &eax, &ebx, &ecx, &edx ); - cpu->family = ( eax >> 8 ) & 0xf; - if( cpu->family == 0xf ) - cpu->family += ( eax >> 20 ) & 0xff; - cpu->model = ( eax >> 4 ) & 0xf; - if( cpu->family >= 6 ) - cpu->model += ( ( eax >> 16 ) & 0xf ) << 4; - cpu->socketlogicalcores = ( ebx >> 16 ) & 0xff; - if( ecx & CAP001_ECX_SSE3 ) - cpu->capsse3 = 1; - if( ecx & CAP001_ECX_PCLMUL ) - cpu->cappclmul = 1; - if( ecx & CAP001_ECX_MWAIT ) - cpu->capmwait = 1; - if( ecx & CAP001_ECX_SSSE3 ) - cpu->capssse3 = 1; - if( ecx & CAP001_ECX_FMA3 ) - cpu->capfma3 = 1; - if( ecx & CAP001_ECX_CMPXCHG16B ) - cpu->capcmpxchg16b = 1; - if( ecx & CAP001_ECX_SSE4_1 ) - cpu->capsse4p1 = 1; - if( ecx & CAP001_ECX_SSE4_2 ) - cpu->capsse4p2 = 1; - if( ecx & CAP001_ECX_POPCNT ) - cpu->cappopcnt = 1; - if( ecx & CAP001_ECX_MOVBE ) - cpu->capmovbe = 1; - if( ecx & CAP001_ECX_AES ) - cpu->capaes = 1; - if( ecx & CAP001_ECX_AVX ) - cpu->capavx = 1; - if( ecx & CAP001_ECX_F16C ) - cpu->capf16c = 1; - if( ecx & CAP001_ECX_RDRND ) - cpu->caprdrnd = 1; - if( edx & CAP001_EDX_TSC ) - cpu->captsc = 1; - if( edx & CAP001_EDX_CMOV ) - cpu->capcmov = 1; - if( edx & CAP001_EDX_CLFLUSH ) - { - cpu->capclflush = 1; - cpu->clflushsize = ( ( ebx >> 8 ) & 0xff ) * 8; - cpu->cacheline = cpu->clflushsize; - } - if( edx & CAP001_EDX_MMX ) - cpu->capmmx = 1; - if( edx & CAP001_EDX_SSE ) - cpu->capsse = 1; - if( edx & CAP001_EDX_SSE2 ) - cpu->capsse2 = 1; - if( edx & CAP001_EDX_HYPERTHREADING ) - cpu->caphyperthreading = 1; - } - - /* Thermal and clock management */ - if( ( cpu->intellevel >= 0x00000006 ) && ( cpu->intellevel <= 0x0000ffff ) ) - { - cpuCpuid( 0x00000006, 0, &eax, &ebx, &ecx, &edx ); - if( eax & CAP006_EAX_THERMALSENSOR ) - cpu->capthermalsensor = 1; - if( eax & CAP006_EAX_CLOCKMODULATION ) - cpu->capclockmodulation = 1; - } - - /* Flags */ - if( ( cpu->intellevel >= 0x00000007 ) && ( cpu->intellevel <= 0x0000ffff ) ) - { - cpuCpuid( 0x00000006, 0, &eax, &ebx, &ecx, &edx ); - if( eax & CAP007_EBX_BMI ) - cpu->capbmi = 1; - if( eax & CAP007_EBX_AVX2 ) - cpu->capavx2 = 1; - if( eax & CAP007_EBX_BMI2 ) - cpu->capbmi2 = 1; - } - - /* AMD flags */ - cpuCpuid( 0x80000000, 0, &cpu->amdlevel, &ebx, &ecx, &edx ); - if( ( cpu->amdlevel >= 0x80000001 ) && ( cpu->amdlevel <= 0x8000ffff ) ) - { - cpuCpuid( 0x80000001, 0, &eax, &ebx, &ecx, &edx ); - if( ecx & CAP801_ECX_NOHT ) - cpu->caphyperthreading = 0; - if( ecx & CAP801_ECX_LZCNT ) - cpu->caplzcnt = 1; - if( ecx & CAP801_ECX_SSE4A ) - cpu->capsse4a = 1; - if( ecx & CAP801_ECX_MISALIGNSSE ) - cpu->capmisalignsse = 1; - if( ecx & CAP801_ECX_XOP ) - cpu->capxop = 1; - if( ecx & CAP801_ECX_FMA4 ) - cpu->capfma4 = 1; - if( ecx & CAP801_ECX_TBM ) - cpu->captbm = 1; - if( edx & CAP801_EDX_MMXEXT ) - cpu->capmmxext = 1; - if( edx & CAP801_EDX_RDTSCP ) - cpu->caprdtscp = 1; - if( edx & CAP801_EDX_LONGMODE ) - cpu->caplongmode = 1; - if( edx & CAP801_EDX_3DNOW ) - cpu->cap3dnow = 1; - if( edx & CAP801_EDX_3DNOWEXT ) - cpu->cap3dnowext = 1; - } - - if( ( cpu->amdlevel >= 0x80000007 ) && ( cpu->amdlevel <= 0x8000ffff ) ) - { - cpuCpuid( 0x80000001, 0, &eax, &ebx, &ecx, &edx ); - if( edx & CAP807_EDX_CONSTANTTSC ) - cpu->capconstanttsc = 1; - } - - return 1; -} - - -//// - - -static void cpuGetAmdModelName( cpuInfo *cpu ) -{ - uint32_t *id; - char *c; - - if( cpu->amdlevel >= 0x80000004 ) - { - id = (uint32_t *)cpu->identifier; - cpuCpuid( 0x80000002, 0, &id[0], &id[1], &id[2], &id[3] ); - cpuCpuid( 0x80000003, 0, &id[4], &id[5], &id[6], &id[7] ); - cpuCpuid( 0x80000004, 0, &id[8], &id[9], &id[10], &id[11] ); - cpu->identifier[48] = 0; - for( c = cpu->identifier ; *c == ' ' ; c++ ); - if( c != cpu->identifier ) - memmove( cpu->identifier, c, strlen(c)+1 ); - } - - return; -} - - -static void cpuGetCacheOld( cpuInfo *cpu ) -{ - uint32_t eax, ebx, ecx, edx; - static const int cacheways[0x10] = - { - [0x0] = 0, - [0x1] = 1, - [0x2] = 2, - [0x3] = 3, /* ??? */ - [0x4] = 4, - [0x5] = 6, /* ??? */ - [0x6] = 8, - [0x7] = 12, /* ??? */ - [0x8] = 16, - [0x9] = 24, /* ??? */ - [0xa] = 32, - [0xb] = 48, - [0xc] = 64, - [0xd] = 96, - [0xe] = 128, - [0xf] = 256 - }; - - if( ( cpu->amdlevel >= 0x80000005 ) && ( ( cpu->cachesizeL1code == -1 ) || ( cpu->cachesizeL1data == -1 ) ) ) - { - cpuCpuid( 0x80000005, 0, &eax, &ebx, &ecx, &edx ); - if( ( ecx | edx ) ) - { - cpu->cachesizeL1code = edx >> 24; - cpu->cachelineL1code = edx & 0xff; - cpu->cacheassociativityL1code = ( edx >> 8 ) & 0xff; - cpu->cachesizeL1data = ecx >> 24; - cpu->cachelineL1data = ecx & 0xff; - cpu->cacheassociativityL1data = ( ecx >> 8 ) & 0xff; - } - } - if( ( cpu->amdlevel >= 0x80000006 ) && ( ( cpu->cachesizeL2 == -1 ) || ( cpu->cachesizeL3 == -1 ) ) ) - { - cpuCpuid( 0x80000006, 0, &eax, &ebx, &ecx, &edx ); - if( ( ecx | edx ) ) - { - cpu->cachesizeL2 = ecx >> 16; - cpu->cachelineL2 = ecx & 0xff; - cpu->cacheassociativityL2 = cacheways[ ( ecx >> 12 ) & 0xf ]; - cpu->cachesizeL3 = ( edx >> 18 ) * 512; - cpu->cachelineL3 = edx & 0xff; - cpu->cacheassociativityL3 = cacheways[ ( edx >> 12 ) & 0xf ]; - } - } - - return; -} - - -static void cpuGetCores( cpuInfo *cpu ) -{ - uint32_t eax, ebx, ecx, edx; - - if( cpu->vendor == CPUINFO_VENDOR_INTEL ) - { - if( cpu->intellevel >= 0x00000004 ) - { - cpuCpuid( 0x00000004, 0, &eax, &ebx, &ecx, &edx ); - if( eax & 0x1f ) - cpu->socketphysicalcores = ( ( eax >> 26 ) & 0x3f ) + 1; - if( cpu->socketphysicalcores == cpu->socketlogicalcores ) - cpu->caphyperthreading = 0; - } - } - - if( cpu->vendor == CPUINFO_VENDOR_AMD ) - { - if( cpu->amdlevel >= 0x80000008 ) - { - cpuCpuid( 0x80000008, 0, &eax, &ebx, &ecx, &edx ); - cpu->socketphysicalcores = ( ecx & 0xff ) + 1; - } - } - - return; -} - - -static void cpuGetCacheNew( cpuInfo *cpu ) -{ - uint32_t cpuidindex; - uint32_t eax, ebx, ecx, edx, queryindex; - uint32_t cachetype, cachelevel, cacheline, cacheassociativity, cachepartitions, cachesets, cachesize, cacheshared; - - cpuidindex = 0; - if( cpu->vendor == CPUINFO_VENDOR_INTEL ) - { - if( cpu->intellevel >= 4 ) - cpuidindex = 0x00000004; - } - else if( cpu->vendor == CPUINFO_VENDOR_AMD ) - { - if( cpu->amdlevel >= 0x8000001d ) - cpuidindex = 0x8000001d; - } - else - { - if( cpu->intellevel >= 4 ) - cpuidindex = 0x00000004; - } - - if( cpuidindex ) - { - for( queryindex = 0 ; queryindex < 0x10 ; queryindex++ ) - { - cpuCpuid( cpuidindex, queryindex, &eax, &ebx, &ecx, &edx ); - cachetype = eax & 0x1f; - if( !( cachetype ) ) - break; - cachelevel = ( eax >> 5 ) & 0x7; - cacheline = ( ebx & 0x0fff ) + 1; - cachepartitions = ( ( ebx >> 12 ) & 0x03ff ) + 1; - cacheassociativity = ( ( ebx >> 22 ) & 0x03ff ) + 1; - cachesets = ecx + 1; - cachesize = ( cacheassociativity * cachepartitions * cacheline * cachesets ) / 1024; - cacheshared = ( ( eax >> 14 ) & 0xfff ) + 1; - switch( cachelevel ) - { - case 1: - if( cachetype & 0x1 ) - { - cpu->cachesizeL1data = cachesize; - cpu->cachelineL1data = cacheline; - cpu->cacheassociativityL1data = cacheassociativity; - cpu->cachesharedL1data = cacheshared; - } - if( cachetype & 0x2 ) - { - cpu->cachesizeL1code = cachesize; - cpu->cachelineL1code = cacheline; - cpu->cacheassociativityL1code = cacheassociativity; - cpu->cachesharedL1code = cacheshared; - } - if( cachetype == 0x3 ) - cpu->cacheunifiedL1 = 1; - break; - case 2: - cpu->cachesizeL2 = cachesize; - cpu->cachelineL2 = cacheline; - cpu->cacheassociativityL2 = cacheassociativity; - cpu->cachesharedL2 = cacheshared; - break; - case 3: - cpu->cachesizeL3 = cachesize; - cpu->cachelineL3 = cacheline; - cpu->cacheassociativityL3 = cacheassociativity; - cpu->cachesharedL3 = cacheshared; - break; - } - } - } - - return; -} - - -#endif - - -static void cpuGetCpuCount( cpuInfo *cpu ) -{ -#if defined(ENV_OS_LINUX) - cpu->totalcorecount = get_nprocs(); -#elif defined(ENV_OS_WINDOWS) - SYSTEM_INFO si; - GetSystemInfo( &si ); - cpu->totalcorecount = si.dwNumberOfProcessors; -#elif defined(ENV_OS_UNIX) - cpu->totalcorecount = sysconf( _SC_NPROCESSORS_CONF ); -#endif - if( cpu->socketlogicalcores ) - cpu->socketcount = cpu->totalcorecount / cpu->socketlogicalcores; - return; -} - - -static void cpuGetSystemMemory( cpuInfo *cpu ) -{ -#ifdef ENV_OS_UNIX - int64_t pages; - pages = sysconf( _SC_PHYS_PAGES ); - if( pages < 0 ) - return; - cpu->sysmemory = pages * (uint64_t)sysconf( _SC_PAGESIZE ); - if( cpu->sysmemory < 0 ) - cpu->sysmemory = 0; -#endif - return; -} - - -static void cpuGetClass( cpuInfo *cpu ) -{ - if( cpu->class != CPUINFO_CLASS_UNKNOWN ) - return; - if( cpu->vendor == CPUINFO_VENDOR_AMD ) - { - if( cpu->family == 0xf+0x7 ) - cpu->class = CPUINFO_CLASS_JAGUAR; - else if( cpu->family == 0xf+0x5 ) - cpu->class = CPUINFO_CLASS_BOBCAT; - else if( cpu->capbmi ) - { - /* - * TODO: I have NO IDEA how to detect a steamroller CPU, I checked every AMD resources I could find. - * Okay, maybe I should wait for the chip to come out first. - */ - if( 0 ) - cpu->class = CPUINFO_CLASS_STEAMROLLER; - else - cpu->class = CPUINFO_CLASS_PILEDRIVER; - } - else if( cpu->capfma4 ) - cpu->class = CPUINFO_CLASS_BULLDOZER; - else if( cpu->capsse4a ) - cpu->class = CPUINFO_CLASS_BARCELONA; - else if( cpu->capsse3 ) - cpu->class = CPUINFO_CLASS_ATHLON64SSE3; - else if( cpu->capsse2 ) - cpu->class = CPUINFO_CLASS_ATHLON64; - else if( cpu->capsse ) - cpu->class = CPUINFO_CLASS_ATHLON; - else if( cpu->cap3dnow ) - cpu->class = CPUINFO_CLASS_K6_2; - else if( cpu->capmmx ) - cpu->class = CPUINFO_CLASS_K6; - else if( cpu->family >= 0x5 ) - cpu->class = CPUINFO_CLASS_I586; - } - else if( cpu->vendor == CPUINFO_VENDOR_INTEL ) - { - if( cpu->caplongmode ) - { - if( cpu->capavx2 ) - cpu->class = CPUINFO_CLASS_COREI7AVX2; - else if( cpu->capavx ) - cpu->class = CPUINFO_CLASS_COREI7AVX; - else if( cpu->capsse4p2 ) - cpu->class = CPUINFO_CLASS_COREI7; - else if( cpu->capssse3 ) - cpu->class = CPUINFO_CLASS_CORE2; - else - cpu->class = CPUINFO_CLASS_NOCONA; - } - else if( cpu->family >= 0x6 ) - { - if( cpu->capsse3 ) - cpu->class = CPUINFO_CLASS_PRESCOTT; - else if( cpu->capsse2 ) - cpu->class = CPUINFO_CLASS_PENTIUM4; - else if( cpu->capsse ) - cpu->class = CPUINFO_CLASS_PENTIUM3; - else - cpu->class = CPUINFO_CLASS_PENTIUM2; - } - else if( cpu->family >= 0x5 ) - cpu->class = CPUINFO_CLASS_I586; - } - else - { - if( cpu->arch == CPUINFO_ARCH_AMD64 ) - cpu->class = CPUINFO_CLASS_AMD64GENERIC; - else if( cpu->arch == CPUINFO_ARCH_IA32 ) - cpu->class = CPUINFO_CLASS_IA32GENERIC; - else - cpu->class = CPUINFO_CLASS_UNKNOWN; - } - return; -} - - -typedef struct -{ - int32_t l1i; - int32_t l1d; - int32_t l2; - int32_t l3; -} cpuClassCache; - -/* -A table of per-class cache sizes, if they are not already known. -We pretty much have to vaguely guess the cache sizes down here... -*/ -static cpuClassCache cpuClassCacheTable[CPUINFO_CLASS_COUNT] = -{ - [CPUINFO_CLASS_STEAMROLLER] = { 64, 64, 2048, 8192 }, - [CPUINFO_CLASS_JAGUAR] = { 32, 32, 2048, 0 }, - [CPUINFO_CLASS_PILEDRIVER] = { 64, 64, 2048, 8192 }, - [CPUINFO_CLASS_BULLDOZER] = { 64, 64, 2048, 8192 }, - [CPUINFO_CLASS_BOBCAT] = { 32, 32, 1024, 0 }, - [CPUINFO_CLASS_BARCELONA] = { 64, 64, 2048, 0 }, - [CPUINFO_CLASS_ATHLON64SSE3] = { 64, 64, 1024, 0 }, - [CPUINFO_CLASS_ATHLON64] = { 64, 64, 1024, 0 }, - [CPUINFO_CLASS_ATHLON] = { 32, 32, 512, 0 }, - [CPUINFO_CLASS_K6_2] = { 8, 8, 256, 0 }, - [CPUINFO_CLASS_K6] = { 8, 8, 256, 0 }, - - [CPUINFO_CLASS_COREI7AVX2] = { 32, 32, 256, 8192 }, - [CPUINFO_CLASS_COREI7AVX] = { 32, 32, 256, 8192 }, - [CPUINFO_CLASS_COREI7] = { 32, 32, 256, 8192 }, - [CPUINFO_CLASS_CORE2] = { 32, 32, 4096, 0 }, - [CPUINFO_CLASS_NOCONA] = { 64, 8, 2048, 0 }, - [CPUINFO_CLASS_PRESCOTT] = { 64, 8, 1024, 0 }, - [CPUINFO_CLASS_PENTIUM4] = { 64, 8, 512, 0 }, - [CPUINFO_CLASS_PENTIUM3] = { 16, 16, 256, 0 }, - [CPUINFO_CLASS_PENTIUM2] = { 16, 16, 256, 0 }, - - [CPUINFO_CLASS_I686] = { 8, 8, 256, 0 }, - [CPUINFO_CLASS_I586] = { 8, 8, 128, 0 }, - - [CPUINFO_CLASS_AMD64GENERIC] = { 64, 64, 512, 0 }, - [CPUINFO_CLASS_IA32GENERIC] = { 8, 8, 128, 0 }, - [CPUINFO_CLASS_UNKNOWN] = { 0, 0, 0, 0 } -}; - -static void cpuGuessCaches( cpuInfo *cpu ) -{ - int32_t cacheline; - cpuClassCache *cache; - - cache = &cpuClassCacheTable[ cpu->class ]; - cacheline = cpu->cacheline; - if( cpu->cachesizeL1code < 0 ) - { - cpu->cachesizeL1code = cache->l1i; - if( cpu->cachesizeL1code ) - cpu->cachelineL1code = cacheline; - } - if( cpu->cachesizeL1data < 0 ) - { - cpu->cachesizeL1data = cache->l1d; - if( cpu->cachesizeL1data ) - cpu->cachelineL1data = cacheline; - } - if( cpu->cachesizeL2 < 0 ) - { - cpu->cachesizeL2 = cache->l2; - if( cpu->cachesizeL2 ) - cpu->cachelineL2 = cacheline; - } - if( cpu->cachesizeL3 < 0 ) - { - cpu->cachesizeL3 = cache->l3; - if( cpu->cachesizeL3 ) - cpu->cachelineL3 = cacheline; - } - - return; -} - - -/* A last pass to apply erratas */ -static void cpuApplyLastFixes( cpuInfo *cpu ) -{ -/* - if( ( cpu->class == CPUINFO_CLASS_PENTIUM4 ) && ( cpu->cacheline == 64 ) ) - cpu->cacheload = 128; -*/ - if( ( ( cpu->family == 0xf ) && ( cpu->model >= 0x03 ) ) || ( ( cpu->family == 0x6 ) && ( cpu->model >= 0x0e ) ) ) - cpu->capconstanttsc = 1; - return; -} - - -//// - - -static void cpuGetEnv( cpuInfo *cpu ) -{ - /* Default cache line */ - cpu->cacheline = 64; - cpu->clflushsize = 64; -#if defined(__tune_bdver3__) - sprintf( cpu->identifier, "AMD Steamroller Class CPU" ); - cpu->class = CPUINFO_CLASS_STEAMROLLER; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capsse4a = 1; - cpu->capsse4p1 = 1; - cpu->capsse4p2 = 1; - cpu->capfma4 = 1; - cpu->capxop = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->capaes = 1; - cpu->capf16c = 1; - cpu->capcmpxchg16b = 1; - cpu->caplongmode = 1; -#elif defined(__tune_bdver2__) - sprintf( cpu->identifier, "AMD Piledriver Class CPU" ); - cpu->class = CPUINFO_CLASS_PILEDRIVER; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capsse4a = 1; - cpu->capsse4p1 = 1; - cpu->capsse4p2 = 1; - cpu->capfma4 = 1; - cpu->capxop = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->capaes = 1; - cpu->capf16c = 1; - cpu->capcmpxchg16b = 1; - cpu->caplongmode = 1; -#elif defined(__tune_bdver1__) - sprintf( cpu->identifier, "AMD Bulldozer Class CPU" ); - cpu->class = CPUINFO_CLASS_BULLDOZER; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capsse4a = 1; - cpu->capsse4p1 = 1; - cpu->capsse4p2 = 1; - cpu->capfma4 = 1; - cpu->capxop = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->capaes = 1; - cpu->capf16c = 1; - cpu->capcmpxchg16b = 1; - cpu->caplongmode = 1; -#elif defined(__tune_btver2__) - sprintf( cpu->identifier, "AMD Jaguar Class CPU" ); - cpu->class = CPUINFO_CLASS_JAGUAR; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capssse3 = 1; - cpu->capsse4a = 1; - cpu->capsse4p1 = 1; - cpu->capsse4p2 = 1; - cpu->capfma4 = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->capaes = 1; - cpu->capf16c = 1; - cpu->capcmpxchg16b = 1; - cpu->caplongmode = 1; -#elif defined(__tune_btver1__) - sprintf( cpu->identifier, "AMD Bobcat Class CPU" ); - cpu->class = CPUINFO_CLASS_BOBCAT; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capssse3 = 1; - cpu->capsse4a = 1; - cpu->capfma4 = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->capaes = 1; - cpu->capcmpxchg16b = 1; - cpu->caplongmode = 1; -#elif defined(__tune_amdfam10__) - sprintf( cpu->identifier, "AMD Barcelona Class CPU" ); - cpu->class = CPUINFO_CLASS_BARCELONA; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capssse3 = 1; - cpu->capsse4a = 1; - cpu->caplzcnt = 1; - cpu->cappopcnt = 1; - cpu->caplongmode = 1; -#elif defined(__tune_k8__) - sprintf( cpu->identifier, "AMD Athlon64 Class CPU" ); - cpu->class = CPUINFO_CLASS_ATHLON64; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->caplongmode = 1; - #if __SSE3__ - cpu->class = CPUINFO_CLASS_ATHLON64SSE3; - cpu->capsse3 = 1; - #endif -#elif defined(__tune_athlon__) - sprintf( cpu->identifier, "AMD Athlon Class CPU" ); - cpu->class = CPUINFO_CLASS_ATHLON; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capmmxext = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->cap3dnow = 1; - cpu->cap3dnowext = 1; -#elif defined(__tune_k6__) - sprintf( cpu->identifier, "AMD K6 Class CPU" ); - cpu->class = CPUINFO_CLASS_K6; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->cap3dnow = 1; - cpu->cacheline = 32; - cpu->clflushsize = 32; -#elif defined(__tune_corei7__) - sprintf( cpu->identifier, "Core i7 Class CPU" ); - cpu->class = CPUINFO_CLASS_COREI7; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capssse3 = 1; - cpu->capsse4a = 1; - cpu->capsse4p1 = 1; - cpu->capsse4p2 = 1; - cpu->caplongmode = 1; - #if __AVX__ - cpu->class = CPUINFO_CLASS_COREI7AVX; - cpu->capavx = 1; - #endif - #if __AVX2__ - cpu->class = CPUINFO_CLASS_COREI7AVX2; - cpu->capavx2 = 1; - cpu->capbmi = 1; - cpu->capbmi2 = 1; - #endif -#elif defined(__tune_core2__) - sprintf( cpu->identifier, "Core2 Class CPU" ); - cpu->class = CPUINFO_CLASS_CORE2; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->capssse3 = 1; - cpu->caplongmode = 1; -#elif defined(__tune_nocona__) - sprintf( cpu->identifier, "Nocona Class CPU" ); - cpu->class = CPUINFO_CLASS_NOCONA; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->capsse3 = 1; - cpu->caplongmode = 1; -#elif defined(__tune_pentium4__) - sprintf( cpu->identifier, "Intel Pentium 4 Class CPU" ); - cpu->class = CPUINFO_CLASS_PENTIUM4; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->caphyperthreading = 1; -#elif defined(__tune_pentium3__) - sprintf( cpu->identifier, "Intel Pentium III Class CPU" ); - cpu->class = CPUINFO_CLASS_PENTIUM3; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->cacheline = 32; - cpu->clflushsize = 32; -#elif defined(__tune_i686__) || defined(__tune_pentium2__) - sprintf( cpu->identifier, "Intel Pentium II Class CPU" ); - cpu->class = CPUINFO_CLASS_I686; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->cacheline = 32; - cpu->clflushsize = 32; -#elif defined(__tune_i586__) - sprintf( cpu->identifier, "Intel Pentium Class CPU" ); - cpu->class = CPUINFO_CLASS_I586; - cpu->capcmov = 1; - cpu->cacheline = 32; - cpu->clflushsize = 32; -#else - if( cpu->arch == CPUINFO_ARCH_AMD64 ) - { - cpu->class = CPUINFO_CLASS_AMD64GENERIC; - cpu->capcmov = 1; - cpu->capmmx = 1; - cpu->capsse = 1; - cpu->capsse2 = 1; - cpu->caplongmode = 1; - } - else if( cpu->arch == CPUINFO_ARCH_IA32 ) - cpu->class = CPUINFO_CLASS_IA32GENERIC; - else - cpu->class = CPUINFO_CLASS_UNKNOWN; -#endif - -#if __MMX__ - cpu->capmmx = 1; -#endif -#if __3dNOW__ - cpu->cap3dnow = 1; -#endif -#if __3dNOW_A__ - cpu->cap3dnowext = 1; -#endif -#if __SSE__ - cpu->capsse = 1; -#endif -#if __SSE2__ - cpu->capsse2 = 1; -#endif -#if __SSE3__ - cpu->capsse3 = 1; -#endif -#if __SSSE3__ - cpu->capssse3 = 1; -#endif -#if __SSE4_1__ - cpu->capsse4p1 = 1; -#endif -#if __SSE4_2__ - cpu->capsse4p2 = 1; -#endif -#if __AVX__ - cpu->capavx = 1; -#endif -#if __AVX2__ - cpu->capavx2 = 1; -#endif -#if __XOP__ - cpu->capxop = 1; -#endif -#if __FMA__ - cpu->capfma3 = 1; -#endif -#if __FMA4__ - cpu->capfma4 = 1; -#endif -#if __POPCNT__ - cpu->cappopcnt = 1; -#endif -#if __LZCNT__ - cpu->caplzcnt = 1; -#endif -#if __AES__ - cpu->capaes = 1; -#endif -#if __F16C__ - cpu->capf16c = 1; -#endif -#if __PCLMUL__ - cpu->cappclmul = 1; -#endif -#if __RDRAND__ - cpu->caprdrnd = 1; -#endif -#if __BMI__ - cpu->capbmi = 1; -#endif -#if __BMI2__ - cpu->capbmi2 = 1; -#endif -#if __TBM__ - cpu->captbm = 1; -#endif - - return; -} - - -//// - - -void cpuGetInfo( cpuInfo *cpu ) -{ - cpuInitInfo( cpu ); - cpuGetEndian( cpu ); -#if defined(ENV_ARCH_IA32) || defined(ENV_ARCH_AMD64) - cpuGetGeneral( cpu ); - cpuGetAmdModelName( cpu ); - cpuGetCores( cpu ); - cpuGetCacheNew( cpu ); - cpuGetCacheOld( cpu ); - cpuGetCpuCount( cpu ); - cpuGetSystemMemory( cpu ); -#endif - cpuGetClass( cpu ); - cpuGuessCaches( cpu ); - cpuApplyLastFixes( cpu ); - return; -} - - - -void cpuGetInfoEnv( cpuInfo *cpu ) -{ - cpuInitInfo( cpu ); - cpuGetEndian( cpu ); - cpuGetEnv( cpu ); - cpuGetClass( cpu ); - cpuGuessCaches( cpu ); - cpuApplyLastFixes( cpu ); - return; -} - - - diff --git a/src/other/gct/Auxiliary/cpuinfo.h b/src/other/gct/Auxiliary/cpuinfo.h deleted file mode 100644 index f3a806499bf..00000000000 --- a/src/other/gct/Auxiliary/cpuinfo.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#ifndef CPUINFO_H -#define CPUINFO_H - - -typedef struct -{ - uint32_t endianness; - uint32_t intellevel; - uint32_t amdlevel; - - uint32_t arch; - char vendorstring[12+1]; - char identifier[48+1]; - - uint32_t vendor; - uint32_t class; - uint32_t family; - uint32_t model; - uint32_t cacheline; - uint32_t clflushsize; - - int32_t cachelineL1code, cachesizeL1code, cacheassociativityL1code, cachesharedL1code; - int32_t cachelineL1data, cachesizeL1data, cacheassociativityL1data, cachesharedL1data; - int32_t cacheunifiedL1; - int32_t cachelineL2, cachesizeL2, cacheassociativityL2, cachesharedL2; - int32_t cachelineL3, cachesizeL3, cacheassociativityL3, cachesharedL3; - - int64_t sysmemory; - uint32_t socketphysicalcores; - uint32_t socketlogicalcores; - uint32_t socketcount; - uint32_t totalcorecount; - uint32_t wordsize; - uint32_t gpregs; - uint32_t fpregs; - - - /* CPU capabilities */ - int capcmov:1; - int capclflush:1; - int captsc:1; - int capmmx:1; - int capmmxext:1; - int cap3dnow:1; - int cap3dnowext:1; - int capsse:1; - int capsse2:1; - int capsse3:1; - int capssse3:1; - int capsse4p1:1; - int capsse4p2:1; - int capsse4a:1; - int capavx:1; - int capavx2:1; - int capxop:1; - int capfma3:1; - int capfma4:1; - int capmisalignsse:1; - int capaes:1; - int cappclmul; - int caprdrnd:1; - int capcmpxchg16b:1; - int cappopcnt:1; - int caplzcnt:1; - int capmovbe:1; - int caprdtscp:1; - int capconstanttsc:1; - int capf16c:1; - int capbmi:1; - int capbmi2:1; - int captbm:1; - int caphyperthreading:1; - int capmwait:1; - int caplongmode:1; - int capthermalsensor:1; - int capclockmodulation:1; - /* CPU capabilities */ - -} cpuInfo; - - -void cpuGetInfo( cpuInfo *cpu ); - -void cpuGetInfoEnv( cpuInfo *cpu ); - - -//// - - -enum -{ - CPUINFO_LITTLE_ENDIAN, - CPUINFO_BIG_ENDIAN, - CPUINFO_MIXED_ENDIAN -}; - - -enum -{ - CPUINFO_ARCH_AMD64, - CPUINFO_ARCH_IA32, - CPUINFO_ARCH_UNKNOWN -}; - - -enum -{ - CPUINFO_VENDOR_AMD, - CPUINFO_VENDOR_INTEL, - CPUINFO_VENDOR_UNKNOWN -}; - - -enum -{ - CPUINFO_CLASS_STEAMROLLER, - CPUINFO_CLASS_JAGUAR, - CPUINFO_CLASS_PILEDRIVER, - CPUINFO_CLASS_BULLDOZER, - CPUINFO_CLASS_BOBCAT, - CPUINFO_CLASS_BARCELONA, - CPUINFO_CLASS_ATHLON64SSE3, - CPUINFO_CLASS_ATHLON64, - CPUINFO_CLASS_ATHLON, - CPUINFO_CLASS_K6_2, - CPUINFO_CLASS_K6, - - CPUINFO_CLASS_COREI7AVX2, - CPUINFO_CLASS_COREI7AVX, - CPUINFO_CLASS_COREI7, - CPUINFO_CLASS_CORE2, - CPUINFO_CLASS_NOCONA, - CPUINFO_CLASS_PRESCOTT, - CPUINFO_CLASS_PENTIUM4, - CPUINFO_CLASS_PENTIUM3, - CPUINFO_CLASS_PENTIUM2, - - CPUINFO_CLASS_I686, - CPUINFO_CLASS_I586, - - CPUINFO_CLASS_AMD64GENERIC, - CPUINFO_CLASS_IA32GENERIC, - CPUINFO_CLASS_UNKNOWN, - - CPUINFO_CLASS_COUNT -}; - - - -#endif /* CPUINFO_H */ - - diff --git a/src/other/gct/Auxiliary/gctcommon.h b/src/other/gct/Auxiliary/gctcommon.h deleted file mode 100644 index aef7caa2a91..00000000000 --- a/src/other/gct/Auxiliary/gctcommon.h +++ /dev/null @@ -1,601 +0,0 @@ -/* gctcommon.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 10/03/13 - * - * Authors(s): - * DRH - * - * Description: - * Any common use functions between all the tools. - * - */ - -#ifndef GCTCOMMON_H -#define GCTCOMMON_H - -/* Standard C/C++ libraries */ -#include -#include -#include -#include -#include -#ifndef COMPILE_FOR_VSL -#include -#include -#endif - -/* Pthread libraries */ -#include -#if defined (_GNU_SOURCE) -#include -#endif - -#ifndef COMPILE_FOR_VSL -extern "C" { -#include "common.h" -#include "bu.h" -#include "vmath.h" -#include "bn.h" -#include "raytrace.h" -#include "rt/geom.h" -#include "wdb.h" -} -#endif - -#ifndef SQ -#define SQ(a) (a)*(a) -#endif - -/* Stuff defined in BRL-CAD but might not be for others */ -#ifndef X -#define X 0 -#endif -#ifndef Y -#define Y 1 -#endif -#ifndef Z -#define Z 2 -#endif - -#ifndef VINIT -#define VINIT(a,s) (a)[X] = (a)[Y] = (a)[Z] = (s) -#endif - -#ifndef VSET -#define VSET(a,b,c,d) { \ - (a)[X] = (b); \ - (a)[Y] = (c); \ - (a)[Z] = (d); } -#endif - -#ifndef VADD2 -#define VADD2(a, b, c) { \ - (a)[X] = (b)[X] + (c)[X]; \ - (a)[Y] = (b)[Y] + (c)[Y]; \ - (a)[Z] = (b)[Z] + (c)[Z]; \ -} -#endif - -#ifndef VEQUAL -#define VEQUAL(a, b) ((a)[X]==(b)[X] && (a)[Y]==(b)[Y] && (a)[Z]==(b)[Z]) -#endif - -#ifndef VMOVE -#define VMOVE(a, b) { \ - (a)[X] = (b)[X]; \ - (a)[Y] = (b)[Y]; \ - (a)[Z] = (b)[Z]; \ -} -#endif - -#ifndef VSCALE -#define VSCALE(a, b, c) { \ - (a)[X] = (b)[X] * (c); \ - (a)[Y] = (b)[Y] * (c); \ - (a)[Z] = (b)[Z] * (c); \ -} -#endif - -#ifndef VSUB2 -#define VSUB2(a, b, c) { \ - (a)[X] = (b)[X] - (c)[X]; \ - (a)[Y] = (b)[Y] - (c)[Y]; \ - (a)[Z] = (b)[Z] - (c)[Z]; \ -} -#endif - -#ifndef VCROSS -#define VCROSS(a,b,c) { \ - (a)[X] = (b)[Y] * (c)[Z] - (b)[Z] * (c)[Y]; \ - (a)[Y] = (b)[Z] * (c)[X] - (b)[X] * (c)[Z]; \ - (a)[Z] = (b)[X] * (c)[Y] - (b)[Y] * (c)[X]; } -#endif - -#ifndef VMAGSQ -#define VMAGSQ(a) (SQ((a)[X]) + SQ((a)[Y]) + SQ((a)[Z])) -#endif - -#ifndef VMAG -#define VMAG(a) sqrt(VMAGSQ(a)) -#endif - -#ifndef VUNITIZE -#define VUNITIZE(a) { \ - register double _f = VMAGSQ(a); \ - _f = sqrt(_f); \ - if (!VM_NEAR(_f, 1.0, VM_UNITIZE_TOL)) { \ - if (_f < VM_DIVIDE_TOL) { \ - VINIT((a), 0.0); \ - } else { \ - _f = 1.0/_f; \ - (a)[X] *= _f; \ - (a)[Y] *= _f; \ - (a)[Z] *= _f; \ - } \ - }\ - } -#endif - -#ifndef VM_NEAR -#define VM_NEAR(v1,v2,tol) ((((v2) - (tol)) <= (v1)) && ((v1) <= ((v2) + (tol)))) -#endif - -#ifndef VM_DIVIDE_TOL -#define VM_DIVIDE_TOL (1.0e-20) -#endif - -#ifndef VM_UNITIZE_TOL -#define VM_UNITIZE_TOL (1.0e-15) -#endif - -#ifndef DIST_PT_PT_SQ -#define DIST_PT_PT_SQ(_a,_b) \ - SQ((_a)[X] - (_b)[X]) + \ - SQ((_a)[Y] - (_b)[Y]) + \ - SQ((_a)[Z] - (_b)[Z]) -#endif - -#ifndef DIST_PT_PT -#define DIST_PT_PT(_a,_b) sqrt(DIST_PT_PT_SQ(_a, _b)) -#endif - -//****************************************************************************** -// NAME ideal_thread_count -// -// INPUTS -// none -// -// DESCRIPTION -// Determine the ideal number of threads to create for multithreading -// applications, based on what is available on the target system. -//****************************************************************************** -static inline -unsigned ideal_thread_count() -{ - int count = 0; -#if defined(PTW32_VERSION) || defined(__hpux) - count = pthread_num_processors_np(); -#elif defined(__APPLE__) || defined(__FreeBSD__) - size_t size=sizeof(count); - count = (sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count); -#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) - count = sysconf(_SC_NPROCESSORS_ONLN); -#elif defined(_GNU_SOURCE) - count = get_nprocs(); -#elif defined(WIN32) - SYSTEM_INFO info={{0}}; - GetSystemInfo(&info); - count = info.dwNumberOfProcessors; -#endif - return (unsigned) (count>0)?count:1; -} - -#ifndef COMPILE_FOR_VSL -//****************************************************************************** -// NAME output_obj -// -// INPUTS -// fp - file pointer to write -// vertex - list of vertices -// normal - list of normals -// indices - list of indices that make up triangles -// gnames - list of geometry names -// offsets - list of offsets between geometry items -// -// DESCRIPTION -// Runs the given lists and creates an OBJ file that holds all the data. -//****************************************************************************** -static inline -void output_obj (FILE *fp, - std::vector &vertex, - std::vector &normal, - std::vector &indices, - std::vector &gnames, - std::vector &offsets) -{ - long i; - - /* output vertices */ - fprintf (fp, "g\n"); - for (i = 0; i < (long)vertex.size(); i += 3) - fprintf (fp, "v %.4f %.4f %.4f\n", - vertex[i], vertex[i+1], vertex[i+2]); - fprintf (fp, "\n# %d vertices\n", (int)vertex.size()/3); - - fprintf (fp, "\n# 0 vertex parms\n"); - fprintf (fp, "\n# 0 texture vertices\n"); - fprintf (fp, "\n"); - - /* output normals */ - fprintf (fp, "g\n"); - for (i = 0; i < (long)normal.size(); i += 3) - fprintf (fp, "vn %.4f %.4f %.4f\n", - normal[i], normal[i+1], normal[i+2]); - fprintf (fp, "\n# %d normals\n", (int)normal.size()/3); - fprintf (fp, "\n"); - - /* out geometries */ - for (i = 0; i < (long)gnames.size(); i++) - { - fprintf (fp, "g %s\n", gnames.at(i).c_str()); - fprintf (fp, "s off\n"); - - long end = (long)indices.size(); - if (i < ((long)gnames.size() -1)) - end = offsets[i+1]; - - /* add 1 to everything because OBJ indices are 1 based, not 0 */ - for (long j = offsets[i]; j < end; j += 3) - fprintf (fp, "f %ld//%ld %ld//%ld %ld//%ld\n", - (indices[j+0] +1), (indices[j+0] +1), - (indices[j+1] +1), (indices[j+1] +1), - (indices[j+2] +1), (indices[j+2] +1)); - fprintf (fp, "\n# %ld facets\n", end - offsets[i]); - } - fprintf (fp, "\n# %d elements\n", (int)gnames.size()); -} - -//****************************************************************************** -// NAME output_brlcad -// -// INPUTS -// ofile - BRL-CAD database file name -// vertex - list of vertices -// normal - list of normals -// indices - list of indices that make up triangles -// gnames - list of geometry names -// offsets - list of offsets between geometry items -// -// DESCRIPTION -// Runs the given lists and creates a BRLCAD database that holds all the data. -//****************************************************************************** -static inline -void output_brlcad (char *ofile, - std::vector &vertex, - std::vector &normal, - std::vector &indices, - std::vector &gnames, - std::vector &offsets) -{ - struct rt_wdb *db_fp; - struct wmember wm_hd; /* defined in wdb.h */ - long i; - unsigned char rgb[3]; /* region color (red) */ - - if ((db_fp = wdb_fopen(ofile)) == NULL) - { - perror(ofile); - return; - } - - VSET(rgb, 255, 0, 0); - mk_id(db_fp, ofile); /* create the database header record */ - - /* assume everything is in mm at this point */ - - /* output components (i.e. Primitives/Regions pairs) */ - for (i = 0; i < (long)gnames.size(); i++) - { - char name[255]; - fastf_t *vertices = NULL; - fastf_t *normals = NULL; - int *faces = NULL; - int nverts = 0, nnrmls = 0, nfaces = 0; - - std::string gname = gnames.at(i).c_str(); - std::size_t pos = gname.find("."); - - /* remove '.r', if it exists */ - if (pos != std::string::npos) - gname = gname.substr(0, pos); - - memset (name, 0, sizeof (char) * 255); - sprintf (name, "%s.s", gname.c_str()); - - long end = (long)indices.size(); - if (i < ((long)gnames.size() -1)) - end = offsets[i+1]; - - /* allocate array to hold face combinations */ - nfaces = (int) (end - offsets[i]); - faces = (int *) malloc (sizeof (int) * nfaces); - memset (faces, 0, sizeof (int) * nfaces); - - /* vector to tell if index is already added to vert/nrml lists */ - std::vector already; - - /* add vertices, normals, and indices */ - for (long j = offsets[i]; j < end; j++) - { - long index = indices[j]; - long myidx = j - offsets[i]; - - if (std::find(already.begin(), - already.end(), index) == already.end()) - { - vertices = (fastf_t*) realloc ((void *) vertices, sizeof(fastf_t) * (nverts + 3)); - normals = (fastf_t*) realloc ((void *) normals, sizeof(fastf_t) * (nnrmls + 3)); - - vertices[nverts] = vertex[index*3+0]; ++nverts; - vertices[nverts] = vertex[index*3+1]; ++nverts; - vertices[nverts] = vertex[index*3+2]; ++nverts; - - normals[nnrmls] = normal[index*3+0]; ++nnrmls; - normals[nnrmls] = normal[index*3+1]; ++nnrmls; - normals[nnrmls] = normal[index*3+2]; ++nnrmls; - - already.push_back(index); - - faces[myidx] = (nverts / 3) -1; - } - else - { - for (long k = 0; k < (long)already.size(); k++) - if (already.at(k) == index) - { - faces[myidx] = k; - break; - } - } - } - - already.clear(); - - /* make a BOT primitive */ - mk_bot_w_normals(db_fp, name, RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, - (nverts / 3), (nfaces / 3), vertices, faces, - (fastf_t *)NULL, (struct bu_bitv *)NULL, - (nnrmls / 3), normals, faces); - - /* Make a region that is the union of this one BOT object. - * To accomplish this, we need to create a linked list of items - * that make up the combination. The wm_hd structure serves as - * the head of the list items. - */ - BU_LIST_INIT(&wm_hd.l); - - /* Create a wmember structure for the item that we want - * in the combination. The return from mk_addmember is a pointer - * to the wmember structure. - */ - (void)mk_addmember(name, &wm_hd.l, NULL, WMOP_UNION); - - /* Create the combination. In this case we are going to make it - * a region, hence the is_region flag is set, and we provide shader - * parameter information. - */ - memset (name, 0, sizeof (char) * 255); - sprintf (name, "%s.r", gname.c_str()); - mk_lcomb(db_fp, - name, /* name of db region */ - &wm_hd, /* list of elements & boolean operations */ - 1, /* is_region flag */ - "plastic", /* optical shader (just guessed) */ - "di=.8 sp=.2", /* shader params (again guessing) */ - rgb, /* item color */ - 0); /* inherit (override) flag */ - - if (vertices) free (vertices); - if (normals) free (normals); - if (faces) free (faces); - } - - db_close(db_fp->dbip); -} - -//****************************************************************************** -// NAME output_fastgen -// -// INPUTS -// fp - file pointer to write -// vertex - list of vertices -// indices - list of indices that make up triangles -// gnames - list of geometry names -// offsets - list of offsets between geometry items -// modes - list of geometry modes -// materials - list of geometry materials -// thicknesses - list of geometry thicknesses -// positions - list of geometry positions -// -// DESCRIPTION -// Runs the given lists and creates a FASTGEN file that holds all the data. -//****************************************************************************** -static inline -void output_fastgen (FILE *fp, - std::vector &vertex, - std::vector &indices, - std::vector &gnames, - std::vector &offsets, - std::vector &modes, - std::vector &materials, - std::vector &thicknesses, - std::vector &positions) -{ - long i; - int cID = 0; - - /* output components (i.e. SECTIONs) */ - for (i = 0; i < (long)gnames.size(); i++) - { - std::string gname = gnames.at(i).c_str(); - std::size_t pos = gname.find("."); - - /* pick 1st comp ID as the one to use */ - if (pos != std::string::npos) - gname = gname.substr(0, pos); - - /* convert name to number */ - if (isdigit (gname.c_str()[0])) - cID = (int) atoi (gname.c_str()); - else cID++; - - /* print SECTION card */ - fprintf (fp, "%-8s%8d%8d%8d%8d\n", "SECTION", (cID / 1000), - (cID % 1000), modes.at(i), 1); - - long end = (long) indices.size(); - if (i < ((long) gnames.size() -1)) - end = offsets[i+1]; - - /* print GRID cards */ - for (long j = 0, id = 1; j < (long)vertex.size(); j+=3, id++) - { - float x = vertex[j+0]; - float y = vertex[j+1]; - float z = vertex[j+2]; - - fprintf (fp, "%-8s%8d%8s%8.2f%8.2f%8.2f\n", "GRID", (int) id, " ", - x, y, z); - } - - /* print CTRI cards */ - /* add 1 to everything because FASTGEN indices are 1 based, not 0 */ - for (long j = offsets[i], id = 1; j < end; j += 3, id++) - { - fprintf (fp, "%-8s%8d%8d%8ld%8ld%8ld%8s%8.2f%8d\n", "CTRI", (int) id, - materials.at(i), - indices[j+0] +1, - indices[j+1] +1, - indices[j+2] +1, - " ", thicknesses.at(i), - positions.at(i)); - } - } - - fprintf (fp, "%-8s\n", "ENDDATA"); -} - -//****************************************************************************** -// NAME output_vrml -// -// INPUTS -// fp - file pointer to write -// vertex - list of vertices -// normal - list of normals -// indices - list of indices that make up triangles -// gnames - list of geometry names -// offsets - list of offsets between geometry items -// -// DESCRIPTION -// Runs the given lists and creates a VRML file that holds all the data. -//****************************************************************************** -static inline -void output_vrml (FILE *fp, - std::vector &vertex, - std::vector &normal, - std::vector &indices, - std::vector &gnames, - std::vector &offsets) -{ - long i; - int cID = 0; - - fprintf (fp, "#VRML V2.0 utf8\n"); - - /* output components (i.e. Shapes) */ - for (i = 0; i < (long)gnames.size(); i++) - { - std::string gname = gnames.at(i).c_str(); - std::size_t pos = gname.find("."); - - /* pick 1st comp ID as the one to use */ - if (pos != std::string::npos) - gname = gname.substr(0, pos); - - /* convert name to number */ - if (isdigit (gname.c_str()[0])) - cID = (int) atoi (gname.c_str()); - else cID++; - - /* print Shape header */ - fprintf (fp, "DEF comp_%d Shape {\n", cID); - fprintf (fp, "\t# Component_ID: %s\n\n", gname.c_str()); - - /* print Geometry header */ - fprintf (fp, "\tgeometry IndexedFaceSet {\n"); - fprintf (fp, "\t\tcoord Coordinate {\n"); - fprintf (fp, "\t\t\tpoint [\n"); - - long end = (long) indices.size(); - if (i < ((long) gnames.size() -1)) - end = offsets[i+1]; - - /* print points */ - for (long j = 0, id = 0; j < (long)vertex.size(); j+=3, id++) - { - float x = vertex[j+0]; - float y = vertex[j+1]; - float z = vertex[j+2]; - - fprintf (fp, "\t\t\t\t%.3f %.3f %.3f, # point %d\n", x, y, z, (int) id); - } - - fprintf (fp, "\t\t\t]\n"); /* close point */ - fprintf (fp, "\t\t}\n"); /* close coord */ - - fprintf (fp, "\t\tcoordIndex [\n"); - for (long j = offsets[i]; j < end; j += 3) - { - fprintf (fp, "\t\t\t%ld, %ld, %ld, -1\n", - indices[j+0], indices[j+1], indices[j+2]); - } - fprintf (fp, "\t\t]\n"); /* close coordIndex */ - - fprintf (fp, "\t\tnormalPerVertex FALSE\n"); - fprintf (fp, "\t\tconvex TRUE\n"); - fprintf (fp, "\t\tcreaseAngle 0.5\n"); - fprintf (fp, "\t\tsolid FALSE\n"); - fprintf (fp, "\t}\n"); /* close geometry */ - fprintf (fp, "}\n"); /* close Shape */ - } -} -#endif // COMPILE_FOR_VSL - -#endif diff --git a/src/other/gct/Auxiliary/math3d.h b/src/other/gct/Auxiliary/math3d.h deleted file mode 100644 index dd84fb724ee..00000000000 --- a/src/other/gct/Auxiliary/math3d.h +++ /dev/null @@ -1,79 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#define M3D_VectorZero(x) ({(x)[0]=0.0;(x)[1]=0.0;(x)[2]=0.0;}) -#define M3D_VectorMagnitude(x) (sqrt((x)[0]*(x)[0]+(x)[1]*(x)[1]+(x)[2]*(x)[2])) -#define M3D_VectorCopy(x,y) ({(x)[0]=(y)[0];(x)[1]=(y)[1];(x)[2]=(y)[2];}) -#define M3D_VectorAdd(x,y) (x)[0]+=(y)[0];(x)[1]+=(y)[1];(x)[2]+=(y)[2] -#define M3D_VectorAddStore(x,y,z) (x)[0]=(y)[0]+(z)[0];(x)[1]=(y)[1]+(z)[1];(x)[2]=(y)[2]+(z)[2] -#define M3D_VectorAddMulScalar(x,y,z) (x)[0]+=(y)[0]*(z);(x)[1]+=(y)[1]*(z);(x)[2]+=(y)[2]*(z) -#define M3D_VectorAddMul(x,y,z) (x)[0]+=(y)[0]*(z)[0];(x)[1]+=(y)[1]*(z)[1];(x)[2]+=(y)[2]*(z)[2] -#define M3D_VectorSub(x,y) (x)[0]-=(y)[0];(x)[1]-=(y)[1];(x)[2]-=(y)[2] -#define M3D_VectorSubStore(x,y,z) (x)[0]=(y)[0]-(z)[0];(x)[1]=(y)[1]-(z)[1];(x)[2]=(y)[2]-(z)[2] -#define M3D_VectorSubMulScalar(x,y,z) (x)[0]-=(y)[0]*(z);(x)[1]-=(y)[1]*(z);(x)[2]-=(y)[2]*(z) -#define M3D_VectorSubMul(x,y,z) (x)[0]-=(y)[0]*(z)[0];(x)[1]-=(y)[1]*(z)[1];(x)[2]-=(y)[2]*(z)[2] -#define M3D_VectorMul(x,y) (x)[0]*=(y)[0];(x)[1]*=(y)[1];(x)[2]*=(y)[2] -#define M3D_VectorMulStore(x,y,z) (x)[0]=(y)[0]*(z)[0];(x)[1]=(y)[1]*(z)[1];(x)[2]=(y)[2]*(z)[2] -#define M3D_VectorMulScalar(x,y) (x)[0]*=(y);(x)[1]*=(y);(x)[2]*=(y) -#define M3D_VectorMulScalarStore(x,y,z) (x)[0]=(y)[0]*(z);(x)[1]=(y)[1]*(z);(x)[2]=(y)[2]*(z) -#define M3D_VectorDiv(x,y) (x)[0]/=(y)[0];(x)[1]/=(y)[1];(x)[2]/=(y)[2] -#define M3D_VectorDivStore(x,y,z) (x)[0]=(y)[0]/(z)[0];(x)[1]=(y)[1]/(z)[1];(x)[2]=(y)[2]/(z)[2] -#define M3D_VectorDotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define M3D_PlanePoint(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]) -#define M3D_VectorNormalize(x) ({typeof(*(x)) _f;_f=1.0/sqrt((x)[0]*(x)[0]+(x)[1]*(x)[1]+(x)[2]*(x)[2]);(x)[0]*=_f;(x)[1]*=_f;(x)[2]*=_f;}) - -#define M3D_VectorCrossProduct(x,y,z) ({(x)[0]=((y)[1]*(z)[2])-((y)[2]*(z)[1]);(x)[1]=((y)[2]*(z)[0])-((y)[0]*(z)[2]);(x)[2]=((y)[0]*(z)[1])-((y)[1]*(z)[0]);}) -#define M3D_VectorAddCrossProduct(x,y,z) ({(x)[0]+=((y)[1]*(z)[2])-((y)[2]*(z)[1]);(x)[1]+=((y)[2]*(z)[0])-((y)[0]*(z)[2]);(x)[2]+=((y)[0]*(z)[1])-((y)[1]*(z)[0]);}) -#define M3D_VectorSubCrossProduct(x,y,z) ({(x)[0]-=((y)[1]*(z)[2])-((y)[2]*(z)[1]);(x)[1]-=((y)[2]*(z)[0])-((y)[0]*(z)[2]);(x)[2]-=((y)[0]*(z)[1])-((y)[1]*(z)[0]);}) - -#define M3D_MatrixMulVector(d,p,m) ({ \ -(d)[0]=(p)[0]*(m)[0*4+0]+(p)[1]*(m)[1*4+0]+(p)[2]*(m)[2*4+0]; \ -(d)[1]=(p)[0]*(m)[0*4+1]+(p)[1]*(m)[1*4+1]+(p)[2]*(m)[2*4+1]; \ -(d)[2]=(p)[0]*(m)[0*4+2]+(p)[1]*(m)[1*4+2]+(p)[2]*(m)[2*4+2]; }) - -#define M3D_MatrixTransMulVector(d,p,m) ({ \ -(d)[0]=(p)[0]*(m)[0*4+0]+(p)[1]*(m)[0*4+1]+(p)[2]*(m)[0*4+2]; \ -(d)[1]=(p)[0]*(m)[1*4+0]+(p)[1]*(m)[1*4+1]+(p)[2]*(m)[1*4+2]; \ -(d)[2]=(p)[0]*(m)[2*4+0]+(p)[1]*(m)[2*4+1]+(p)[2]*(m)[2*4+2]; }) - -#define M3D_MatrixMulVectorSelf(p,m) ({ \ -typeof(*(p)) _n[3] = { p[0], p[1], p[2] }; \ -(p)[0]=(_n)[0]*(m)[0*4+0]+(_n)[1]*(m)[1*4+0]+(_n)[2]*(m)[2*4+0]; \ -(p)[1]=(_n)[0]*(m)[0*4+1]+(_n)[1]*(m)[1*4+1]+(_n)[2]*(m)[2*4+1]; \ -(p)[2]=(_n)[0]*(m)[0*4+2]+(_n)[1]*(m)[1*4+2]+(_n)[2]*(m)[2*4+2]; }) - -#define M3D_MatrixMulPoint(d,p,m) ({ \ -(d)[0]=(p)[0]*(m)[0*4+0]+(p)[1]*(m)[1*4+0]+(p)[2]*(m)[2*4+0]+(m)[3*4+0]; \ -(d)[1]=(p)[0]*(m)[0*4+1]+(p)[1]*(m)[1*4+1]+(p)[2]*(m)[2*4+1]+(m)[3*4+1]; \ -(d)[2]=(p)[0]*(m)[0*4+2]+(p)[1]*(m)[1*4+2]+(p)[2]*(m)[2*4+2]+(m)[3*4+2]; }) - -#define M3D_MatrixMulPointSelf(p,m) ({ \ -typeof(*(p)) _n[3] = { p[0], p[1], p[2] }; \ -(p)[0]=(_n)[0]*(m)[0*4+0]+(_n)[1]*(m)[1*4+0]+(_n)[2]*(m)[2*4+0]+(m)[3*4+0]; \ -(p)[1]=(_n)[0]*(m)[0*4+1]+(_n)[1]*(m)[1*4+1]+(_n)[2]*(m)[2*4+1]+(m)[3*4+1]; \ -(p)[2]=(_n)[0]*(m)[0*4+2]+(_n)[1]*(m)[1*4+2]+(_n)[2]*(m)[2*4+2]+(m)[3*4+2]; }) - diff --git a/src/other/gct/Auxiliary/mm.c b/src/other/gct/Auxiliary/mm.c deleted file mode 100644 index 720370cc042..00000000000 --- a/src/other/gct/Auxiliary/mm.c +++ /dev/null @@ -1,3399 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ -/** - * @file - * - * Global memory management routines. - * - * This file includes all the generic memory management routines used - * throughout the code : linked lists, balanced trees, block memory allocation, - * growing memory allocation, page-based pointer directories, aligned memory - * allocation, memory volume management, memory leak or buffer overrun - * tracking, etc. - */ - - -#define MM_THREADING - - -#ifdef MM_THREADING - #define _GNU_SOURCE - #include - #include -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" -#include "cc.h" -#include "mm.h" - - -#if defined(MM_UNIX) - #include - #include - #include - #include - #include - #include -#elif defined(MM_WINDOWS) - #include -#endif - -#if _POSIX_MAPPED_FILES > 0 - #include - #define MM_ZONE_SUPPORT 1 -#endif - -#if defined(MM_LINUX) - #include -#endif - - -#ifndef ADDRESS -#define ADDRESS(p,o) ((void *)(((char *)p)+(o))) -#endif - -#ifndef ADDRESSDIFF -#define ADDRESSDIFF(a,b) (((char *)a)-((char *)b)) -#endif - - -#if MM_DEBUG - #define MM_PASSPARAMS , file, line -#else - #define MM_PASSPARAMS -#endif - - -//// - - -int mmInitStatus = 0; - -mmContext mmcontext; - -#ifdef MT_MUTEX_INITIALIZER -static mtMutex mmGlobalMutex = MT_MUTEX_INITIALIZER; -#else -static mtMutex mmGlobalMutex; -#endif - -#ifdef MM_NUMA - -int mmNumaInit() -{ - int nodeindex, cpuindex, cpurange; - int nodecpucount; - struct bitmask *cpus; - if( numa_available() == -1 ) - return 0; - mmcontext.numaflag = 1; - cpurange = numa_num_configured_cpus(); - if( cpurange >= MM_CPU_COUNT_MAXIMUM ) - { - fprintf( stderr, "CPU count %d exceeds %d, increase MM_CPU_COUNT_MAXIMUM in mm.h and try again.\n", cpurange, MM_CPU_COUNT_MAXIMUM ); - exit( 1 ); - } - mmcontext.nodecount = numa_num_configured_nodes(); - if( mmcontext.nodecount >= MM_NODE_COUNT_MAXIMUM ) - { - fprintf( stderr, "Node count %d exceeds %d, increase MM_NODE_COUNT_MAXIMUM in mm.h and try again.\n", mmcontext.nodecount, MM_NODE_COUNT_MAXIMUM ); - exit( 1 ); - } - mmcontext.cpucount = 0; - mmcontext.sysmemory = 0; - for( nodeindex = 0 ; nodeindex < mmcontext.nodecount ; nodeindex++ ) - { - mmcontext.nodesize[nodeindex] = numa_node_size64( nodeindex, 0 ); - mmcontext.sysmemory += mmcontext.nodesize[nodeindex]; - mmcontext.nodecpucount[nodeindex] = 0; - if( !( numa_bitmask_isbitset( numa_all_nodes_ptr, nodeindex ) ) ) - continue; - nodecpucount = 0; - cpus = numa_bitmask_alloc( cpurange ); - if( numa_node_to_cpus( nodeindex, cpus ) >= 0 ) - { - for( cpuindex = 0 ; cpuindex < cpurange ; cpuindex++ ) - { - if( numa_bitmask_isbitset( cpus, cpuindex ) ) - { - mmcontext.cpunode[ cpuindex ] = nodeindex; - nodecpucount++; - } - } - } - numa_bitmask_free( cpus ); - mmcontext.nodecpucount[nodeindex] = nodecpucount; - mmcontext.cpucount += nodecpucount; - } - return 1; -} - -#endif - -void numa_warn( int num, char *fmt, ... ) -{ - return; -} - -void mmInit() -{ - int64_t sysmemory; - if( mmInitStatus ) - return; - mmcontext.numaflag = 0; -#ifdef MM_NUMA - mmNumaInit(); -#endif - if( !( mmcontext.numaflag ) ) - { - mmcontext.nodecount = 1; - sysmemory = -1; - #if defined(MM_LINUX) - mmcontext.cpucount = get_nprocs(); - mmcontext.pagesize = sysconf(_SC_PAGESIZE); - #elif defined(MM_UNIX) - mmcontext.cpucount = sysconf( _SC_NPROCESSORS_CONF ); - mmcontext.pagesize = sysconf(_SC_PAGESIZE); - #elif defined(MM_WIN32) - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - mmcontext.cpucount = sysinfo.dwNumberOfProcessors; - mmcontext.pagesize = sysinfo.dwPageSize; - #else - mmcontext.cpucount = 1; - #endif - #if defined(MM_UNIX) && defined(_SC_PHYS_PAGES) - sysmemory = sysconf( _SC_PHYS_PAGES ); - if( sysmemory > 0 ) - sysmemory *= mmcontext.pagesize; - #endif - mmcontext.sysmemory = sysmemory; - mmcontext.nodesize[0] = mmcontext.sysmemory; - mmcontext.nodecpucount[0] = mmcontext.cpucount; - } - mtMutexInit( &mmGlobalMutex ); - mmInitStatus = 1; -/* - { - int nodeindex, cpuindex; - printf( "NUMA nodes : %d\n", mmcontext.nodecount ); - for( nodeindex = 0 ; nodeindex < mmcontext.nodecount ; nodeindex++ ) - printf( " NUMA node %d, size %lld, CPU count %d\n", nodeindex, (long long)mmcontext.nodesize[nodeindex], mmcontext.nodecpucount[nodeindex] ); - printf( "CPUs : %d\n", mmcontext.cpucount ); - for( cpuindex = 0 ; cpuindex < mmcontext.cpucount ; cpuindex++ ) - printf( " CPU %d on node %d\n", cpuindex, mmcontext.cpunode[ cpuindex ] ); - } -*/ - return; -} - - -void mmEnd() -{ - mtMutexDestroy( &mmGlobalMutex ); - return; -} - - -//// - - -void mmThreadBindToNode( int nodeindex ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - { - numa_run_on_node( nodeindex ); - return; - } -#endif -#if defined(MM_LINUX) - int cpuindex; - cpu_set_t cpuset; - CPU_ZERO( &cpuset ); - for( cpuindex = 0 ; cpuindex < mmcontext.cpucount ; cpuindex++ ) - CPU_SET( cpuindex, &cpuset ); - sched_setaffinity( 0, sizeof(cpu_set_t), &cpuset ); -#endif - return; -} - -void mmThreadBindToCpu( int cpuindex ) -{ -#if defined(MM_LINUX) - cpu_set_t cpuset; - CPU_ZERO( &cpuset ); - CPU_SET( cpuindex, &cpuset ); - sched_setaffinity( 0, sizeof(cpu_set_t), &cpuset ); -#endif - return; -} - -int mmCpuGetNode( int cpuindex ) -{ - return mmcontext.cpunode[ cpuindex ]; -} - - -//// - - -void *mmNodeAlloc( int nodeindex, size_t size ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - return numa_alloc_onnode( size, nodeindex ); -#endif - return malloc( size ); -} - -void mmNodeFree( int nodeindex, void *v, size_t size ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - { - numa_free( v, size ); - return; - } -#endif - free( v ); - return; -} - -void mmNodeMap( int nodeindex, void *start, size_t bytes ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - numa_tonode_memory( start, bytes, nodeindex ); -#endif - return; -} - -static void *mmNodeRelayAlloc( void *head, size_t bytes MM_PARAMS ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - return numa_alloc_onnode( bytes, (int)((intptr_t)head) ); -#endif - return malloc( bytes ); -} - -static void mmNodeRelayFree( void *head, void *v, size_t bytes MM_PARAMS ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - { - numa_free( v, bytes ); - return; - } -#endif - free( v ); - return; -} - - -void *mmNodeAlignAlloc( int nodeindex, size_t bytes, intptr_t align ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - return numa_alloc_onnode( bytes, nodeindex ); -#endif - return mmAlignAlloc( bytes, align ); -} - -void mmNodeAlignFree( int nodeindex, void *v, size_t bytes ) -{ -#ifdef MM_NUMA - if( mmcontext.numaflag ) - { - numa_free( v, bytes ); - return; - } -#endif - mmAlignFree( v ); - return; -} - - - - -//// - - -#ifndef MM_INLINE_LIST_FUNCTIONS - -/** - * Add the item to a linked list. - * - * The head of the linked list should be defined as a void pointer. The list - * parameter can be a pointer to it, or a pointer to the mmListNode.next - * variable of the preceeding item. The offset parameter should be the offset - * of the mmListNode structure within the structure of the item. It can be - * easily obtained with the offsetof(,) macro. - */ -void mmListAdd( void **list, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - node->prev = list; - node->next = *list; - if( *list ) - { - next = ADDRESS( *list, offset ); - next->prev = &(node->next); - } - *list = item; - return; -} - -/** - * Remove the item from a linked list. - * - * The offset parameter should be the offset of the mmListNode structure - * within the structure of the item. It can be easily obtained with the - * offsetof(,) macro. - */ -void mmListRemove( void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - *(node->prev) = (void *)node->next; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = node->prev; - } - return; -} - - - -void mmListMergeList( void **listdst, void **listsrc, intptr_t offset ) -{ - void *item; - mmListNode *node; - if( !( *listsrc ) ) - return; - for( item = *listdst ; item ; item = node->next ) - { - node = ADDRESS( item, offset ); - listdst = &node->next; - } - item = *listsrc; - node = ADDRESS( item, offset ); - node->prev = listdst; - *listdst = item; - *listsrc = 0; - return; -} - - -void mmListMoveList( void **listdst, void **listsrc, intptr_t offset ) -{ - void *item; - mmListNode *node; - if( !( *listsrc ) ) - { - *listdst = 0; - return; - } - item = *listsrc; - node = ADDRESS( item, offset ); - node->prev = listdst; - *listdst = item; - *listsrc = 0; - return; -} - - - -/** - * Initialize a dual-direction linked list. - * - * The head of the linked list should be defined as a mmListDualHead - * structure, with the head parameter being a pointer to it. - */ -void mmListDualInit( mmListDualHead *head ) -{ - head->first = 0; - head->last = &head->first; - return; -} - - -/** - * Add the item to the beginning of a dual-direction linked list. - * - * The head of the linked list should be defined as a mmListDualHead structure, - * with the head parameter being a pointer to it. The offset parameter should - * be the offset of the mmListNode structure within the structure of the item. - * It can be easily obtained with the offsetof(,) macro. - */ -void mmListDualAddFirst( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - node->prev = &head->first; - node->next = head->first; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = &(node->next); - } - else - head->last = &(node->next); - head->first = item; - return; -} - - -/** - * Add the item to the end of a dual-direction linked list. - * - * The head of the linked list should be defined as a mmListDualHead structure, - * with the head parameter being a pointer to it. The offset parameter should - * be the offset of the mmListNode structure within the structure of the item. - * It can be easily obtained with the offsetof(,) macro. - */ -void mmListDualAddLast( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node; - void **prev; - prev = head->last; - *prev = item; - node = ADDRESS( item, offset ); - node->prev = head->last; - head->last = &(node->next); - node->next = 0; - return; -} - - -/** - * Remove the item from a dual-direction linked list. - * - * The head of the linked list should be defined as a mmListDualHead structure, - * with the head parameter being a pointer to it. The offset parameter should - * be the offset of the mmListNode structure within the structure of the item. - * It can be easily obtained with the offsetof(,) macro. - */ -void mmListDualRemove( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - *(node->prev) = (void *)node->next; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = node->prev; - } - else - head->last = node->prev; - return; -} - - -void *mmListDualLast( mmListDualHead *head, intptr_t offset ) -{ - if( !( head->first ) ) - return 0; - return ADDRESS( head->last, -( offset + offsetof(mmListNode,next) ) ); -} - - -#endif - - -void mmListLoopInit( mmListLoopHead *head ) -{ - head->first = 0; - head->last = 0; - return; -} - - -void mmListLoopAddFirst( mmListLoopHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *prev, *next; - node = ADDRESS( item, offset ); - if( !( head->first ) ) - { - head->first = item; - head->last = item; - node->prev = item; - node->next = item; - return; - } - node->prev = head->last; - node->next = head->first; - next = ADDRESS( head->first, offset ); - next->prev = item; - prev = ADDRESS( head->last, offset ); - prev->next = item; - head->first = item; - return; -} - - -void mmListLoopAddLast( mmListLoopHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *prev, *next; - node = ADDRESS( item, offset ); - if( !( head->first ) ) - { - head->first = item; - head->last = item; - node->prev = item; - node->next = item; - return; - } - prev = ADDRESS( head->last, offset ); - prev->next = item; - next = ADDRESS( head->first, offset ); - next->prev = item; - node->prev = head->last; - node->next = head->first; - head->last = item; - return; -} - - -void mmListLoopInsert( mmListLoopHead *head, void *previtem, void *item, intptr_t offset ) -{ - mmListNode *prev, *node, *next; - node = ADDRESS( item, offset ); - if( !( head->first ) ) - { - head->first = item; - head->last = item; - node->prev = item; - node->next = item; - return; - } - node->prev = previtem; - prev = ADDRESS( previtem, offset ); - node->next = prev->next; - prev->next = item; - next = ADDRESS( node->next, offset ); - next->prev = item; - if( head->last == previtem ) - head->last = item; - return; -} - - -void mmListLoopRemove( mmListLoopHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *prev, *next; - node = ADDRESS( item, offset ); - prev = ADDRESS( node->prev, offset ); - prev->next = node->next; - if( head->first == item ) - { - head->first = node->next; - if( head->first == item ) - head->first = 0; - } - next = ADDRESS( node->next, offset ); - next->prev = node->prev; - if( head->last == item ) - { - head->last = node->prev; - if( head->last == item ) - head->last = 0; - } - return; -} - - - -//// - - - -/** - * Private function to balance a branch of the tree after an insertion. - * - * The details of the implementation are left as an exercise to the reader. - */ -static void mmBTreeInsertBalance( void *item, intptr_t offset, void **root ) -{ - void *parent, *relative, *ancestor, *link; - mmBTreeNode *node, *pnode, *rnode, *anode, *lnode, *tnode; - - node = ADDRESS( item, offset ); - parent = node->parent; - - if( !( parent ) ) - { - node->flags |= MM_BTREE_FLAGS_STEP; - *root = item; - return; - } - - pnode = ADDRESS( parent, offset ); - if( pnode->flags & MM_BTREE_FLAGS_STEP ) - return; - - ancestor = pnode->parent; - anode = ADDRESS( ancestor, offset ); - - relative = anode->child[ ( pnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) ^ 1 ]; - if( ( relative ) && !( ( rnode = ADDRESS( relative, offset ) )->flags & MM_BTREE_FLAGS_STEP ) ) - { - anode->flags &= ~MM_BTREE_FLAGS_STEP; - pnode->flags |= MM_BTREE_FLAGS_STEP; - rnode->flags |= MM_BTREE_FLAGS_STEP; - mmBTreeInsertBalance( ancestor, offset, root ); - return; - } - - if( ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) != ( pnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) ) - { - if( ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) == MM_BTREE_FLAGS_RIGHT ) - { - node->flags = ( anode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - link = anode->parent; - - anode->parent = item; - anode->flags = MM_BTREE_FLAGS_RIGHT; - anode->child[0] = node->child[1]; - if( anode->child[0] ) - { - tnode = ADDRESS( anode->child[0], offset ); - tnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - tnode->parent = ancestor; - } - - pnode->parent = item; - pnode->child[1] = node->child[0]; - if( pnode->child[1] ) - { - tnode = ADDRESS( pnode->child[1], offset ); - tnode->flags |= MM_BTREE_FLAGS_RIGHT; - tnode->parent = parent; - } - - if( relative ) - ( (mmBTreeNode *)ADDRESS( relative, offset ) )->flags |= MM_BTREE_FLAGS_STEP; - - node->child[0] = parent; - node->child[1] = ancestor; - node->parent = link; - if( link ) - { - lnode = ADDRESS( link, offset ); - lnode->child[ node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = item; - return; - } - *root = item; - return; - } - else - { - node->flags = ( anode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - link = anode->parent; - - anode->parent = item; - anode->flags = 0; - anode->child[1] = node->child[0]; - if( anode->child[1] ) - { - tnode = ADDRESS( anode->child[1], offset ); - tnode->flags |= MM_BTREE_FLAGS_RIGHT; - tnode->parent = ancestor; - } - - pnode->parent = item; - pnode->child[0] = node->child[1]; - if( pnode->child[0] ) - { - tnode = ADDRESS( pnode->child[0], offset ); - tnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - tnode->parent = parent; - } - - if( relative ) - ( (mmBTreeNode *)ADDRESS( relative, offset ) )->flags |= MM_BTREE_FLAGS_STEP; - - node->child[0] = ancestor; - node->child[1] = parent; - node->parent = link; - if( link ) - { - lnode = ADDRESS( link, offset ); - lnode->child[ node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = item; - return; - } - *root = item; - return; - } - } - - if( ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) == MM_BTREE_FLAGS_RIGHT ) - { - pnode->flags = ( anode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - link = anode->parent; - - anode->parent = parent; - anode->flags = 0; - anode->child[1] = pnode->child[0]; - if( anode->child[1] ) - { - tnode = ADDRESS( anode->child[1], offset ); - tnode->flags |= MM_BTREE_FLAGS_RIGHT; - tnode->parent = ancestor; - } - - pnode->child[0] = ancestor; - pnode->child[1] = item; - pnode->parent = link; - if( link ) - { - lnode = ADDRESS( link, offset ); - lnode->child[ pnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = parent; - return; - } - *root = parent; - return; - } - else - { - pnode->flags = ( anode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - link = anode->parent; - - anode->parent = parent; - anode->flags = MM_BTREE_FLAGS_RIGHT; - anode->child[0] = pnode->child[1]; - if( anode->child[0] ) - { - tnode = ADDRESS( anode->child[0], offset ); - tnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - tnode->parent = ancestor; - } - - pnode->child[0] = item; - pnode->child[1] = ancestor; - pnode->parent = link; - if( link ) - { - lnode = ADDRESS( link, offset ); - lnode->child[ pnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = parent; - return; - } - *root = parent; - return; - } - - return; -} - - -/** - * Insert an item within the balanced tree - * - * Inserts the item specified at the position specified by the parent pointer - * and the itemflag, which can be either MM_BTREE_FLAGS_LEFT or - * MM_BTREE_FLAGS_RIGHT to indicate on which side of the parent to insert. The - * parent pointer can be null to indicate the top of the tree. The offset - * parameter should be the offset of the mmBTreeNode structure within the - * structure of the item. The root parameter is a pointer to the root of the - * tree. - */ -void mmBTreeInsert( void *item, void *parent, int itemflag, intptr_t offset, void **root ) -{ - mmBTreeNode *node, *pnode; - - node = ADDRESS( item, offset ); - node->parent = parent; - node->child[0] = 0; - node->child[1] = 0; - node->flags = itemflag; - if( parent ) - { - pnode = ADDRESS( parent, offset ); - pnode->child[itemflag] = item; - } - - mmBTreeInsertBalance( item, offset, root ); - - return; -} - - -/** - * Find lowest left gap to use as pivot for removal. - */ -static void *mmBTreeRemoveSeek( void *item, intptr_t offset ) -{ - mmBTreeNode *node; - - node = ADDRESS( item, offset ); - item = node->child[1]; - for( ; ; ) - { - node = ADDRESS( item, offset ); - if( !( node->child[0] ) ) - break; - item = node->child[0]; - } - - return item; -} - - -static void mmBTreeRemoveBalanceLeft( void *item, intptr_t offset, void **root ); -static void mmBTreeRemoveBalanceRight( void *item, intptr_t offset, void **root ); - - -/** - * Private function to balance a left branch of the tree after a removal. - * - * The details of the implementation are left as an exercise to the reader. - */ -static void mmBTreeRemoveBalanceLeft( void *item, intptr_t offset, void **root ) -{ - int mask; - void **plink; - void *litem, *llitem, *lritem, *lrritem, *lrlitem; - mmBTreeNode *node, *lnode, *llnode, *lrnode, *lrrnode, *lrlnode, *tempnode; - - node = ADDRESS( item, offset ); - litem = node->child[0]; - lnode = ADDRESS( litem, offset ); - lritem = lnode->child[1]; - lrnode = ADDRESS( lritem, offset ); - - plink = root; - if( node->parent ) - plink = &( (mmBTreeNode *)ADDRESS( node->parent, offset ) )->child[ node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ]; - - if( !( lnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - lrlitem = lrnode->child[0]; - lrlnode = ADDRESS( lrlitem, offset ); - lrritem = lrnode->child[1]; - lrrnode = ADDRESS( lrritem, offset ); - - if( !( lrlitem ) ) - { - if( lrritem ) - { - lnode->flags = node->flags; - lnode->parent = node->parent; - lnode->child[1] = lrritem; - *plink = litem; - - lrrnode->flags = MM_BTREE_FLAGS_RIGHT; - lrrnode->parent = litem; - lrrnode->child[0] = lritem; - lrrnode->child[1] = item; - - lrnode->flags = MM_BTREE_FLAGS_STEP; - lrnode->parent = lrritem; - lrnode->child[1] = 0; - - node->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - node->parent = lrritem; - node->child[0] = 0; - } - else - goto lshift; - } - else if( !( lrlnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - lrnode->flags = node->flags; - lrnode->parent = node->parent; - lrnode->child[0] = litem; - lrnode->child[1] = item; - *plink = lritem; - - node->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - node->parent = lritem; - node->child[0] = lrritem; - if( lrritem ) - { - lrrnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - lrrnode->parent = item; - } - - lnode->flags = 0; - lnode->parent = lritem; - lnode->child[1] = lrlitem; - lrlnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - lrlnode->parent = litem; - } - else if( lrrnode->flags & MM_BTREE_FLAGS_STEP ) - { - lshift: - lnode->flags = node->flags; - lnode->parent = node->parent; - lnode->child[1] = item; - *plink = litem; - - node->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - node->parent = litem; - node->child[0] = lritem; - lrnode->flags = 0; - lrnode->parent = item; - } - else - { - lnode->flags = node->flags; - lnode->parent = node->parent; - lnode->child[1] = lrritem; - *plink = litem; - - node->flags = MM_BTREE_FLAGS_RIGHT; - node->parent = lrritem; - node->child[0] = lrrnode->child[1]; - if( node->child[0] ) - { - tempnode = ADDRESS( node->child[0], offset ); - tempnode->flags = MM_BTREE_FLAGS_STEP; - tempnode->parent = item; - } - - lrnode->flags = 0; - lrnode->parent = lrritem; - lrnode->child[1] = lrrnode->child[0]; - if( lrnode->child[1] ) - { - tempnode = ADDRESS( lrnode->child[1], offset ); - tempnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - tempnode->parent = lritem; - } - - lrrnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - lrrnode->parent = litem; - lrrnode->child[0] = lritem; - lrrnode->child[1] = item; - } - - return; - } - - mask = node->flags & MM_BTREE_FLAGS_STEP; - llitem = lnode->child[0]; - llnode = ADDRESS( llitem, offset ); - - if( ( lritem ) && !( lrnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - lrlitem = lrnode->child[0]; - lrritem = lrnode->child[1]; - - lrnode->flags = node->flags; - lrnode->parent = node->parent; - lrnode->child[0] = litem; - lrnode->child[1] = item; - *plink = lritem; - - node->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - node->parent = lritem; - node->child[0] = lrritem; - if( lrritem ) - { - lrrnode = ADDRESS( lrritem, offset ); - lrrnode->parent = item; - lrrnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - } - - lnode->flags = MM_BTREE_FLAGS_STEP; - lnode->parent = lritem; - lnode->child[1] = lrlitem; - if( lrlitem ) - { - lrlnode = ADDRESS( lrlitem, offset ); - lrlnode->parent = litem; - lrlnode->flags |= MM_BTREE_FLAGS_RIGHT; - } - } - else if( ( llitem ) && !( llnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - lnode->flags = node->flags | MM_BTREE_FLAGS_STEP; - lnode->parent = node->parent; - lnode->child[1] = item; - *plink = litem; - - node->flags = MM_BTREE_FLAGS_RIGHT | mask; - node->parent = litem; - node->child[0] = lritem; - if( lritem ) - { - lrnode->parent = item; - lrnode->flags = MM_BTREE_FLAGS_STEP; - } - - llnode->flags = mask; - } - else if( !( mask ) ) - { - node->flags |= MM_BTREE_FLAGS_STEP; - lnode->flags = 0; - } - else - { - lnode->flags = 0; - if( node->parent ) - ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ? mmBTreeRemoveBalanceLeft : mmBTreeRemoveBalanceRight )( node->parent, offset, root ); - } - - return; -} - - -/** - * Private function to balance a right branch of the tree after a removal. - * - * The details of the implementation are left as an exercise to the reader. - */ -static void mmBTreeRemoveBalanceRight( void *item, intptr_t offset, void **root ) -{ - int mask; - void **plink; - void *ritem, *rritem, *rlitem, *rllitem, *rlritem; - mmBTreeNode *node, *rnode, *rrnode, *rlnode, *rllnode, *rlrnode, *tempnode; - - node = ADDRESS( item, offset ); - ritem = node->child[1]; - rnode = ADDRESS( ritem, offset ); - rlitem = rnode->child[0]; - rlnode = ADDRESS( rlitem, offset ); - - plink = root; - if( node->parent ) - plink = &( (mmBTreeNode *)ADDRESS( node->parent, offset ) )->child[ node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ]; - - if( !( rnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - rlritem = rlnode->child[1]; - rlrnode = ADDRESS( rlritem, offset ); - rllitem = rlnode->child[0]; - rllnode = ADDRESS( rllitem, offset ); - - if( !( rlritem ) ) - { - if( rllitem ) - { - rnode->flags = node->flags; - rnode->parent = node->parent; - rnode->child[0] = rllitem; - *plink = ritem; - - rllnode->flags = 0; - rllnode->parent = ritem; - rllnode->child[1] = rlitem; - rllnode->child[0] = item; - - rlnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - rlnode->parent = rllitem; - rlnode->child[0] = 0; - - node->flags = MM_BTREE_FLAGS_STEP; - node->parent = rllitem; - node->child[1] = 0; - } - else - goto rshift; - } - else if( !( rlrnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - rlnode->flags = node->flags; - rlnode->parent = node->parent; - rlnode->child[1] = ritem; - rlnode->child[0] = item; - *plink = rlitem; - - node->flags = MM_BTREE_FLAGS_STEP; - node->parent = rlitem; - node->child[1] = rllitem; - if( rllitem ) - { - rllnode->flags |= MM_BTREE_FLAGS_RIGHT; - rllnode->parent = item; - } - - rnode->flags = MM_BTREE_FLAGS_RIGHT; - rnode->parent = rlitem; - rnode->child[0] = rlritem; - rlrnode->flags = MM_BTREE_FLAGS_STEP; - rlrnode->parent = ritem; - } - else if( rllnode->flags & MM_BTREE_FLAGS_STEP ) - { - rshift: - rnode->flags = node->flags; - rnode->parent = node->parent; - rnode->child[0] = item; - *plink = ritem; - - node->flags = MM_BTREE_FLAGS_STEP; - node->parent = ritem; - node->child[1] = rlitem; - rlnode->flags = MM_BTREE_FLAGS_RIGHT; - rlnode->parent = item; - } - else - { - rnode->flags = node->flags; - rnode->parent = node->parent; - rnode->child[0] = rllitem; - *plink = ritem; - - node->flags = 0; - node->parent = rllitem; - node->child[1] = rllnode->child[0]; - if( node->child[1] ) - { - tempnode = ADDRESS( node->child[1], offset ); - tempnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - tempnode->parent = item; - } - - rlnode->flags = MM_BTREE_FLAGS_RIGHT; - rlnode->parent = rllitem; - rlnode->child[0] = rllnode->child[1]; - if( rlnode->child[0] ) - { - tempnode = ADDRESS( rlnode->child[0], offset ); - tempnode->flags = MM_BTREE_FLAGS_STEP; - tempnode->parent = rlitem; - } - - rllnode->flags = MM_BTREE_FLAGS_STEP; - rllnode->parent = ritem; - rllnode->child[1] = rlitem; - rllnode->child[0] = item; - } - - return; - } - - mask = node->flags & MM_BTREE_FLAGS_STEP; - rritem = rnode->child[1]; - rrnode = ADDRESS( rritem, offset ); - - if( ( rlitem ) && !( rlnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - rlritem = rlnode->child[1]; - rllitem = rlnode->child[0]; - - rlnode->flags = node->flags; - rlnode->parent = node->parent; - rlnode->child[1] = ritem; - rlnode->child[0] = item; - *plink = rlitem; - - node->flags = MM_BTREE_FLAGS_STEP; - node->parent = rlitem; - node->child[1] = rllitem; - if( rllitem ) - { - rllnode = ADDRESS( rllitem, offset ); - rllnode->parent = item; - rllnode->flags |= MM_BTREE_FLAGS_RIGHT; - } - - rnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - rnode->parent = rlitem; - rnode->child[0] = rlritem; - if( rlritem ) - { - rlrnode = ADDRESS( rlritem, offset ); - rlrnode->parent = ritem; - rlrnode->flags &= ~MM_BTREE_FLAGS_RIGHT; - } - } - else if( ( rritem ) && !( rrnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - rnode->flags = node->flags | MM_BTREE_FLAGS_STEP; - rnode->parent = node->parent; - rnode->child[0] = item; - *plink = ritem; - - node->flags = mask; - node->parent = ritem; - node->child[1] = rlitem; - if( rlitem ) - { - rlnode->parent = item; - rlnode->flags = MM_BTREE_FLAGS_RIGHT | MM_BTREE_FLAGS_STEP; - } - - rrnode->flags = MM_BTREE_FLAGS_RIGHT | mask; - } - else if( !( mask ) ) - { - node->flags |= MM_BTREE_FLAGS_STEP; - rnode->flags = MM_BTREE_FLAGS_RIGHT; - } - else - { - rnode->flags = MM_BTREE_FLAGS_RIGHT; - if( node->parent ) - ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ? mmBTreeRemoveBalanceLeft : mmBTreeRemoveBalanceRight )( node->parent, offset, root ); - } - - return; -} - - -/** - * Remove an item within the balanced tree - * - * Remove the item specified from the balanced tree. The offset parameter - * should be the offset of the mmBTreeNode structure within the structure - * of the item. The root parameter is a pointer to the root of the tree. - */ -void mmBTreeRemove( void *item, intptr_t offset, void **root ) -{ - void *target, *parent, *child; - mmBTreeNode *node, *tnode, *pnode, *cnode; - - node = ADDRESS( item, offset ); - if( !( node->child[0] ) || !( node->child[1] ) ) - target = item; - else - target = mmBTreeRemoveSeek( item, offset ); - - tnode = ADDRESS( target, offset ); - child = tnode->child[0]; - if( tnode->child[1] ) - child = tnode->child[1]; - cnode = ADDRESS( child, offset ); - - parent = tnode->parent; - pnode = ADDRESS( parent, offset ); - - if( !( tnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - if( child ) - { - cnode->parent = parent; - cnode->flags = ( tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - } - if( parent ) - pnode->child[ tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = child; - else - *root = child; - } - else if( ( child ) && !( cnode->flags & MM_BTREE_FLAGS_STEP ) ) - { - cnode->parent = parent; - cnode->flags = ( tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) | MM_BTREE_FLAGS_STEP; - if( parent ) - pnode->child[ tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = child; - else - *root = child; - } - else - { - if( child ) - { - cnode->parent = parent; - cnode->flags = tnode->flags; - } - if( parent ) - { - pnode->child[ tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = child; - ( tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ? mmBTreeRemoveBalanceLeft : mmBTreeRemoveBalanceRight )( parent, offset, root ); - } - else - *root = child; - } - - if( item != target ) - { - memcpy( tnode, node, sizeof(mmBTreeNode) ); - if( tnode->parent ) - ( (mmBTreeNode *)ADDRESS( tnode->parent, offset ) )->child[ tnode->flags & MM_BTREE_FLAGS_DIRECTION_MASK ] = target; - else - *root = target; - if( tnode->child[0] ) - ( (mmBTreeNode *)ADDRESS( tnode->child[0], offset ) )->parent = target; - if( tnode->child[1] ) - ( (mmBTreeNode *)ADDRESS( tnode->child[1], offset ) )->parent = target; - } - - return; -} - - -void *mmBtreeMostLeft( void *root, intptr_t offset ) -{ - mmBTreeNode *node; - if( !( root ) ) - return 0; - node = ADDRESS( root, offset ); - while( node->child[MM_BTREE_FLAGS_LEFT] ) - { - root = node->child[MM_BTREE_FLAGS_LEFT]; - node = ADDRESS( root, offset ); - } - return root; -} - - -void *mmBtreeMostRight( void *root, intptr_t offset ) -{ - mmBTreeNode *node; - if( !( root ) ) - return 0; - node = ADDRESS( root, offset ); - while( node->child[MM_BTREE_FLAGS_RIGHT] ) - { - root = node->child[MM_BTREE_FLAGS_RIGHT]; - node = ADDRESS( root, offset ); - } - return root; -} - - -void *mmBtreeNeighbourLeft( void *item, intptr_t offset ) -{ - mmBTreeNode *node; - node = ADDRESS( item, offset ); - if( node->child[MM_BTREE_FLAGS_LEFT] ) - { - item = node->child[MM_BTREE_FLAGS_LEFT]; - node = ADDRESS( item, offset ); - while( node->child[MM_BTREE_FLAGS_RIGHT] ) - { - item = node->child[MM_BTREE_FLAGS_RIGHT]; - node = ADDRESS( item, offset ); - } - return item; - } - while( node->parent ) - { - node = ADDRESS( item, offset ); - item = node->parent; - if( ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) == MM_BTREE_FLAGS_RIGHT ) - return item; - } - return 0; -} - - -void *mmBtreeNeighbourRight( void *item, intptr_t offset ) -{ - mmBTreeNode *node; - node = ADDRESS( item, offset ); - if( node->child[MM_BTREE_FLAGS_RIGHT] ) - { - item = node->child[MM_BTREE_FLAGS_RIGHT]; - node = ADDRESS( item, offset ); - while( node->child[MM_BTREE_FLAGS_LEFT] ) - { - item = node->child[MM_BTREE_FLAGS_LEFT]; - node = ADDRESS( item, offset ); - } - return item; - } - while( node->parent ) - { - node = ADDRESS( item, offset ); - item = node->parent; - if( ( node->flags & MM_BTREE_FLAGS_DIRECTION_MASK ) == MM_BTREE_FLAGS_LEFT ) - return item; - } - return 0; -} - - -int mmBtreeListOrdered( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v ) -{ - mmBTreeNode *node; - node = ADDRESS( root, offset ); - if( !( root ) ) - return 1; - if( !( mmBtreeListOrdered( node->child[MM_BTREE_FLAGS_LEFT], offset, callback, v ) ) ) - return 0; - if( !( callback( root, v ) ) ) - return 0; - if( !( mmBtreeListOrdered( node->child[MM_BTREE_FLAGS_RIGHT], offset, callback, v ) ) ) - return 0; - return 1; -} - - -int mmBtreeListBalanced( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v ) -{ - mmBTreeNode *node; - node = ADDRESS( root, offset ); - if( !( root ) ) - return 1; - if( !( callback( root, v ) ) ) - return 0; - if( !( mmBtreeListOrdered( node->child[MM_BTREE_FLAGS_LEFT], offset, callback, v ) ) ) - return 0; - if( !( mmBtreeListOrdered( node->child[MM_BTREE_FLAGS_RIGHT], offset, callback, v ) ) ) - return 0; - return 1; -} - - -intptr_t mmBtreeItemCount( void *root, intptr_t offset ) -{ - mmBTreeNode *node; - if( !( root ) ) - return 0; - node = ADDRESS( root, offset ); - return 1 + mmBtreeItemCount( node->child[0], offset ) + mmBtreeItemCount( node->child[1], offset ); -} - - - -//// - - - -/** - * Initialize the memory block head specified. - * - * The parameters chunksize and chunkperblock define the size of each memory - * chunk and the number of chunks per block. - */ -void MM_FUNC(BlockInit)( mmBlockHead *head, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS ) -{ - memset( head, 0, sizeof(mmBlockHead) ); - head->alignment = 0; - - head->chunksize = chunksize; - if( head->chunksize < sizeof(mmListNode) ) - head->chunksize = sizeof(mmListNode); - if( alignment >= 0x10 ) - { - head->alignment = alignment - 1; - head->chunksize = ( chunksize + head->alignment ) & ~head->alignment; - } - head->chunkfreecount = 0; - head->relayalloc = mmAlloc; - head->relayfree = mmFree; - head->relayvalue = 0; - head->chunkperblock = chunkperblock; - head->allocsize = sizeof(mmBlock) + head->chunksize * head->chunkperblock; - head->keepfreecount = keepfreecount + chunkperblock; - mtSpinInit( &head->spinlock ); - return; -} - - -void MM_FUNC(BlockNodeInit)( mmBlockHead *head, int nodeindex, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS ) -{ - MM_FUNC(BlockInit)( head, chunksize, chunkperblock, keepfreecount, alignment MM_PASSPARAMS ); - head->relayalloc = mmNodeRelayAlloc; - head->relayfree = mmNodeRelayFree; - head->relayvalue = (void *)((intptr_t)nodeindex); - return; -} - - -static void mmBlockTreeInsert( mmBlock *block, void **treeroot ) -{ - mmBlock *root = *treeroot; - if( !( root ) ) - { - mmBTreeInsert( block, 0, 0, offsetof(mmBlock,node), treeroot ); - return; - } - for( ; ; ) - { - if( block < root ) - { - if( root->node.child[0] ) - { - root = root->node.child[0]; - continue; - } - mmBTreeInsert( block, root, MM_BTREE_FLAGS_LEFT, offsetof(mmBlock,node), treeroot ); - break; - } - else - { - if( root->node.child[1] ) - { - root = root->node.child[1]; - continue; - } - mmBTreeInsert( block, root, MM_BTREE_FLAGS_RIGHT, offsetof(mmBlock,node), treeroot ); - break; - } - } - return; -} - - -static mmBlock *mmBlockResolveChunk( void *p, mmBlock *root ) -{ - mmBlock *best = 0; - for( ; root ; ) - { - if( p < (void *)root ) - root = root->node.child[0]; - else - { - best = root; - root = root->node.child[1]; - } - } - return best; -} - - -/** - * Allocates a chunk of memory from the block. - * - * The size of the memory chunk returned was defined during the initialisation - * of the specified memory block head. - */ -void *MM_FUNC(BlockAlloc)( mmBlockHead *head MM_PARAMS ) -{ - int a; - mmBlock *block; - void *chunk; - mtSpinLock( &head->spinlock ); - if( !( head->freelist ) ) - { - if( head->alignment ) - block = MM_FUNC(AlignRelayAlloc)( head->relayalloc, head->relayvalue, head->allocsize, head->alignment, sizeof(mmBlock) MM_PASSPARAMS ); - else - block = head->relayalloc( head->relayvalue, head->allocsize MM_PASSPARAMS ); - if( !( block ) ) - { - fprintf( stderr, "ERROR %s:%d\n", __FILE__, __LINE__ ); - return 0; - } - block->freecount = head->chunkperblock; - mmListAdd( &head->blocklist, block, offsetof(mmBlock,listnode) ); - chunk = ADDRESS( block, sizeof(mmBlock) ); - for( a = 0 ; a < head->chunkperblock ; a++, chunk = ADDRESS( chunk, head->chunksize ) ) - mmListAdd( &head->freelist, chunk, 0 ); - mmBlockTreeInsert( block, &head->treeroot ); - head->chunkfreecount += head->chunkperblock; - } - chunk = head->freelist; - block = mmBlockResolveChunk( chunk, head->treeroot ); - mmListRemove( chunk, 0 ); - block->freecount--; - head->chunkfreecount--; - mtSpinUnlock( &head->spinlock ); - return chunk; -} - - -/** - * Free a chunk of memory previously allocated by mmBlockAlloc(). - */ -void MM_FUNC(BlockFree)( mmBlockHead *head, void *v MM_PARAMS ) -{ - int a; - mmBlock *block; - void *chunk; - chunk = v; - mtSpinLock( &head->spinlock ); - block = mmBlockResolveChunk( chunk, head->treeroot ); - block->freecount++; - head->chunkfreecount++; - mmListAdd( &head->freelist, chunk, 0 ); - if( ( block->freecount == head->chunkperblock ) && ( head->chunkfreecount >= head->keepfreecount ) ) - { - mmListRemove( block, offsetof(mmBlock,listnode) ); - chunk = ADDRESS( block, sizeof(mmBlock) ); - for( a = 0 ; a < head->chunkperblock ; a++, chunk = ADDRESS( chunk, head->chunksize ) ) - mmListRemove( chunk, 0 ); - mmBTreeRemove( block, offsetof(mmBlock,node), &head->treeroot ); - if( head->alignment ) - MM_FUNC(AlignRelayFree)( head->relayfree, head->relayvalue, block, head->allocsize MM_PASSPARAMS ); - else - head->relayfree( head->relayvalue, block, head->allocsize MM_PASSPARAMS ); - head->chunkfreecount -= head->chunkperblock; - } - mtSpinUnlock( &head->spinlock ); - return; -} - - -/** - * Release a chunk of memory previously allocated by mmBlockAlloc(). - * - * Unlike mmBlockFree(), this function will collect but never free unused - * memory, improving performance if the memory pages are to be soon reused. - */ -void MM_FUNC(BlockRelease)( mmBlockHead *head, void *v MM_PARAMS ) -{ - mmBlock *block; - void *chunk; - chunk = v; - mtSpinLock( &head->spinlock ); - block = mmBlockResolveChunk( chunk, head->treeroot ); - block->freecount++; - head->chunkfreecount++; - mmListAdd( &head->freelist, chunk, 0 ); - mtSpinUnlock( &head->spinlock ); - return; -} - - -/** - * Free all memory allocated by a block head. - */ -void MM_FUNC(BlockFreeAll)( mmBlockHead *head MM_PARAMS ) -{ - mmBlock *block, *blocknext; - mtSpinLock( &head->spinlock ); - for( block = head->blocklist ; block ; block = blocknext ) - { - blocknext = block->listnode.next; - if( head->alignment ) - MM_FUNC(AlignRelayFree)( head->relayfree, head->relayvalue, block, head->allocsize MM_PASSPARAMS ); - else - head->relayfree( head->relayvalue, block, head->allocsize MM_PASSPARAMS ); - } - head->blocklist = 0; - head->freelist = 0; - head->treeroot = 0; - mtSpinUnlock( &head->spinlock ); - mtSpinDestroy( &head->spinlock ); - return; -} - - -void MM_FUNC(BlockProcessList)( mmBlockHead *head, void *userpointer, int (*processchunk)( void *chunk, void *userpointer ) MM_PARAMS ) -{ - int i, blockcount, blockrefsize, chunkperblock; - intptr_t **bitsref; - intptr_t *blockmask; - intptr_t blockindex, chunkindex; - size_t chunksize; - void *p, *chunk; - mmBlock *block; - mmListNode *list; - - mtSpinLock( &head->spinlock ); - - blockcount = 0; - for( block = head->blocklist ; block ; block = block->listnode.next ) - block->blockindex = blockcount++; - - chunksize = head->chunksize; - chunkperblock = head->chunkperblock; - blockrefsize = ( ( chunkperblock + CPUCONF_INTPTR_BITS - 1 ) >> CPUCONF_INTPTR_BITSHIFT ) * sizeof(intptr_t); - bitsref = malloc( blockcount * ( sizeof(intptr_t *) + blockrefsize ) ); - memset( bitsref, 0, blockcount * ( sizeof(intptr_t *) + blockrefsize ) ); - - p = ADDRESS( bitsref, blockcount * sizeof(intptr_t *) ); - for( i = 0 ; i < blockcount ; i++ ) - { - bitsref[i] = p; - p = ADDRESS( p, blockrefsize ); - } - for( list = head->freelist ; list ; list = list->next ) - { - block = mmBlockResolveChunk( list, head->treeroot ); - chunkindex = ADDRESSDIFF( list, ADDRESS( block, sizeof(mmBlock) ) ) / chunksize; - bitsref[ block->blockindex ][ chunkindex >> CPUCONF_INTPTR_BITSHIFT ] |= (intptr_t)1 << ( chunkindex & (CPUCONF_INTPTR_BITS-1) ); - } - - blockindex = 0; - for( block = head->blocklist ; block ; block = block->listnode.next ) - { - blockmask = bitsref[ blockindex ]; - chunk = ADDRESS( block, sizeof(mmBlock) ); - for( chunkindex = 0 ; chunkindex < chunkperblock ; chunkindex++, chunk = ADDRESS( chunk, chunksize ) ) - { - if( blockmask[ chunkindex >> CPUCONF_INTPTR_BITSHIFT ] & ( (intptr_t)1 << ( chunkindex & (CPUCONF_INTPTR_BITS-1) ) ) ) - continue; - if( processchunk( chunk, userpointer ) ) - goto end; - } - blockindex++; - } - - end: - free( bitsref ); - mtSpinUnlock( &head->spinlock ); - - return; -} - - -int MM_FUNC(BlockUseCount)( mmBlockHead *head MM_PARAMS ) -{ - int blockcount, chunkcount; - mmBlock *block; - mmListNode *list; - - mtSpinLock( &head->spinlock ); - - blockcount = 0; - for( block = head->blocklist ; block ; block = block->listnode.next ) - blockcount++; - chunkcount = blockcount * head->chunkperblock; - for( list = head->freelist ; list ; list = list->next ) - chunkcount--; - - mtSpinUnlock( &head->spinlock ); - - return chunkcount; -} - - -int MM_FUNC(BlockFreeCount)( mmBlockHead *head MM_PARAMS ) -{ - int chunkcount; - - mtSpinLock( &head->spinlock ); - chunkcount = head->chunkfreecount; - mtSpinUnlock( &head->spinlock ); - - return chunkcount; -} - - - -//// - - - -typedef struct -{ - intptr_t index; - mmBTreeNode node; -} mmIndex; - -void mmIndexInit( mmIndexHead *head, int indexesperblock ) -{ - mmBlockInit( &head->indexblock, sizeof(mmIndex), indexesperblock, indexesperblock, 0x10 ); - head->indextree = 0; - mtSpinInit( &head->spinlock ); - return; -} - -void mmIndexFreeAll( mmIndexHead *head ) -{ - mmBlockFreeAll( &head->indexblock ); - head->indextree = 0; - mtSpinDestroy( &head->spinlock ); - return; -} - -void mmIndexAdd( mmIndexHead *head, intptr_t index ) -{ - mmIndex *indexnode, *root; - mtSpinLock( &head->spinlock ); - indexnode = mmBlockAlloc( &head->indexblock ); - indexnode->index = index; - if( !( head->indextree ) ) - { - mmBTreeInsert( indexnode, 0, 0, offsetof(mmIndex,node), &head->indextree ); - mtSpinUnlock( &head->spinlock ); - return; - } - for( root = head->indextree ; ; ) - { - if( index < root->index ) - { - if( root->node.child[0] ) - { - root = root->node.child[0]; - continue; - } - mmBTreeInsert( indexnode, root, MM_BTREE_FLAGS_LEFT, offsetof(mmIndex,node), &head->indextree ); - break; - } - else - { - if( root->node.child[1] ) - { - root = root->node.child[1]; - continue; - } - mmBTreeInsert( indexnode, root, MM_BTREE_FLAGS_RIGHT, offsetof(mmIndex,node), &head->indextree ); - break; - } - } - mtSpinUnlock( &head->spinlock ); - return; -} - -intptr_t mmIndexGet( mmIndexHead *head ) -{ - intptr_t index; - mmIndex *indexnode; - mtSpinLock( &head->spinlock ); - if( !( head->indextree ) ) - index = head->indexlimit++; - else - { - for( indexnode = head->indextree ; indexnode->node.child[0] ; ) - indexnode = indexnode->node.child[0]; - index = indexnode->index; - mmBTreeRemove( indexnode, offsetof(mmIndex,node), &head->indextree ); - mmBlockFree( &head->indexblock, indexnode ); - } - mtSpinUnlock( &head->spinlock ); - return index; -} - -int mmIndexRemove( mmIndexHead *head, intptr_t index ) -{ - intptr_t limit; - mmIndex *indexnode; - mtSpinLock( &head->spinlock ); - if( index >= head->indexlimit ) - { - for( limit = head->indexlimit ; limit < index ; limit++ ) - mmIndexAdd( head, index ); - head->indexlimit = index + 1; - mtSpinUnlock( &head->spinlock ); - return 1; - } - for( indexnode = head->indextree ; ; ) - { - if( !( indexnode ) ) - { - mtSpinUnlock( &head->spinlock ); - return 0; - } - if( index == indexnode->index ) - break; - if( index < indexnode->index ) - indexnode = indexnode->node.child[0]; - else - indexnode = indexnode->node.child[1]; - } - mmBTreeRemove( indexnode, offsetof(mmIndex,node), &head->indextree ); - mmBlockFree( &head->indexblock, indexnode ); - mtSpinUnlock( &head->spinlock ); - return 1; -} - -size_t mmIndexCount( mmIndexHead *head ) -{ - intptr_t count; - mtSpinLock( &head->spinlock ); - count = mmBtreeItemCount( head->indextree, offsetof(mmIndex,node) ); - mtSpinUnlock( &head->spinlock ); - return count; -} - - - -//// - - - -#define MM_BITTABLE_SIZEBYTES(head) ((((head->mapsize)<bitshift))>>CPUCONF_CHAR_BITSHIFT) -#define MM_BITTABLE_MINALIGN (4096) - -void mmBitTableInit( mmBitTableHead *head, int bitsperentry, int chunksize, int initmask ) -{ - int i; - head->bitshift = ccLog2Int32( ccAlignInt32( bitsperentry ) ); - head->bitmask = ( 1 << bitsperentry ) - 1; - head->countalign = ccAlignIntPtr( chunksize ); - if( head->countalign < MM_BITTABLE_MINALIGN ) - head->countalign = MM_BITTABLE_MINALIGN; - head->indexshift = CPUCONF_INTPTR_BITSHIFT >> head->bitshift; - head->indexmask = ( 1 << head->indexshift ) - 1; - head->mapsize = 0; - head->map = 0; - initmask &= ( 1 << head->bitmask ) - 1; - head->initmask = 0; - for( i = 0 ; i < CPUCONF_INTPTR_BITS ; i += head->bitmask ) - head->initmask |= initmask << i; - mtSpinInit( &head->spinlock ); - return; -} - -void mmBitTableFreeAll( mmBitTableHead *head ) -{ - free( head->map ); - head->map = 0; - head->mapsize = 0; - mtSpinDestroy( &head->spinlock ); - return; -} - -void mmBitTableSet( mmBitTableHead *head, uintptr_t index, int flags, int editmask ) -{ - uintptr_t *map; - uintptr_t offset, shift, mapindex, mapindexend; - mtSpinLock( &head->spinlock ); - map = head->map; - if( index >= head->mapsize ) - { - mapindex = head->mapsize >> CPUCONF_INTPTR_BITSHIFT; - head->mapsize = ( index + head->countalign ) & ( head->countalign - 1 ); - head->map = realloc( head->map, MM_BITTABLE_SIZEBYTES( head ) ); - mapindexend = head->mapsize >> CPUCONF_INTPTR_BITSHIFT; - map = head->map; - for( ; mapindex < mapindexend ; mapindex++ ) - map[mapindex] = head->initmask; - } - offset = index >> head->indexshift; - shift = ( index & head->indexmask ) << head->bitshift; - map[ offset ] &= ~( editmask << shift ); - map[ offset ] |= ( ( flags & editmask ) << shift ); - mtSpinUnlock( &head->spinlock ); - return; -} - -uintptr_t mmBitTableGet( mmBitTableHead *head, uintptr_t index ) -{ - uintptr_t *map; - uintptr_t offset, shift, value; - mtSpinLock( &head->spinlock ); - if( index >= head->mapsize ) - { - mtSpinUnlock( &head->spinlock ); - return head->initmask; - } - map = head->map; - offset = index >> head->indexshift; - shift = ( index & head->indexmask ) << head->bitshift; - value = ( map[ offset ] >> shift ) & head->bitmask; - mtSpinUnlock( &head->spinlock ); - return value; -} - - - -//// - - - -#define MM_GROW_NODE_MEM(x,b) ADDRESS(x,sizeof(mmGrowNode)+b) - -/** - * Private function to add a new node to the packed growing memory allocator - */ -static int mmGrowAdd( mmGrow *mgrow, int size MM_PARAMS ) -{ - mmGrowNode *mnode; - if( !( mnode = mmAlloc( 0, sizeof(mmGrowNode) + size MM_PASSPARAMS ) ) ) - return 0; - mnode->size = size; - mnode->used = 0; - mnode->next = mgrow->first; - mgrow->first = mnode; - return 1; -} - - -/** - * Initialize a packed growing memory allocator. - * - * While no space is wasted between allocated chunks of memory, it is - * impossible to free individual allocations. A growing memory allocator - * must be freed entirely at once. - */ -int MM_FUNC(GrowInit)( mmGrow *mgrow, size_t nodesize MM_PARAMS ) -{ - mgrow->first = 0; - mgrow->nodesize = nodesize; - mtSpinInit( &mgrow->spinlock ); - return mmGrowAdd( mgrow, nodesize MM_PASSPARAMS ); -} - - -/** - * Free all chunks of a growing memory allocator. - */ -void MM_FUNC(GrowFreeAll)( mmGrow *mgrow MM_PARAMS ) -{ - mmGrowNode *mnode, *next; - mtSpinLock( &mgrow->spinlock ); - for( mnode = mgrow->first ; mnode ; mnode = next ) - { - next = mnode->next; - mmFree( 0, mnode, 0 MM_PASSPARAMS ); - } - mgrow->first = 0; - mtSpinUnlock( &mgrow->spinlock ); - mtSpinDestroy( &mgrow->spinlock ); - return; -} - - -/** - * Allocate a chunk of memory from a growing memoy allocator. - * - * The memory can only be freed with mmGrowFreeAll() for the whole allocator. - * There are no memory alignment garantees for the allocations, yet as all - * memory is tightly packed, the alignment is directly dependant on the size - * of the previous allocations. - */ -void *MM_FUNC(GrowAlloc)( mmGrow *mgrow, size_t bytes MM_PARAMS ) -{ - size_t a, fbytes; - mmGrowNode *mnode; - mtSpinLock( &mgrow->spinlock ); - mnode = mgrow->first; - fbytes = mnode->size - mnode->used; - if( fbytes >= bytes ) - { - a = mnode->used; - mnode->used += bytes; - mtSpinUnlock( &mgrow->spinlock ); - return MM_GROW_NODE_MEM( mnode, a ); - } - mmGrowAdd( mgrow, ( bytes > mgrow->nodesize ) ? bytes : mgrow->nodesize MM_PASSPARAMS ); - mnode = mgrow->first; - mnode->used = bytes; - mtSpinUnlock( &mgrow->spinlock ); - return MM_GROW_NODE_MEM( mnode, 0 ); -} - - - -//// - - - -#if 0 - -/** - * Initialize a directory structure. - * - * The pageshift parameter indicates the power of two defining the count of - * entries per page. The pagecount parameter specifies the initial count of - * pages, which can grow as required. - */ -int MM_FUNC(DirInit)( mmDirectory *dir, intptr_t pageshift, intptr_t pagecount MM_PARAMS ) -{ - if( !( dir->table = mmAlloc( 0, pagecount * sizeof(void **) MM_PASSPARAMS ) ) ) - return 0; - memset( dir->table, 0, pagecount * sizeof(void **) ); - dir->pagecount = pagecount; - dir->pageshift = pageshift; - dir->pagesize = 1 << pageshift; - dir->pagemask = dir->pagesize - 1; - mtSpinInit( &dir->spinlock ); - return 1; -} - - -/** - * Private function to resize a directory page table. - */ -static inline void mmDirResizeTable( mmDirectory *dir, intptr_t newcount MM_PARAMS ) -{ - intptr_t page; - for( page = newcount ; page < dir->pagecount ; page++ ) - { - if( dir->table[ page ] ) - mmFree( 0, dir->table[ page ], 0 MM_PASSPARAMS ); - } - if( !( dir->table = mmRealloc( 0, dir->table, newcount * sizeof(void **) MM_PASSPARAMS ) ) ) - return; - if( newcount > dir->pagecount ) - memset( ADDRESS( dir->table, dir->pagecount * sizeof(void **) ), 0, ( newcount - dir->pagecount ) * sizeof(void **) ); - dir->pagecount = newcount; - return; -} - - -void MM_FUNC(DirSize)( mmDirectory *dir, intptr_t size MM_PARAMS ) -{ - intptr_t page, pagecount; - pagecount = ( size >> dir->pageshift ) + 1; - size &= dir->pagemask; - mtSpinLock( &dir->spinlock ); - if( pagecount != dir->pagecount ) - mmDirResizeTable( dir, pagecount MM_PASSPARAMS ); - for( page = 0 ; page < pagecount ; page++ ) - { - if( dir->table[ page ] ) - continue; - if( !( dir->table[ page ] = mmAlloc( 0, dir->pagesize * sizeof(void *) MM_PASSPARAMS ) ) ) - return; - } - mtSpinUnlock( &dir->spinlock ); - return; -} - - -/** - * Sets the directory's item specified by the index to the pointer of the entry - * parameter. - * - * If the directory is too small to accept the new entry, the internal table of - * pages grow in size. The MM_DIR_ENTRY(dir,index) macro can be used to access - * directory entries, both for reading and writing, only if the entry is known - * to have been previously set. - */ -void MM_FUNC(DirSet)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS ) -{ - intptr_t page; - page = index >> dir->pageshift; - index &= dir->pagemask; - mtSpinLock( &dir->spinlock ); - if( page >= dir->pagecount ) - mmDirResizeTable( dir, ( dir->pagecount ? dir->pagecount << 1 : 1 ) MM_PASSPARAMS ); - if( !( dir->table[ page ] ) ) - { - if( !( dir->table[ page ] = mmAlloc( 0, dir->pagesize * sizeof(void *) MM_PASSPARAMS ) ) ) - return; - } - dir->table[ page ][ index ] = entry; - mtSpinUnlock( &dir->spinlock ); - return; -} - - -void *MM_FUNC(DirGet)( mmDirectory *dir, intptr_t index MM_PARAMS ) -{ - intptr_t page; - void *entry; - page = index >> dir->pageshift; - index &= dir->pagemask; - mtSpinLock( &dir->spinlock ); - if( (uintptr_t)page >= dir->pagecount ) - return 0; - if( !( dir->table[ page ] ) ) - return 0; - entry = dir->table[ page ][ index ]; - mtSpinUnlock( &dir->spinlock ); - return entry; -} - - -void MM_FUNC(DirSetFast)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS ) -{ - mtSpinLock( &dir->spinlock ); - dir->table[ index >> dir->pageshift ][ index & dir->pagemask ] = entry; - mtSpinUnlock( &dir->spinlock ); - return; -} - -void *MM_FUNC(DirGetFast)( mmDirectory *dir, intptr_t index MM_PARAMS ) -{ - void *entry; - mtSpinLock( &dir->spinlock ); - entry = dir->table[ index >> dir->pageshift ][ index & dir->pagemask ]; - mtSpinUnlock( &dir->spinlock ); - return entry; -} - - -/** - * Free a directory structure. - */ -void MM_FUNC(DirFree)( mmDirectory *dir MM_PARAMS ) -{ - intptr_t page; - if( !( dir->table ) ) - return; - mtSpinLock( &dir->spinlock ); - for( page = dir->pagecount-1 ; page >= 0 ; page-- ) - { - if( dir->table[ page ] ) - mmFree( 0, dir->table[ page ], 0 MM_PASSPARAMS ); - } - dir->pagecount = 0; - mmFree( 0, dir->table, 0 MM_PASSPARAMS ); - dir->table = 0; - mtSpinUnlock( &dir->spinlock ); - mtSpinDestroy( &dir->spinlock ); - return; -} - -#endif - - - -//// - - - -typedef struct -{ - int padding; -} mmAlign; - - -/** - * Allocate a chunk of memory with the alignment specified. - * - * The alignment parameter must be a power of two. The allocated memory must be - * freed with the mmAlignFree() function. - */ -void *MM_FUNC(AlignAlloc)( size_t bytes, intptr_t align MM_PARAMS ) -{ - intptr_t i; - void *v; - mmAlign *malign; - align--; - if( !( v = mmAlloc( 0, bytes + align + sizeof(mmAlign) MM_PASSPARAMS ) ) ) - return 0; - i = ( (intptr_t)v + align + sizeof(mmAlign) ) & ~align; - malign = ADDRESS( (void *)i, -(int)sizeof(mmAlign) ); - malign->padding = ADDRESSDIFF( i, v ); - return (void *)i; -} - -/** - * Free a chunk of memory that was allocated by mmAlignAlloc(). - */ -void MM_FUNC(AlignFree)( void *v MM_PARAMS ) -{ - mmAlign *malign; - malign = ADDRESS( v, -sizeof(mmAlign) ); - mmFree( 0, ADDRESS( v, -malign->padding ), 0 MM_PASSPARAMS ); - return; -} - -void *MM_FUNC(AlignGrow)( void *v, size_t bytes, size_t copybytes, intptr_t align MM_PARAMS ) -{ - void *newv; - newv = MM_FUNC(AlignAlloc)( bytes, align ); - memcpy( newv, v, copybytes ); - MM_FUNC(AlignFree)( v ); - return newv; -} - - -void *MM_FUNC(AlignRelayAlloc)( void *(*relayalloc)( void *head, size_t bytes MM_PARAMS ), void *relayvalue, size_t bytes, intptr_t align, size_t displacement MM_PARAMS ) -{ - intptr_t i; - void *v; - mmAlign *malign; - align--; - if( !( v = relayalloc( relayvalue, bytes + align + sizeof(mmAlign) + displacement MM_PASSPARAMS ) ) ) - return 0; - i = ( (intptr_t)v + align + sizeof(mmAlign) + displacement ) & ~align; - i -= displacement; - malign = ADDRESS( (void *)i, -(int)sizeof(mmAlign) ); - malign->padding = ADDRESSDIFF( i, v ); - return (void *)i; -} - - -void MM_FUNC(AlignRelayFree)( void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS ), void *relayvalue, void *v, size_t bytes MM_PARAMS ) -{ - mmAlign *malign; - malign = ADDRESS( v, -sizeof(mmAlign) ); - relayfree( relayvalue, ADDRESS( v, -malign->padding ), bytes MM_PASSPARAMS ); - return; -} - - - -//// - - - -typedef struct -{ - size_t bigsize; - mmListNode list; - int alignment; -} mmVolume; - -typedef struct -{ - int32_t nextoffset; - int32_t prevoffset; -} mmVolumeChunkHeader; - -typedef struct -{ - mmVolumeChunkHeader h; - mmBTreeNode node; -} mmVolumeChunk; - -#define MM_VOLUME_CHUNK_FLAGS_FREE (0x1) -#define MM_VOLUME_CHUNK_FLAGS_LAST (0x2) -#define MM_VOLUME_CHUNK_FLAGS_MASK (0x3) - -#define MM_VOLUME_CHUNK_GET_FLAGS(c) ((c)->h.nextoffset&MM_VOLUME_CHUNK_FLAGS_MASK) -#define MM_VOLUME_CHUNK_SET_FLAGS(c,f) (c)->h.nextoffset=(((c)->h.nextoffset&~MM_VOLUME_CHUNK_FLAGS_MASK)|(f)) -#define MM_VOLUME_CHUNK_GET_NEXTOFFSET(c) ((c)->h.nextoffset&~MM_VOLUME_CHUNK_FLAGS_MASK) -#define MM_VOLUME_CHUNK_SET_NEXTOFFSET(c,n) (c)->h.nextoffset=((c)->h.nextoffset&MM_VOLUME_CHUNK_FLAGS_MASK)|(n) -#define MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS(c,n,f) (c)->h.nextoffset=((n)|(f)) - -#define MM_VOLUME_BIGCHUNK_THRESHOLD (1<<30) - - -/** - * Initialize a memory volume. - * - * The parameter volumesize defines the default size of each chunk of memory - * internally allocated by the volume manager, chunks which will be sliced - * accordingly to memory allocation needs. The parameter minchunksize defines - * the minimum size a chunk of memory must have not to be fused. - */ -void MM_FUNC(VolumeInit)( mmVolumeHead *head, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS ) -{ - head->alignment = 3; - if( alignment > 4 ) - head->alignment = alignment - 1; - head->volumesize = volumesize; - if( head->volumesize > (((size_t)1)<<31)-1 ) - head->volumesize = (((size_t)1)<<31)-1; - head->volumeblocksize = ( sizeof(mmVolume) + head->alignment ) & ~head->alignment; - head->minchunksize = ( ( minchunksize > sizeof(mmVolumeChunk) ? minchunksize : sizeof(mmVolumeChunk) ) + head->alignment ) & ~head->alignment; - head->volumechunksize = ( sizeof(mmVolumeChunkHeader) + head->alignment ) & ~head->alignment; - head->keepfreesize = keepfreesize; - head->totalfreesize = 0; - head->freeroot = 0; - head->volumelist = 0; - head->relayalloc = mmAlloc; - head->relayfree = mmFree; - head->relayvalue = 0; - mtSpinInit( &head->spinlock ); - return; -} - - -void MM_FUNC(VolumeNodeInit)( mmVolumeHead *head, int nodeindex, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS ) -{ - MM_FUNC(VolumeInit)( head, volumesize, minchunksize, keepfreesize, alignment MM_PASSPARAMS ); - head->relayalloc = mmNodeRelayAlloc; - head->relayfree = mmNodeRelayFree; - head->relayvalue = (void *)((intptr_t)nodeindex); - return; -} - - -/** - * Private function to search for the best match given a desired memory chunk size. - */ -static mmVolumeChunk *mmVolumeFindFreeChunk( int32_t bytes, mmVolumeChunk *root ) -{ - int32_t chunksize; - mmVolumeChunk *best = 0; - for( ; root ; ) - { - chunksize = MM_VOLUME_CHUNK_GET_NEXTOFFSET( root ); - if( bytes <= chunksize ) - { - best = root; - if( bytes == chunksize ) - return best; - root = root->node.child[0]; - } - else - root = root->node.child[1]; - } - return best; -} - - -/** - * Private function to add a new free chunk within the balanced binary tree. - */ -static void mmVolumeAddFreeChunk( mmVolumeChunk *chunk, void **rootfree ) -{ - int32_t nextoffset = chunk->h.nextoffset; - mmVolumeChunk *root = *rootfree; - if( !( root ) ) - { - mmBTreeInsert( chunk, 0, 0, offsetof(mmVolumeChunk,node), rootfree ); - return; - } - for( ; ; ) - { - if( nextoffset < root->h.nextoffset ) - { - if( root->node.child[0] ) - { - root = root->node.child[0]; - continue; - } - mmBTreeInsert( chunk, root, MM_BTREE_FLAGS_LEFT, offsetof(mmVolumeChunk,node), rootfree ); - break; - } - else - { - if( root->node.child[1] ) - { - root = root->node.child[1]; - continue; - } - mmBTreeInsert( chunk, root, MM_BTREE_FLAGS_RIGHT, offsetof(mmVolumeChunk,node), rootfree ); - break; - } - } - return; -} - - - -void mmVolumeDebugList( mmVolumeHead *volumehead ) -{ - int32_t prevoffset, nextoffset, chunkflags, volumesize, nextcheck; - mmVolume *volume; - mmVolumeChunk *chunk; - - printf( "\n==== BEGIN ====\n" ); - fflush( stdout ); - - for( volume = volumehead->volumelist ; volume ; volume = volume->list.next ) - { - chunk = ADDRESS( volume, volumehead->volumeblocksize ); - - volumesize = 0; - nextcheck = 0; - - for( ; ; ) - { - chunkflags = MM_VOLUME_CHUNK_GET_FLAGS( chunk ); - nextoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - prevoffset = chunk->h.prevoffset; - - printf( "Chunk %p\n", chunk ); - printf( " Prevoffset : %d\n", prevoffset ); - printf( " Nextoffset : %d\n", nextoffset ); - printf( " Chunkflags : %d\n", chunkflags ); - fflush( stdout ); - - volumesize += nextoffset; - if( ( nextcheck ) && ( prevoffset != nextcheck ) ) - exit( 1 ); - nextcheck = nextoffset; - - if( chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ) - break; - - chunk = ADDRESS( chunk, nextoffset ); - } - - printf( "Volume size : %d\n", volumesize ); - printf( "\n" ); - } - - printf( "==== END ====\n\n" ); - fflush( stdout ); - - return; -} - - - - -/** - * Allocate memory from a volume. - * - * The function allocates a chunk of memory of arbitrary size from the - * specified volume manager. - */ -void *MM_FUNC(VolumeAlloc)( mmVolumeHead *head, size_t bytes MM_PARAMS ) -{ - int32_t chunkflags, nextoffset; - size_t allocsize, minsize, extrasize; - intptr_t vmem; - mmVolume *volume; - mmVolumeChunk *chunk, *newchunk, *nextchunk; - - mtSpinLock( &head->spinlock ); - - /* Big chunk handling */ - if( bytes >= MM_VOLUME_BIGCHUNK_THRESHOLD ) - { - allocsize = bytes + ( head->volumeblocksize + head->volumechunksize ); - - vmem = (intptr_t)head->relayalloc( head->relayvalue, allocsize MM_PASSPARAMS ); - volume = (void *)( ( vmem + head->alignment ) & ~head->alignment ); - volume->bigsize = allocsize; - volume->alignment = (intptr_t)volume - vmem; - mmListAdd( &head->volumelist, volume, offsetof(mmVolume,list) ); - - chunk = ADDRESS( volume, head->volumeblocksize ); - chunk->h.prevoffset = 0; - chunk->h.nextoffset = 0; - - mtSpinUnlock( &head->spinlock ); - return ADDRESS( chunk, head->volumechunksize ); - } - - /* Find best match among free chunks */ - bytes += head->volumechunksize; - if( bytes < head->minchunksize ) - bytes = head->minchunksize; - bytes = ( bytes + head->alignment ) & ~head->alignment; - chunk = mmVolumeFindFreeChunk( bytes, head->freeroot ); - - /* Allocate a new volume */ - if( !( chunk ) ) - { - allocsize = head->volumesize; - - /* Allocate new volume and add to list */ - minsize = bytes + ( head->volumeblocksize + head->volumechunksize ); - if( minsize > allocsize ) - allocsize = minsize; - - head->totalfreesize += allocsize - ( head->volumeblocksize + head->volumechunksize ); - - vmem = (intptr_t)head->relayalloc( head->relayvalue, allocsize MM_PASSPARAMS ); - volume = (void *)( ( vmem + head->alignment ) & ~head->alignment ); - volume->bigsize = 0; - volume->alignment = (intptr_t)volume - vmem; - mmListAdd( &head->volumelist, volume, offsetof(mmVolume,list) ); - - /* Add a free chunk to cover the whole volume */ - chunk = ADDRESS( volume, head->volumeblocksize ); - - chunk->h.prevoffset = 0; - allocsize -= head->volumeblocksize + volume->alignment; - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( chunk, allocsize, MM_VOLUME_CHUNK_FLAGS_FREE | MM_VOLUME_CHUNK_FLAGS_LAST ); - - mmVolumeAddFreeChunk( chunk, &head->freeroot ); - } - - /* Remove best match of free chunk from btree */ - mmBTreeRemove( chunk, offsetof(mmVolumeChunk,node), &head->freeroot ); - chunkflags = MM_VOLUME_CHUNK_GET_FLAGS( chunk ); - MM_VOLUME_CHUNK_SET_FLAGS( chunk, chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ); - - nextoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - head->totalfreesize -= nextoffset - head->volumechunksize; - extrasize = nextoffset - bytes; - if( extrasize >= head->minchunksize ) - { - /* Split and spawn a new free chunk */ - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( chunk, bytes, 0 ); - newchunk = ADDRESS( chunk, bytes ); - newchunk->h.prevoffset = bytes; - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( newchunk, extrasize, MM_VOLUME_CHUNK_FLAGS_FREE | ( chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ) ); - if( !( chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ) ) - { - nextchunk = ADDRESS( chunk, nextoffset ); - nextchunk->h.prevoffset = extrasize; - } - head->totalfreesize += extrasize - head->volumechunksize; - mmVolumeAddFreeChunk( newchunk, &head->freeroot ); - } - - mtSpinUnlock( &head->spinlock ); - return ADDRESS( chunk, head->volumechunksize ); -} - - -static mmVolumeChunk *mmVolumeMergeFree( mmVolumeHead *head, mmVolumeChunk *chunk ) -{ - int32_t nextoffset, chunkflags, next2offset; - mmVolumeChunk *prev, *next, *next2; - - prev = 0; - if( chunk->h.prevoffset ) - prev = ADDRESS( chunk, -chunk->h.prevoffset ); - chunkflags = MM_VOLUME_CHUNK_GET_FLAGS( chunk ); - nextoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - head->totalfreesize += nextoffset - head->volumechunksize; - next = 0; - if( !( chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ) ) - next = ADDRESS( chunk, nextoffset ); - if( ( prev ) && ( MM_VOLUME_CHUNK_GET_FLAGS( prev ) & MM_VOLUME_CHUNK_FLAGS_FREE ) ) - { - /* Merge free space with previous chunk */ - mmBTreeRemove( prev, offsetof(mmVolumeChunk,node), &head->freeroot ); - prev->h.nextoffset += nextoffset; - MM_VOLUME_CHUNK_SET_FLAGS( prev, chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ); - chunk = prev; - head->totalfreesize += head->volumechunksize; -/* - prev = 0; - if( chunk->h.prevoffset ) - prev = ADDRESS( chunk, -chunk->h.prevoffset ); -*/ - if( next ) - { - next->h.prevoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - if( MM_VOLUME_CHUNK_GET_FLAGS( next ) & MM_VOLUME_CHUNK_FLAGS_FREE ) - goto mergenext; - } - } - else if( ( next ) && ( MM_VOLUME_CHUNK_GET_FLAGS( next ) & MM_VOLUME_CHUNK_FLAGS_FREE ) ) - { - /* Merge free space with next chunk */ - mergenext: - mmBTreeRemove( next, offsetof(mmVolumeChunk,node), &head->freeroot ); - next2offset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( next ); - chunk->h.nextoffset += next2offset; - head->totalfreesize += head->volumechunksize; - if( MM_VOLUME_CHUNK_GET_FLAGS( next ) & MM_VOLUME_CHUNK_FLAGS_LAST ) - MM_VOLUME_CHUNK_SET_FLAGS( chunk, MM_VOLUME_CHUNK_FLAGS_FREE | MM_VOLUME_CHUNK_FLAGS_LAST ); - else - { - MM_VOLUME_CHUNK_SET_FLAGS( chunk, MM_VOLUME_CHUNK_FLAGS_FREE ); - next2 = ADDRESS( next, next2offset ); - next2->h.prevoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - } - } - else - { - /* Solitary free chunk */ - MM_VOLUME_CHUNK_SET_FLAGS( chunk, chunkflags | MM_VOLUME_CHUNK_FLAGS_FREE ); - } - - return chunk; -} - - -void MM_FUNC(VolumeRelease)( mmVolumeHead *head, void *v MM_PARAMS ) -{ - mmVolumeChunk *chunk; - mmVolume *volume; - - chunk = ADDRESS( v, -head->volumechunksize ); - mtSpinLock( &head->spinlock ); - - /* Big chunk handling */ - if( !( chunk->h.nextoffset ) ) - { - volume = ADDRESS( chunk, -head->volumeblocksize ); - mmListRemove( volume, offsetof(mmVolume,list) ); - head->relayfree( head->relayvalue, ADDRESS( volume, -volume->alignment ), volume->bigsize MM_PASSPARAMS ); - mtSpinUnlock( &head->spinlock ); - return; - } - - chunk = mmVolumeMergeFree( head, chunk ); - - /* Register the new free chunk */ - mmVolumeAddFreeChunk( chunk, &head->freeroot ); - - mtSpinUnlock( &head->spinlock ); - return; -} - - -/** - * Free a chunk of memory that was allocated by mmVolumeAlloc(). - * - * The flags parameter may contain the flag MM_VOLUME_FLAGS_RELEASE, which - * instructs the volume manager not to free unused memory, improving - * performance if the blocks are to be soon reused. - */ -void MM_FUNC(VolumeFree)( mmVolumeHead *head, void *v MM_PARAMS ) -{ - size_t totalfreesize; - mmVolumeChunk *chunk; - mmVolume *volume; - - chunk = ADDRESS( v, -head->volumechunksize ); - mtSpinLock( &head->spinlock ); - - /* Big chunk handling */ - if( !( chunk->h.nextoffset ) ) - { - volume = ADDRESS( chunk, -head->volumeblocksize ); - mmListRemove( volume, offsetof(mmVolume,list) ); - head->relayfree( head->relayvalue, ADDRESS( volume, -volume->alignment ), volume->bigsize MM_PASSPARAMS ); - mtSpinUnlock( &head->spinlock ); - return; - } - - chunk = mmVolumeMergeFree( head, chunk ); - - totalfreesize = head->totalfreesize - ( MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ) - head->volumechunksize ); - - /* If our free chunk is alone in there, free the whole volume */ - if( ( MM_VOLUME_CHUNK_GET_FLAGS( chunk ) & MM_VOLUME_CHUNK_FLAGS_LAST ) && !( chunk->h.prevoffset ) && ( totalfreesize >= head->keepfreesize ) ) - { - head->totalfreesize = totalfreesize; - volume = ADDRESS( chunk, -head->volumeblocksize ); - mmListRemove( volume, offsetof(mmVolume,list) ); - head->relayfree( head->relayvalue, ADDRESS( volume, -volume->alignment ), MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ) MM_PASSPARAMS ); - mtSpinUnlock( &head->spinlock ); - return; - } - - /* Register the new free chunk */ - mmVolumeAddFreeChunk( chunk, &head->freeroot ); - - mtSpinUnlock( &head->spinlock ); - return; -} - - - - -/** - * Shrink a chunk of memory that was allocated by mmVolumeAlloc(). - * - * The bytes parameter defines the new size of the chunk of memory. The - * specified pointer remains valid as the chunk is never relocated elsewhere. - * This function can not be used to attempt to increase the size of a chunk. - */ -void MM_FUNC(VolumeShrink)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS ) -{ - int32_t nextoffset, newoffset, chunkflags, nextflags, next2offset; - size_t freesize; - mmVolumeChunk *chunk, *next, *next2, *newchunk; - - chunk = ADDRESS( v, -head->volumechunksize ); - mtSpinLock( &head->spinlock ); - next = 0; - chunkflags = MM_VOLUME_CHUNK_GET_FLAGS( chunk ); - nextoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - if( !( chunkflags & MM_VOLUME_CHUNK_FLAGS_LAST ) ) - { - next = ADDRESS( chunk, nextoffset ); - nextflags = MM_VOLUME_CHUNK_GET_FLAGS( next ); - next2offset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( next ); - } - - bytes += head->volumechunksize; - if( bytes < head->minchunksize ) - bytes = head->minchunksize; - bytes = ( bytes + head->alignment ) & ~head->alignment; - freesize = nextoffset - bytes; - if( ( freesize < head->minchunksize ) && ( !( next ) || !( nextflags & MM_VOLUME_CHUNK_FLAGS_FREE ) ) ) - { - mtSpinUnlock( &head->spinlock ); - return; - } - newoffset = bytes; - - newchunk = ADDRESS( chunk, newoffset ); - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( chunk, newoffset, 0 ); - newchunk->h.prevoffset = newoffset; - head->totalfreesize += freesize - head->volumechunksize; - if( !( next ) ) - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( newchunk, freesize, MM_VOLUME_CHUNK_FLAGS_FREE | MM_VOLUME_CHUNK_FLAGS_LAST ); - else - { - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( newchunk, freesize, MM_VOLUME_CHUNK_FLAGS_FREE ); - if( !( nextflags & MM_VOLUME_CHUNK_FLAGS_FREE ) ) - next->h.prevoffset = freesize; - else - { - mmBTreeRemove( next, offsetof(mmVolumeChunk,node), &head->freeroot ); - MM_VOLUME_CHUNK_SET_NEXTOFFSET_AND_FLAGS( newchunk, freesize + next2offset, nextflags ); - if( !( nextflags & MM_VOLUME_CHUNK_FLAGS_LAST ) ) - { - next2 = ADDRESS( next, next2offset ); - next2->h.prevoffset = freesize + next2offset; - } - } - } - mmVolumeAddFreeChunk( newchunk, &head->freeroot ); - - mtSpinUnlock( &head->spinlock ); - return; -} - - -size_t MM_FUNC(VolumeGetAllocSize)( mmVolumeHead *head, void *v ) -{ - mmVolumeChunk *chunk; - chunk = ADDRESS( v, -head->volumechunksize ); - return MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ) - head->volumechunksize; -} - - -/** - * Inspect a volume manager and free unused pages of memory. - * - * This function may only free memory if MM_VOLUME_FLAGS_RELEASE was used when - * freeing chunks of memory allocated by the manager. - */ -void MM_FUNC(VolumeClean)( mmVolumeHead *head MM_PARAMS ) -{ - mmVolume *volume, *next; - mmVolumeChunk *chunk; - mtSpinLock( &head->spinlock ); - for( volume = head->volumelist ; volume ; volume = next ) - { - next = volume->list.next; - chunk = ADDRESS( volume, head->volumeblocksize ); - if( ( MM_VOLUME_CHUNK_GET_FLAGS(chunk) & MM_VOLUME_CHUNK_FLAGS_LAST ) && !( chunk->h.prevoffset ) ) - { - head->totalfreesize -= MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - mmListRemove( volume, offsetof(mmVolume,list) ); - head->relayfree( head->relayvalue, ADDRESS( volume, -volume->alignment ), MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ) MM_PASSPARAMS ); - } - } - mtSpinUnlock( &head->spinlock ); - return; -} - - -/** - * Free all memory allocated by the memory volume manager. - */ -void MM_FUNC(VolumeFreeAll)( mmVolumeHead *head MM_PARAMS ) -{ - int32_t nextoffset; - size_t volumesize; - mmVolume *volume, *next; - mmVolumeChunk *chunk; - mtSpinLock( &head->spinlock ); - for( volume = head->volumelist ; volume ; volume = next ) - { - next = volume->list.next; - chunk = ADDRESS( volume, head->volumeblocksize ); - volumesize = volume->bigsize; - if( chunk->h.nextoffset ) - { - volumesize = 0; - for( ; ; ) - { - nextoffset = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ); - volumesize += nextoffset; - if( MM_VOLUME_CHUNK_GET_FLAGS( chunk ) & MM_VOLUME_CHUNK_FLAGS_LAST ) - break; - chunk = ADDRESS( chunk, nextoffset ); - } - } - head->relayfree( head->relayvalue, ADDRESS( volume, -volume->alignment ), volumesize MM_PASSPARAMS ); - } - mtSpinUnlock( &head->spinlock ); - mtSpinDestroy( &head->spinlock ); - return; -} - - -void *MM_FUNC(VolumeRealloc)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS ) -{ - size_t chunksize; - void *newv; - mmVolumeChunk *chunk; - if( !( v ) ) - return MM_FUNC(VolumeAlloc)( head, bytes MM_PASSPARAMS ); - chunk = ADDRESS( v, -head->volumechunksize ); - chunksize = MM_VOLUME_CHUNK_GET_NEXTOFFSET( chunk ) - head->volumechunksize; - if( bytes < chunksize ) - { - MM_FUNC(VolumeShrink)( head, v, bytes MM_PASSPARAMS ); - return v; - } - newv = MM_FUNC(VolumeAlloc)( head, bytes MM_PASSPARAMS ); - memcpy( newv, v, chunksize ); - MM_FUNC(VolumeFree)( head, v MM_PASSPARAMS ); - return newv; -} - - - -//// - - -#ifdef MM_ZONE_SUPPORT - - -typedef struct -{ - int32_t flags; - void *next, *prev; -} mmZoneChunk; - -#define MM_ZONE_CHUNK_FLAGS_FREE (0x1) -#define MM_ZONE_CHUNK_FLAGS_LAST (0x2) - - -int MM_FUNC(ZoneInit)( mmZoneHead *head, size_t zonesize, intptr_t alignment MM_PARAMS ) -{ - mmZoneChunk *chunk; - - memset( head, 0, sizeof(mmZoneHead) ); - mtSpinInit( &head->spinlock ); - head->pagesize = sysconf( _SC_PAGESIZE ) - 1; - head->pagealignment = head->pagesize - 1; - zonesize = ( zonesize + head->pagealignment ) & ~head->pagealignment; - head->zonesize = zonesize; - mtSpinLock( &head->spinlock ); - - head->address = mmap( 0x0, head->zonesize, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); - if( head->address == MAP_FAILED ) - { -#ifdef MAP_NORESERVE - head->address = mmap( 0x0, head->zonesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0 ); - if( head->address == MAP_FAILED ) - return 0; -#else - return 0; -#endif - } - - head->alignment = 3; - if( alignment > 4 ) - head->alignment = alignment - 1; - head->chunkheadersize = ( sizeof(mmZoneChunk) + head->alignment ) & ~head->alignment; - - mprotect( head->address, head->pagesize, PROT_READ | PROT_WRITE ); - madvise( head->address, head->pagesize, MADV_NORMAL ); - chunk = head->address; - chunk->flags = MM_ZONE_CHUNK_FLAGS_FREE | MM_ZONE_CHUNK_FLAGS_LAST; - chunk->prev = 0; - chunk->next = ADDRESS( chunk, head->zonesize ); - head->chunklist = chunk; - - mtSpinUnlock( &head->spinlock ); - return 1; -} - - -void *MM_FUNC(ZoneAlloc)( mmZoneHead *head, size_t bytes MM_PARAMS ) -{ - int32_t lastflag, chunkflags; - mmZoneChunk *chunk, *newchunk, *nextchunk; - size_t chunknewsize, chunksize, unlocksize; - - bytes += head->chunkheadersize; - bytes = ( bytes + head->alignment ) & ~head->alignment; - - lastflag = 0; - for( chunk = head->chunklist ; ; chunk = chunk->next ) - { - if( lastflag ) - { - /* Our zone runs out of space? This is bad. Bad bad bad. */ - printf( "CRITICAL : Memory zone exhausted all virtual mapping space!\n" ); - return 0; - } - lastflag = chunk->flags & MM_ZONE_CHUNK_FLAGS_LAST; - if( !( chunk->flags & MM_ZONE_CHUNK_FLAGS_FREE ) ) - continue; - chunksize = ADDRESSDIFF( chunk->next, chunk ); - if( chunksize >= bytes ) - break; - } - - chunkflags = chunk->flags; - chunknewsize = ( bytes + head->pagealignment ) & ~head->pagealignment; - if( ( chunksize - chunknewsize ) >= head->pagesize ) - { - chunk->flags = 0; - newchunk = ADDRESS( chunk, chunknewsize ); - unlocksize = chunknewsize + head->chunkheadersize; - mprotect( chunk, unlocksize, PROT_READ | PROT_WRITE ); - madvise( chunk, unlocksize, MADV_NORMAL ); - newchunk->flags = chunkflags; - newchunk->prev = chunk; - newchunk->next = chunk->next; - if( !( chunkflags & MM_ZONE_CHUNK_FLAGS_LAST ) ) - { - nextchunk = chunk->next; - nextchunk->prev = newchunk; - } - chunk->next = newchunk; - } - else - { - chunk->flags &= ~MM_ZONE_CHUNK_FLAGS_FREE; - mprotect( chunk, chunknewsize, PROT_READ | PROT_WRITE ); - madvise( chunk, chunknewsize, MADV_NORMAL ); - } - - return ADDRESS( chunk, head->chunkheadersize ); -} - - -void MM_FUNC(ZoneFree)( mmZoneHead *head, void *v MM_PARAMS ) -{ - mmZoneChunk *chunk, *prevchunk, *nextchunk, *next2chunk; - size_t extrasize; - void *page; - - chunk = ADDRESS( v, -head->chunkheadersize ); - page = (void *)( ( (intptr_t)v + head->pagealignment ) & ~head->pagealignment ); - extrasize = ADDRESSDIFF( chunk->next, page ); - mprotect( page, extrasize, PROT_READ ); - madvise( page, extrasize, MADV_DONTNEED ); - - chunk->flags |= MM_ZONE_CHUNK_FLAGS_FREE; - prevchunk = chunk->prev; - nextchunk = 0; - if( !( chunk->flags & MM_ZONE_CHUNK_FLAGS_LAST ) ) - nextchunk = chunk->next; - - if( ( nextchunk ) && ( nextchunk->flags & MM_ZONE_CHUNK_FLAGS_FREE ) ) - { - chunk->next = nextchunk->next; - chunk->flags |= nextchunk->flags & MM_ZONE_CHUNK_FLAGS_LAST; - next2chunk = 0; - if( !( nextchunk->flags & MM_ZONE_CHUNK_FLAGS_LAST ) ) - { - next2chunk = nextchunk->next; - next2chunk->prev = chunk; - } - mprotect( nextchunk, head->pagesize, PROT_READ ); - madvise( nextchunk, head->pagesize, MADV_DONTNEED ); - nextchunk = 0; - if( !( chunk->flags & MM_ZONE_CHUNK_FLAGS_LAST ) ) - nextchunk = chunk->next; - } - - if( ( prevchunk ) && ( prevchunk->flags & MM_ZONE_CHUNK_FLAGS_FREE ) ) - { - prevchunk->next = chunk->next; - if( nextchunk ) - nextchunk->prev = prevchunk; - mprotect( chunk, head->pagesize, PROT_READ ); - madvise( chunk, head->pagesize, MADV_DONTNEED ); - } - - return; -} - - -void MM_FUNC(ZoneFreeAll)( mmZoneHead *head MM_PARAMS ) -{ - mtSpinLock( &head->spinlock ); - munmap( head->address, head->zonesize ); - mtSpinUnlock( &head->spinlock ); - return; -} - - -#endif - - - -//// - - - -#if MM_DEBUG - -#undef malloc -#undef free -#undef realloc - -#endif - -#undef mmDebugAlloc -#undef mmDebugFree -#undef mmDebugRealloc -#undef mmListUses - - -typedef struct -{ - char *file; - int line; - size_t size; - size_t count; - mmListNode list; -#if MM_DEBUG_GUARD_BYTES - char guard[MM_DEBUG_GUARD_BYTES]; -#endif -} mmChunk; - -static void *mmChunkList = 0; -static size_t mmCount = 0; -static size_t mmMaxCount = 0; - - -void *mmDebugAlloc( size_t bytes, char *file, int line ) -{ -#if MM_DEBUG_GUARD_BYTES - int guard; - char *endguard; -#endif - mmChunk *chunk; - mtMutexLock( &mmGlobalMutex ); -#if MM_DEBUG_MMAP - if( !( chunk = mmap( 0, sizeof(mmChunk) + bytes + MM_DEBUG_GUARD_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ) ) ) -#else - if( !( chunk = malloc( sizeof(mmChunk) + bytes + MM_DEBUG_GUARD_BYTES ) ) ) -#endif - { -#if MM_WINDOWS - fprintf( stderr, "FATAL : Denied memory allocation ( %ld ) at %s:%d !\nExiting\n", (long)bytes, file, line ); -#else - fprintf( stderr, "FATAL : Denied memory allocation ( %lld ) at %s:%d !\nExiting\n", (long long)bytes, file, line ); -#endif - exit( 1 ); - } - mmListAdd( &mmChunkList, chunk, offsetof(mmChunk,list) ); - chunk->file = file; - chunk->line = line; - chunk->size = bytes; -#if MM_DEBUG_GUARD_BYTES - endguard = ADDRESS( chunk, sizeof(mmChunk) + bytes ); - for( guard = 0 ; guard < MM_DEBUG_GUARD_BYTES ; guard++ ) - { - chunk->guard[guard] = 0x55; - endguard[guard] = 0x75; - } -#endif - mmCount += bytes; - if( mmCount > mmMaxCount ) - mmMaxCount = mmCount; - mtMutexUnlock( &mmGlobalMutex ); - return ADDRESS( chunk, sizeof(mmChunk) ); -} - - -void *mmDebugRealloc( void *v, size_t bytes, char *file, int line ) -{ - size_t size; - mmChunk *chunk; - void *newchunk = 0; - newchunk = mmDebugAlloc( bytes, file, line ); - if( v ) - { - size = bytes; - chunk = ADDRESS( v, -sizeof(mmChunk) ); - if( chunk->size < size ) - size = chunk->size; - if( size ) - memcpy( newchunk, v, size ); - mmDebugFree( v, file, line ); - } - return newchunk; -} - - -void mmDebugFree( void *v, char *file, int line ) -{ - mmChunk *chunk; -#if MM_DEBUG_GUARD_BYTES - int guard; - char *endguard; -#endif - chunk = ADDRESS( v, -sizeof(mmChunk) ); -#if MM_DEBUG_GUARD_BYTES - endguard = ADDRESS( chunk, sizeof(mmChunk) + chunk->size ); - for( guard = 0 ; guard < MM_DEBUG_GUARD_BYTES ; guard++ ) - { - if( chunk->guard[guard] != 0x55 ) - { - fprintf( stderr, "MALLOC START[%d] GUARD ERROR : Corruption of %s:%d\n", guard, chunk->file, chunk->line ); - exit( 1 ); - } - if( endguard[guard] != 0x75 ) - { - fprintf( stderr, "MALLOC END[%d] GUARD ERROR : Corruption of %s:%d\n", guard, chunk->file, chunk->line ); - exit( 1 ); - } - } -#endif - mtMutexLock( &mmGlobalMutex ); - mmListRemove( chunk, offsetof(mmChunk,list) ); - mmCount -= chunk->size; -#if MM_DEBUG_MMAP - #if MM_DEBUG_MMAP_LINGERING - mprotect( chunk, sizeof(mmChunk) + chunk->size + MM_DEBUG_GUARD_BYTES, PROT_NONE ); - #else - munmap( chunk, sizeof(mmChunk) + chunk->size + MM_DEBUG_GUARD_BYTES ); - #endif -#else - free( chunk ); -#endif - mtMutexUnlock( &mmGlobalMutex ); - return; -} - - -void *mmAlloc( void *unused, size_t bytes MM_PARAMS ) -{ -#if MM_DEBUG - return mmDebugAlloc( bytes MM_PASSPARAMS ); -#else - void *chunk; - #if MM_WINDOWS - if( !( chunk = malloc( bytes ) ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %ld )!\nExiting\n", (long)bytes ); - #else - if( !( chunk = malloc( bytes ) ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %lld )!\nExiting\n", (long long)bytes ); - #endif - return chunk; -#endif -} - - -void *mmRealloc( void *unused, void *v, size_t bytes MM_PARAMS ) -{ -#if MM_DEBUG - return mmDebugRealloc( v, bytes MM_PASSPARAMS ); -#else - #if MM_WINDOWS - if( !( v = realloc( v, bytes ) ) && ( bytes ) ) - fprintf( stderr, "WARNING : Denied memory reallocation ( %ld )!\nExiting\n", (long)bytes ); - #else - if( !( v = realloc( v, bytes ) ) && ( bytes ) ) - fprintf( stderr, "WARNING : Denied memory reallocation ( %lld )!\nExiting\n", (long long)bytes ); - #endif - return v; -#endif -} - - -void mmFree( void *unused, void *v, size_t bytes MM_PARAMS ) -{ -#if MM_DEBUG - mmDebugFree( v MM_PASSPARAMS ); -#else - free( v ); -#endif - return; -} - - - -/** - * Private function to add the sorted memory item in the linked list. - */ -static void mmListSortAdd( mmChunk *chunk, void **sortlist ) -{ - intptr_t i; - char *s0, *s1; - mmChunk *sortchunk; - s0 = chunk->file; - for( ; *sortlist ; sortlist = &sortchunk->list.next ) - { - sortchunk = *sortlist; - s1 = sortchunk->file; - for( i = 0 ; ; i++ ) - { - if( s0[i] < s1[i] ) - goto insert; - if( s0[i] > s1[i] ) - break; - if( s1[i] ) - continue; - if( chunk->line > sortchunk->line ) - break; - goto insert; - } - } - insert: - mmListAdd( sortlist, chunk, offsetof(mmChunk,list) ); - return; -} - - -/** - * List all memory allocations at any time and print the results on stdout. - */ -void mmListUses( char *file, int line ) -{ - mmChunk *chunk; - mmChunk *chunksort; - void *sortlist; - size_t totalsize; - mtMutexLock( &mmGlobalMutex ); - printf( "-- Memory allocation listing at %s:%d --\n", file, line ); - if( !( mmChunkList ) ) - { - printf( " List empty\n\n" ); - mtMutexUnlock( &mmGlobalMutex ); - return; - } - sortlist = 0; - for( chunk = mmChunkList ; chunk ; chunk = chunk->list.next ) - { - for( chunksort = sortlist ; chunksort ; chunksort = chunksort->list.next ) - { - if( chunk->file != chunksort->file ) - continue; - if( chunk->line != chunksort->line ) - continue; - goto found; - } - if( !( chunksort = malloc( sizeof(mmChunk) ) ) ) - { - mtMutexUnlock( &mmGlobalMutex ); - return; - } - memset( chunksort, 0, sizeof(mmChunk) ); - chunksort->file = chunk->file; - chunksort->line = chunk->line; - chunksort->count = 0; - mmListSortAdd( chunksort, &sortlist ); - found: - chunksort->size += chunk->size; - chunksort->count++; - } - totalsize = 0; - for( chunksort = sortlist ; chunksort ; chunksort = chunk ) - { - printf( " %10ld bytes in %6ld chunk(s) allocated at %s:%d\n", (long)chunksort->size, (long)chunksort->count, chunksort->file, chunksort->line ); - totalsize += chunksort->size; - chunk = chunksort->list.next; - free( chunksort ); - } -#if MM_WINDOWS - printf( " %10ld bytes total\n", (long)totalsize ); - printf( " %10ld bytes maximum reached\n\n", (long)mmMaxCount ); -#else - printf( " %10lld bytes total\n", (long long)totalsize ); - printf( " %10lld bytes maximum reached\n\n", (long long)mmMaxCount ); -#endif - mtMutexUnlock( &mmGlobalMutex ); - return; -} - - - -//// - - - -#ifdef __WIN32__ - -#include -#include - -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL - -int mmGetTimeOfDay( struct timeval *tv ) -{ - FILETIME ft; - uint64_t curtime; - if( tv ) - { - GetSystemTimeAsFileTime( &ft ); - curtime = ft.dwHighDateTime; - curtime <<= 32; - curtime |= ft.dwLowDateTime; - curtime /= 10; - curtime -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long)( curtime / 1000000UL ); - tv->tv_usec = (long)( curtime % 1000000UL ); - } - return 0; -} - -#endif - - - diff --git a/src/other/gct/Auxiliary/mm.h b/src/other/gct/Auxiliary/mm.h deleted file mode 100644 index 719ff431d34..00000000000 --- a/src/other/gct/Auxiliary/mm.h +++ /dev/null @@ -1,776 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ -/** - * @file - * - * Global memory management header. - */ - - -#ifndef MM_H -#define MM_H - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#define MM_DEBUG 0 - -#define MM_INLINE_LIST_FUNCTIONS - -#define MM_ALLOC_CHECK - - -#define MM_DEBUG_GUARD_BYTES (32) -#define MM_DEBUG_MMAP (1) -/* Enabling this will lead to ever growing memory usage! Strictly for debugging. */ -#define MM_DEBUG_MMAP_LINGERING (0) - - - -//// - - -#ifdef MM_NUMA - #include -#endif - - -#if defined(__linux__) || defined(__gnu_linux__) || defined(__linux) || defined(__linux) - #define MM_LINUX (1) - #define MM_UNIX (1) -#elif defined(__APPLE__) - #define MM_OSX (1) - #define MM_UNIX (1) -#elif defined(__unix__) || defined(__unix) || defined(unix) - #define MM_UNIX (1) -#elif defined(_WIN64) || defined(__WIN64__) || defined(WIN64) - #define MM_WIN64 (1) - #define MM_WIN32 (1) - #define MM_WINDOWS (1) -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - #define MM_WIN32 (1) - #define MM_WINDOWS (1) -#endif - -#if __MINGW64__ - #define MM_MINGW32 (1) - #define MM_MINGW64 (1) -#elif __MINGW32__ - #define MM_MINGW32 (1) -#endif - - -#if !MM_UNIX - #undef MM_DEBUG_MMAP - #define MM_DEBUG_MMAP (0) -#endif - - -#define MM_CPU_COUNT_MAXIMUM (1024) -#define MM_NODE_COUNT_MAXIMUM (256) - - -#ifndef CPUCONF_CACHE_LINE_SIZE - #define CPUCONF_CACHE_LINE_SIZE 64 -#endif - - -#if defined(__GNUC__) - #define MM_CACHE_ALIGN __attribute__((aligned(CPUCONF_CACHE_LINE_SIZE))) - #define MM_RESTRICT __restrict - #define MM_NOINLINE __attribute__((noinline)) -#else - #define MM_CACHE_ALIGN - #define MM_RESTRICT - #define MM_NOINLINE -#endif - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - #define MM_ALIGN16 __attribute__((aligned(16))) - #define MM_ALIGN16_SAFE (1) -#elif defined(_MSC_VER) - #define MM_ALIGN16 __declspec(align(16)) - #define MM_ALIGN16_SAFE (1) -#else - #define MM_ALIGN16 - #define MM_ALIGN16_SAFE (0) -#endif - - - -#define MM_ERROR() {printf("MM Error at %s:%d\n",file,line);exit(1)} - -#ifndef ADDRESS - #define ADDRESS(p,o) ((void *)(((char *)p)+(o))) -#endif - -#ifndef ADDRESSDIFF - #define ADDRESSDIFF(a,b) (((char *)a)-((char *)b)) -#endif - - -#include - -#ifdef __WIN32__ -int mmGetTimeOfDay( struct timeval *tv ); -#define gettimeofday(a,b) mmGetTimeOfDay(a) -#endif - - -typedef struct -{ - int numaflag; - int pagesize; - int cpucount; - int nodecount; - int cpunode[MM_CPU_COUNT_MAXIMUM]; - int64_t nodesize[MM_NODE_COUNT_MAXIMUM]; - int nodecpucount[MM_NODE_COUNT_MAXIMUM]; - int64_t sysmemory; -} mmContext; - -extern mmContext mmcontext; - - -#include "mmatomic.h" -#include "mmthread.h" - - -#if MM_DEBUG - #define MM_FUNC(n) mm##n##Debug - #define MM_PARAMS , char *file, int line -#else - #define MM_FUNC(n) mm##n - #define MM_PARAMS -#endif - - -//// - - -void mmInit(); -void mmEnd(); - - -void mmThreadBindToNode( int nodeindex ); -void mmThreadBindToNode( int nodeindex ); -void mmThreadBindToCpu( int cpuindex ); -int mmCpuGetNode( int cpuindex ); - -void *mmNodeAlloc( int nodeindex, size_t size ); -void mmNodeFree( int nodeindex, void *v, size_t size ); -void mmNodeMap( int nodeindex, void *start, size_t bytes ); - -void *mmNodeAlignAlloc( int nodeindex, size_t size, intptr_t align ); -void mmNodeAlignFree( int nodeindex, void *v, size_t size ); - - - -//// - - - -typedef struct -{ - void **prev; - void *next; -} mmListNode; - -typedef struct -{ - void *first; - void **last; -} mmListDualHead; - -typedef struct -{ - void *first; - void *last; -} mmListLoopHead; - -#ifndef MM_INLINE_LIST_FUNCTIONS - -void mmListAdd( void **list, void *item, intptr_t offset ); -void mmListRemove( void *item, intptr_t offset ); -void mmListMergeList( void **listdst, void **listsrc, intptr_t offset ); -void mmListMoveList( void **listdst, void **listsrc, intptr_t offset ); - -void mmListDualInit( mmListDualHead *head ); -void mmListDualAddFirst( mmListDualHead *head, void *item, intptr_t offset ); -void mmListDualAddLast( mmListDualHead *head, void *item, intptr_t offset ); -void mmListDualRemove( mmListDualHead *head, void *item, intptr_t offset ); -void *mmListDualLast( mmListDualHead *head, intptr_t offset ); - -#else - -static inline void mmListAdd( void **list, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - node->prev = list; - node->next = *list; - if( *list ) - { - next = ADDRESS( *list, offset ); - next->prev = &(node->next); - } - *list = item; - return; -} - -static inline void mmListRemove( void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - *(node->prev) = (void *)node->next; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = node->prev; - } - return; -} - -static inline void mmListMergeList( void **listdst, void **listsrc, intptr_t offset ) -{ - void *item; - mmListNode *node; - if( !( *listsrc ) ) - return; - for( item = *listdst ; item ; item = node->next ) - { - node = ADDRESS( item, offset ); - listdst = &node->next; - } - item = *listsrc; - node = ADDRESS( item, offset ); - node->prev = listdst; - *listdst = item; - *listsrc = 0; - return; -} - -static inline void mmListMoveList( void **listdst, void **listsrc, intptr_t offset ) -{ - void *item; - mmListNode *node; - if( !( *listsrc ) ) - { - *listdst = 0; - return; - } - item = *listsrc; - node = ADDRESS( item, offset ); - node->prev = listdst; - *listdst = item; - *listsrc = 0; - return; -} - -static inline void mmListDualInit( mmListDualHead *head ) -{ - head->first = 0; - head->last = &head->first; - return; -} - -static inline void mmListDualAddFirst( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - node->prev = &head->first; - node->next = head->first; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = &(node->next); - } - else - head->last = &(node->next); - head->first = item; - return; -} - -static inline void mmListDualAddLast( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node; - void **prev; - prev = head->last; - *prev = item; - node = ADDRESS( item, offset ); - node->prev = head->last; - head->last = &(node->next); - node->next = 0; - return; -} - -static inline void mmListDualRemove( mmListDualHead *head, void *item, intptr_t offset ) -{ - mmListNode *node, *next; - node = ADDRESS( item, offset ); - *(node->prev) = (void *)node->next; - if( node->next ) - { - next = ADDRESS( node->next, offset ); - next->prev = node->prev; - } - else - head->last = node->prev; - return; -} - -static inline void *mmListDualLast( mmListDualHead *head, intptr_t offset ) -{ - if( !( head->first ) ) - return 0; - return ADDRESS( head->last, -( offset + offsetof(mmListNode,next) ) ); -} - -#endif - -void mmListLoopInit( mmListLoopHead *head ); -void mmListLoopAddFirst( mmListLoopHead *head, void *item, intptr_t offset ); -void mmListLoopAddLast( mmListLoopHead *head, void *item, intptr_t offset ); -void mmListLoopInsert( mmListLoopHead *head, void *previtem, void *item, intptr_t offset ); -void mmListLoopRemove( mmListLoopHead *head, void *item, intptr_t offset ); -void *mmListLoopLast( mmListLoopHead *head, intptr_t offset ); - - - -//// - - - -typedef struct -{ - void *child[2]; - void *parent; - int flags; -} mmBTreeNode; - -#define MM_BTREE_FLAGS_LEFT (0) -#define MM_BTREE_FLAGS_RIGHT (1) -#define MM_BTREE_FLAGS_DIRECTION_MASK (1) -#define MM_BTREE_FLAGS_STEP (2) - -void mmBTreeInsert( void *item, void *parent, int itemflag, intptr_t offset, void **root ); -void mmBTreeRemove( void *item, intptr_t offset, void **root ); - -void *mmBtreeMostLeft( void *root, intptr_t offset ); -void *mmBtreeMostRight( void *root, intptr_t offset ); -void *mmBtreeNeighbourLeft( void *item, intptr_t offset ); -void *mmBtreeNeighbourRight( void *item, intptr_t offset ); -intptr_t mmBtreeItemCount( void *root, intptr_t offset ); -int mmBtreeListOrdered( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v ); -int mmBtreeListBalanced( void *root, intptr_t offset, int (*callback)( void *item, void *v ), void *v ); - - - -//// - - - -typedef struct -{ - mmListNode listnode; - mmBTreeNode node; - int freecount; - int blockindex; -} mmBlock; - -typedef struct -{ - void *blocklist; - void *freelist; - size_t chunksize; - int chunkperblock; - int alignment; - size_t allocsize; - int keepfreecount; - int chunkfreecount; - void *treeroot; - void *(*relayalloc)( void *head, size_t bytes MM_PARAMS ); - void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS ); - void *relayvalue; - mtSpin spinlock; -} mmBlockHead; - -void MM_FUNC(BlockInit)( mmBlockHead *head, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS ); -void MM_FUNC(BlockNodeInit)( mmBlockHead *head, int nodeindex, size_t chunksize, int chunkperblock, int keepfreecount, int alignment MM_PARAMS ); -void *MM_FUNC(BlockAlloc)( mmBlockHead *head MM_PARAMS ); -void MM_FUNC(BlockRelease)( mmBlockHead *head, void *v MM_PARAMS ); -void MM_FUNC(BlockFree)( mmBlockHead *head, void *v MM_PARAMS ); -void MM_FUNC(BlockFreeAll)( mmBlockHead *head MM_PARAMS ); -void MM_FUNC(BlockProcessList)( mmBlockHead *head, void *userpointer, int (*processchunk)( void *chunk, void *userpointer ) MM_PARAMS ); -int MM_FUNC(BlockUseCount)( mmBlockHead *head MM_PARAMS ); -int MM_FUNC(BlockFreeCount)( mmBlockHead *head MM_PARAMS ); - -#if MM_DEBUG - #define mmBlockInit(v,w,x,y,z) MM_FUNC(BlockInit)(v,w,x,y,z,__FILE__,__LINE__) - #define mmBlockNodeInit(u,v,w,x,y,z) MM_FUNC(BlockNodeInit)(u,v,w,x,y,z,__FILE__,__LINE__) - #define mmBlockAlloc(x) MM_FUNC(BlockAlloc)(x,__FILE__,__LINE__) - #define mmBlockRelease(x,y) MM_FUNC(BlockRelease)(x,y,__FILE__,__LINE__) - #define mmBlockFree(x,y) MM_FUNC(BlockFree)(x,y,__FILE__,__LINE__) - #define mmBlockFreeAll(x) MM_FUNC(BlockFreeAll)(x,__FILE__,__LINE__) - #define mmBlockProcessList(x,y,z) MM_FUNC(BlockProcessList)(x,y,z,__FILE__,__LINE__) - #define mmBlockUseCount(x) MM_FUNC(BlockProcessList)(x,__FILE__,__LINE__) - #define mmBlockFreeCount(x) MM_FUNC(BlockProcessList)(x,__FILE__,__LINE__) -#endif - -/* -void mmBlockRelayByVolume( mmBlockHead *head, void *volumehead ); -void mmBlockRelayByZone( mmBlockHead *head, void *zonehead ); -*/ - - - -//// - - - -typedef struct -{ - mmBlockHead indexblock; - void *indextree; - intptr_t indexlimit; - mtSpin spinlock; -} mmIndexHead; - -void mmIndexInit( mmIndexHead *head, int indexesperblock ); -void mmIndexFreeAll( mmIndexHead *head ); -void mmIndexAdd( mmIndexHead *head, intptr_t index ); -intptr_t mmIndexGet( mmIndexHead *head ); -int mmIndexRemove( mmIndexHead *head, intptr_t index ); -size_t mmIndexCount( mmIndexHead *head ); - - - -//// - - - -typedef struct -{ - uintptr_t bitmask; - int bitshift; - uintptr_t countalign; - uintptr_t indexshift; - uintptr_t indexmask; - uintptr_t initmask; - size_t mapsize; - uintptr_t *map; - mtSpin spinlock; -} mmBitTableHead; - -void mmBitTableInit( mmBitTableHead *head, int bitsperentry, int chunksize, int initmask ); -void mmBitTableFreeAll( mmBitTableHead *head ); -void mmBitTableSet( mmBitTableHead *head, uintptr_t index, int flags, int editmask ); -uintptr_t mmBitTableGet( mmBitTableHead *head, uintptr_t index ); - - - -//// - - - -typedef struct -{ - size_t size; - size_t used; - void *next; -} mmGrowNode; - -typedef struct -{ - mmGrowNode *first; - size_t nodesize; - mtSpin spinlock; -} mmGrow; - -int MM_FUNC(GrowInit)( mmGrow *mgrow, size_t nodesize MM_PARAMS ); -void MM_FUNC(GrowFreeAll)( mmGrow *mgrow MM_PARAMS ); -void *MM_FUNC(GrowAlloc)( mmGrow *mgrow, size_t bytes MM_PARAMS ); - -#if MM_DEBUG - #define mmGrowInit(x,y) MM_FUNC(GrowInit)(x,y,__FILE__,__LINE__) - #define mmGrowFreeAll(x) MM_FUNC(GrowFreeAll)(x,__FILE__,__LINE__) - #define mmGrowAlloc(x,y) MM_FUNC(GrowAlloc)(x,y,__FILE__,__LINE__) -#endif - - - -//// - - -#if 0 - -typedef struct -{ - void ***table; - intptr_t pagecount; - intptr_t pagesize; - intptr_t pagemask; - intptr_t pageshift; - mtSpin spinlock; -} mmDirectory; - -#define MM_DIR_ENTRY(dir,index) ( (dir)->table[ index >> (dir)->pageshift ][ index & (dir)->pagemask ] ) - -int MM_FUNC(DirInit)( mmDirectory *dir, intptr_t pageshift, intptr_t pagecount MM_PARAMS ); -void MM_FUNC(DirSize)( mmDirectory *dir, intptr_t size MM_PARAMS ); -void MM_FUNC(DirSet)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS ); -void *MM_FUNC(DirGet)( mmDirectory *dir, intptr_t index MM_PARAMS ); -void MM_FUNC(DirSetFast)( mmDirectory *dir, intptr_t index, void *entry MM_PARAMS ); -void *MM_FUNC(DirGetFast)( mmDirectory *dir, intptr_t index MM_PARAMS ); -void MM_FUNC(DirFree)( mmDirectory *dir MM_PARAMS ); - -#if MM_DEBUG - #define mmDirInit(x,y,z) MM_FUNC(DirInit)(x,y,z,__FILE__,__LINE__) - #define mmDirSize(x,y) MM_FUNC(DirSize)(x,y,__FILE__,__LINE__) - #define mmDirSet(x,y,z) MM_FUNC(DirSet)(x,y,z,__FILE__,__LINE__) - #define mmDirGet(x,y) MM_FUNC(DirGet)(x,y,__FILE__,__LINE__) - #define mmDirSetFast(x,y,z) MM_FUNC(DirSetFast)(x,y,z,__FILE__,__LINE__) - #define mmDirGetFast(x,y) MM_FUNC(DirGetFast)(x,y,__FILE__,__LINE__) - #define mmDirFree(x) MM_FUNC(DirFree)(x,__FILE__,__LINE__) -#endif - -#endif - - -//// - - - -void *MM_FUNC(AlignAlloc)( size_t bytes, intptr_t align MM_PARAMS ); -void MM_FUNC(AlignFree)( void *v MM_PARAMS ); -void *MM_FUNC(AlignGrow)( void *v, size_t bytes, size_t copybytes, intptr_t align MM_PARAMS ); -void *MM_FUNC(AlignRelayAlloc)( void *(*relayalloc)( void *head, size_t bytes MM_PARAMS ), void *relayvalue, size_t bytes, intptr_t align, size_t displacement MM_PARAMS ); -void MM_FUNC(AlignRelayFree)( void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS ), void *relayvalue, void *v, size_t bytes MM_PARAMS ); - -#if MM_DEBUG - #define mmAlignAlloc(x,y) MM_FUNC(AlignAlloc)(x,y,__FILE__,__LINE__) - #define mmAlignFree(x) MM_FUNC(AlignFree)(x,__FILE__,__LINE__) - #define mmAlignGrow(x) MM_FUNC(AlignGrow)(x,__FILE__,__LINE__) - #define mmAlignRelayAlloc(v,w,x,y,z) MM_FUNC(AlignRelayAlloc)(v,w,x,y,z,__FILE__,__LINE__) - #define mmAlignRelayFree(w,x,y,z) MM_FUNC(AlignRelayFree)(w,x,y,z,__FILE__,__LINE__) -#endif - - - -//// - - - -typedef struct -{ - size_t volumesize; - size_t volumeblocksize; - size_t minchunksize; - size_t volumechunksize; - size_t keepfreesize; - size_t totalfreesize; - size_t alignment; - void *freeroot; - void *volumelist; - void *(*relayalloc)( void *head, size_t bytes MM_PARAMS ); - void (*relayfree)( void *head, void *v, size_t bytes MM_PARAMS ); - void *relayvalue; - mtSpin spinlock; -} mmVolumeHead; - -void MM_FUNC(VolumeInit)( mmVolumeHead *head, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS ); -void MM_FUNC(VolumeNodeInit)( mmVolumeHead *head, int nodeindex, size_t volumesize, size_t minchunksize, size_t keepfreesize, size_t alignment MM_PARAMS ); -void *MM_FUNC(VolumeAlloc)( mmVolumeHead *head, size_t bytes MM_PARAMS ); -void MM_FUNC(VolumeRelease)( mmVolumeHead *head, void *v MM_PARAMS ); -void MM_FUNC(VolumeFree)( mmVolumeHead *head, void *v MM_PARAMS ); -void MM_FUNC(VolumeShrink)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS ); -size_t MM_FUNC(VolumeGetAllocSize)( mmVolumeHead *head, void *v ); -void MM_FUNC(VolumeClean)( mmVolumeHead *head MM_PARAMS ); -void MM_FUNC(VolumeFreeAll)( mmVolumeHead *head MM_PARAMS ); -void *MM_FUNC(VolumeRealloc)( mmVolumeHead *head, void *v, size_t bytes MM_PARAMS ); - -#if MM_DEBUG - #define mmVolumeInit(w,x,y,z,a) MM_FUNC(VolumeInit)(w,x,y,z,a,__FILE__,__LINE__); - #define mmVolumeNodeInit(v,w,x,y,z) MM_FUNC(VolumeNodeInit)(v,w,x,y,z,__FILE__,__LINE__); - #define mmVolumeAlloc(x,y) MM_FUNC(VolumeAlloc)(x,y,__FILE__,__LINE__); - #define mmVolumeRelease(x,y) MM_FUNC(VolumeRelease)(x,y,__FILE__,__LINE__); - #define mmVolumeFree(x,y) MM_FUNC(VolumeFree)(x,y,__FILE__,__LINE__); - #define mmVolumeShrink(x,y,z) MM_FUNC(VolumeShrink)(x,y,z,__FILE__,__LINE__); - #define mmVolumeGetAllocSize(x) MM_FUNC(VolumeGetAllocSize)(x,y,__FILE__,__LINE__); - #define mmVolumeClean(x) MM_FUNC(VolumeClean)(x,__FILE__,__LINE__); - #define mmVolumeFreeAll(x) MM_FUNC(VolumeFreeAll)(x,__FILE__,__LINE__); - #define mmVolumeRealloc(x) MM_FUNC(VolumeRealloc)(x,y,z,__FILE__,__LINE__); - - #define mmVolumeAlloc MM_FUNC(VolumeAlloc) - #define mmVolumeRelease MM_FUNC(VolumeRelease) - #define mmVolumeFree MM_FUNC(VolumeFree) - -#endif - -/* -void mmVolumeRelayByZone( mmVolumeHead *head, void *zonehead ); -*/ - - - -//// - - - -typedef struct -{ - void *address; - size_t pagesize; - size_t pagealignment; - size_t zonesize; - size_t alignment; - size_t chunkheadersize; - void *chunklist; - mtSpin spinlock; -} mmZoneHead; - -int MM_FUNC(ZoneInit)( mmZoneHead *head, size_t zonesize, intptr_t alignment MM_PARAMS ); -void *MM_FUNC(ZoneAlloc)( mmZoneHead *head, size_t bytes MM_PARAMS ); -void MM_FUNC(ZoneFree)( mmZoneHead *head, void *v MM_PARAMS ); -void MM_FUNC(ZoneFreeAll)( mmZoneHead *head MM_PARAMS ); - -#if MM_DEBUG - #define mmZoneInit(x,y,z) MM_FUNC(ZoneInit)(x,y,z,__FILE__,__LINE__); - #define mmZoneAlloc(x,y) MM_FUNC(ZoneAlloc)(x,y,__FILE__,__LINE__); - #define mmZoneFree(x,y) MM_FUNC(ZoneFree)(x,y,__FILE__,__LINE__); - #define mmZoneFreeAll(x) MM_FUNC(ZoneFreeAll)(x,__FILE__,__LINE__); -#endif - - - -//// - - - -void *mmAlloc( void *unused, size_t bytes MM_PARAMS ); -void *mmRealloc( void *unused, void *v, size_t bytes MM_PARAMS ); -void mmFree( void *unused, void *v, size_t bytes MM_PARAMS ); - -void *mmDebugAlloc( size_t bytes, char *file, int line ); -void *mmDebugRealloc( void *v, size_t bytes, char *file, int line ); -void mmDebugFree( void *v, char *file, int line ); -#define mmDebugAlloc(x) mmDebugAlloc(x,__FILE__,__LINE__) -#define mmDebugFree(x) mmDebugFree(x,__FILE__,__LINE__) -#define mmDebugRealloc(x,y) mmDebugRealloc(x,y,__FILE__,__LINE__) - -void mmListUses( char *file, int line ); -#define mmListUses() mmListUses(__FILE__,__LINE__); - - -//// - - -#if MM_DEBUG - #define malloc(x) mmAlloc(0,(x),__FILE__,__LINE__) - #define realloc(x,y) mmRealloc(0,(x),(y),__FILE__,__LINE__) - #define free(x) mmFree(0,(x),0,__FILE__,__LINE__) -#elif defined(MM_ALLOC_CHECK) - -static inline void *mmAllocCheck( size_t size, char *file, int line ) -{ - void *p; - p = malloc( size ); -#if MM_WINDOWS - if( !( p ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %ld bytes ) at %s:%d\n", (long)size, file, line ); -#else - if( !( p ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %lld bytes ) at %s:%d\n", (long long)size, file, line ); -#endif - return p; -} - -static inline void *mmReallocCheck( void *p, size_t size, char *file, int line ) -{ - p = realloc( p, size ); -#if MM_WINDOWS - if( !( p ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %ld bytes ) at %s:%d\n", (long)size, file, line ); -#else - if( !( p ) ) - fprintf( stderr, "WARNING : Denied memory allocation ( %lld bytes ) at %s:%d\n", (long long)size, file, line ); -#endif - return p; -} - - #define malloc(x) mmAllocCheck((x),__FILE__,__LINE__) - #define realloc(x,y) mmReallocCheck((x),(y),__FILE__,__LINE__) -#endif - - - - -//// - - - -static inline uint64_t mmGetMillisecondsTime() -{ - struct timeval lntime; - gettimeofday( &lntime, 0 ); - return ( (uint64_t)lntime.tv_sec * 1000 ) + ( (uint64_t)lntime.tv_usec / 1000 ); -} - - -static inline uint64_t mmGetMicrosecondsTime() -{ - struct timeval lntime; - gettimeofday( &lntime, 0 ); - return ( (uint64_t)lntime.tv_sec * 1000000 ) + (uint64_t)lntime.tv_usec; -} - - -static inline uint64_t mmGetNanosecondsTime() -{ - struct timeval lntime; - gettimeofday( &lntime, 0 ); - return ( (uint64_t)lntime.tv_sec * 1000000000 ) + ( (uint64_t)lntime.tv_usec * 1000 ); -} - - - -//// - - - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/src/other/gct/Auxiliary/mmatomic.c b/src/other/gct/Auxiliary/mmatomic.c deleted file mode 100644 index 4831d8807f1..00000000000 --- a/src/other/gct/Auxiliary/mmatomic.c +++ /dev/null @@ -1,529 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include - -#include "cpuconfig.h" -#include "mm.h" - - -void mmAtomicListAdd( mmAtomicP *list, void *item, intptr_t offset ) -{ - mmAtomicListNode *node, *nextnode; - void *nextitem; - - node = ADDRESS( item, offset ); - mmAtomicWriteP( &node->prev, list ); - for( ; ; ) - { - /* Mark prev->next as busy */ - nextitem = mmAtomicReadP( list ); - if( ( nextitem == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( list, nextitem, MM_ATOMIC_LIST_BUSY ) ) ) - continue; - mmAtomicWriteP( &node->next, nextitem ); - if( nextitem ) - { - nextnode = ADDRESS( nextitem, offset ); - /* Set next->prev to node->next */ - if( !( mmAtomicCmpReplaceP( &nextnode->prev, list, &(node->next) ) ) ) - { - mmAtomicWriteP( list, nextitem ); - continue; - } - } - mmAtomicWrite32( &node->status, MM_ATOMIC_LIST_VALID ); - /* Finally set prev->next to point to the item */ - mmAtomicWriteP( list, item ); - break; - } - - return; -} - - -void mmAtomicListRemove( void *item, intptr_t offset ) -{ - mmAtomicListNode *node, *nextnode; - mmAtomicP *prevnext; - void *nextitem; - - node = ADDRESS( item, offset ); - if( !( mmAtomicCmpReplace32( &node->status, MM_ATOMIC_LIST_VALID, MM_ATOMIC_LIST_DELETED ) ) ) - return; - for( ; ; ) - { - /* Mark item->next as busy */ - nextitem = mmAtomicReadP( &node->next ); - if( ( nextitem == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &node->next, nextitem, MM_ATOMIC_LIST_BUSY ) ) ) - continue; - - /* Mark item->prev as busy */ - prevnext = mmAtomicReadP( &node->prev ); - if( ( prevnext == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &node->prev, prevnext, MM_ATOMIC_LIST_BUSY ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - continue; - } - - /* Mark prev->next as busy */ - if( !( mmAtomicCmpReplaceP( prevnext, item, MM_ATOMIC_LIST_BUSY ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - mmAtomicWriteP( &node->prev, prevnext ); - continue; - } - - /* Fix next item */ - if( nextitem ) - { - nextnode = ADDRESS( nextitem, offset ); - if( !( mmAtomicCmpReplaceP( &nextnode->prev, &node->next, prevnext ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - mmAtomicWriteP( &node->prev, prevnext ); - mmAtomicWriteP( prevnext, item ); - continue; - } - } - - /* Finally set prev->next to point to the next item */ - mmAtomicWriteP( prevnext, nextitem ); - break; - } - - return; -} - - - - - -void mmAtomicListDualInit( mmAtomicListDualHead *head ) -{ - mmAtomicWriteP( &head->first, 0 ); - mmAtomicWriteP( &head->last, &head->first ); - return; -} - - -void mmAtomicListDualAddFirst( mmAtomicListDualHead *head, void *item, intptr_t offset ) -{ - mmAtomicListNode *node, *nextnode; - mmAtomicP *nextprev; - void *nextitem; - - node = ADDRESS( item, offset ); - mmAtomicWriteP( &node->prev, &head->first ); - for( ; ; ) - { - /* Mark prev->next as busy */ - nextitem = mmAtomicReadP( &head->first ); - if( ( nextitem == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &head->first, nextitem, MM_ATOMIC_LIST_BUSY ) ) ) - continue; - mmAtomicWriteP( &node->next, nextitem ); - - nextprev = &head->last; - if( nextitem ) - { - nextnode = ADDRESS( nextitem, offset ); - nextprev = &nextnode->prev; - } - - /* Set next->prev to node->next */ - if( !( mmAtomicCmpReplaceP( nextprev, &head->first, &(node->next) ) ) ) - { - mmAtomicWriteP( &head->first, nextitem ); - continue; - } - - mmAtomicWrite32( &node->status, MM_ATOMIC_LIST_VALID ); - - /* Finally set prev->next to point to the item */ - mmAtomicWriteP( &head->first, item ); - break; - } - - return; -} - - -void mmAtomicListDualAddLast( mmAtomicListDualHead *head, void *item, intptr_t offset ) -{ - mmAtomicListNode *node; - mmAtomicP *lastnext; - - node = ADDRESS( item, offset ); - mmAtomicWriteP( &node->next, 0 ); - for( ; ; ) - { - /* Mark head->last as busy */ - lastnext = mmAtomicReadP( &head->last ); - if( ( lastnext == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &head->last, lastnext, MM_ATOMIC_LIST_BUSY ) ) ) - continue; - mmAtomicWriteP( &node->prev, lastnext ); - - /* Mark last->next as busy */ - if( !( mmAtomicCmpReplaceP( lastnext, 0, MM_ATOMIC_LIST_BUSY ) ) ) - { - mmAtomicWriteP( &head->last, lastnext ); - continue; - } - - /* Set head->first to item if the list is empty */ -/* -TODO TODO - - firstitem = mmAtomicReadP( &head->first ); - if( ( firstitem == MM_ATOMIC_LIST_BUSY ) || ( !( firstitem ) && !( mmAtomicCmpReplaceP( &head->last, MM_ATOMIC_LIST_BUSY, &(node->next) ) ) ) ) - { - mmAtomicWriteP( &head->last, lastnext ); - mmAtomicWriteP( lastnext, 0 ); - continue; - } -*/ - - mmAtomicWrite32( &node->status, MM_ATOMIC_LIST_VALID ); - - /* Set prev->next to item */ - mmAtomicWriteP( lastnext, item ); - - /* Finally set head->last to point to node->next */ - mmAtomicWriteP( &head->last, &(node->next) ); - break; - } - - return; -} - - -void mmAtomicListDualRemove( mmAtomicListDualHead *head, void *item, intptr_t offset ) -{ - mmAtomicListNode *node, *nextnode; - mmAtomicP *prevnext, *nextprev; - void *nextitem; - - node = ADDRESS( item, offset ); - if( !( mmAtomicCmpReplace32( &node->status, MM_ATOMIC_LIST_VALID, MM_ATOMIC_LIST_DELETED ) ) ) - return; - for( ; ; ) - { - /* Mark item->next as busy */ - nextitem = mmAtomicReadP( &node->next ); - if( ( nextitem == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &node->next, nextitem, MM_ATOMIC_LIST_BUSY ) ) ) - continue; - - /* Mark item->prev as busy */ - prevnext = mmAtomicReadP( &node->prev ); - if( ( prevnext == MM_ATOMIC_LIST_BUSY ) || !( mmAtomicCmpReplaceP( &node->prev, prevnext, MM_ATOMIC_LIST_BUSY ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - continue; - } - - /* Mark prev->next as busy */ - if( !( mmAtomicCmpReplaceP( prevnext, item, MM_ATOMIC_LIST_BUSY ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - mmAtomicWriteP( &node->prev, prevnext ); - continue; - } - - /* Fix next item */ - nextprev = &head->last; - if( nextitem ) - { - nextnode = ADDRESS( nextitem, offset ); - nextprev = &nextnode->prev; - } - if( !( mmAtomicCmpReplaceP( nextprev, &node->next, prevnext ) ) ) - { - mmAtomicWriteP( &node->next, nextitem ); - mmAtomicWriteP( &node->prev, prevnext ); - mmAtomicWriteP( prevnext, item ); - continue; - } - - /* Finally set prev->next to point to the next item */ - mmAtomicWriteP( prevnext, nextitem ); - break; - } - - return; -} - - - -//// - - - -void mmAtomicBarrierBuild( mmAtomicBarrier *barrier, int childcount, mmAtomicBarrier *parent ) -{ - mmAtomicWrite32( &barrier->flag, 0 ); - barrier->flagref = 0; - barrier->resetvalue = childcount; - mmAtomicWrite32( &barrier->counter, childcount ); - barrier->parent = parent; - return; -} - - - -#ifdef CPUCONF_STORE_REODERING_AFTER_STORE - #ifndef MM_ATOMIC_BARRIER_DELAYED_RESET - #undef MM_ATOMIC_BARRIER_DELAYED_RESET - #endif -#endif - -#define MM_ATOMIC_BARRIER_NEXTFLAGREF(x) (x+1) - -/* -int fooooooo = 0; -*/ - -int mmAtomicBarrierWait( mmAtomicBarrier *barrier, int32_t spinwaitcounter, mmAtomicBarrierStat *barrierstat ) -{ - int32_t flagref, nextflagref, spincountdown; - mmAtomicBarrier *leaf; - - leaf = barrier; - flagref = barrier->flagref; - -#ifdef MM_ATOMIC_BARRIER_DEBUG - if( mmAtomicRead32( &barrier->flag ) != flagref ) - printf( "Error, %d != %d\n", mmAtomicRead32( &barrier->flag ), flagref ); -#endif - - nextflagref = MM_ATOMIC_BARRIER_NEXTFLAGREF( flagref ); - for( ; ; ) - { - if( !( mmAtomicAddTestZero32( &barrier->counter, -1 ) ) ) - break; - -#ifndef MM_ATOMIC_BARRIER_DELAYED_RESET - barrier->flagref = nextflagref; - MM_ATOMIC_ACCESS_32(&barrier->counter) += barrier->resetvalue; -#endif - - if( barrier->parent ) - barrier = barrier->parent; - else - { - /* Barrier fully cleared */ - barrierstat->clearcounter++; - -#ifndef MM_ATOMIC_BARRIER_DELAYED_RESET - #ifdef CPUCONF_STORE_REODERING_AFTER_STORE - mmWriteBarrier(); - #endif - for( barrier = leaf ; barrier ; barrier = barrier->parent ) - mmAtomicWrite32( &barrier->flag, nextflagref ); -#else - for( barrier = leaf ; barrier ; barrier = barrier->parent ) - { - barrier->flagref = nextflagref; - MM_ATOMIC_ACCESS_32(&barrier->counter) += barrier->resetvalue; - /* No barrier : earlier, we disallowed delayed reset if CPUCONF_STORE_REODERING_AFTER_STORE */ - mmAtomicWrite32( &barrier->flag, nextflagref ); - } -#endif - - return 1; - } - } - - - /* Spin! */ - if( !( spinwaitcounter ) ) - goto spinyield; - if( !( spincountdown = mmAtomicSpinWaitNeq32Count( &barrier->flag, flagref, spinwaitcounter ) ) ) - { - barrierstat->yieldcounter++; - spinyield: - - -/* -printf( "YIELD %d\n", fooooooo++ ); -*/ - - - for( ; mmAtomicRead32( &barrier->flag ) == flagref ; ) - mtYield(); - } - - - -#ifndef MM_ATOMIC_BARRIER_DELAYED_RESET - #ifdef CPUCONF_STORE_REODERING_AFTER_STORE - mmWriteBarrier(); - #endif - for( ; leaf != barrier ; leaf = leaf->parent ) - mmAtomicWrite32( &leaf->flag, nextflagref ); -#else - for( ; leaf != barrier ; leaf = leaf->parent ) - { - leaf->flagref = nextflagref; - MM_ATOMIC_ACCESS_32(&leaf->counter) += leaf->resetvalue; - /* No barrier : earlier, we disallowed delayed reset if CPUCONF_STORE_REODERING_AFTER_STORE */ - mmAtomicWrite32( &leaf->flag, nextflagref ); - } -#endif - - - return 0; -} - - - - - - -//// - - - - - - -static int mmAtomicCounterBuildStage( mmAtomicCounter *counter, int itembase, int itemcount, int counterstagesize, void *parent, int * const nodeindex ) -{ - int nodesize, nodebasesize, itemremainder, childcount, nodecount; - mmAtomicCounterNode *node; - - if( itemcount == 1 ) - { - counter->locknode[itembase] = parent; - return 1; - } - nodebasesize = itemcount / counterstagesize; - itemremainder = itemcount - ( nodebasesize * counterstagesize ); - for( nodecount = 0 ; itemcount ; nodecount++, itemcount -= nodesize ) - { - nodesize = nodebasesize; - if( nodecount < itemremainder ) - nodesize++; - if( nodesize >= 2 ) - { - node = &counter->nodearray[ (*nodeindex)++ ]; - childcount = mmAtomicCounterBuildStage( counter, itembase, nodesize, counterstagesize, node, nodeindex ); - node->resetvalue = childcount; - mmAtomicWrite32( &node->counter, childcount ); - node->parent = parent; - } - else - counter->locknode[itembase] = parent; - itembase += nodesize; - } - - return nodecount; -} - - -void mmAtomicCounterInit( mmAtomicCounter *counter, int lockcount, int stagesize ) -{ - int stagecount, nodecount, childcount; - void *alloc; - mmAtomicCounterNode *node; - - counter->nodearray = 0; - stagecount = lockcount; - nodecount = 1; - for( ; stagecount > 1 ; ) - { - stagecount = ( stagecount + (stagesize-1) ) / stagesize; - nodecount += stagecount; - } - - alloc = mmAlignAlloc( nodecount * sizeof(mmAtomicCounterNode) + lockcount * sizeof(mmAtomicCounterNode *), CPUCONF_CACHE_LINE_SIZE ); - counter->lockcount = lockcount; - counter->nodecount = nodecount; - counter->nodearray = alloc; - counter->locknode = ADDRESS( alloc, nodecount * sizeof(mmAtomicCounterNode) ); - - counter->nodecount = 0; - node = &counter->nodearray[ counter->nodecount++ ]; - childcount = mmAtomicCounterBuildStage( counter, 0, lockcount, stagesize, node, &counter->nodecount ); - if( counter->nodecount > nodecount ) - { - printf( "What the hell?\n" ); - exit( 1 ); - } - node->resetvalue = childcount; - mmAtomicWrite32( &node->counter, childcount ); - node->parent = 0; - - return; -} - - -void mmAtomicCounterDestroy( mmAtomicCounter *counter ) -{ - if( counter->nodearray ) - { - mmAlignFree( counter->nodearray ); - counter->nodearray = 0; - } - return; -} - - -int mmAtomicCounterHit( mmAtomicCounter *counter, int lockindex ) -{ - mmAtomicCounterNode *node; - node = counter->locknode[lockindex]; - for( ; ; ) - { - if( !( mmAtomicAddTestZero32( &node->counter, -1 ) ) ) - break; - MM_ATOMIC_ACCESS_32(&node->counter) += node->resetvalue; - -/* -printf( "Node %d ; %d\n", (int)( node - counter->nodearray ), MM_ATOMIC_ACCESS_32(&node->counter) ); -*/ - - if( node->parent ) - node = node->parent; - else - return 1; - } - return 0; -} - - - - -/* - -Implement a counter without all threads trashing each other's cache - - -*/ - - diff --git a/src/other/gct/Auxiliary/mmatomic.h b/src/other/gct/Auxiliary/mmatomic.h deleted file mode 100644 index 15b2383000f..00000000000 --- a/src/other/gct/Auxiliary/mmatomic.h +++ /dev/null @@ -1,2496 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ -/** - * @file - * - * Atomic memory operations. - */ - - - - -#if ( defined(CPUCONF_ARCH_IA32) || defined(CPUCONF_ARCH_AMD64) ) && defined(__GNUC__) && !defined(MM_ATOMIC_SUPPORT) - - -#define MM_ATOMIC_SUPPORT - - -#ifdef CPUCONF_ARCH_AMD64 - #define MM_ATOMIC_64_BITS_SUPPORT -#endif - - -typedef struct { volatile int8_t value; } mmAtomic8; -typedef struct { volatile int16_t value; } mmAtomic16; -typedef struct { volatile int32_t value; } mmAtomic32; -#ifdef MM_ATOMIC_64_BITS_SUPPORT -typedef struct { volatile int64_t value; } mmAtomic64; -#endif - - -//// - - -/* - -Architecture Memory Ordering - -Memory model for x86 and amd64 ---- Aligned stores can not be partially seen by loads ---- Loads can NOT be reordered after loads ---- Loads can NOT be reordered after stores ---- Stores can NOT be reordered after stores --X- Stores CAN be reordered after loads ---- Atomic instructions are NOT reordered with loads ---- Atomic instructions are NOT reordered with stores ---- Dependent loads can NOT be reordered - -*/ - - -/* Memory model configuration for x86/amd64 */ -// #define CPUCONF_LOAD_REODERING_AFTER_LOAD -// #define CPUCONF_LOAD_REODERING_AFTER_STORE -#define CPUCONF_STORE_REODERING_AFTER_LOAD -// #define CPUCONF_STORE_REODERING_AFTER_STORE -// #define CPUCONF_ATOMIC_REODERING_WITH_LOAD -// #define CPUCONF_ATOMIC_REODERING_WITH_STORE -// #define CPUCONF_DEPENDENT_REODERING - - -//// - - -/* Do nothing, prevent compiler reordering */ -static inline void mmBarrier() -{ - __asm__ __volatile__( "":::"memory" ); - return; -} - -/* All previous loads must complete before future loads */ -static inline void mmReadBarrier() -{ -#ifdef CPUCONF_CAP_SSE2 - __asm__ __volatile__( "lfence":::"memory" ); -#else - __asm__ __volatile__( "lock ; addl $0,(%%esp)":::"memory" ); -#endif - return; -} - -/* All previous stores must complete before future stores */ -static inline void mmWriteBarrier() -{ - /* x86 and AMD64 never reorder stores : the sfence instruction is useless unless chatting with devices on MMIO */ - __asm__ __volatile__( "":::"memory" ); - return; -} - -/* All previous loads/stores must complete before future loads/stores */ -static inline void mmFullBarrier() -{ -#ifdef CPUCONF_CAP_SSE2 - __asm__ __volatile__( "mfence":::"memory" ); -#else - __asm__ __volatile__( "lock ; addl $0,(%%esp)":::"memory" ); -#endif - return; -} - - -//// - - -/* Direct access to the atomic variables, for use when the caller knows no atomicity is needed */ -#define MM_ATOMIC_ACCESS_8(v) ((v)->value) -#define MM_ATOMIC_ACCESS_16(v) ((v)->value) -#define MM_ATOMIC_ACCESS_32(v) ((v)->value) -#ifdef MM_ATOMIC_64_BITS_SUPPORT - #define MM_ATOMIC_ACCESS_64(v) ((v)->value) -#endif - - -//// - - -/* -mmAtomicRead*() -Atomically read the value -*/ -static inline int8_t mmAtomicRead8( mmAtomic8 *v ) -{ - mmBarrier(); - return v->value; -} - -static inline int16_t mmAtomicRead16( mmAtomic16 *v ) -{ - mmBarrier(); - return v->value; -} - -static inline int32_t mmAtomicRead32( mmAtomic32 *v ) -{ - mmBarrier(); - return v->value; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicRead64( mmAtomic64 *v ) -{ - mmBarrier(); - return v->value; -} -#endif - - -//// - - -/* -mmAtomicWrite*() -Atomically write the value -*/ -static inline void mmAtomicWrite8( mmAtomic8 *v, int8_t i ) -{ - mmBarrier(); - v->value = i; - return; -} - -static inline void mmAtomicWrite16( mmAtomic16 *v, int16_t i ) -{ - mmBarrier(); - v->value = i; - return; -} - -static inline void mmAtomicWrite32( mmAtomic32 *v, int32_t i ) -{ - mmBarrier(); - v->value = i; - return; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicWrite64( mmAtomic64 *v, int64_t i ) -{ - mmBarrier(); - v->value = i; - return; -} -#endif - - -//// - - -/* -mmAtomicBarrierWrite*() -Atomically write the value and act as a full memory barrier -*/ -static inline void mmAtomicBarrierWrite8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; xchgb %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return; -} - -static inline void mmAtomicBarrierWrite16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; xchgw %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return; -} - -static inline void mmAtomicBarrierWrite32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; xchgl %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicBarrierWrite64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; xchgq %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return; -} -#endif - - -//// - - -static inline void mmAtomicAdd8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; addb %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicAdd16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; addw %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicAdd32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; addl %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicAdd64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; addq %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline void mmAtomicSub8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; subb %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicSub16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; subw %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicSub32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; subl %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicSub64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; subq %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline int mmAtomicAddTestZero8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addb %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAddTestZero16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addw %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAddTestZero32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addl %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicAddTestZero64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addq %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - -//// - - -static inline int mmAtomicSubTestZero8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subb %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicSubTestZero16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subw %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicSubTestZero32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subl %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicSubTestZero64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subq %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - -//// - - -static inline void mmAtomicInc8( mmAtomic8 *v ) -{ - __asm__ __volatile__( - "lock ; incb %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -static inline void mmAtomicInc16( mmAtomic16 *v ) -{ - __asm__ __volatile__( - "lock ; incw %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -static inline void mmAtomicInc32( mmAtomic32 *v ) -{ - __asm__ __volatile__( - "lock ; incl %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicInc64( mmAtomic64 *v ) -{ - __asm__ __volatile__( - "lock ; incq %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline void mmAtomicDec8( mmAtomic8 *v ) -{ - __asm__ __volatile__( - "lock ; decl %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -static inline void mmAtomicDec16( mmAtomic16 *v ) -{ - __asm__ __volatile__( - "lock ; decl %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -static inline void mmAtomicDec32( mmAtomic32 *v ) -{ - __asm__ __volatile__( - "lock ; decl %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicDec64( mmAtomic64 *v ) -{ - __asm__ __volatile__( - "lock ; decq %0" - :"=m"(v->value) - :"m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline int mmAtomicIncTestZero8( mmAtomic8 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; incb %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -static inline int mmAtomicIncTestZero16( mmAtomic16 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; incw %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -static inline int mmAtomicIncTestZero32( mmAtomic32 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; incl %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicIncTestZero64( mmAtomic64 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; incq %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} -#endif - - -//// - - -static inline int mmAtomicDecTestZero8( mmAtomic8 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decb %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -static inline int mmAtomicDecTestZero16( mmAtomic16 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decw %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -static inline int mmAtomicDecTestZero32( mmAtomic32 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decl %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicDecTestZero64( mmAtomic64 *v ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decq %0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"m"(v->value) :"memory" ); - return c != 0; -} -#endif - - -//// - - -static inline int mmAtomicAddTestNegative8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addb %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAddTestNegative16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addw %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAddTestNegative32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addl %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicAddTestNegative64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; addq %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - -//// - - -static inline int mmAtomicSubTestNegative8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subb %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicSubTestNegative16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subw %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicSubTestNegative32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subl %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicSubTestNegative64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; subq %2,%0 ; sets %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - - -//////////////// - - - -static inline void mmAtomicAnd8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; andb %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicAnd16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; andw %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicAnd32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; andl %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicAnd64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; andq %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline int mmAtomicAndTestZero8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; andb %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAndTestZero16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; andw %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicAndTestZero32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; andl %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicAndTestZero64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; andq %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - -//// - - -static inline void mmAtomicOr8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; orb %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicOr16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; orw %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicOr32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; orl %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicOr64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; orq %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline int mmAtomicOrTestZero8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; orb %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicOrTestZero16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; orw %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicOrTestZero32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; orl %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicOrTestZero64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; orq %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - -//// - - -static inline void mmAtomicXor8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; xorb %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicXor16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; xorw %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -static inline void mmAtomicXor32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; xorl %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicXor64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; xorq %1,%0" - :"=m"(v->value) - :"ir"(i), "m"(v->value) :"memory" ); -} -#endif - - -//// - - -static inline int mmAtomicXorTestZero8( mmAtomic8 *v, int8_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; xorb %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicXorTestZero16( mmAtomic16 *v, int16_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; xorw %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -static inline int mmAtomicXorTestZero32( mmAtomic32 *v, int32_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; xorl %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicXorTestZero64( mmAtomic64 *v, int64_t i ) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; xorq %2,%0 ; setz %1" - :"=m"(v->value), "=qm"(c) - :"ir"(i), "m"(v->value) :"memory" ); - return c; -} -#endif - - - -//////////////// - - - -static inline int8_t mmAtomicXchg8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "lock ; xchgb %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return i; -} - -static inline int16_t mmAtomicXchg16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "lock ; xchgw %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return i; -} - -static inline int32_t mmAtomicXchg32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "lock ; xchgl %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicXchg64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "lock ; xchgq %0,%1" - :"=q"(i) - :"m"(v->value), "0"(i) :"memory" ); - return i; -} -#endif - - -//// - - -static inline int8_t mmAtomicCmpXchg8( mmAtomic8 *v, int8_t old, int8_t new ) -{ - int8_t prev; - __asm__ __volatile__( - "lock ; cmpxchgb %1,%2" - :"=a"(prev) - :"r"(new), "m"(v->value), "a"(old) :"memory" ); - return prev; -} - -static inline int16_t mmAtomicCmpXchg16( mmAtomic16 *v, int16_t old, int16_t new ) -{ - int16_t prev; - __asm__ __volatile__( - "lock ; cmpxchgw %1,%2" - :"=a"(prev) - :"r"(new), "m"(v->value), "a"(old) :"memory" ); - return prev; -} - -static inline int32_t mmAtomicCmpXchg32( mmAtomic32 *v, int32_t old, int32_t new ) -{ - int32_t prev; - __asm__ __volatile__( - "lock ; cmpxchgl %1,%2" - :"=a"(prev) - :"r"(new), "m"(v->value), "a"(old) :"memory" ); - return prev; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicCmpXchg64( mmAtomic64 *v, int64_t old, int64_t new ) -{ - int64_t prev; - __asm__ __volatile__( - "lock ; cmpxchgq %1,%2" - :"=a"(prev) - :"r"(new), "m"(v->value), "a"(old) :"memory" ); - return prev; -} -#endif - - - -//////////////// - - - -static inline void mmAtomicPause() -{ - __asm__ __volatile__( - "rep ; nop" - : - ::"memory" ); - return; -} - - -static inline void mmAtomicSpinWaitEq8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpb %1,%0\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -static inline void mmAtomicSpinWaitEq16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpw %1,%0\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -static inline void mmAtomicSpinWaitEq32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpl %1,%0\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicSpinWaitEq64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpq %1,%0\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} -#endif - - -static inline int32_t mmAtomicSpinWaitEq8Count( mmAtomic8 *v, int8_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpb %2,%1\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -static inline int32_t mmAtomicSpinWaitEq16Count( mmAtomic16 *v, int16_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpw %2,%1\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -static inline int32_t mmAtomicSpinWaitEq32Count( mmAtomic32 *v, int32_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpl %2,%1\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int32_t mmAtomicSpinWaitEq64Count( mmAtomic64 *v, int64_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpq %2,%1\n" - "jnz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} -#endif - - -static inline void mmAtomicSpinWaitNeq8( mmAtomic8 *v, int8_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpb %1,%0\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -static inline void mmAtomicSpinWaitNeq16( mmAtomic16 *v, int16_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpw %1,%0\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -static inline void mmAtomicSpinWaitNeq32( mmAtomic32 *v, int32_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpl %1,%0\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} - - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicSpinWaitNeq64( mmAtomic64 *v, int64_t i ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "rep ; nop\n" - "1:\n" - "cmpq %1,%0\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - : - :"m"(v->value), "r"(i) :"memory" ); - return; -} -#endif - - -static inline int32_t mmAtomicSpinWaitNeq8Count( mmAtomic8 *v, int8_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpb %2,%1\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -static inline int32_t mmAtomicSpinWaitNeq16Count( mmAtomic16 *v, int16_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpw %2,%1\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -static inline int32_t mmAtomicSpinWaitNeq32Count( mmAtomic32 *v, int32_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpl %2,%1\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} - - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int32_t mmAtomicSpinWaitNeq64Count( mmAtomic64 *v, int64_t i, int32_t spinmaxcount ) -{ - __asm__ __volatile__( - "jmp 1f\n" - ".p2align 6\n" - "2:\n" - "subl $1,%0\n" - "jz 3f\n" - "rep ; nop\n" - "1:\n" - "cmpq %2,%1\n" - "jz 2b\n" - ".p2align 4\n" - "3:\n" - :"=q"(spinmaxcount) - :"m"(v->value), "r"(i), "0"(spinmaxcount) :"memory" ); - return spinmaxcount; -} -#endif - - -//// - - -static inline void mmAtomicSpin8( mmAtomic8 *v, int8_t old, int8_t new ) -{ - for( ; mmAtomicCmpXchg8( v, old, new ) != old ; ) - { - for( ; mmAtomicRead8( v ) != old ; ) - mmAtomicPause(); - } - return; -} - -static inline void mmAtomicSpin16( mmAtomic16 *v, int16_t old, int16_t new ) -{ - for( ; mmAtomicCmpXchg16( v, old, new ) != old ; ) - { - for( ; mmAtomicRead16( v ) != old ; ) - mmAtomicPause(); - } - return; -} - -static inline void mmAtomicSpin32( mmAtomic32 *v, int32_t old, int32_t new ) -{ - for( ; mmAtomicCmpXchg32( v, old, new ) != old ; ) - { - for( ; mmAtomicRead32( v ) != old ; ) - mmAtomicPause(); - } - return; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline void mmAtomicSpin64( mmAtomic64 *v, int64_t old, int64_t new ) -{ - for( ; mmAtomicCmpXchg64( v, old, new ) != old ; ) - { - for( ; mmAtomicRead64( v ) != old ; ) - mmAtomicPause(); - } - return; -} -#endif - - -static inline int mmAtomicTrySpin8( mmAtomic8 *v, int8_t old, int8_t new, int spincount ) -{ - for( ; mmAtomicCmpXchg8( v, old, new ) != old ; ) - { - for( ; mmAtomicRead8( v ) != old ; ) - { - if( !( --spincount ) ) - return 0; - mmAtomicPause(); - } - } - return 1; -} - -static inline int mmAtomicTrySpin16( mmAtomic16 *v, int16_t old, int16_t new, int spincount ) -{ - for( ; mmAtomicCmpXchg16( v, old, new ) != old ; ) - { - for( ; mmAtomicRead16( v ) != old ; ) - { - if( !( --spincount ) ) - return 0; - mmAtomicPause(); - } - } - return 1; -} - -static inline int mmAtomicTrySpin32( mmAtomic32 *v, int32_t old, int32_t new, int spincount ) -{ - for( ; mmAtomicCmpXchg32( v, old, new ) != old ; ) - { - for( ; mmAtomicRead32( v ) != old ; ) - { - if( !( --spincount ) ) - return 0; - mmAtomicPause(); - } - } - return 1; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int mmAtomicTrySpin64( mmAtomic64 *v, int64_t old, int64_t new, int spincount ) -{ - for( ; mmAtomicCmpXchg64( v, old, new ) != old ; ) - { - for( ; mmAtomicRead64( v ) != old ; ) - { - if( !( --spincount ) ) - return 0; - mmAtomicPause(); - } - } - return 1; -} -#endif - - -//////////////// - - -static inline int8_t mmAtomicAddRead8( mmAtomic8 *v, int8_t add ) -{ - int8_t i; - do - { - i = mmAtomicRead8( v ); - } while( mmAtomicCmpXchg8( v, i, i + add ) != i ); - return i + add; -} - -static inline int16_t mmAtomicAddRead16( mmAtomic16 *v, int16_t add ) -{ - int16_t i; - do - { - i = mmAtomicRead16( v ); - } while( mmAtomicCmpXchg16( v, i, i + add ) != i ); - return i + add; -} - -static inline int32_t mmAtomicAddRead32( mmAtomic32 *v, int32_t add ) -{ - int32_t i; - do - { - i = mmAtomicRead32( v ); - } while( mmAtomicCmpXchg32( v, i, i + add ) != i ); - return i + add; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicAddRead64( mmAtomic64 *v, int64_t add ) -{ - int64_t i; - do - { - i = mmAtomicRead64( v ); - } while( mmAtomicCmpXchg64( v, i, i + add ) != i ); - return i + add; -} -#endif - - -//// - - -static inline int8_t mmAtomicReadAdd8( mmAtomic8 *v, int8_t add ) -{ - int8_t i; - do - { - i = mmAtomicRead8( v ); - } while( mmAtomicCmpXchg8( v, i, i + add ) != i ); - return i; -} - -static inline int16_t mmAtomicReadAdd16( mmAtomic16 *v, int16_t add ) -{ - int16_t i; - do - { - i = mmAtomicRead16( v ); - } while( mmAtomicCmpXchg16( v, i, i + add ) != i ); - return i; -} - -static inline int32_t mmAtomicReadAdd32( mmAtomic32 *v, int32_t add ) -{ - int32_t i; - do - { - i = mmAtomicRead32( v ); - } while( mmAtomicCmpXchg32( v, i, i + add ) != i ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicReadAdd64( mmAtomic64 *v, int64_t add ) -{ - int64_t i; - do - { - i = mmAtomicRead64( v ); - } while( mmAtomicCmpXchg64( v, i, i + add ) != i ); - return i; -} -#endif - - -//// - - -static inline int8_t mmAtomicReadAnd8( mmAtomic8 *v, int8_t mask ) -{ - int8_t i, j; - do - { - i = mmAtomicRead8( v ); - j = i & mask; - } while( mmAtomicCmpXchg8( v, i, j ) != i ); - return i; -} - -static inline int16_t mmAtomicReadAnd16( mmAtomic16 *v, int16_t mask ) -{ - int16_t i, j; - do - { - i = mmAtomicRead16( v ); - j = i & mask; - } while( mmAtomicCmpXchg16( v, i, j ) != i ); - return i; -} - -static inline int32_t mmAtomicReadAnd32( mmAtomic32 *v, int32_t mask ) -{ - int32_t i, j; - do - { - i = mmAtomicRead32( v ); - j = i & mask; - } while( mmAtomicCmpXchg32( v, i, j ) != i ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicReadAnd64( mmAtomic64 *v, int64_t mask ) -{ - int64_t i, j; - do - { - i = mmAtomicRead64( v ); - j = i & mask; - } while( mmAtomicCmpXchg64( v, i, j ) != i ); - return i; -} -#endif - - -//// - - -static inline int8_t mmAtomicReadOr8( mmAtomic8 *v, int8_t mask ) -{ - int8_t i, j; - do - { - i = mmAtomicRead8( v ); - j = i | mask; - } while( mmAtomicCmpXchg8( v, i, j ) != i ); - return i; -} - -static inline int16_t mmAtomicReadOr16( mmAtomic16 *v, int16_t mask ) -{ - int16_t i, j; - do - { - i = mmAtomicRead16( v ); - j = i | mask; - } while( mmAtomicCmpXchg16( v, i, j ) != i ); - return i; -} - -static inline int32_t mmAtomicReadOr32( mmAtomic32 *v, int32_t mask ) -{ - int32_t i, j; - do - { - i = mmAtomicRead32( v ); - j = i | mask; - } while( mmAtomicCmpXchg32( v, i, j ) != i ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicReadOr64( mmAtomic64 *v, int64_t mask ) -{ - int64_t i, j; - do - { - i = mmAtomicRead64( v ); - j = i | mask; - } while( mmAtomicCmpXchg64( v, i, j ) != i ); - return i; -} -#endif - - -//// - - -static inline int8_t mmAtomicReadIncLoop8( mmAtomic8 *v, int8_t max ) -{ - int8_t i, j; - do - { - i = mmAtomicRead8( v ); - j = i + 1; - if( j >= max ) - j = 0; - } while( mmAtomicCmpXchg8( v, i, j ) != i ); - return i; -} - -static inline int16_t mmAtomicReadIncLoop16( mmAtomic16 *v, int16_t max ) -{ - int16_t i, j; - do - { - i = mmAtomicRead16( v ); - j = i + 1; - if( j >= max ) - j = 0; - } while( mmAtomicCmpXchg16( v, i, j ) != i ); - return i; -} - -static inline int32_t mmAtomicReadIncLoop32( mmAtomic32 *v, int32_t max ) -{ - int32_t i, j; - do - { - i = mmAtomicRead32( v ); - j = i + 1; - if( j >= max ) - j = 0; - } while( mmAtomicCmpXchg32( v, i, j ) != i ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicReadIncLoop64( mmAtomic64 *v, int64_t max ) -{ - int64_t i, j; - do - { - i = mmAtomicRead64( v ); - j = i + 1; - if( j >= max ) - j = 0; - } while( mmAtomicCmpXchg64( v, i, j ) != i ); - return i; -} -#endif - - -//// - - -static inline int8_t mmAtomicReadAddLoop8( mmAtomic8 *v, int8_t add, int8_t base, int8_t max ) -{ - int8_t i, j; - do - { - i = mmAtomicRead8( v ); - j = i + add; - if( j >= max ) - j = base; - } while( mmAtomicCmpXchg8( v, i, j ) != i ); - return i; -} - -static inline int16_t mmAtomicReadAddLoop16( mmAtomic16 *v, int16_t add, int16_t base, int16_t max ) -{ - int16_t i, j; - do - { - i = mmAtomicRead16( v ); - j = i + add; - if( j >= max ) - j = base; - } while( mmAtomicCmpXchg16( v, i, j ) != i ); - return i; -} - -static inline int32_t mmAtomicReadAddLoop32( mmAtomic32 *v, int32_t add, int32_t base, int32_t max ) -{ - int32_t i, j; - do - { - i = mmAtomicRead32( v ); - j = i + add; - if( j >= max ) - j = base; - } while( mmAtomicCmpXchg32( v, i, j ) != i ); - return i; -} - -#ifdef MM_ATOMIC_64_BITS_SUPPORT -static inline int64_t mmAtomicReadAddLoop64( mmAtomic64 *v, int64_t add, int64_t base, int64_t max ) -{ - int64_t i, j; - do - { - i = mmAtomicRead64( v ); - j = i + add; - if( j >= max ) - j = base; - } while( mmAtomicCmpXchg64( v, i, j ) != i ); - return i; -} -#endif - - - -//////////////// - - - - -#define mmAtomicCmpReplace8(v,old,new) (mmAtomicCmpXchg8(v,old,new)==(old)) -#define mmAtomicCmpReplace16(v,old,new) (mmAtomicCmpXchg16(v,old,new)==(old)) -#define mmAtomicCmpReplace32(v,old,new) (mmAtomicCmpXchg32(v,old,new)==(old)) -#define mmAtomicCmpReplace64(v,old,new) (mmAtomicCmpXchg64(v,old,new)==(old)) - - -#if CPUCONF_POINTER_BITS == 64 - #define mmAtomicP mmAtomic64 - #define MM_ATOMIC_ACCESS_P(v) (void *)MM_ATOMIC_ACCESS_64(v) - #define mmAtomicReadP(v) (void *)mmAtomicRead64(v) - #define mmAtomicWriteP(v,i) mmAtomicWrite64(v,(int64_t)i) - #define mmAtomicAddP(v,i) mmAtomicAdd64(v,(int64_t)i) - #define mmAtomicSubP(v,i) mmAtomicSub64(v,(int64_t)i) - #define mmAtomicAddTestZeroP(v,i) mmAtomicAddTestZero64(v,(int64_t)i) - #define mmAtomicSubTestZeroP(v,i) mmAtomicSubTestZero64(v,(int64_t)i) - #define mmAtomicIncP(v) mmAtomicInc64(v) - #define mmAtomicDecP(v) mmAtomicDec64(v) - #define mmAtomicIncTestZeroP(v) mmAtomicIncTestZero64(v) - #define mmAtomicDecTestZeroP(v) mmAtomicDecTestZero64(v) - #define mmAtomicAddTestNegativeP(v,i) mmAtomicAddTestNegative64(v,(int64_t)i) - #define mmAtomicSubTestNegativeP(v,i) mmAtomicSubTestNegative64(v,(int64_t)i) - #define mmAtomicAndP(v,i) mmAtomicAnd64(v,(int64_t)i) - #define mmAtomicAndTestZeroP(v,i) mmAtomicAndTestZero64(v,(int64_t)i) - #define mmAtomicOrP(v,i) mmAtomicOr64(v,(int64_t)i) - #define mmAtomicOrTestZeroP(v,i) mmAtomicOrTestZero64(v,(int64_t)i) - #define mmAtomicXorP(v,i) mmAtomicXor64(v,(int64_t)i) - #define mmAtomicXorTestZeroP(v,i) mmAtomicXorTestZero64(v,(int64_t)i) - #define mmAtomicXchgP(v,i) (void *)mmAtomicXchg64(v,(int64_t)i) - #define mmAtomicCmpXchgP(v,i,j) (void *)mmAtomicCmpXchg64(v,(int64_t)i,(int64_t)j) - #define mmAtomicCmpReplaceP(v,i,j) mmAtomicCmpReplace64(v,(int64_t)i,(int64_t)j) - #define mmAtomicSpinP(v,i,j) (void *)mmAtomicSpin64(v,(int64_t)i,(int64_t)j) - #define mmAtomicAddReadP(v,i) (void *)mmAtomicAddRead64(v,(int64_t)i) -#elif CPUCONF_POINTER_BITS == 32 - #define mmAtomicP mmAtomic32 - #define MM_ATOMIC_ACCESS_P(v) (void *)MM_ATOMIC_ACCESS_32(v) - #define mmAtomicReadP(v) (void *)mmAtomicRead32(v) - #define mmAtomicWriteP(v,i) mmAtomicWrite32(v,(int32_t)i) - #define mmAtomicAddP(v,i) mmAtomicAdd32(v,(int32_t)i) - #define mmAtomicSubP(v,i) mmAtomicSub32(v,(int32_t)i) - #define mmAtomicAddTestZeroP(v,i) mmAtomicAddTestZero32(v,(int32_t)i) - #define mmAtomicSubTestZeroP(v,i) mmAtomicSubTestZero32(v,(int32_t)i) - #define mmAtomicIncP(v) mmAtomicInc32(v) - #define mmAtomicDecP(v) mmAtomicDec32(v) - #define mmAtomicIncTestZeroP(v) mmAtomicIncTestZero32(v) - #define mmAtomicDecTestZeroP(v) mmAtomicDecTestZero32(v) - #define mmAtomicAddTestNegativeP(v,i) mmAtomicAddTestNegative32(v,(int32_t)i) - #define mmAtomicSubTestNegativeP(v,i) mmAtomicSubTestNegative32(v,(int32_t)i) - #define mmAtomicAndP(v,i) mmAtomicAnd32(v,(int32_t)i) - #define mmAtomicAndTestZeroP(v,i) mmAtomicAndTestZero32(v,(int32_t)i) - #define mmAtomicOrP(v,i) mmAtomicOr32(v,(int32_t)i) - #define mmAtomicOrTestZeroP(v,i) mmAtomicOrTestZero32(v,(int32_t)i) - #define mmAtomicXorP(v,i) mmAtomicXor32(v,(int32_t)i) - #define mmAtomicXorTestZeroP(v,i) mmAtomicXorTestZero32(v,(int32_t)i) - #define mmAtomicXchgP(v,i) (void *)mmAtomicXchg32(v,(int32_t)i) - #define mmAtomicCmpXchgP(v,i,j) (void *)mmAtomicCmpXchg32(v,(int32_t)i,(int32_t)j) - #define mmAtomicCmpReplaceP(v,i,j) mmAtomicCmpReplace32(v,(int32_t)i,(int32_t)j) - #define mmAtomicSpinP(v,i,j) (void *)mmAtomicSpin32(v,(int32_t)i,(int32_t)j) - #define mmAtomicAddReadP(v,i) (void *)mmAtomicAddRead32(v,(int32_t)i) -#else - #error CPUCONF_POINTER_BITS undefined -#endif - -#ifdef MM_ATOMIC_64_BITS_SUPPORT - #define intlarge int64_t - #define uintlarge uint64_t - #define mmAtomicL mmAtomic64 - #define MM_ATOMIC_ACCESS_L(v) MM_ATOMIC_ACCESS_64(v) - #define mmAtomicReadL(v) mmAtomicRead64(v) - #define mmAtomicWriteL(v,i) mmAtomicWrite64(v,i) - #define mmAtomicAddL(v,i) mmAtomicAdd64(v,i) - #define mmAtomicSubL(v,i) mmAtomicSub64(v,i) - #define mmAtomicAddTestZeroL(v,i) mmAtomicAddTestZero64(v,i) - #define mmAtomicSubTestZeroL(v,i) mmAtomicSubTestZero64(v,i) - #define mmAtomicIncL(v) mmAtomicInc64(v) - #define mmAtomicDecL(v) mmAtomicDec64(v) - #define mmAtomicIncTestZeroL(v) mmAtomicIncTestZero64(v) - #define mmAtomicDecTestZeroL(v) mmAtomicDecTestZero64(v) - #define mmAtomicAddTestNegativeL(v,i) mmAtomicAddTestNegative64(v,i) - #define mmAtomicSubTestNegativeL(v,i) mmAtomicSubTestNegative64(v,i) - #define mmAtomicAndL(v,i) mmAtomicAnd64(v,i) - #define mmAtomicAndTestZeroL(v,i) mmAtomicAndTestZero64(v,i) - #define mmAtomicOrL(v,i) mmAtomicOr64(v,i) - #define mmAtomicOrTestZeroL(v,i) mmAtomicOrTestZero64(v,i) - #define mmAtomicXorL(v,i) mmAtomicXor64(v,i) - #define mmAtomicXorTestZeroL(v,i) mmAtomicXorTestZero64(v,i) - #define mmAtomicXchgL(v,i) mmAtomicXchg64(v,i) - #define mmAtomicCmpXchgL(v,i,j) mmAtomicCmpXchg64(v,i,j) - #define mmAtomicCmpReplaceL(v,i,j) mmAtomicCmpReplace64(v,i,j) - #define mmAtomicSpinL(v,i,j) mmAtomicSpin64(v,i,j) - #define mmAtomicAddReadL(v,i) mmAtomicAddRead64(v,(int64_t)i) -#else - #define intlarge int32_t - #define uintlarge uint32_t - #define mmAtomicL mmAtomic32 - #define MM_ATOMIC_ACCESS_L(v) MM_ATOMIC_ACCESS_32(v) - #define mmAtomicReadL(v) mmAtomicRead32(v) - #define mmAtomicWriteL(v,i) mmAtomicWrite32(v,i) - #define mmAtomicAddL(v,i) mmAtomicAdd32(v,i) - #define mmAtomicSubL(v,i) mmAtomicSub32(v,i) - #define mmAtomicAddTestZeroL(v,i) mmAtomicAddTestZero32(v,i) - #define mmAtomicSubTestZeroL(v,i) mmAtomicSubTestZero32(v,i) - #define mmAtomicIncL(v) mmAtomicInc32(v) - #define mmAtomicDecL(v) mmAtomicDec32(v) - #define mmAtomicIncTestZeroL(v) mmAtomicIncTestZero32(v) - #define mmAtomicDecTestZeroL(v) mmAtomicDecTestZero32(v) - #define mmAtomicAddTestNegativeL(v,i) mmAtomicAddTestNegative32(v,i) - #define mmAtomicSubTestNegativeL(v,i) mmAtomicSubTestNegative32(v,i) - #define mmAtomicAndL(v,i) mmAtomicAnd32(v,i) - #define mmAtomicAndTestZeroL(v,i) mmAtomicAndTestZero32(v,i) - #define mmAtomicOrL(v,i) mmAtomicOr32(v,i) - #define mmAtomicOrTestZeroL(v,i) mmAtomicOrTestZero32(v,i) - #define mmAtomicXorL(v,i) mmAtomicXor32(v,i) - #define mmAtomicXorTestZeroL(v,i) mmAtomicXorTestZero32(v,i) - #define mmAtomicXchgL(v,i) mmAtomicXchg32(v,i) - #define mmAtomicCmpXchgL(v,i,j) mmAtomicCmpXchg32(v,i,j) - #define mmAtomicCmpReplaceL(v,i,j) mmAtomicCmpReplace32(v,i,j) - #define mmAtomicSpinL(v,i,j) mmAtomicSpin32(v,i,j) - #define mmAtomicAddReadL(v,i) mmAtomicAddRead32(v,(int32_t)i) -#endif - - - -//////////////// - - - -typedef struct { mmAtomic8 v; } mmAtomicLock8; - -#define MM_ATOMIC_LOCK8_WRITE (-((int8_t)0x7f)) - -static inline void mmAtomicLockInit8( mmAtomicLock8 *v ) -{ - mmAtomicWrite8( &v->v, 0 ); - return; -} - -static inline int mmAtomicLockAttemptRead8( mmAtomicLock8 *v ) -{ - if( mmAtomicAddTestNegative8( &v->v, 1 ) ) - { - mmAtomicAdd8( &v->v, -1 ); - return 0; - } - return 1; -} - -static inline int mmAtomicLockAttemptWrite8( mmAtomicLock8 *v ) -{ - if( mmAtomicCmpXchg8( &v->v, 0, MM_ATOMIC_LOCK8_WRITE ) ) - return 0; - return 1; -} - -static inline void mmAtomicLockSpinRead8( mmAtomicLock8 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead8( &v->v ) < 0 ; ) - mmAtomicPause(); - if( !( mmAtomicAddTestNegative8( &v->v, 1 ) ) ) - break; - mmAtomicAdd8( &v->v, -1 ); - } - return; -} - -static inline void mmAtomicLockSpinWrite8( mmAtomicLock8 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead8( &v->v ) ; ) - mmAtomicPause(); - if( !( mmAtomicCmpXchg8( &v->v, 0, MM_ATOMIC_LOCK8_WRITE ) ) ) - break; - } - return; -} - -static inline int mmAtomicLockTryRead8( mmAtomicLock8 *v, int spincount ) -{ - do - { - if( mmAtomicRead8( &v->v ) < 0 ) - mmAtomicPause(); - else - { - if( !( mmAtomicAddTestNegative8( &v->v, 1 ) ) ) - return 1; - mmAtomicAdd8( &v->v, -1 ); - } - } while( --spincount ); - return 0; -} - -static inline int mmAtomicLockTryWrite8( mmAtomicLock8 *v, int spincount ) -{ - do - { - if( mmAtomicRead8( &v->v ) ) - mmAtomicPause(); - else - { - if( !( mmAtomicCmpXchg8( &v->v, 0, MM_ATOMIC_LOCK8_WRITE ) ) ) - return 1; - } - } while( --spincount ); - return 0; -} - -static inline void mmAtomicLockDoneRead8( mmAtomicLock8 *v ) -{ - mmAtomicAdd8( &v->v, -1 ); - return; -} - -static inline void mmAtomicLockDoneWrite8( mmAtomicLock8 *v ) -{ - mmAtomicAdd8( &v->v, -MM_ATOMIC_LOCK8_WRITE ); - return; -} - - -//// - - -typedef struct { mmAtomic16 v; } mmAtomicLock16; - -#define MM_ATOMIC_LOCK16_WRITE (-((int16_t)0x7fff)) - -static inline void mmAtomicLockInit16( mmAtomicLock16 *v ) -{ - mmAtomicWrite16( &v->v, 0 ); - return; -} - -static inline int mmAtomicLockAttemptRead16( mmAtomicLock16 *v ) -{ - if( mmAtomicAddTestNegative16( &v->v, 1 ) ) - { - mmAtomicAdd16( &v->v, -1 ); - return 0; - } - return 1; -} - -static inline int mmAtomicLockAttemptWrite16( mmAtomicLock16 *v ) -{ - if( mmAtomicCmpXchg16( &v->v, 0, MM_ATOMIC_LOCK16_WRITE ) ) - return 0; - return 1; -} - -static inline void mmAtomicLockSpinRead16( mmAtomicLock16 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead16( &v->v ) < 0 ; ) - mmAtomicPause(); - if( !( mmAtomicAddTestNegative16( &v->v, 1 ) ) ) - break; - mmAtomicAdd16( &v->v, -1 ); - } - return; -} - -static inline void mmAtomicLockSpinWrite16( mmAtomicLock16 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead16( &v->v ) ; ) - mmAtomicPause(); - if( !( mmAtomicCmpXchg16( &v->v, 0, MM_ATOMIC_LOCK16_WRITE ) ) ) - break; - } - return; -} - -static inline int mmAtomicLockTryRead16( mmAtomicLock16 *v, int spincount ) -{ - do - { - if( mmAtomicRead16( &v->v ) < 0 ) - mmAtomicPause(); - else - { - if( !( mmAtomicAddTestNegative16( &v->v, 1 ) ) ) - return 1; - mmAtomicAdd16( &v->v, -1 ); - } - } while( --spincount ); - return 0; -} - -static inline int mmAtomicLockTryWrite16( mmAtomicLock16 *v, int spincount ) -{ - do - { - if( mmAtomicRead16( &v->v ) ) - mmAtomicPause(); - else - { - if( !( mmAtomicCmpXchg16( &v->v, 0, MM_ATOMIC_LOCK16_WRITE ) ) ) - return 1; - } - } while( --spincount ); - return 0; -} - -static inline void mmAtomicLockDoneRead16( mmAtomicLock16 *v ) -{ - mmAtomicAdd16( &v->v, -1 ); - return; -} - -static inline void mmAtomicLockDoneWrite16( mmAtomicLock16 *v ) -{ - mmAtomicAdd16( &v->v, -MM_ATOMIC_LOCK16_WRITE ); - return; -} - - -//// - - -typedef struct { mmAtomic32 v; } mmAtomicLock32; - -/* -#define MM_ATOMIC_LOCK32_WRITE (-((int32_t)0x7fffffff)) -*/ -#define MM_ATOMIC_LOCK32_WRITE (-((int32_t)0x10000000)) - -static inline void mmAtomicLockInit32( mmAtomicLock32 *v ) -{ - mmAtomicWrite32( &v->v, 0 ); - return; -} - -static inline int mmAtomicLockAttemptRead32( mmAtomicLock32 *v ) -{ - if( mmAtomicAddTestNegative32( &v->v, 1 ) ) - { - mmAtomicAdd32( &v->v, -1 ); - return 0; - } - return 1; -} - -static inline int mmAtomicLockAttemptWrite32( mmAtomicLock32 *v ) -{ - if( mmAtomicCmpXchg32( &v->v, 0, MM_ATOMIC_LOCK32_WRITE ) ) - return 0; - return 1; -} - -static inline void mmAtomicLockSpinRead32( mmAtomicLock32 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead32( &v->v ) < 0 ; ) - mmAtomicPause(); - if( !( mmAtomicAddTestNegative32( &v->v, 1 ) ) ) - break; - mmAtomicAdd32( &v->v, -1 ); - } - return; -} - -static inline void mmAtomicLockSpinWrite32( mmAtomicLock32 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead32( &v->v ) ; ) - mmAtomicPause(); - if( !( mmAtomicCmpXchg32( &v->v, 0, MM_ATOMIC_LOCK32_WRITE ) ) ) - break; - } - return; -} - -static inline int mmAtomicLockTryRead32( mmAtomicLock32 *v, int spincount ) -{ - do - { - if( mmAtomicRead32( &v->v ) < 0 ) - mmAtomicPause(); - else - { - if( !( mmAtomicAddTestNegative32( &v->v, 1 ) ) ) - return 1; - mmAtomicAdd32( &v->v, -1 ); - } - } while( --spincount ); - return 0; -} - -static inline int mmAtomicLockTryWrite32( mmAtomicLock32 *v, int spincount ) -{ - do - { - if( mmAtomicRead32( &v->v ) ) - mmAtomicPause(); - else - { - if( !( mmAtomicCmpXchg32( &v->v, 0, MM_ATOMIC_LOCK32_WRITE ) ) ) - return 1; - } - } while( --spincount ); - return 0; -} - -static inline void mmAtomicLockDoneRead32( mmAtomicLock32 *v ) -{ - mmAtomicAdd32( &v->v, -1 ); - return; -} - -static inline void mmAtomicLockDoneWrite32( mmAtomicLock32 *v ) -{ - mmAtomicAdd32( &v->v, -MM_ATOMIC_LOCK32_WRITE ); - return; -} - - -//// - - -#ifdef MM_ATOMIC_64_BITS_SUPPORT - -typedef struct { mmAtomic64 v; } mmAtomicLock64; - -#define MM_ATOMIC_LOCK64_WRITE (-((int64_t)0x7fffffffffffffff)) - -static inline void mmAtomicLockInit64( mmAtomicLock64 *v ) -{ - mmAtomicWrite64( &v->v, 0 ); - return; -} - -static inline int mmAtomicLockAttemptRead64( mmAtomicLock64 *v ) -{ - if( mmAtomicAddTestNegative64( &v->v, 1 ) ) - { - mmAtomicAdd64( &v->v, -1 ); - return 0; - } - return 1; -} - -static inline int mmAtomicLockAttemptWrite64( mmAtomicLock64 *v ) -{ - if( mmAtomicCmpXchg64( &v->v, 0, MM_ATOMIC_LOCK64_WRITE ) ) - return 0; - return 1; -} - -static inline void mmAtomicLockSpinRead64( mmAtomicLock64 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead64( &v->v ) < 0 ; ) - mmAtomicPause(); - if( !( mmAtomicAddTestNegative64( &v->v, 1 ) ) ) - break; - mmAtomicAdd64( &v->v, -1 ); - } - return; -} - -static inline void mmAtomicLockSpinWrite64( mmAtomicLock64 *v ) -{ - for( ; ; ) - { - for( ; mmAtomicRead64( &v->v ) ; ) - mmAtomicPause(); - if( !( mmAtomicCmpXchg64( &v->v, 0, MM_ATOMIC_LOCK64_WRITE ) ) ) - break; - } - return; -} - -static inline int mmAtomicLockTryRead64( mmAtomicLock64 *v, int spincount ) -{ - do - { - if( mmAtomicRead64( &v->v ) < 0 ) - mmAtomicPause(); - else - { - if( !( mmAtomicAddTestNegative64( &v->v, 1 ) ) ) - return 1; - mmAtomicAdd64( &v->v, -1 ); - } - } while( --spincount ); - return 0; -} - -static inline int mmAtomicLockTryWrite64( mmAtomicLock64 *v, int spincount ) -{ - do - { - if( mmAtomicRead64( &v->v ) ) - mmAtomicPause(); - else - { - if( !( mmAtomicCmpXchg64( &v->v, 0, MM_ATOMIC_LOCK64_WRITE ) ) ) - return 1; - } - } while( --spincount ); - return 0; -} - -static inline void mmAtomicLockDoneRead64( mmAtomicLock64 *v ) -{ - mmAtomicAdd64( &v->v, -1 ); - return; -} - -static inline void mmAtomicLockDoneWrite64( mmAtomicLock64 *v ) -{ - mmAtomicAdd64( &v->v, -MM_ATOMIC_LOCK64_WRITE ); - return; -} - -#endif - - - -//////////////// - - - -#define MM_ATOMIC_LIST_BUSY ((void *)0x1) - -typedef struct -{ - mmAtomicP prev; /* mmAtomicP* to &(prev->next) */ - mmAtomicP next; /* void* to next */ - mmAtomic32 status; -} mmAtomicListNode; - -#define MM_ATOMIC_LIST_VALID (0x0) -#define MM_ATOMIC_LIST_DELETED (0x1) - -typedef struct -{ - mmAtomicP first; /* void* to item */ - mmAtomicP last; /* mmAtomicP* to &(lastitem->next) */ -} mmAtomicListDualHead; - - -void mmAtomicListAdd( mmAtomicP *list, void *item, intptr_t offset ); -void mmAtomicListRemove( void *item, intptr_t offset ); - -static inline void *mmAtomicListFirst( mmAtomicP *head ) -{ - void *item; - for( ; ( item = mmAtomicReadP( head ) ) == MM_ATOMIC_LIST_BUSY ; ) - mmAtomicPause(); - return item; -} - -static inline void *mmAtomicListNext( mmAtomicListNode *node ) -{ - void *item; - for( ; ; ) - { - item = mmAtomicReadP( &node->next ); - if( mmAtomicRead32( &node->status ) == MM_ATOMIC_LIST_DELETED ) - return 0; - /* At the time we have read node->next, the node has not been deleted yet */ - if( item != MM_ATOMIC_LIST_BUSY ) - break; - mmAtomicPause(); - } - return item; -} - - -void mmAtomicListDualInit( mmAtomicListDualHead *head ); -void mmAtomicListDualAddFirst( mmAtomicListDualHead *head, void *item, intptr_t offset ); -void mmAtomicListDualAddLast( mmAtomicListDualHead *head, void *item, intptr_t offset ); -void mmAtomicListDualRemove( mmAtomicListDualHead *head, void *item, intptr_t offset ); - -static inline void *mmAtomicListDualFirst( mmAtomicListDualHead *head ) -{ - void *item; - for( ; ( item = mmAtomicReadP( &head->first ) ) == MM_ATOMIC_LIST_BUSY ; ) - mmAtomicPause(); - return item; -} - -static inline void *mmAtomicListDualNext( mmAtomicListNode *node ) -{ - void *item; - for( ; ; ) - { - item = mmAtomicReadP( &node->next ); - if( mmAtomicRead32( &node->status ) == MM_ATOMIC_LIST_DELETED ) - return 0; - /* At the time we have read node->next, the node has not been deleted yet */ - if( item != MM_ATOMIC_LIST_BUSY ) - break; - mmAtomicPause(); - } - return item; -} - - - -//////////////// - - - -/* -#define MM_ATOMIC_BARRIER_DEBUG -*/ - - -#define MM_ATOMIC_BARRIER_DELAYED_RESET - - -typedef struct -{ - int32_t clearcounter; - int32_t yieldcounter; -} mmAtomicBarrierStat; - -typedef struct -{ - mmAtomic32 flag MM_CACHE_ALIGN; - mmAtomic32 counter MM_CACHE_ALIGN; - volatile int32_t flagref MM_CACHE_ALIGN; - void *parent MM_CACHE_ALIGN; - int32_t resetvalue; -} mmAtomicBarrier; - -void mmAtomicBarrierBuild( mmAtomicBarrier *barrier, int childcount, mmAtomicBarrier *parent ); -int mmAtomicBarrierWait( mmAtomicBarrier *barrier, int32_t spinwaitcounter, mmAtomicBarrierStat *barrierstat ); - - - - -//// - - - -typedef struct -{ - mmAtomic32 counter MM_CACHE_ALIGN; - /* Data below remains constant */ - void *parent MM_CACHE_ALIGN; - int32_t resetvalue; -} mmAtomicCounterNode; - -typedef struct -{ - int32_t lockcount; - int32_t nodecount; - mmAtomicCounterNode *nodearray; - mmAtomicCounterNode **locknode; -} mmAtomicCounter; - -void mmAtomicCounterInit( mmAtomicCounter *counter, int lockcount, int stagesize ); -void mmAtomicCounterDestroy( mmAtomicCounter *counter ); -int mmAtomicCounterHit( mmAtomicCounter *counter, int lockindex ); - - - -//// - - -/* -Stockpile callbacks for freeing items - -*/ - -typedef struct -{ - mmAtomicP p; - - -} mmAtomicRcu; - -static inline void mmAtomicRcuEnter( mmAtomicRcu *rcu ) -{ - /* On archs with messed up memory models like Alpha, we would need some memory barrier here */ - return; -} - -static inline void mmAtomicRcuLeave( mmAtomicRcu *rcu ) -{ - /* On archs with messed up memory models like Alpha, we would need some memory barrier here */ - return; -} - - -/* -To reiterate, synchronize_rcu() waits only for ongoing RCU read-side critical sections to complete, -not necessarily for any that begin after synchronize_rcu() is invoked. -*/ -static inline void mmAtomicRcuSync() -{ - -} - -static inline void mmAtomicRcuRead() -{ - - -} - - -static inline void mmAtomicRcuWrite() -{ - - -} - - - -#endif - - diff --git a/src/other/gct/Auxiliary/mmbinsort.c b/src/other/gct/Auxiliary/mmbinsort.c deleted file mode 100644 index d0121cbadd4..00000000000 --- a/src/other/gct/Auxiliary/mmbinsort.c +++ /dev/null @@ -1,526 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cc.h" -#include "mm.h" - -#include "mmbinsort.h" - - - -/* -#define MM_BINSORT_INSERTION_SORT -*/ - - - -typedef float mmbsf; -#define mmbsffloor(x) floorf(x) -#define mmbsfceil(x) ceilf(x) - - - -typedef struct -{ - int itemcount; - int flags; - mmbsf min, max; - void *p; - void **last; -} mmBinSortBucket; - -#define MM_BINSORT_BUCKET_FLAGS_SUBGROUP (0x1) - - -typedef struct -{ - mmbsf groupbase, groupmax, bucketrange; - int bucketmax; - mmBinSortBucket bucket[]; -} mmBinSortGroup; - - -typedef struct -{ - int numanodeindex; - size_t memsize; - size_t itemlistoffset; - int rootbucketcount; /* Count of buckets for root */ - int groupbucketcount; /* Count of buckets per group */ - int groupthreshold; /* Count of items required in a bucket */ - int collapsethreshold; - int maxdepth; - - /* Callback to user code to obtain the value of an item */ - double (*itemvalue)( void *item ); - - /* Memory management */ - mmBlockHead bucketblock; - mmBlockHead groupblock; - - /* Top-level group, *MUST* be at end of struct due to bucket[] zero-length array */ - mmBinSortGroup root; - -} mmBinSortHead; - - -/****/ - - -void *mmBinSortInit( size_t itemlistoffset, int rootbucketcount, int groupbucketcount, double rootmin, double rootmax, int groupthreshold, double (*itemvaluecallback)( void *item ), int maxdepth, int numanodeindex ) -{ - int bucketindex; - size_t memsize; - mmBinSortHead *bsort; - mmBinSortGroup *group; - mmBinSortBucket *bucket; - - if( !( mmcontext.numaflag ) ) - numanodeindex = -1; - memsize = sizeof(mmBinSortHead) + ( rootbucketcount * sizeof(mmBinSortBucket) ); - if( numanodeindex >= 0 ) - { - bsort = mmNodeAlloc( numanodeindex, memsize ); - mmBlockNodeInit( &bsort->bucketblock, numanodeindex, sizeof(mmBinSortBucket), 1024, 1024, 0x40 ); - mmBlockNodeInit( &bsort->groupblock, numanodeindex, sizeof(mmBinSortGroup) + ( groupbucketcount * sizeof(mmBinSortBucket) ), 16, 16, 0x40 ); - } - else - { - bsort = malloc( memsize ); - mmBlockInit( &bsort->bucketblock, sizeof(mmBinSortBucket), 1024, 1024, 0x40 ); - mmBlockInit( &bsort->groupblock, sizeof(mmBinSortGroup) + ( groupbucketcount * sizeof(mmBinSortBucket) ), 16, 16, 0x40 ); - } - bsort->numanodeindex = numanodeindex; - bsort->memsize = memsize; - - bsort->itemlistoffset = itemlistoffset; - bsort->rootbucketcount = rootbucketcount; - bsort->groupbucketcount = groupbucketcount; - bsort->groupthreshold = groupthreshold; - bsort->collapsethreshold = groupthreshold >> 2; - bsort->maxdepth = maxdepth; - - bsort->itemvalue = itemvaluecallback; - - group = &bsort->root; - group->groupbase = rootmin; - group->groupmax = rootmax; - group->bucketrange = ( rootmax - rootmin ) / (double)rootbucketcount; - group->bucketmax = rootbucketcount - 1; - bucket = group->bucket; - for( bucketindex = 0 ; bucketindex < rootbucketcount ; bucketindex++ ) - { - bucket->flags = 0; - bucket->itemcount = 0; - bucket->min = FLT_MAX; - bucket->max = -FLT_MAX; - bucket->p = 0; - bucket++; - } - - return bsort; -} - - -void mmBinSortFree( void *binsort ) -{ - mmBinSortHead *bsort; - bsort = binsort; - mmBlockFreeAll( &bsort->bucketblock ); - mmBlockFreeAll( &bsort->groupblock ); - if( bsort->numanodeindex >= 0 ) - mmNodeFree( bsort->numanodeindex, bsort, bsort->memsize ); - else - free( bsort ); - return; -} - - -static int MM_NOINLINE mmBinSortBucketIndex( mmBinSortGroup *group, mmbsf value ) -{ - int bucketindex = (int)mmbsffloor( ( value - group->groupbase ) / group->bucketrange ); - if( bucketindex < 0 ) - bucketindex = 0; - if( bucketindex > group->bucketmax ) - bucketindex = group->bucketmax; - return bucketindex; -} - - -/****/ - - -static mmBinSortGroup *mmBinSortSpawnGroup( mmBinSortHead *bsort, void *itembase, mmbsf base, mmbsf range ) -{ - int bucketindex; - mmbsf value; - void *item, *itemnext; - mmBinSortGroup *group; - mmBinSortBucket *bucket; - - group = mmBlockAlloc( &bsort->groupblock ); - group->groupbase = base; - group->groupmax = base + range; - group->bucketrange = range / (mmbsf)bsort->groupbucketcount; - group->bucketmax = bsort->groupbucketcount - 1; - - bucket = group->bucket; - for( bucketindex = 0 ; bucketindex < bsort->groupbucketcount ; bucketindex++ ) - { - bucket->flags = 0; - bucket->itemcount = 0; - bucket->min = FLT_MAX; - bucket->max = -FLT_MAX; - bucket->p = 0; - bucket->last = &bucket->p; - bucket++; - } - - for( item = itembase ; item ; item = itemnext ) - { - itemnext = ((mmListNode *)ADDRESS( item, bsort->itemlistoffset ))->next; - - value = bsort->itemvalue( item ); - bucketindex = mmBinSortBucketIndex( group, value ); - - if( value < bucket->min ) - bucket->min = value; - if( value > bucket->max ) - bucket->max = value; - - bucket = &group->bucket[ bucketindex ]; - bucket->itemcount++; - mmListAdd( bucket->last, item, bsort->itemlistoffset ); - bucket->last = &((mmListNode *)ADDRESS( item, bsort->itemlistoffset ))->next; - } - - return group; -} - - -/* Debugging */ -/* -static int mmBinSortBucketCount( mmBinSortHead *bsort, mmBinSortBucket *bucket ) -{ - int itemcount; - void *item; - itemcount = 0; - for( item = bucket->p ; item ; item = ((mmListNode *)ADDRESS( item, bsort->itemlistoffset ))->next ) - itemcount++; - return itemcount; -} - - -static int mmBinSortGroupCount( mmBinSortHead *bsort, mmBinSortGroup *group ) -{ - int itemcount, bucketindex; - mmBinSortBucket *bucket; - bucket = group->bucket; - itemcount = 0; - for( bucketindex = 0, bucket = group->bucket ; bucketindex < bsort->groupbucketcount ; bucketindex++, bucket++ ) - { - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - itemcount += mmBinSortGroupCount( bsort, bucket->p ); - else - itemcount += mmBinSortBucketCount( bsort, bucket ); - } - return itemcount; -} - - -static void mmBinSortBucketCheck( mmBinSortHead *bsort, mmBinSortBucket *bucket ) -{ - int itemcount; - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - itemcount = mmBinSortGroupCount( bsort, bucket->p ); - else - itemcount = mmBinSortBucketCount( bsort, bucket ); - printf( "Countcheck (0x%x) %d ~ %d\n", bucket->flags, itemcount, bucket->itemcount ); - if( itemcount != bucket->itemcount ) - exit( 1 ); - return; -} -*/ - - - - -static void mmBinSortCollapseGroup( mmBinSortHead *bsort, mmBinSortBucket *parentbucket ) -{ - int bucketindex, itemcount; - mmBinSortGroup *group; - mmBinSortBucket *bucket; - void *item, *itemnext; - - group = parentbucket->p; - parentbucket->p = 0; - parentbucket->last = &parentbucket->p; - - itemcount = 0; - for( bucketindex = 0, bucket = group->bucket ; bucketindex < bsort->groupbucketcount ; bucketindex++, bucket++ ) - { - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - mmBinSortCollapseGroup( bsort, bucket ); - for( item = bucket->p ; item ; item = itemnext ) - { - itemnext = ((mmListNode *)ADDRESS( item, bsort->itemlistoffset ))->next; - mmListAdd( parentbucket->last, item, bsort->itemlistoffset ); - parentbucket->last = &((mmListNode *)ADDRESS( item, bsort->itemlistoffset ))->next; - itemcount++; - } - } - parentbucket->flags &= ~MM_BINSORT_BUCKET_FLAGS_SUBGROUP; - parentbucket->itemcount = itemcount; - - return; -} - - -/****/ - - -void mmBinSortAdd( void *binsort, void *item, double itemvalue ) -{ - int bucketindex, depth; - mmbsf value; - mmBinSortHead *bsort; - mmBinSortGroup *group, *subgroup; - mmBinSortBucket *bucket; - - bsort = binsort; - value = itemvalue; - group = &bsort->root; - for( depth = 0 ; ; group = bucket->p, depth++ ) - { - bucketindex = mmBinSortBucketIndex( group, value ); - bucket = &group->bucket[ bucketindex ]; - bucket->itemcount++; - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - continue; - if( ( bucket->itemcount >= bsort->groupthreshold ) && ( depth < bsort->maxdepth ) ) - { - /* Build a new sub group, sort all entries into it */ - subgroup = mmBinSortSpawnGroup( bsort, bucket->p, group->groupbase + ( (mmbsf)bucketindex * group->bucketrange ), group->bucketrange ); - bucket->flags |= MM_BINSORT_BUCKET_FLAGS_SUBGROUP; - bucket->p = subgroup; - continue; - } - if( value < bucket->min ) - bucket->min = value; - if( value > bucket->max ) - bucket->max = value; - -#ifdef MM_BINSORT_INSERTION_SORT - void *itemfind, *itemnext; - void **insert; - insert = &bucket->p; - for( itemfind = bucket->p ; itemfind ; itemfind = itemnext ) - { - itemnext = ((mmListNode *)ADDRESS( itemfind, bsort->itemlistoffset ))->next; - if( itemvalue <= bsort->itemvalue( itemfind ) ) - break; - insert = &((mmListNode *)ADDRESS( itemfind, bsort->itemlistoffset ))->next; - } - mmListAdd( insert, item, bsort->itemlistoffset ); -#else - mmListAdd( &bucket->p, item, bsort->itemlistoffset ); -#endif - - break; - } - - return; -} - -void mmBinSortRemove( void *binsort, void *item, double itemvalue ) -{ - int bucketindex; - mmbsf value; - mmBinSortHead *bsort; - mmBinSortGroup *group; - mmBinSortBucket *bucket; - - bsort = binsort; - value = itemvalue; - group = &bsort->root; - for( ; ; group = bucket->p ) - { - bucketindex = mmBinSortBucketIndex( group, value ); - bucket = &group->bucket[ bucketindex ]; - bucket->itemcount--; - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - { - if( bucket->itemcount >= bsort->collapsethreshold ) - continue; - mmBinSortCollapseGroup( bsort, bucket ); - } - break; - } - mmListRemove( item, bsort->itemlistoffset ); - - return; -} - - -void mmBinSortUpdate( void *binsort, void *item, double olditemvalue, double newitemvalue ) -{ - mmBinSortRemove( binsort, item, olditemvalue ); - mmBinSortAdd( binsort, item, newitemvalue ); - return; -} - - -/****/ - - -void *mmBinSortGetRootBucket( void *binsort, int bucketindex, int *itemcount ) -{ - mmBinSortHead *bsort; - mmBinSortBucket *bucket; - - bsort = binsort; - bucket = &bsort->root.bucket[ bucketindex ]; - - *itemcount = bucket->itemcount; - return bucket->p; -} - - -void *mmBinSortGetGroupBucket( void *binsortgroup, int bucketindex, int *itemcount ) -{ - mmBinSortGroup *group; - mmBinSortBucket *bucket; - - group = binsortgroup; - bucket = &group->bucket[ bucketindex ]; - - *itemcount = bucket->itemcount; - return bucket->p; -} - - -/****/ - - -static void *mmBinSortGroupFirstItem( mmBinSortHead *bsort, mmBinSortGroup *group, mmbsf failmax ) -{ - int bucketindex, topbucket; - void *item; - mmBinSortBucket *bucket; - mmBinSortGroup *subgroup; - - if( failmax > group->groupmax ) - topbucket = group->bucketmax; - else - { - topbucket = (int)mmbsfceil( ( failmax - group->groupbase ) / group->bucketrange ); - if( ( topbucket < 0 ) || ( topbucket > group->bucketmax ) ) - topbucket = group->bucketmax; - } -/* -printf( " Failmax %f ; Base %f ; Range %f ; Index %f\n", failmax, group->groupbase, group->bucketrange, mmbsfceil( failmax - group->groupbase ) / group->bucketrange ); -printf( " Top bucket : %d\n", topbucket ); -*/ - bucket = group->bucket; - for( bucketindex = 0 ; bucketindex <= topbucket ; bucketindex++, bucket++ ) - { -/* -printf( " Bucket %d ; Count %d ; Flags 0x%x ; %p\n", bucketindex, bucket->itemcount, bucket->flags, bucket->p ); -*/ - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - { - subgroup = bucket->p; - item = mmBinSortGroupFirstItem( bsort, subgroup, failmax ); - if( item ) - return item; - } - else if( bucket->p ) - return bucket->p; - } - - return 0; -} - - -void *mmBinSortGetFirstItem( void *binsort, double failmax ) -{ - int bucketindex, topbucket; - mmBinSortHead *bsort; - mmBinSortGroup *group; - mmBinSortBucket *bucket; - void *item; - - bsort = binsort; - if( failmax > bsort->root.groupmax ) - topbucket = bsort->root.bucketmax; - else - { - topbucket = (int)mmbsfceil( ( (mmbsf)failmax - bsort->root.groupbase ) / bsort->root.bucketrange ); - if( ( topbucket < 0 ) || ( topbucket > bsort->root.bucketmax ) ) - topbucket = bsort->root.bucketmax; - } - -/* - printf( "TopBucket : %d / %d\n", topbucket, bsort->root.bucketmax ); -*/ - bucket = bsort->root.bucket; - for( bucketindex = 0 ; bucketindex <= topbucket ; bucketindex++, bucket++ ) - { -/* -printf( " Bucket %d ; Count %d ; Flags 0x%x ; %p\n", bucketindex, bucket->itemcount, bucket->flags, bucket->p ); -*/ - if( bucket->flags & MM_BINSORT_BUCKET_FLAGS_SUBGROUP ) - { - group = bucket->p; - item = mmBinSortGroupFirstItem( bsort, group, (mmbsf)failmax ); - if( item ) - return item; - } - else if( bucket->p ) - return bucket->p; - } - - return 0; -} - - -/****/ - - - - diff --git a/src/other/gct/Auxiliary/mmbinsort.h b/src/other/gct/Auxiliary/mmbinsort.h deleted file mode 100644 index 543982e4fbe..00000000000 --- a/src/other/gct/Auxiliary/mmbinsort.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -void *mmBinSortInit( size_t itemlistoffset, int rootbucketcount, int groupbucketcount, double rootmin, double rootmax, int groupthreshold, double (*itemvaluecallback)( void *item ), int maxdepth, int numanodeindex ); -void mmBinSortFree( void *binsort ); - - -void mmBinSortAdd( void *binsort, void *item, double itemvalue ); -void mmBinSortRemove( void *binsort, void *item, double itemvalue ); -void mmBinSortUpdate( void *binsort, void *item, double olditemvalue, double newitemvalue ); - -void *mmBinSortGetRootBucket( void *binsort, int bucketindex, int *itemcount ); -void *mmBinSortGetGroupBucket( void *binsortgroup, int bucketindex, int *itemcount ); - - -void *mmBinSortGetFirstItem( void *binsort, double failmax ); - - diff --git a/src/other/gct/Auxiliary/mmbitmap.c b/src/other/gct/Auxiliary/mmbitmap.c deleted file mode 100644 index 428cb0a5813..00000000000 --- a/src/other/gct/Auxiliary/mmbitmap.c +++ /dev/null @@ -1,487 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -#include -#include -#include -#include -#include -#include - -#include "cpuconfig.h" -#include "cc.h" -#include "mm.h" -#include "mmbitmap.h" - - -/* Friendlier to cache on SMP systems */ -#define BP_BITMAP_PREWRITE_CHECK - - -/* -TODO -If we don't have atomic instruction support, we need a much better mutex locking mechanism!! -*/ - - -void mmBitMapInit( mmBitMap *bitmap, size_t entrycount, int initvalue ) -{ - size_t mapsize, index; - long value; -#ifdef MM_ATOMIC_SUPPORT - mmAtomicL *map; -#else - long *map; -#endif - - mapsize = ( entrycount + CPUCONF_LONG_BITS - 1 ) >> CPUCONF_LONG_BITSHIFT; - bitmap->map = malloc( mapsize * sizeof(mmAtomicL) ); - bitmap->mapsize = mapsize; - bitmap->entrycount = entrycount; - - map = bitmap->map; - value = ( initvalue & 0x1 ? ~0x0 : 0x0 ); -#ifdef MM_ATOMIC_SUPPORT - for( index = 0 ; index < mapsize ; index++ ) - mmAtomicWriteL( &map[index], value ); -#else - for( index = 0 ; index < mapsize ; index++ ) - map[index] = value; - mtMutexInit( &bitmap->mutex ); -#endif - - return; -} - -void mmBitMapReset( mmBitMap *bitmap, int resetvalue ) -{ - size_t index; - long value; -#ifdef MM_ATOMIC_SUPPORT - mmAtomicL *map; -#else - long *map; -#endif - - map = bitmap->map; - value = ( resetvalue & 0x1 ? ~(long)0x0 : (long)0x0 ); -#ifdef MM_ATOMIC_SUPPORT - for( index = 0 ; index < bitmap->mapsize ; index++ ) - mmAtomicWriteL( &map[index], value ); -#else - for( index = 0 ; index < bitmap->mapsize ; index++ ) - map[index] = value; -#endif - - return; -} - -void mmBitMapFree( mmBitMap *bitmap ) -{ - free( bitmap->map ); - bitmap->map = 0; - bitmap->mapsize = 0; -#ifndef MM_ATOMIC_SUPPORT - mtMutexDestroy( &bitmap->mutex ); -#endif - return; -} - -int mmBitMapDirectGet( mmBitMap *bitmap, size_t entryindex ) -{ - int value; - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = ( MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) >> shift ) & 0x1; -#else - value = ( bitmap->map[index] >> shift ) & 0x1; -#endif - return value; -} - -void mmBitMapDirectSet( mmBitMap *bitmap, size_t entryindex ) -{ - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) |= (long)1 << shift; -#else - bitmap->map[index] |= (long)1 << shift; -#endif - return; -} - -void mmBitMapDirectClear( mmBitMap *bitmap, size_t entryindex ) -{ - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) &= ~( (long)1 << shift ); -#else - bitmap->map[index] &= ~( (long)1 << shift ); -#endif - return; -} - -int mmBitMapDirectMaskGet( mmBitMap *bitmap, size_t entryindex, long mask ) -{ - int value; - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = ( MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) >> shift ) & mask; -#else - value = ( bitmap->map[index] >> shift ) & mask; -#endif - return value; -} - -void mmBitMapDirectMaskSet( mmBitMap *bitmap, size_t entryindex, long value, long mask ) -{ - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) = ( MM_ATOMIC_ACCESS_L( &bitmap->map[index] ) & ~( mask << shift ) ) | ( value << shift ); -#else - bitmap->map[index] = ( bitmap->map[index] & ~( mask << shift ) ) | ( value << shift ); -#endif - return; -} - -int mmBitMapGet( mmBitMap *bitmap, size_t entryindex ) -{ - int value; - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = ( mmAtomicReadL( &bitmap->map[index] ) >> shift ) & 0x1; -#else - mtMutexLock( &bitmap->mutex ); - value = ( bitmap->map[index] >> shift ) & 0x1; - mtMutexUnlock( &bitmap->mutex ); -#endif - return value; -} - -void mmBitMapSet( mmBitMap *bitmap, size_t entryindex ) -{ - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - #ifdef BP_BITMAP_PREWRITE_CHECK - if( !( mmAtomicReadL( &bitmap->map[index] ) & ( (long)1 << shift ) ) ) - mmAtomicOrL( &bitmap->map[index], (long)1 << shift ); - #else - mmAtomicOrL( &bitmap->map[index], (long)1 << shift ); - #endif -#else - mtMutexLock( &bitmap->mutex ); - bitmap->map[index] |= (long)1 << shift; - mtMutexUnlock( &bitmap->mutex ); -#endif - return; -} - -void mmBitMapClear( mmBitMap *bitmap, size_t entryindex ) -{ - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - #ifdef BP_BITMAP_PREWRITE_CHECK - if( mmAtomicReadL( &bitmap->map[index] ) & ( (long)1 << shift ) ) - mmAtomicAndL( &bitmap->map[index], ~( (long)1 << shift ) ); - #else - mmAtomicAndL( &bitmap->map[index], ~( (long)1 << shift ) ); - #endif -#else - mtMutexLock( &bitmap->mutex ); - bitmap->map[index] &= ~( (long)1 << shift ); - mtMutexUnlock( &bitmap->mutex ); -#endif - return; -} - -int mmBitMapMaskGet( mmBitMap *bitmap, size_t entryindex, long mask ) -{ - int value; - size_t index, shift; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = ( mmAtomicReadL( &bitmap->map[index] ) >> shift ) & mask; -#else - mtMutexLock( &bitmap->mutex ); - value = ( bitmap->map[index] >> shift ) & mask; - mtMutexUnlock( &bitmap->mutex ); -#endif - return value; -} - -void mmBitMapMaskSet( mmBitMap *bitmap, size_t entryindex, long value, long mask ) -{ - size_t index, shift; - long oldvalue, newvalue; - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shift = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - for( ; ; ) - { - oldvalue = mmAtomicReadL( &bitmap->map[index] ); - newvalue = ( oldvalue & ~( mask << shift ) ) | ( value << shift ); - if( mmAtomicCmpReplaceL( &bitmap->map[index], oldvalue, newvalue ) ) - break; - } -#else - mtMutexLock( &bitmap->mutex ); - bitmap->map[index] = ( bitmap->map[index] & ~( mask << shift ) ) | ( value << shift ); - mtMutexUnlock( &bitmap->mutex ); -#endif - return; -} - -/* TODO: Yeah... That code was written in one go, maybe I should test if it's working fine, just in case? */ -int mmBitMapFindSet( mmBitMap *bitmap, size_t entryindex, size_t entryindexlast, size_t *retentryindex ) -{ - unsigned long value; - size_t index, shift, shiftbase, shiftmax, indexlast, shiftlast; - - indexlast = entryindexlast >> CPUCONF_LONG_BITSHIFT; - shiftlast = entryindexlast & ( CPUCONF_LONG_BITS - 1 ); - - /* Leading bits search */ - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shiftbase = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - mtMutexLock( &bitmap->mutex ); - value = bitmap->map[index]; -#endif - if( value != (unsigned long)0x0 ) - { - shiftmax = CPUCONF_LONG_BITS; - if( ( index == indexlast ) && ( shiftlast > shiftbase ) ) - shiftmax = shiftlast; - value >>= shiftbase; - for( shift = shiftbase ; shift < shiftmax ; shift++, value >>= 1 ) - { - if( !( value & 0x1 ) ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - *retentryindex = entryindex; - return 1; - } - } - if( ( index == indexlast ) && ( shiftlast > shiftbase ) ) - { -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - return 0; - } - - /* Main search */ - for( ; ; ) - { - index = ( index + 1 ) % bitmap->mapsize; - if( index == indexlast ) - break; -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - value = bitmap->map[index]; -#endif - if( value != (unsigned long)0x0 ) - { - for( shift = 0 ; ; shift++, value >>= 1 ) - { - if( !( value & 0x1 ) ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - *retentryindex = entryindex; - return 1; - } - } - } - - /* Trailing bits search */ - shiftlast = entryindexlast & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - value = bitmap->map[index]; -#endif - if( value != (unsigned long)0x0 ) - { - for( shift = 0 ; shift < shiftlast ; shift++, value >>= 1 ) - { - if( !( value & 0x1 ) ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - if( ( index == indexlast ) && ( shift >= shiftlast ) ) - return 0; - *retentryindex = entryindex; - return 1; - } - } -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - - return 0; -} - -int mmBitMapFindClear( mmBitMap *bitmap, size_t entryindex, size_t entryindexlast, size_t *retentryindex ) -{ - unsigned long value; - size_t index, shift, shiftbase, shiftmax, indexlast, shiftlast; - - indexlast = entryindexlast >> CPUCONF_LONG_BITSHIFT; - shiftlast = entryindexlast & ( CPUCONF_LONG_BITS - 1 ); - - /* Leading bits search */ - index = entryindex >> CPUCONF_LONG_BITSHIFT; - shiftbase = entryindex & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - mtMutexLock( &bitmap->mutex ); - value = bitmap->map[index]; -#endif - if( value != ~(unsigned long)0x0 ) - { - shiftmax = CPUCONF_LONG_BITS; - if( ( index == indexlast ) && ( shiftlast > shiftbase ) ) - shiftmax = shiftlast; - value >>= shiftbase; - for( shift = shiftbase ; shift < shiftmax ; shift++, value >>= 1 ) - { - if( value & 0x1 ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - *retentryindex = entryindex; - return 1; - } - } - if( ( index == indexlast ) && ( shiftlast > shiftbase ) ) - { -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - return 0; - } - - /* Main search */ - for( ; ; ) - { - index = ( index + 1 ) % bitmap->mapsize; - if( index == indexlast ) - break; -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - value = bitmap->map[index]; -#endif - if( value != ~(unsigned long)0x0 ) - { - for( shift = 0 ; ; shift++, value >>= 1 ) - { - if( value & 0x1 ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - *retentryindex = entryindex; - return 1; - } - } - } - - /* Trailing bits search */ - shiftlast = entryindexlast & ( CPUCONF_LONG_BITS - 1 ); -#ifdef MM_ATOMIC_SUPPORT - value = mmAtomicReadL( &bitmap->map[index] ); -#else - value = bitmap->map[index]; -#endif - if( value != ~(unsigned long)0x0 ) - { - for( shift = 0 ; shift < shiftlast ; shift++, value >>= 1 ) - { - if( value & 0x1 ) - continue; - entryindex = ( index << CPUCONF_LONG_BITSHIFT ) | shift; - if( entryindex >= bitmap->entrycount ) - break; -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - if( ( index == indexlast ) && ( shift >= shiftlast ) ) - return 0; - *retentryindex = entryindex; - return 1; - } - } -#ifndef MM_ATOMIC_SUPPORT - mtMutexUnlock( &bitmap->mutex ); -#endif - - return 0; -} diff --git a/src/other/gct/Auxiliary/mmbitmap.h b/src/other/gct/Auxiliary/mmbitmap.h deleted file mode 100644 index f1eac4c571b..00000000000 --- a/src/other/gct/Auxiliary/mmbitmap.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -typedef struct -{ - size_t entrycount; - size_t mapsize; -#ifdef MM_ATOMIC_SUPPORT - mmAtomicL *map; -#else - long *map; - mtMutex mutex; -#endif -} mmBitMap; - -void mmBitMapInit( mmBitMap *bitmap, size_t entrycount, int initvalue ); -void mmBitMapReset( mmBitMap *bitmap, int resetvalue ); -void mmBitMapFree( mmBitMap *bitmap ); - -int mmBitMapDirectGet( mmBitMap *bitmap, size_t entryindex ); -void mmBitMapDirectSet( mmBitMap *bitmap, size_t entryindex ); -void mmBitMapDirectClear( mmBitMap *bitmap, size_t entryindex ); - -int mmBitMapDirectMaskGet( mmBitMap *bitmap, size_t entryindex, long mask ); -void mmBitMapDirectMaskSet( mmBitMap *bitmap, size_t entryindex, long value, long mask ); - -int mmBitMapGet( mmBitMap *bitmap, size_t entryindex ); -void mmBitMapSet( mmBitMap *bitmap, size_t entryindex ); -void mmBitMapClear( mmBitMap *bitmap, size_t entryindex ); - -int mmBitMapMaskGet( mmBitMap *bitmap, size_t entryindex, long mask ); -void mmBitMapMaskSet( mmBitMap *bitmap, size_t entryindex, long value, long mask ); - -int mmBitMapFindSet( mmBitMap *bitmap, size_t entryindex, size_t entryindexlast, size_t *retentryindex ); -int mmBitMapFindClear( mmBitMap *bitmap, size_t entryindex, size_t entryindexlast, size_t *retentryindex ); - - - diff --git a/src/other/gct/Auxiliary/mmhash.c b/src/other/gct/Auxiliary/mmhash.c deleted file mode 100644 index e3330a6f75f..00000000000 --- a/src/other/gct/Auxiliary/mmhash.c +++ /dev/null @@ -1,1910 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -#include -#include -#include -#include -#include -#include - -#include "cpuconfig.h" -#include "cc.h" -#include "mm.h" -#include "mmhash.h" - - - - -typedef struct -{ -#ifdef MM_ATOMIC_SUPPORT - /* Powerful atomic read/write lock */ - mmAtomicLock32 lock; - mmAtomicP owner; -#else - /* Mutex, or how to ruin performance */ - mtMutex mutex; - void *owner; -#endif -} mmHashPage MM_CACHE_ALIGN; - -typedef struct -{ - uint32_t status; - uint32_t flags; - size_t entrysize; - - /* Page locks */ - uint32_t pageshift; - uint32_t pagecount; - uint32_t pagemask; - mmHashPage *page; - - /* Hash size */ - uint32_t minhashbits; - uint32_t hashbits; - uint32_t hashsize; - uint32_t hashmask; - - /* Entry count tracking if hash table is dynamic */ -#ifdef MM_ATOMIC_SUPPORT - mmAtomic32 entrycount; -#else - mtMutex countmutex; - uint32_t entrycount; -#endif - uint32_t lowcount; - uint32_t highcount; - - /* Global lock as the final word to resolve fighting between threads trying to access the same entry */ - char paddingA[64]; -#ifdef MM_ATOMIC_SUPPORT - mmAtomic32 globallock; -#else - mtMutex globalmutex; -#endif - char paddingB[64]; - -#ifdef MM_HASH_DEBUG_STATISTICS - long entrycountmax; - mmAtomicL statentrycount; - mmAtomicL accesscount; - mmAtomicL collisioncount; - mmAtomicL relocationcount; -#endif - -} mmHashTable; - -#define MM_HASH_ATOMIC_TRYCOUNT (16) - -#define MM_HASH_SIZEOF_ALIGN16(x) ((sizeof(x)+0xF)&~0xF) -#define MM_HASH_SIZEOF_ALIGN64(x) ((sizeof(x)+0x3F)&~0x3F) -#define MM_HASH_ALIGN64(x) ((x+0x3F)&~0x3F) -#define MM_HASH_ENTRYLIST(table) (void *)ADDRESS(table,MM_HASH_SIZEOF_ALIGN64(mmHashTable)) -#define MM_HASH_ENTRY(table,index) (void *)ADDRESS(table,MM_HASH_SIZEOF_ALIGN64(mmHashTable)+((index)*(table)->entrysize)) -#define MM_HASH_PAGELIST(table) (void *)ADDRESS(table,MM_HASH_ALIGN64(MM_HASH_SIZEOF_ALIGN64(mmHashTable)+((table)->hashsize*(table)->entrysize))) - - - -//// - - - -static void mmHashSetBounds( mmHashTable *table ) -{ - table->lowcount = 0; - if( table->hashbits > table->minhashbits ) - table->lowcount = table->hashsize / 5; - table->highcount = table->hashsize / 2; - return; -} - - -size_t mmHashRequiredSize( size_t entrysize, uint32_t hashbits, uint32_t pageshift ) -{ - uint32_t entrycount; - uint32_t pagecount; - entrycount = 1 << hashbits; - pagecount = entrycount >> pageshift; - if( !( pagecount ) ) - pagecount = 1; - return MM_HASH_ALIGN64( MM_HASH_SIZEOF_ALIGN16(mmHashTable) + ( entrycount * entrysize ) ) + ( pagecount * sizeof(mmHashPage) ); -} - - -void mmHashInit( void *hashtable, mmHashAccess *access, size_t entrysize, uint32_t hashbits, uint32_t pageshift, uint32_t flags ) -{ - uint32_t hashkey, pageindex; - void *entry; - mmHashTable *table; - mmHashPage *page; - - table = hashtable; - table->status = MM_HASH_STATUS_NORMAL; - if( flags & MM_HASH_FLAGS_NO_COUNT ) - table->status = MM_HASH_STATUS_UNKNOWN; - table->flags = flags; - table->entrysize = entrysize; - table->minhashbits = hashbits; - table->hashbits = hashbits; - table->hashsize = 1 << table->hashbits; - table->hashmask = table->hashsize - 1; - table->pageshift = pageshift; - table->pagecount = table->hashsize >> pageshift; - if( !( table->pagecount ) ) - table->pagecount = 1; - table->pagemask = table->pagecount - 1; - table->page = MM_HASH_PAGELIST( table ); -#ifdef MM_ATOMIC_SUPPORT - mmAtomicWrite32( &table->entrycount, 0 ); -#else - mtMutexInit( &table->countmutex ); - table->entrycount = 0; -#endif - mmHashSetBounds( table ); - - /* Clear the table */ - entry = MM_HASH_ENTRYLIST( table ); - for( hashkey = 0 ; hashkey < table->hashsize ; hashkey++ ) - { - access->clearentry( entry ); - entry = ADDRESS( entry, entrysize ); - } - - /* Clear the lock pages */ - page = table->page; -#ifdef MM_ATOMIC_SUPPORT - for( pageindex = table->pagecount ; pageindex ; pageindex--, page++ ) - { - mmAtomicLockInit32( &page->lock ); - mmAtomicWriteP( &page->owner, 0 ); - } - mmAtomicWrite32( &table->globallock, 0x0 ); -#else - for( pageindex = table->pagecount ; pageindex ; pageindex--, page++ ) - { - mtMutexInit( &page->mutex ); - page->owner = 0; - } - mtMutexInit( &table->globalmutex ); -#endif - -#ifdef MM_HASH_DEBUG_STATISTICS - table->entrycountmax = 0; - mmAtomicWriteL( &table->statentrycount, 0 ); - mmAtomicWriteL( &table->accesscount, 0 ); - mmAtomicWriteL( &table->collisioncount, 0 ); - mmAtomicWriteL( &table->relocationcount, 0 ); -#endif - - return; -} - - -int mmHashGetStatus( void *hashtable, int *rethashbits ) -{ - mmHashTable *table; - table = hashtable; - if( rethashbits ) - *rethashbits = table->hashbits; - return table->status; -} - - - -//// - - - -#ifdef MM_ATOMIC_SUPPORT - - #define MM_HASH_LOCK_TRY_READ(t,p) (mmAtomicLockTryRead32(&t->page[p].lock,MM_HASH_ATOMIC_TRYCOUNT)) - #define MM_HASH_LOCK_TRY_WRITE(t,p) (mmAtomicLockTryWrite32(&t->page[p].lock,MM_HASH_ATOMIC_TRYCOUNT)) - #define MM_HASH_LOCK_DONE_READ(t,p) (mmAtomicLockDoneRead32(&t->page[p].lock)) - #define MM_HASH_LOCK_DONE_WRITE(t,p) (mmAtomicLockDoneWrite32(&t->page[p].lock)) - #define MM_HASH_GLOBAL_LOCK(t) (mmAtomicSpin32(&t->globallock,0x0,0x1)) - #define MM_HASH_GLOBAL_UNLOCK(t) (mmAtomicWrite32(&t->globallock,0x0)) - #define MM_HASH_ENTRYCOUNT_ADD_READ(t,c) (mmAtomicAddRead32(&table->entrycount,c)) - -#else - - #define MM_HASH_LOCK_TRY_READ(t,p) (mtMutexTryLock(&t->page[p].mutex)) - #define MM_HASH_LOCK_TRY_WRITE(t,p) (mtMutexTryLock(&t->page[p].mutex)) - #define MM_HASH_LOCK_DONE_READ(t,p) (mtMutexUnlock(&t->page[p].mutex)) - #define MM_HASH_LOCK_DONE_WRITE(t,p) (mtMutexUnlock(&t->page[p].mutex)) - #define MM_HASH_GLOBAL_LOCK(t) (mtMutexLock(&t->globalmutex)) - #define MM_HASH_GLOBAL_UNLOCK(t) (mtMutexUnlock(&t->globalmutex)) - -static inline uint32_t MM_HASH_ENTRYCOUNT_ADD_READ( mmHashTable *t, int32_t c ) -{ - uint32_t entrycount; - mtMutexLock( &t->countmutex ); - t->entrycount += c; - entrycount = t->entrycount; - mtMutexUnlock( &t->countmutex ); - return entrycount; -} - -#endif - - - -//// - - - -void *mmHashDirectFindEntry( void *hashtable, mmHashAccess *access, void *findentry ) -{ - int cmpvalue; - uint32_t hashkey; - void *entry; - mmHashTable *table; - - table = hashtable; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( findentry ) & table->hashmask; - - /* Search the entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, findentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - return entry; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - return 0; -} - - -static int mmHashTryFindEntry( mmHashTable *table, mmHashAccess *access, void *findentry, void **retentry ) -{ - uint32_t hashkey; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( findentry ) & table->hashmask; - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_READ( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search the entry */ - entry = 0; - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_READ( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - break; - } - pagefinal = pageindex; - } - - /* Check for entry match */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, findentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - { - retvalue = MM_HASH_FAILURE; - entry = 0; - break; - } - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_READ( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - *retentry = entry; - return retvalue; -} - - -void *mmHashLockFindEntry( void *hashtable, mmHashAccess *access, void *findentry ) -{ - int retvalue; - void *entry; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryFindEntry( table, access, findentry, &entry ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryFindEntry( table, access, findentry, &entry ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return entry; -} - - - -//// - - - -void mmHashDirectListEntry( void *hashtable, mmHashAccess *access, void *listentry, void *opaque ) -{ - int cmpvalue; - uint32_t hashkey; - void *entry; - mmHashTable *table; - - table = hashtable; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( listentry ) & table->hashmask; - - /* Search the entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrylist( opaque, entry, listentry ); - if( cmpvalue == MM_HASH_ENTRYLIST_BREAK ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - return; -} - - -static int mmHashTryListEntry( mmHashTable *table, mmHashAccess *access, void *listentry, void *opaque ) -{ - uint32_t hashkey; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( listentry ) & table->hashmask; - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_READ( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search the entry */ - entry = 0; - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_READ( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - break; - } - pagefinal = pageindex; - } - - /* Check for entry match */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrylist( opaque, entry, listentry ); - if( cmpvalue == MM_HASH_ENTRYLIST_BREAK ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_READ( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - -void mmHashLockListEntry( void *hashtable, mmHashAccess *access, void *listentry, void *opaque ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryListEntry( table, access, listentry, opaque ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryListEntry( table, access, listentry, opaque ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return; -} - - - -//// - - - -int mmHashDirectReadEntry( void *hashtable, mmHashAccess *access, void *readentry ) -{ - int cmpvalue; - uint32_t hashkey; - void *entry; - mmHashTable *table; - - table = hashtable; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( readentry ) & table->hashmask; - - /* Search the entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, readentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - memcpy( readentry, entry, table->entrysize ); - return MM_HASH_SUCCESS; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - return MM_HASH_FAILURE; -} - - -static int mmHashTryReadEntry( mmHashTable *table, mmHashAccess *access, void *readentry ) -{ - uint32_t hashkey; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - - /* Hash key of entry */ - hashkey = access->entrykey( readentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_READ( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search the entry */ - entry = 0; - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_READ( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - break; - } - pagefinal = pageindex; - } - - /* Check for entry match */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, readentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - { - retvalue = MM_HASH_FAILURE; - entry = 0; - break; - } - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( entry ) - memcpy( readentry, entry, table->entrysize ); - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_READ( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - -int mmHashLockReadEntry( void *hashtable, mmHashAccess *access, void *readentry ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryReadEntry( table, access, readentry ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryReadEntry( table, access, readentry ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return retvalue; -} - - - -//// - - - -int mmHashDirectCallEntry( void *hashtable, mmHashAccess *access, void *callentry, void (*callback)( void *opaque, void *entry, int newflag ), void *opaque, int addflag ) -{ - int cmpvalue; - uint32_t hashkey, entrycount; - void *entry; - mmHashTable *table; - - table = hashtable; - - /* Hash key of entry */ - hashkey = access->entrykey( callentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Search an available entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, callentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - callback( opaque, entry, 0 ); - return MM_HASH_SUCCESS; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( !( addflag ) ) - return MM_HASH_FAILURE; - - /* Store new entry */ - memcpy( entry, callentry, table->entrysize ); - callback( opaque, entry, 1 ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - return MM_HASH_SUCCESS; -} - - -static int mmHashTryCallEntry( mmHashTable *table, mmHashAccess *access, void *callentry, void (*callback)( void *opaque, void *entry, int newflag ), void *opaque, int addflag ) -{ - uint32_t hashkey, entrycount; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - - /* Hash key of entry */ - hashkey = access->entrykey( callentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search an available entry */ - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - goto end; - } - pagefinal = pageindex; - } - - /* Check for entry available */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, callentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - callback( opaque, entry, 0 ); - retvalue = MM_HASH_SUCCESS; - goto end; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( !( addflag ) ) - { - retvalue = MM_HASH_FAILURE; - goto end; - } - - /* Store new entry */ - memcpy( entry, callentry, table->entrysize ); - callback( opaque, entry, 1 ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - end: - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - -int mmHashLockCallEntry( void *hashtable, mmHashAccess *access, void *callentry, void (*callback)( void *opaque, void *entry, int newflag ), void *opaque, int addflag ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryCallEntry( table, access, callentry, callback, opaque, addflag ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryCallEntry( table, access, callentry, callback, opaque, addflag ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return retvalue; -} - - - -//// - - - -int mmHashDirectReplaceEntry( void *hashtable, mmHashAccess *access, void *replaceentry, int addflag ) -{ - int cmpvalue; - uint32_t hashkey, entrycount; - void *entry; - mmHashTable *table; - - table = hashtable; - - /* Hash key of entry */ - hashkey = access->entrykey( replaceentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Search an available entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, replaceentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - memcpy( entry, replaceentry, table->entrysize ); - return MM_HASH_SUCCESS; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( !( addflag ) ) - return MM_HASH_FAILURE; - - /* Store new entry */ - memcpy( entry, replaceentry, table->entrysize ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - return MM_HASH_SUCCESS; -} - - -static int mmHashTryReplaceEntry( mmHashTable *table, mmHashAccess *access, void *replaceentry, int addflag ) -{ - uint32_t hashkey, entrycount; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - - /* Hash key of entry */ - hashkey = access->entrykey( replaceentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - - /* Search an available entry */ - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - goto end; - } - pagefinal = pageindex; - } - - /* Check for entry available */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, replaceentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - memcpy( entry, replaceentry, table->entrysize ); - retvalue = MM_HASH_SUCCESS; - goto end; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( !( addflag ) ) - { - retvalue = MM_HASH_FAILURE; - goto end; - } - - /* Store new entry */ - memcpy( entry, replaceentry, table->entrysize ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - end: - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - -int mmHashLockReplaceEntry( void *hashtable, mmHashAccess *access, void *replaceentry, int addflag ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryReplaceEntry( table, access, replaceentry, addflag ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryReplaceEntry( table, access, replaceentry, addflag ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return retvalue; -} - - - -//// - - - -int mmHashDirectAddEntry( void *hashtable, mmHashAccess *access, void *addentry, int nodupflag ) -{ - int cmpvalue; - uint32_t hashkey, entrycount; - void *entry; - mmHashTable *table; - - table = hashtable; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( addentry ) & table->hashmask; - - /* Search an available entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - /* Do we allow duplicate entries? */ - if( nodupflag ) - { - cmpvalue = access->entrycmp( entry, addentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - return MM_HASH_FAILURE; - } - else - { - if( !( access->entryvalid( entry ) ) ) - break; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - /* Store new entry */ - memcpy( entry, addentry, table->entrysize ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - return MM_HASH_SUCCESS; -} - - -static int mmHashTryAddEntry( mmHashTable *table, mmHashAccess *access, void *addentry, int nodupflag ) -{ - uint32_t hashkey, entrycount; - uint32_t pageindex, pagestart, pagefinal; - int cmpvalue, retvalue; - void *entry; - - /* Hash key of entry */ - hashkey = access->entrykey( addentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search an available entry */ - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - goto end; - } - pagefinal = pageindex; - } - - /* Check for entry available */ - entry = MM_HASH_ENTRY( table, hashkey ); - /* Do we allow duplicate entries? */ - if( nodupflag ) - { - cmpvalue = access->entrycmp( entry, addentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - break; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - { - retvalue = MM_HASH_FAILURE; - goto end; - } - } - else - { - if( !( access->entryvalid( entry ) ) ) - break; - } -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - /* Store new entry */ - memcpy( entry, addentry, table->entrysize ); - - /* Increment count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, 1 ); - if( entrycount >= table->highcount ) - table->status = MM_HASH_STATUS_MUSTGROW; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - int statentrycount = mmAtomicAddReadL( &table->statentrycount, 1 ); - if( statentrycount > table->entrycountmax ) - table->entrycountmax = statentrycount; -#endif - - end: - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - - -int mmHashLockAddEntry( void *hashtable, mmHashAccess *access, void *addentry, int nodupflag ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryAddEntry( table, access, addentry, nodupflag ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryAddEntry( table, access, addentry, nodupflag ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return retvalue; -} - - - -//// - - -#define MM_ROBUST_DELETION - - -int mmHashDirectDeleteEntry( void *hashtable, mmHashAccess *access, void *deleteentry, int readflag ) -{ - int cmpvalue; - uint32_t hashkey, srckey, srcpos, targetpos = 0, targetkey, entrycount; -#ifdef MM_ROBUST_DELETION - uint32_t delbase; -#else - int32_t halftablesize, distance; -#endif - void *entry, *srcentry, *targetentry; - mmHashTable *table; - - table = hashtable; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Hash key of entry */ - hashkey = access->entrykey( deleteentry ) & table->hashmask; - - /* Search the entry */ - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, deleteentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - return MM_HASH_FAILURE; - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( readflag ) - memcpy( deleteentry, entry, table->entrysize ); - -#ifdef MM_ROBUST_DELETION - for( delbase = hashkey ; ; ) - { - delbase = ( delbase - 1 ) & table->hashmask; - if( !( access->entryvalid( MM_HASH_ENTRY( table, delbase ) ) ) ) - break; - } - delbase = ( delbase + 1 ) & table->hashmask; -#else - halftablesize = table->hashsize >> 1; -#endif - - /* Entry found, delete it */ - for( ; ; ) - { - /* Find replacement target */ - targetkey = hashkey; - targetentry = 0; - for( srcpos = hashkey ; ; ) - { - srcpos = ( srcpos + 1 ) & table->hashmask; - - /* Try next entry */ - srcentry = MM_HASH_ENTRY( table, srcpos ); - if( !( access->entryvalid( srcentry ) ) ) - break; - srckey = access->entrykey( srcentry ) & table->hashmask; - -#ifdef MM_ROBUST_DELETION - if( targetkey >= delbase ) - { - if( ( srckey < delbase ) || ( srckey > targetkey ) ) - continue; - } - else if( ( srckey > targetkey ) && ( srckey < delbase ) ) - continue; - targetentry = srcentry; - targetkey = srckey; - targetpos = srcpos; -#else - /* Check if moving the entry backwards is allowed without breaking chain */ - distance = (int32_t)targetkey - (int32_t)srckey; - if( distance > halftablesize ) - distance -= table->hashsize; - else if( distance < -halftablesize ) - distance += table->hashsize; - if( distance >= 0 ) - { - targetentry = srcentry; - targetkey = srckey; - targetpos = srcpos; - } -#endif - } - - /* No replacement found, just clear it */ - entry = MM_HASH_ENTRY( table, hashkey ); - if( !( targetentry ) ) - { - access->clearentry( entry ); - break; - } - - /* Move entry in place and continue the repair process */ - memcpy( entry, targetentry, table->entrysize ); - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->relocationcount, 1 ); -#endif - - hashkey = targetpos; - } - - /* Decrement count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, -1 ); - if( entrycount < table->lowcount ) - table->status = MM_HASH_STATUS_MUSTSHRINK; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->statentrycount, -1 ); -#endif - - return MM_HASH_SUCCESS; -} - - -static int mmHashTryDeleteEntry( mmHashTable *table, mmHashAccess *access, void *deleteentry, int readflag ) -{ - uint32_t hashkey, srckey, srcpos, srcend, targetpos = 0, targetkey, entrycount; - uint32_t pageindex, pagestart, pagefinal; -#ifdef MM_ROBUST_DELETION - uint32_t delbase; -#else - int32_t halftablesize, distance; -#endif - int cmpvalue, retvalue; - void *entry, *srcentry, *targetentry; - - /* Hash key of entry */ - hashkey = access->entrykey( deleteentry ) & table->hashmask; - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->accesscount, 1 ); -#endif - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - - /* Search the entry */ - retvalue = MM_HASH_SUCCESS; - for( ; ; hashkey = ( hashkey + 1 ) & table->hashmask ) - { - /* Lock new pages */ - pageindex = hashkey >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - goto end; - } - pagefinal = pageindex; - } - - /* Check for entry match */ - entry = MM_HASH_ENTRY( table, hashkey ); - cmpvalue = access->entrycmp( entry, deleteentry ); - if( cmpvalue == MM_HASH_ENTRYCMP_INVALID ) - { - retvalue = MM_HASH_FAILURE; - goto end; - } - else if( cmpvalue == MM_HASH_ENTRYCMP_FOUND ) - break; -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->collisioncount, 1 ); -#endif - } - - if( readflag ) - memcpy( deleteentry, entry, table->entrysize ); - -#ifdef MM_ROBUST_DELETION - for( delbase = hashkey ; ; ) - { - delbase = ( delbase - 1 ) & table->hashmask; - if( !( access->entryvalid( MM_HASH_ENTRY( table, delbase ) ) ) ) - break; - } - delbase = ( delbase + 1 ) & table->hashmask; -#else - halftablesize = table->hashsize >> 1; -#endif - - /* Preemtively lock all pages in the stream before starting the operation */ - for( srcend = hashkey ; ; ) - { - srcend = ( srcend + 1 ) & table->hashmask; - - /* Lock new pages */ - pageindex = srcend >> table->pageshift; - if( pageindex != pagefinal ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) ) - { - retvalue = MM_HASH_TRYAGAIN; - goto end; - } - pagefinal = pageindex; - } - - /* Check for valid entry */ - srcentry = MM_HASH_ENTRY( table, srcend ); - if( !( access->entryvalid( srcentry ) ) ) - break; - } - - /* Entry found, delete it and reorder the hash stream of entries */ - for( ; ; ) - { - /* Find replacement target */ - targetkey = hashkey; - targetentry = 0; - for( srcpos = hashkey ; ; ) - { - srcpos = ( srcpos + 1 ) & table->hashmask; - srcentry = MM_HASH_ENTRY( table, srcpos ); - - /* Don't loop beyond the end of hash stream */ - if( srcpos == srcend ) - break; - - /* Try next entry */ - srckey = access->entrykey( srcentry ) & table->hashmask; - -#ifdef MM_ROBUST_DELETION - if( targetkey >= delbase ) - { - if( ( srckey < delbase ) || ( srckey > targetkey ) ) - continue; - } - else if( ( srckey > targetkey ) && ( srckey < delbase ) ) - continue; - targetentry = srcentry; - targetkey = srckey; - targetpos = srcpos; -#else - /* Check if moving the entry backwards is allowed without breaking chain */ - distance = (int32_t)targetkey - (int32_t)srckey; - if( distance > halftablesize ) - distance -= table->hashsize; - else if( distance < -halftablesize ) - distance += table->hashsize; - if( distance >= 0 ) - { - targetentry = srcentry; - targetkey = srckey; - targetpos = srcpos; - } -#endif - } - - /* No replacement found, just clear it */ - entry = MM_HASH_ENTRY( table, hashkey ); - if( !( targetentry ) ) - { - access->clearentry( entry ); - break; - } - - /* Move entry in place and continue the repair process */ - memcpy( entry, targetentry, table->entrysize ); - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->relocationcount, 1 ); -#endif - - hashkey = targetpos; - } - - /* Decrement count of entries in table */ - if( !( table->flags & MM_HASH_FLAGS_NO_COUNT ) ) - { - entrycount = MM_HASH_ENTRYCOUNT_ADD_READ( table, -1 ); - if( entrycount < table->lowcount ) - table->status = MM_HASH_STATUS_MUSTSHRINK; - } - -#ifdef MM_HASH_DEBUG_STATISTICS - mmAtomicAddL( &table->statentrycount, -1 ); -#endif - - end: - - /* Unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - - return retvalue; -} - - -int mmHashLockDeleteEntry( void *hashtable, mmHashAccess *access, void *deleteentry, int readflag ) -{ - int retvalue; - mmHashTable *table; - - table = hashtable; - retvalue = mmHashTryDeleteEntry( table, access, deleteentry, readflag ); - if( retvalue == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - retvalue = mmHashTryDeleteEntry( table, access, deleteentry, readflag ); - } while( retvalue == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return retvalue; -} - - - -//// - - - -/* Must be called while NO other thread will ever access the table for writing */ -void mmHashResize( void *newtable, void *oldtable, mmHashAccess *access, uint32_t hashbits, uint32_t pageshift ) -{ - uint32_t hashkey, hashpos, dstkey, dstpos, pageindex; - void *srcentry, *dstentry; - mmHashTable *dst, *src; - mmHashPage *page; - - dst = newtable; - src = oldtable; - dst->status = MM_HASH_STATUS_NORMAL; - dst->flags = src->flags; - dst->entrysize = src->entrysize; - dst->minhashbits = src->minhashbits; - dst->hashbits = hashbits; - dst->hashsize = 1 << dst->hashbits; - dst->hashmask = dst->hashsize - 1; - dst->pageshift = pageshift; - dst->pagecount = dst->hashsize >> pageshift; - dst->pagemask = dst->pagecount - 1; - dst->page = MM_HASH_PAGELIST( dst ); -#ifdef MM_ATOMIC_SUPPORT - mmAtomicWrite32( &dst->entrycount, mmAtomicRead32( &src->entrycount ) ); -#else - dst->entrycount = src->entrycount; -#endif - mmHashSetBounds( dst ); - - /* Clear the whole destination table */ - dstentry = MM_HASH_ENTRYLIST( dst ); - for( hashpos = 0 ; hashpos < dst->hashsize ; hashpos++ ) - { - access->clearentry( dstentry ); - dstentry = ADDRESS( dstentry, dst->entrysize ); - } - - /* Clear the lock pages */ -#ifdef MM_ATOMIC_SUPPORT - page = dst->page; - for( pageindex = 0 ; pageindex < dst->pagecount ; pageindex++, page++ ) - { - mmAtomicLockInit32( &page->lock ); - mmAtomicWriteP( &page->owner, (void *)0 ); - } - mmAtomicWrite32( &dst->globallock, 0x0 ); -#else - page = src->page; - for( pageindex = src->pagecount ; pageindex ; pageindex--, page++ ) - mtMutexDestroy( &page->mutex ); - mtMutexDestroy( &src->globalmutex ); - page = dst->page; - for( pageindex = dst->pagecount ; pageindex ; pageindex--, page++ ) - { - mtMutexInit( &page->mutex ); - page->owner = 0; - } - mtMutexInit( &dst->globalmutex ); -#endif - - /* Move all entries from the src table to the dst table */ - srcentry = MM_HASH_ENTRYLIST( src ); - for( hashpos = 0 ; hashpos < src->hashsize ; hashpos++ ) - { - hashkey = access->entrykey( srcentry ); - dstkey = hashkey & dst->hashmask; - - /* Search an empty spot in the destination table */ - for( dstpos = dstkey ; ; dstpos = ( dstpos + 1 ) & dst->hashmask ) - { - dstentry = MM_HASH_ENTRY( dst, dstpos ); - if( !( access->entryvalid( dstentry ) ) ) - break; - } - - /* Copy entry from src table to dst table */ - memcpy( dstentry, srcentry, src->entrysize ); - srcentry = ADDRESS( srcentry, src->entrysize ); - } - - return; -} - - - -//// - - -static int mmHashLockRangeTry( mmHashTable *table, mmHashAccess *access, mmHashLock *hashlock, mmHashLockRange *lockrange, uint32_t hashkey ) -{ - int newcount; - uint32_t srckey; - uint32_t pageindex, pagestart, pagefinal; - void *srcentry; - - /* Lock first page */ - pagestart = hashkey >> table->pageshift; - pagefinal = pagestart; -#ifdef MM_ATOMIC_SUPPORT - if( mmAtomicReadP( &table->page[pagestart].owner ) != (void *)hashlock ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - } - mmAtomicWriteP( &table->page[pagestart].owner, (void *)hashlock ); -#else - if( table->page[pagestart].owner != (void *)hashlock ) - { - if( !( MM_HASH_LOCK_TRY_WRITE( table, pagestart ) ) ) - return MM_HASH_TRYAGAIN; - } - table->page[pagestart].owner = hashlock; -#endif - - /* Lock all pages in stream */ - newcount = hashlock->newcount; - for( srckey = hashkey ; ; ) - { - srckey = ( srckey + 1 ) & table->hashmask; - - /* Lock new pages */ - pageindex = srckey >> table->pageshift; - if( pageindex != pagefinal ) - { -#ifdef MM_ATOMIC_SUPPORT - if( mmAtomicReadP( &table->page[pageindex].owner ) != (void *)hashlock ) - { - if( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) - { - mmAtomicWriteP( &table->page[pageindex].owner, (void *)hashlock ); - continue; - } - /* Failed, unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - mmAtomicWriteP( &table->page[pageindex].owner, (void *)0 ); - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - return MM_HASH_TRYAGAIN; - } -#else - if( table->page[pageindex].owner != (void *)hashlock ) - { - if( MM_HASH_LOCK_TRY_WRITE( table, pageindex ) ) - { - table->page[pageindex].owner = (void *)hashlock; - continue; - } - /* Failed, unlock all pages */ - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { - table->page[pageindex].owner = 0; - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - if( pageindex == pagefinal ) - break; - } - return MM_HASH_TRYAGAIN; - } -#endif - pagefinal = pageindex; - } - - /* Check for valid entry */ - srcentry = MM_HASH_ENTRY( table, srckey ); - if( !( access->entryvalid( srcentry ) ) ) - { - if( --newcount <= 0 ) - break; - } - } - - /* Store lock pagestart and pagefinal */ - lockrange->pagestart = pagestart; - lockrange->pagefinal = pagefinal; - - return MM_HASH_SUCCESS; -} - - -static void mmHashLockReleaseAll( mmHashTable *table, mmHashLock *hashlock ) -{ - uint32_t pageindex, pagestart, pagefinal; - mmHashLockRange *lockrange; - - for( lockrange = hashlock->rangelist ; lockrange ; lockrange = lockrange->next ) - { - if( lockrange->pagestart == ~(uint32_t)0x0 ) - continue; - pagestart = lockrange->pagestart; - pagefinal = lockrange->pagefinal; - for( pageindex = pagestart ; ; pageindex = ( pageindex + 1 ) & table->pagemask ) - { -#ifdef MM_ATOMIC_SUPPORT - if( mmAtomicReadP( &table->page[pageindex].owner ) == (void *)hashlock ) - { - mmAtomicWriteP( &table->page[pageindex].owner, (void *)0 ); - mmAtomicLockDoneWrite32( &table->page[pageindex].lock ); - } -#else - if( table->page[pageindex].owner == (void *)hashlock ) - { - table->page[pageindex].owner = (void *)0; - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - } -#endif - if( pageindex == pagefinal ) - break; - } - } - - for( lockrange = hashlock->rangelist ; lockrange ; lockrange = lockrange->next ) - { - lockrange->pagestart = ~0x0; - lockrange->pagefinal = ~0x0; - } - - return; -} - - -static int mmHashLockApplyAll( mmHashTable *table, mmHashAccess *access, mmHashLock *hashlock ) -{ - mmHashLockRange *lockrange, *lockrangenext; - // 2012-10-22 ch3: rangelist set but never used, so commented - //mmHashLockRange *rangelist; - - //rangelist = hashlock->rangelist; - for( lockrange = hashlock->rangelist ; lockrange ; lockrange = lockrangenext ) - { - lockrangenext = lockrange->next; - if( mmHashLockRangeTry( table, access, hashlock, lockrange, lockrange->hashkey ) == MM_HASH_TRYAGAIN ) - { - /* Failure, release all locks */ - mmHashLockReleaseAll( table, hashlock ); - return MM_HASH_TRYAGAIN; - } - } - - return MM_HASH_SUCCESS; -} - - - -//// - - - -void mmHashLockInit( mmHashLock *hashlock, int newcount ) -{ - memset( hashlock, 0, sizeof(mmHashLock) ); - hashlock->newcount = newcount; - return; -} - -void mmHashLockAdd( void *hashtable, mmHashAccess *access, void *entry, mmHashLock *hashlock, mmHashLockRange *lockrange ) -{ - uint32_t hashkey; - mmHashTable *table; - - /* Hash key of entry */ - table = hashtable; - hashkey = access->entrykey( entry ) & table->hashmask; - - lockrange->hashkey = hashkey; - lockrange->pagestart = ~0x0; - lockrange->pagefinal = ~0x0; - lockrange->next = hashlock->rangelist; - hashlock->rangelist = lockrange; - - return; -} - -void mmHashLockAcquire( void *hashtable, mmHashAccess *access, mmHashLock *hashlock ) -{ - int status; - mmHashTable *table; - - table = hashtable; - status = mmHashLockApplyAll( table, access, hashlock ); - if( status == MM_HASH_TRYAGAIN ) - { - MM_HASH_GLOBAL_LOCK( table ); - do - { - status = mmHashLockApplyAll( table, access, hashlock ); - } while( status == MM_HASH_TRYAGAIN ); - MM_HASH_GLOBAL_UNLOCK( table ); - } - - return; -} - -void mmHashLockRelease( void *hashtable, mmHashLock *hashlock ) -{ - mmHashTable *table; - - table = hashtable; - mmHashLockReleaseAll( table, hashlock ); - - return; -} - - -//// - - -void mmHashGlobalLockEnable( void *hashtable ) -{ - uint32_t pageindex; - mmHashTable *table; - - table = hashtable; - MM_HASH_GLOBAL_LOCK( table ); - for( pageindex = 0 ; pageindex < table->pagecount ; pageindex++ ) - MM_HASH_LOCK_TRY_WRITE( table, pageindex ); - - return; -} - - -void mmHashGlobalLockDisable( void *hashtable ) -{ - uint32_t pageindex; - mmHashTable *table; - - table = hashtable; - for( pageindex = 0 ; pageindex < table->pagecount ; pageindex++ ) - MM_HASH_LOCK_DONE_WRITE( table, pageindex ); - MM_HASH_GLOBAL_UNLOCK( table ); - - return; -} - - -//// - - - -void mmHashDirectDebugDuplicate( void *hashtable, mmHashAccess *access, void (*callback)( void *opaque, void *entry0, void *entry1 ), void *opaque ) -{ - uint32_t hashbase, hashkey; - void *baseentry, *entry; - mmHashTable *table; - - table = hashtable; - - for( hashbase = 0 ; hashbase < table->hashsize ; hashbase++ ) - { - baseentry = MM_HASH_ENTRY( table, hashbase ); - for( hashkey = hashbase ; ; ) - { - hashkey = ( hashkey + 1 ) & table->hashmask; - entry = MM_HASH_ENTRY( table, hashkey ); - if( !( access->entryvalid( entry ) ) ) - break; - if( access->entrycmp( entry, baseentry ) ) - callback( opaque, entry, baseentry ); - } - } - - return; -} - - -void mmHashDirectDebugPages( void *hashtable ) -{ - uint32_t pageindex; - mmHashTable *table; - mmHashPage *page; - - table = hashtable; - -#ifdef MM_ATOMIC_SUPPORT - page = table->page; - for( pageindex = 0 ; pageindex < table->pagecount ; pageindex++, page++ ) - { - if( ( page->lock.v.value ) || mmAtomicReadP( &page->owner ) ) - printf( "Page[%d] = 0x%x ; %p\n", pageindex, page->lock.v.value, mmAtomicReadP( &page->owner ) ); - } - fflush( stdout ); -#endif - - return; -} - - - -void mmHashStatistics( void *hashtable, long *accesscount, long *collisioncount, long *relocationcount, long *entrycount, long *entrycountmax, long *hashsizemax ) -{ - mmHashTable *table; - - table = hashtable; -#ifdef MM_HASH_DEBUG_STATISTICS - *accesscount = mmAtomicReadL( &table->accesscount ); - *collisioncount = mmAtomicReadL( &table->collisioncount ); - *relocationcount = mmAtomicReadL( &table->relocationcount ); - *entrycount = mmAtomicReadL( &table->statentrycount ); - *entrycountmax = table->entrycountmax; - *hashsizemax = 1 << table->hashbits; -#else - *accesscount = 0; - *collisioncount = 0; - *relocationcount = 0; - *entrycount = 0; - *entrycountmax = 0; - *hashsizemax = 1 << table->hashbits; -#endif - - return; -} diff --git a/src/other/gct/Auxiliary/mmhash.h b/src/other/gct/Auxiliary/mmhash.h deleted file mode 100644 index b7fd9368acb..00000000000 --- a/src/other/gct/Auxiliary/mmhash.h +++ /dev/null @@ -1,154 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - - -/* -#define MM_HASH_DEBUG_STATISTICS -*/ - - -enum -{ - MM_HASH_ENTRYCMP_INVALID, - MM_HASH_ENTRYCMP_FOUND, - MM_HASH_ENTRYCMP_SKIP -}; - -enum -{ - MM_HASH_ENTRYLIST_BREAK, - MM_HASH_ENTRYLIST_CONTINUE -}; - -typedef struct -{ - /* Clear the entry so that entryvalid() returns zero */ - void (*clearentry)( void *entry ); - /* Returns non-zero if the entry is valid and existing */ - int (*entryvalid)( void *entry ); - /* Return key for an arbitrary set of user-defined data */ - uint32_t (*entrykey)( void *entry ); - /* Return MM_HASH_ENTRYCMP* to stop or continue the search */ - int (*entrycmp)( void *entry, void *entryref ); - /* Return MM_HASH_ENTRYLIST* to stop or continue the search */ - int (*entrylist)( void *opaque, void *entry, void *entryref ); -} mmHashAccess; - - -/* Do not keep track of entry count, table will not be able to say when it needs to shrink or grow */ -#define MM_HASH_FLAGS_NO_COUNT (0x1) - - -size_t mmHashRequiredSize( size_t entrysize, uint32_t hashbits, uint32_t pageshift ); -void mmHashInit( void *hashtable, mmHashAccess *access, size_t entrysize, uint32_t hashbits, uint32_t pageshift, uint32_t flags ); -int mmHashGetStatus( void *hashtable, int *rethashbits ); - -enum -{ - MM_HASH_STATUS_MUSTGROW, - MM_HASH_STATUS_MUSTSHRINK, - MM_HASH_STATUS_NORMAL, - MM_HASH_STATUS_UNKNOWN -}; - - -void *mmHashDirectFindEntry( void *hashtable, mmHashAccess *access, void *findentry ); -void *mmHashLockFindEntry( void *hashtable, mmHashAccess *access, void *findentry ); - -void mmHashDirectListEntry( void *hashtable, mmHashAccess *access, void *listentry, void *opaque ); -void mmHashLockListEntry( void *hashtable, mmHashAccess *access, void *listentry, void *opaque ); - -int mmHashDirectReadEntry( void *hashtable, mmHashAccess *access, void *readentry ); -int mmHashLockReadEntry( void *hashtable, mmHashAccess *access, void *readentry ); - -int mmHashDirectCallEntry( void *hashtable, mmHashAccess *access, void *callentry, void (*callback)( void *opaque, void *entry, int newflag ), void *opaque, int addflag ); -int mmHashLockCallEntry( void *hashtable, mmHashAccess *access, void *callentry, void (*callback)( void *opaque, void *entry, int newflag ), void *opaque, int addflag ); - -/* The hash key for replaced entries must remain the same! */ -int mmHashDirectReplaceEntry( void *hashtable, mmHashAccess *access, void *replaceentry, int addflag ); -int mmHashLockReplaceEntry( void *hashtable, mmHashAccess *access, void *replaceentry, int addflag ); - -int mmHashDirectAddEntry( void *hashtable, mmHashAccess *access, void *adddentry, int nodupflag ); -int mmHashLockAddEntry( void *hashtable, mmHashAccess *access, void *adddentry, int nodupflag ); - -int mmHashDirectDeleteEntry( void *hashtable, mmHashAccess *access, void *deleteentry, int readflag ); -int mmHashLockDeleteEntry( void *hashtable, mmHashAccess *access, void *deleteentry, int readflag ); - -void mmHashResize( void *newtable, void *oldtable, mmHashAccess *access, uint32_t hashbits, uint32_t pageshift ); - - -enum -{ - MM_HASH_FAILURE, - MM_HASH_SUCCESS, - MM_HASH_TRYAGAIN /* Internal, can not be returned by any public call */ -}; - - - -//// - - - -typedef struct -{ - uint32_t hashkey; - uint32_t pagestart; - uint32_t pagefinal; - void *next; -} mmHashLockRange; - -typedef struct -{ - void *hashtable; - void *rangelist; - int newcount; -} mmHashLock; - - -void mmHashLockInit( mmHashLock *hashlock, int newcount ); -void mmHashLockAdd( void *hashtable, mmHashAccess *access, void *entry, mmHashLock *hashlock, mmHashLockRange *lockrange ); -void mmHashLockAcquire( void *hashtable, mmHashAccess *access, mmHashLock *hashlock ); -void mmHashLockRelease( void *hashtable, mmHashLock *hashlock ); - -void mmHashGlobalLockEnable( void *hashtable ); -void mmHashGlobalLockDisable( void *hashtable ); - - - -//// - - - -void mmHashDirectDebugDuplicate( void *hashtable, mmHashAccess *access, void (*callback)( void *opaque, void *entry0, void *entry1 ), void *opaque ); - -void mmHashDirectDebugPages( void *hashtable ); - -void mmHashStatistics( void *hashtable, long *accesscount, long *collisioncount, long *relocationcount, long *entrycount, long *entrycountmax, long *hashsizemax ); - - - diff --git a/src/other/gct/Auxiliary/mmthread.h b/src/other/gct/Auxiliary/mmthread.h deleted file mode 100644 index 1bad98a8413..00000000000 --- a/src/other/gct/Auxiliary/mmthread.h +++ /dev/null @@ -1,540 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ -/** - * @file - * - * Threading interface, POSIX implementation. - */ - - -#ifndef STAND_ALONE_MD - -#if defined(COMPILE_FOR_VSL) - #define MT_QT -#endif - -#endif - - -#if defined(MT_QT) - - #include "mmthreadqt.h" - -#elif defined(MT_DISABLED) - -struct mtNull -{ -}; - -typedef struct mtNull mtMutex; -typedef struct mtNull mtSpin; -typedef struct mtNull mtSignal; - - #define mtMutexInit(a) - #define mtMutexDestroy(a) - #define mtMutexLock(a) - #define mtMutexUnlock(a) - #define mtMutexTryLock(a) - - #define mtSpinInit(a) - #define mtSpinDestroy(a) - #define mtSpinLock(a) - #define mtSpinUnlock(a) - #define mtSpinTryLock(a) - - #define mtSignalInit(a) - #define mtSignalDestroy(a) - #define mtSignalDispatch(a) - #define mtSignalBroadcast(a) - #define mtSignalMutexWait(a,b) - -#else - - #include - #include - #include - #include - - #if _POSIX_SPIN_LOCKS > 0 - #define MT_SPIN_LOCK_SUPPORT - #endif -/* - #define MT_BARRIER_SUPPORT - #define MT_RWLOCK_SUPPORT -*/ - - -static inline void mtYield() -{ - sched_yield(); - return; -} - - -typedef struct mtThread mtThread; - -struct mtThread -{ - pthread_t pthread; -}; - - -#define MT_THREAD_FLAGS_JOINABLE (0x1) -#define MT_THREAD_FLAGS_SETSTACK (0x2) - - -static inline void mtThreadCreate( mtThread *thread, void *(*threadmain)( void *value ), void *value, int flags, void *stack, size_t stacksize ) -{ - pthread_attr_t attr; - - pthread_attr_init( &attr ); -#if !MM_WIN32 && !MM_WIN64 - if( flags & MT_THREAD_FLAGS_SETSTACK ) - pthread_attr_setstack( &attr, stack, stacksize ); -#endif - if( flags & MT_THREAD_FLAGS_JOINABLE ) - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - else - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ); - pthread_create( &thread->pthread, &attr, threadmain, value ); - pthread_attr_destroy( &attr ); - - return; -} - -static inline void mtThreadExit() -{ - pthread_exit( 0 ); - return; -} - -static inline void mtThreadJoin( mtThread *thread ) -{ - void *ret; - pthread_join( thread->pthread, &ret ); - return; -} - - -static inline size_t mtGetMinimumStackSize() -{ - #ifdef PTHREAD_STACK_MIN - return PTHREAD_STACK_MIN; - #else - return ( mmcontext.pagesize ? 4*mmcontext.pagesize : 16384 ); - #endif -} - - - - #ifdef MT_DEBUG - #ifndef DEBUG_WARNING() - #define DEBUG_WARNING() ({printf( "\nRF WARNING : %s %s %d\n", __FILE__, __FUNCTION__, __LINE__ ); fflush( stdout );}) - #endif - #endif - - - -typedef struct mtMutex mtMutex; - -struct mtMutex -{ -#ifdef MT_DEBUG - unsigned char *function; - unsigned char *file; - int line; -#endif - pthread_mutex_t pmutex; -}; - -static inline void mtMutexInit( mtMutex *mutex ) -{ - pthread_mutex_init( &mutex->pmutex, 0 ); - return; -} - -static inline void mtMutexDestroy( mtMutex *mutex ) -{ - pthread_mutex_destroy( &mutex->pmutex ); - return; -} - - #ifdef MT_DEBUG - - #define mtMutexLock(a) mtMutexLockDebug(a,__FUNCTION__,__FILE__,__LINE__) - #define mtMutexUnlock(a) mtMutexUnlockDebug(a,__FUNCTION__,__FILE__,__LINE__) - #define mtMutexTryLock(a) mtMutexTryLockDebug(a,__FUNCTION__,__FILE__,__LINE__) - -static inline void mtMutexLockDebug( mtMutex *mutex, const unsigned char *function, const unsigned char *file, const int line ) -{ - printf( "Mutex lock : Thread %d on %p from %s() in %s:%d\n", (int)pthread_self(), mutex, function, file, line ); - fflush( stdout ); - if( pthread_mutex_trylock( &mutex->pmutex ) ) - { - printf( " Mutex %p locked by %s() in %s:%d\n", mutex, mutex->function, mutex->file, mutex->line ); - fflush( stdout ); - if( pthread_mutex_lock( &mutex->pmutex ) ) - DEBUG_WARNING(); - } - mutex->function = (unsigned char *)function; - mutex->file = (unsigned char *)file; - mutex->line = line; - return; -} - -static inline void mtMutexUnlockDebug( mtMutex *mutex, const unsigned char *function, const unsigned char *file, const int line ) -{ - mutex->function = (unsigned char *)function; - mutex->file = (unsigned char *)file; - mutex->line = line; - printf( "Mutex Unlock : Thread %d on %p from %s() in %s:%d\n", (int)pthread_self(), mutex, function, file, line ); - fflush( stdout ); - if( pthread_mutex_unlock( &mutex->pmutex ) ) - DEBUG_WARNING(); - return; -} - -static inline int mtMutexTryLockDebug( mtMutex *mutex, const unsigned char *function, const unsigned char *file, const int line ) -{ - printf( "Mutex Trylock : Thread %d on %p from %s() in %s:%d\n", (int)pthread_self(), mutex, function, file, line ); - fflush( stdout ); - if( !( pthread_mutex_trylock( &mutex->pmutex ) ) ) - { - mutex->function = (unsigned char *)function; - mutex->file = (unsigned char *)file; - mutex->line = line; - return 1; - } - else - return 0; -} - - #else - -static inline void mtMutexLock( mtMutex *mutex ) -{ - pthread_mutex_lock( &mutex->pmutex ); - return; -} - -static inline void mtMutexUnlock( mtMutex *mutex ) -{ - pthread_mutex_unlock( &mutex->pmutex ); - return; -} - -static inline int mtMutexTryLock( mtMutex *mutex ) -{ - return !( pthread_mutex_trylock( &mutex->pmutex ) ); -} - - #endif - - - -//// - - - -typedef struct mtSignal mtSignal; - -struct mtSignal -{ - pthread_cond_t pcond; -}; - -static inline void mtSignalInit( mtSignal *signal ) -{ - pthread_cond_init( &signal->pcond, 0 ); - return; -} - -static inline void mtSignalDestroy( mtSignal *signal ) -{ - pthread_cond_destroy( &signal->pcond ); - return; -} - -static inline void mtSignalWake( mtSignal *signal ) -{ - #ifdef MT_DEBUG - if( pthread_cond_signal( &signal->pcond ) ) - DEBUG_WARNING(); - #else - pthread_cond_signal( &signal->pcond ); - #endif - return; -} - -static inline void mtSignalBroadcast( mtSignal *signal ) -{ - #ifdef MT_DEBUG - if( pthread_cond_broadcast( &signal->pcond ) ) - DEBUG_WARNING(); - #else - pthread_cond_broadcast( &signal->pcond ); - #endif - return; -} - -static inline void mtSignalWait( mtSignal *signal, mtMutex *mutex ) -{ - #ifdef MT_DEBUG - if( pthread_cond_wait( &signal->pcond, &mutex->pmutex ) ) - DEBUG_WARNING(); - #else - pthread_cond_wait( &signal->pcond, &mutex->pmutex ); - #endif - return; -} - -static inline void mtSignalWaitTimeout( mtSignal *signal, mtMutex *mutex, long milliseconds ) -{ - uint64_t microsecs; - struct timespec ts; - struct timeval tp; - gettimeofday( &tp, NULL ); - ts.tv_sec = tp.tv_sec + ( milliseconds / 1000 ); - microsecs = tp.tv_usec + ( ( milliseconds % 1000 ) * 1000 ); - if( microsecs >= 1000000 ) - { - ts.tv_sec++; - microsecs -= 1000000; - } - ts.tv_nsec = microsecs * 1000; - pthread_cond_timedwait( &signal->pcond, &mutex->pmutex, &ts ); - return; -} - - #ifdef MT_DEBUG - #define MT_MUTEX_INITIALIZER { 0, 0, 0, PTHREAD_MUTEX_INITIALIZER } - #else - #define MT_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } - #endif - - - -//// - - - - #ifdef MM_ATOMIC_SUPPORT - -typedef struct mtSpin mtSpin; - -struct mtSpin -{ - mmAtomic32 atomicspin; -}; - -static inline void mtSpinInit( mtSpin *spin ) -{ - mmAtomicWrite32( &spin->atomicspin, 0x0 ); - return; -} - -static inline void mtSpinDestroy( mtSpin *spin ) -{ - return; -} - -static inline void mtSpinLock( mtSpin *spin ) -{ - mmAtomicSpin32( &spin->atomicspin, 0x0, 0x1 ); - return; -} - -static inline void mtSpinUnlock( mtSpin *spin ) -{ - mmAtomicWrite32( &spin->atomicspin, 0x0 ); - return; -} - -static inline int mtSpinTryLock( mtSpin *spin ) -{ - return mmAtomicCmpReplace32( &spin->atomicspin, 0x0, 0x1 ); -} - - #elif _POSIX_SPIN_LOCKS > 0 - -typedef struct mtSpin mtSpin; - -struct mtSpin -{ - #ifdef MT_DEBUG - unsigned char *function; - unsigned char *file; - int line; - #endif - pthread_spinlock_t pspinlock; -}; - -static inline void mtSpinInit( mtSpin *spin ) -{ - pthread_spin_init( &spin->pspinlock, PTHREAD_PROCESS_PRIVATE ); - return; -} - -static inline void mtSpinDestroy( mtSpin *spin ) -{ - pthread_spin_destroy( &spin->pspinlock ); - return; -} - -static inline void mtSpinLock( mtSpin *spin ) -{ - #ifdef MT_DEBUG - if( pthread_spin_lock( &spin->pspinlock ) ) - DEBUG_WARNING(); - #else - pthread_spin_lock( &spin->pspinlock ); - #endif - return; -} - -static inline void mtSpinUnlock( mtSpin *spin ) -{ - #ifdef MT_DEBUG - if( pthread_spin_unlock( &spin->pspinlock ) ) - DEBUG_WARNING(); - #else - pthread_spin_unlock( &spin->pspinlock ); - #endif - return; -} - -static inline int mtSpinTryLock( mtSpin *spin ) -{ - return !( pthread_spin_trylock( &spin->pspinlock ) ); -} - - #else - -typedef struct mtMutex mtSpin; - - #define mtSpinInit(a) mtMutexInit(a) - #define mtSpinDestroy(a) mtMutexDestroy(a) - #define mtSpinLock(a) mtMutexLock(a) - #define mtSpinUnlock(a) mtMutexUnlock(a) - #define mtSpinTryLock(a) mtMutexTryLock(a) - - #endif - - - -//// - - - - #ifdef MT_BARRIER_SUPPORT - -typedef struct -{ - pthread_barrier_t pbarrier; -} mtBarrier; - -static inline void mtBarrierInit( mtBarrier *barrier, int count ) -{ - pthread_barrier_init( &barrier->pbarrier, 0, count ); - return; -} - -static inline void mtBarrierDestroy( mtBarrier *barrier ) -{ - pthread_barrier_destroy( &barrier->pbarrier ); - return; -} - -static inline int mtBarrierWait( mtBarrier *barrier ) -{ - return pthread_barrier_wait( &barrier->pbarrier ); -} - - #endif - - - -//// - - - - #ifdef MT_RWLOCK_SUPPORT - -typedef struct mtRWlock mtRWlock; - -struct mtRWlock -{ - pthread_rwlock_t prwlock; -}; - - -static inline void mtRWlockInit( mtRWlock *rwlock ) -{ - pthread_rwlock_init( &rwlock->prwlock, 0 ); - return; -} - -static inline void mtRWlockDestroy( mtRWlock *rwlock ) -{ - pthread_rwlock_destroy( &rwlock->prwlock ); - return; -} - -static inline void mtRWlockRead( mtRWlock *rwlock ) -{ - pthread_rwlock_rdlock( &rwlock->prwlock ); - return; -} - -static inline void mtRWlockWrite( mtRWlock *rwlock ) -{ - pthread_rwlock_wrlock( &rwlock->prwlock ); - return; -} - -static inline void mtRWlockUnlock( mtRWlock *rwlock ) -{ - pthread_rwlock_unlock( &rwlock->prwlock ); - return; -} - -static inline int mtRWlockTryRead( mtRWlock *rwlock ) -{ - return pthread_rwlock_rdlock( &rwlock->prwlock ); -} - -static inline int mtRWlockTryWrite( mtRWlock *rwlock ) -{ - return pthread_rwlock_wrlock( &rwlock->prwlock ); -} - - #endif - - -#endif - - diff --git a/src/other/gct/BRLCAD/BrlcadAppWalker.cpp b/src/other/gct/BRLCAD/BrlcadAppWalker.cpp deleted file mode 100644 index 95e9567611c..00000000000 --- a/src/other/gct/BRLCAD/BrlcadAppWalker.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* BrlcadAppWalker.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the comb_pre_func, comb_post_func, and primitive_func operations - * that the BrlcadTreeWalker will call. - */ - -/* Standard libraries */ -#include - -/* BRL-CAD libraries */ -extern "C" { -#include "vmath.h" -#include "nmg.h" -#include "rt/geom.h" -#include "bu.h" -#include "rt/func.h" -#include "raytrace.h" -#include "rt/db4.h" -} - -/* Local headers */ -#include "BrlcadAppWalker.h" - -//****************************************************************************** -// NAME constructor -// -// INPUTS -// none -// -// DESCRIPTION -// Construct the object. -//****************************************************************************** -BrlcadAppWalker::BrlcadAppWalker() -{ - regionNeedsConversion = false; -} - -//****************************************************************************** -// NAME destructor -// -// DESCRIPTION -// Cleanup the object. -//****************************************************************************** -BrlcadAppWalker::~BrlcadAppWalker() -{ -} - -void BrlcadAppWalker::comb_pre_func(struct directory *dp, - BrlcadTreeWalker *btw) -{ - int regCount = btw->inRegion(); - //fprintf(stderr, "entering %s inRegion(%d)", dp->d_namep, regCount); - //btw->printObjStack(); - //fprintf(stderr, "flags..."); - //btw->printFlags(); - //btw->printFlagStack(); - int tf = btw->getFlags(); - if (regCount == 1) - { - if (dp->d_flags & RT_DIR_REGION) - { - regionNeedsConversion = false; - } - } - else if (regCount > 1) - { - if (tf & FLAG_UNION) - { - // Should never happen. Union of region into region is bogus - regionNeedsConversion = true; - } - else if (tf & (FLAG_SUBTRACT|FLAG_INTERSECT|FLAG_NOT|FLAG_XOR)) - { - regionNeedsConversion = true; - } - } -} - -void BrlcadAppWalker::comb_post_func(struct directory *dp, - struct rt_comb_internal *comb, - BrlcadTreeWalker *btw) -{ - int regCount = btw->inRegion(); - //fprintf(stderr, "leaving %s inRegion(%d)", dp->d_namep, regCount); - //btw->printObjStack(); btw->printFlags(); - //btw->printFlagStack(); - - //fprintf(stderr, "groupstack: %ld\n", m_groupStack.size()); - int tf = btw->getFlags(); - if (regCount == 1 ) - { - if (dp->d_flags & RT_DIR_REGION) - { - if (regionNeedsConversion) - if (m_nonBotRegions.empty()) - m_nonBotRegions.push_back(dp->d_namep); - else if (std::find(m_nonBotRegions.begin(), - m_nonBotRegions.end(), - dp->d_namep) == m_nonBotRegions.end()) - m_nonBotRegions.push_back(dp->d_namep); - } - } -} - -void BrlcadAppWalker::primitive_func(struct directory *dp, - BrlcadTreeWalker *btw) -{ - int tf = btw->getFlags(); - int inRegion = btw->inRegion(); - - // btw->printObjStack(); btw->printFlags(); - - if (inRegion > 0) - { - // if non-bot - // rnc = true - // add wireframe - // else - // add triangles - - if (tf & (FLAG_SUBTRACT|FLAG_INTERSECT|FLAG_NOT|FLAG_XOR)) - { - regionNeedsConversion = true; - } - - struct rt_db_internal intern; - btw->brlcad_get_internal(&intern, dp, NULL); - - if (intern.idb_minor_type == ID_BOT) - { - //fprintf(stderr, "%s is a bot\n", dp->d_namep); - // add a drawable for the triangles from this BOT - if (m_botRegions.empty()) - m_botRegions.push_back(dp->d_namep); - else if (std::find(m_botRegions.begin(), - m_botRegions.end(), - dp->d_namep) == m_botRegions.end()) - m_botRegions.push_back(dp->d_namep); - } - else - { - //fprintf(stderr, "%s is a prim in region %s\n", dp->d_namep, m_currentGeode->getName().c_str()); - regionNeedsConversion = true; - } - } - else - { - // Just a primitive hanging out in space in no region? - struct rt_db_internal intern; - btw->brlcad_get_internal(&intern, dp, NULL); - - if (intern.idb_minor_type == ID_BOT) - { - if (m_botRegions.empty()) - m_botRegions.push_back(dp->d_namep); - else if (std::find(m_botRegions.begin(), - m_botRegions.end(), - dp->d_namep) == m_botRegions.end()) - m_botRegions.push_back(dp->d_namep); - } - } - //fprintf(stderr, "%s done\n", dp->d_namep); -} diff --git a/src/other/gct/BRLCAD/BrlcadAppWalker.h b/src/other/gct/BRLCAD/BrlcadAppWalker.h deleted file mode 100644 index 41fe1485f93..00000000000 --- a/src/other/gct/BRLCAD/BrlcadAppWalker.h +++ /dev/null @@ -1,76 +0,0 @@ -/* BrlcadAppWalker.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the comb_pre_func, comb_post_func, and primitive_func operations - * that the BrlcadTreeWalker will call. - */ - -#ifndef BRLCADAPPWALKER_H -#define BRLCADAPPWALKER_H - -/* Standard libraries */ -#include -#include - -/* Linterface headers */ -#include "Interface/AppWalkerInterface.h" - -/* Local headers */ -#include "BrlcadTreeWalker.h" - -class BrlcadAppWalker : public AppWalkerInterface -{ - public: - BrlcadAppWalker(); - ~BrlcadAppWalker(); - - virtual void comb_pre_func(struct directory *dp, - BrlcadTreeWalker *btw); - virtual void comb_post_func(struct directory *dp, - struct rt_comb_internal *comb, - BrlcadTreeWalker *btw); - virtual void primitive_func(struct directory *dp, - BrlcadTreeWalker *btw); - - std::vector getBotRegions() { return m_botRegions; } - std::vector getNonBotRegions() { return m_nonBotRegions; } - - private: - std::vector m_botRegions; - std::vector m_nonBotRegions; - bool regionNeedsConversion; // region needs conversion -}; - -#endif diff --git a/src/other/gct/BRLCAD/BrlcadLoader.cpp b/src/other/gct/BRLCAD/BrlcadLoader.cpp deleted file mode 100644 index 2f3f28c333f..00000000000 --- a/src/other/gct/BRLCAD/BrlcadLoader.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* BrlcadLoader.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * This class contains the functions to comb a BRL-CAD database file and - * return region names. - */ - -/* Local headers */ -#include "BrlcadLoader.h" -#include "BrlcadAppWalker.h" - -//****************************************************************************** -// NAME constructor -// -// INPUTS -// filename - target file name -// -// DESCRIPTION -// Construct the object. -//****************************************************************************** -BrlcadLoader::BrlcadLoader(const std::string filename) - : GLoaderInterface(filename) - , m_dbip(NULL) -{ -} - -//****************************************************************************** -// NAME destructor -// -// DESCRIPTION -// Cleanup the object. -//****************************************************************************** -BrlcadLoader::~BrlcadLoader() -{ -} - -//****************************************************************************** -// NAME startLoader -// -// INPUTS -// none -// -// DESCRIPTION -// Walk geometry to get all the region names within. -//****************************************************************************** -void BrlcadLoader::startLoader() -{ - m_status = true; - - // First initialize the librt resource - if (rt_uniresource.re_magic != RESOURCE_MAGIC) - { - rt_init_resource(&rt_uniresource, 0, NULL); - } - - // - // Open the database and load the geometry - // - if ((m_dbip = db_open(m_fileName.c_str(), "r")) == DBI_NULL) - { - m_status = false; - return; - } - - if (db_dirbuild(m_dbip)) - { - m_status = false; - return; - } - - - // update all objects with the correct number of - // times the object is referenced by other objects - db_update_nref(m_dbip, &rt_uniresource); - - BrlcadAppWalker appWalker; - BrlcadTreeWalker tw(m_dbip, &rt_uniresource, appWalker); - struct directory *dp; - - // Look at all items in the geometry file - FOR_ALL_DIRECTORY_START(dp, m_dbip) { - // if an item isn't referred to by any other object - // this is a top level object we should start traversing - // to construct the geometry - if (dp->d_nref == 0) - tw.brlcad_functree(dp); // Traverse the tree, generating geometry - } FOR_ALL_DIRECTORY_END; - //fprintf(stderr, "final\n"); - - // set both bot and non-bot lists - m_botRegionNames = appWalker.getBotRegions(); - m_nonbotRegionNames = appWalker.getNonBotRegions(); - - db_close(m_dbip); - m_dbip = NULL; -} diff --git a/src/other/gct/BRLCAD/BrlcadLoader.h b/src/other/gct/BRLCAD/BrlcadLoader.h deleted file mode 100644 index f7c98fdb75a..00000000000 --- a/src/other/gct/BRLCAD/BrlcadLoader.h +++ /dev/null @@ -1,72 +0,0 @@ -/* BrlcadLoader.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * This class contains the functions to comb a BRL-CAD database file and - * return region names. - */ - -#ifndef BRLCAD_LOADER_H -#define BRLCAD_LOADER_H - -/* BRL-CAD libraries */ -extern "C" { -#include "vmath.h" -#include "raytrace.h" -#include "rt/geom.h" -} - -/* Interface headers */ -#include "Interface/GLoaderInterface.h" - -/* Class */ -class BrlcadLoader : public GLoaderInterface -{ - public: - BrlcadLoader(const std::string); - ~BrlcadLoader(); - - std::vector getBotRegionNames() const { return m_botRegionNames; } - std::vector getNonbotRegionNames() const { return m_nonbotRegionNames; } - - virtual std::vector getGeomNames() { return getNonbotRegionNames(); } - virtual void startLoader(); - - protected: - struct db_i *m_dbip; - std::vector m_botRegionNames; - std::vector m_nonbotRegionNames; -}; - -#endif diff --git a/src/other/gct/BRLCAD/BrlcadTreeWalker.cpp b/src/other/gct/BRLCAD/BrlcadTreeWalker.cpp deleted file mode 100644 index aa02c04ca93..00000000000 --- a/src/other/gct/BRLCAD/BrlcadTreeWalker.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* BrlcadTreeWalker.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * This object walks a brlcad heirarchy starting at a particular - * directory entry. - */ - -#include "BrlcadTreeWalker.h" - -BrlcadTreeWalker::BrlcadTreeWalker(struct db_i* dbip, - struct resource *resp, - AppWalkerInterface &appWalker) - : m_dbip(dbip) - , m_resp(resp) - , m_inRegion(0) - , m_appWalker(appWalker) -{ - m_treeFlags.push_back(0); - RT_CK_DBI(m_dbip); - if (m_resp) - { - RT_CK_RESOURCE(m_resp); - } - - // XXX This dreck is necessary because the ft_plot() functions expect RTG to be initialized - if (BU_LIST_FIRST(bu_list, &RTG.rtg_vlfree) == 0) - { - char *envflags; - envflags = getenv("LIBRT_DEBUG"); - if (envflags) - { - if (RTG.debug) - bu_log("WARNING: discarding LIBRT_DEBUG value in favor of application specified flags\n"); - else - RTG.debug = strtol(envflags, NULL, 0x10); - } - - BU_LIST_INIT(&RTG.rtg_vlfree); - } -} - -BrlcadTreeWalker::~BrlcadTreeWalker() -{ -} - -int BrlcadTreeWalker::brlcad_get_internal(struct rt_db_internal *intern, - struct directory *dp, - matp_t matrix) -{ - return rt_db_get_internal(intern, dp, m_dbip, matrix, m_resp); -} - -void BrlcadTreeWalker::brlcad_functree(struct directory *dp) -{ - RT_CK_DBI(m_dbip); - if (m_resp) - { - RT_CK_RESOURCE(m_resp); - } - - if (!dp) - { - return; /* nothing to do */ - } - - m_objStack.push_back(StackNode(dp)); - - if (dp->d_flags & RT_DIR_COMB) - { - if (dp->d_flags & RT_DIR_REGION) - { - if (m_inRegion == 0) - { - m_topRegionName = dp->d_namep; - } - m_inRegion++; - } - - m_appWalker.comb_pre_func(dp, this); - struct rt_db_internal in; - struct rt_comb_internal *comb = (struct rt_comb_internal *)NULL; - - if (rt_db_get_internal(&in, dp, m_dbip, /*mat_t*/ NULL, m_resp) < 0) - return; - - comb = (struct rt_comb_internal *)in.idb_ptr; - if (!comb) - { - bu_log("%s:%d null comb pointer for combination called %s", - __FILE__, __LINE__, dp->d_namep); - bu_bomb(""); - } - - m_treeFlags.push_back(FLAG_NONE); - brlcad_functree_subtree(comb->tree, dp); - m_treeFlags.pop_back(); - - /* Finally, the combination post process */ - m_appWalker.comb_post_func(dp, comb, this); - - rt_db_free_internal(&in); - - if (dp->d_flags & RT_DIR_REGION) - { - m_inRegion--; - if (m_inRegion == 0) - m_topRegionName.clear(); - } - } - else if (dp->d_flags & RT_DIR_SOLID || dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK) - { - m_appWalker.primitive_func(dp, this); - } - else if (strcmp("_GLOBAL", dp->d_namep)) - { - // This is not the _GLOBAL and isn't a solid/primtive or combination - bu_log("brlcad_functree: %s is neither COMB nor SOLID? %d %d\n", - dp->d_namep, dp->d_major_type, dp->d_minor_type); - } - - m_objStack.pop_back(); -} - -/*** - * The parent argument exists solely to be able to report error status against - * a particular object in the BRLCAD database. - */ -void BrlcadTreeWalker::brlcad_functree_subtree(union tree *tp, - struct directory *parent) -{ - if (!tp) - return; - - switch (tp->tr_op) - { - case OP_DB_LEAF: - { - struct directory *dp; - - if (tp->tr_l.tl_mat) - { - m_objStack.push_back(StackNode(tp->tr_l.tl_mat)); - m_treeFlags.push_back(m_treeFlags.back()|FLAG_MATRIX); - } - - if ((dp=db_lookup(m_dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL) - { - break; - } - - brlcad_functree(dp); - - if (tp->tr_l.tl_mat) - { - m_treeFlags.pop_back(); - m_objStack.pop_back(); - } - break; - } - case OP_UNION: - case OP_INTERSECT: - case OP_SUBTRACT: - case OP_XOR: - m_objStack.push_back(StackNode(tp->tr_op)); - // add union to treeFlags & push new value - m_treeFlags.push_back(m_treeFlags.back()|FLAG_UNION); - brlcad_functree_subtree(tp->tr_b.tb_left, parent); - m_treeFlags.pop_back(); - - // add flag to treeFlags & push new value - m_treeFlags.push_back(m_treeFlags.back()|op2flag(tp->tr_op)); - brlcad_functree_subtree(tp->tr_b.tb_right, parent); - m_treeFlags.pop_back(); - - m_objStack.pop_back(); - break; - case OP_SOLID: - case OP_REGION: - case OP_NOP: - case OP_NOT: - case OP_GUARD: - case OP_XNOP: - case OP_NMG_TESS: - case OP_FREE: - // These types not implemented. - break; - default: - bu_log("%s:%d brlcad_functree_subtree: unrecognized operator %d in \"%s\"\n", - __FILE__, __LINE__, tp->tr_op, parent->d_namep); - bu_bomb(""); - } -} diff --git a/src/other/gct/BRLCAD/BrlcadTreeWalker.h b/src/other/gct/BRLCAD/BrlcadTreeWalker.h deleted file mode 100644 index dddf06129e7..00000000000 --- a/src/other/gct/BRLCAD/BrlcadTreeWalker.h +++ /dev/null @@ -1,168 +0,0 @@ -/* BrlcadTreeWalker.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * This object walks a brlcad heirarchy starting at a particular - * directory entry. - */ - -#ifndef BRLCADTREEWALKER_H -#define BRLCADTREEWALKER_H - -/* Standard libraries */ -#include - -/* BRL-CAD libraries */ -extern "C" { -#include "vmath.h" -#include "nmg.h" -#include "rt/geom.h" -#include "bu.h" -#include "raytrace.h" -#include "rt/db4.h" -} - -/* Interface headers */ -#include "Interface/AppWalkerInterface.h" - -/** enumeration of all the types of operators that might be on the - * heirarchy of the graph that the BrlcadTreeWalker maintains - * - * Shared by the BrlcadTreeWalker and BrlcadBotLoader - */ -enum treeFlags { FLAG_NONE=0, - FLAG_MATRIX=1, - FLAG_SUBTRACT=2, - FLAG_INTERSECT=4, - FLAG_UNION=8, - FLAG_NOT=16, - FLAG_XOR=32, - FLAG_LEAF=64 -}; - -/** - * HELPER CLASS: StackNode - * - * This encapsulates a single item on the directed acyclic graph of a - * BRLCAD heirarchy. The stack is maintained by the BrlcadTreeWalker to - * keep track of various states along the path. - * - * XXX This really should be private to the BrlcadTreeWalker. No-one else has - * any business looking at this. - */ -class StackNode { - public: - enum ItemType { OBJECT, OPERATION, MATRIX }; - - StackNode(struct directory *dp) : m_itemType(OBJECT) { m_dp = dp; } - StackNode(int op) : m_itemType(OPERATION) { m_op = op; } - StackNode(mat_t m) : m_itemType(MATRIX) { MAT_COPY(m_mat, m); } - - ItemType getType() const { return m_itemType; } - struct directory *getDirectory() const - { - if (m_itemType == OBJECT) { - return m_dp; - } - abort(); - return NULL; // make compiler happy - } - int getOperation() const - { - if (m_itemType == OPERATION) { - return m_op; - } - abort(); - return 0; // make compiler happy - } - fastf_t * getMatrix() const - { - if (m_itemType == MATRIX) { - return (fastf_t *)m_mat; - } - abort(); - return NULL; // make compiler happy - } - void print(const int depth); - - private: - ItemType m_itemType; - struct directory *m_dp; - int m_op; - mat_t m_mat; -}; - -/* Class */ -class BrlcadTreeWalker -{ - public: - BrlcadTreeWalker(struct db_i* dbip, - struct resource *resp, - AppWalkerInterface &appWalker); - ~BrlcadTreeWalker(); - - /// Start walking the heirarchy at a particular directory entry - void brlcad_functree(struct directory *); - int brlcad_get_internal(struct rt_db_internal *intern, - struct directory *dp, - mat_t matrix); - inline int inRegion() const { return m_inRegion; } - inline const char *regionName() const { return m_topRegionName.c_str(); } - inline int getFlags() const { if (m_treeFlags.size() > 0) return m_treeFlags.back(); else return 0; } - - private: - // This is a helper function for brlcad_functree which - // handles walking the union tree structure for a single combination - void brlcad_functree_subtree(union tree *, struct directory *); - static inline int op2flag(int op) - { - switch (op) { - case OP_UNION : return FLAG_UNION; - case OP_SUBTRACT : return FLAG_SUBTRACT; - case OP_INTERSECT : return FLAG_INTERSECT; - case OP_XOR : return FLAG_XOR; - } - return 0; - } - - struct db_i *m_dbip; - struct resource *m_resp; - int m_inRegion; - std::string m_topRegionName; - AppWalkerInterface &m_appWalker; - std::vectorm_objStack; - std::vector m_treeFlags; -}; - -#endif diff --git a/src/other/gct/BRLCAD/CMakeLists.txt b/src/other/gct/BRLCAD/CMakeLists.txt deleted file mode 100644 index 02fa17a4d1c..00000000000 --- a/src/other/gct/BRLCAD/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -set(GCT_BRLCAD_SRCS - BrlcadAppWalker.cpp - BrlcadLoader.cpp - BrlcadTreeWalker.cpp - DbGeometry.cpp - DbTracer.cpp - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../openNURBS - ${CMAKE_CURRENT_SOURCE_DIR}/../../tcl/generic - ) - -add_library(BrlcadGCT SHARED ${GCT_BRLCAD_SRCS}) -set_target_properties(BrlcadGCT PROPERTIES VERSION 1.1.0 SOVERSION 1) - -install(TARGETS BrlcadGCT - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR}) - -if(MSVC) - set_property(TARGET BrlcadGCT APPEND PROPERTY COMPILE_DEFINITIONS "BRLCADGCT_DLL_EXPORTS") -endif(MSVC) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 - diff --git a/src/other/gct/BRLCAD/DbGeometry.cpp b/src/other/gct/BRLCAD/DbGeometry.cpp deleted file mode 100644 index 59888ea4389..00000000000 --- a/src/other/gct/BRLCAD/DbGeometry.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* DbGeometry.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/20/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the INativeGeometry interface for BRL-CAD targets. - */ - -// Local headers -#include "DbGeometry.h" - -namespace GeomConversion { - - namespace BRLCAD { - - static struct resource resource[MAX_PSW]; - - //******************************************************************* - // NAME constructor - // - // INPUTS - // filename - target file name - // - // DESCRIPTION - // Construct the object. - //******************************************************************* - DbGeometry::DbGeometry(std::string filename) - : Interface::INativeGeometry(filename) - , m_rtip(RTI_NULL) - { - char titleBuf[1028]; - m_rtip = rt_dirbuild(filename.c_str(), titleBuf, sizeof(titleBuf)); - if (m_rtip == RTI_NULL) - return; // throw exception??? - - /* Initialize all the per-CPU memory resources. The number of - * processors can change at runtime, init them all. - */ - for (int i=0; i < MAX_PSW; i++) - { - rt_init_resource(&(resource[i]), i, m_rtip); - bn_rand_init(resource[i].re_randptr, i); - } - - m_geometryType = Interface::BRLCAD; - } - - //******************************************************************* - // NAME destructor - // - // DESCRIPTION - // Cleanup the object. - //******************************************************************* - DbGeometry::~DbGeometry() - { - // cleanup rt_i - if (m_rtip != RTI_NULL) - { - rt_free_rti(m_rtip); - m_rtip = RTI_NULL; - } - } - - //******************************************************************* - // NAME getGeometry - // - // INPUTS - // none - // - // DESCRIPTION - // Return a reference to the internal target data. - //******************************************************************* - void* DbGeometry::getGeometry() - { - return ((void*) m_rtip); - } - - //******************************************************************* - // NAME getResources - // - // INPUTS - // i - index of the desired resource - // - // DESCRIPTION - // Return a reference to CPU resource for the given index. - //******************************************************************* - struct resource* DbGeometry::getResource(int i) - { - return &(resource[i]); - } - - //******************************************************************* - // NAME loadGeometry - // - // INPUTS - // rname - region name - // tcount - thread count - // - // DESCRIPTION - // Load a given piece of the geometry. - //******************************************************************* - void DbGeometry::loadGeometry(std::string rname, int tcount) - { - m_rtip->useair = 1; // convert air objects when found - - if (rt_gettree(m_rtip, rname.c_str())) - { - bu_log("BRLCAD::DbGeometry::loadRegion - Error loading <%s>\n", - rname.c_str()); - return; - } - - rt_prep_parallel(m_rtip, tcount); - } - - //******************************************************************* - // NAME cleanupGeometry - // - // INPUTS - // none - // - // DESCRIPTION - // Perform cleanup of any geometry. - //******************************************************************* - void DbGeometry::cleanupGeometry() - { - rt_clean(m_rtip); - } - - //******************************************************************* - // NAME getGeometryMin - // - // INPUTS - // none - // - // DESCRIPTION - // Return minimum 3D dimension of the loaded geometry. - //******************************************************************* - double* DbGeometry::getGeometryMin() - { - return m_rtip->rti_pmin; - } - - //******************************************************************* - // NAME getGeometryMax - // - // INPUTS - // none - // - // DESCRIPTION - // Return maximum 3D dimension of the loaded geometry. - //******************************************************************* - double* DbGeometry::getGeometryMax() - { - return m_rtip->rti_pmax; - } - - } // namespace BRLCAD - -} // namespace GeomConversion diff --git a/src/other/gct/BRLCAD/DbGeometry.h b/src/other/gct/BRLCAD/DbGeometry.h deleted file mode 100644 index de2a49afad1..00000000000 --- a/src/other/gct/BRLCAD/DbGeometry.h +++ /dev/null @@ -1,83 +0,0 @@ -/* DbGeometry.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/20/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the INativeGeometry interface for BRL-CAD targets. - */ - -#ifndef BRLCADDBGEOMETRY_H -#define BRLCADDBGEOMETRY_H - -// BRL-CAD headers -extern "C" { -#include "bu.h" -#include "raytrace.h" -} - -// Local headers -#include "Interface/INativeGeometry.h" - -namespace GeomConversion { - - namespace BRLCAD { - - /** - * DbGeometry - * - * Implements the INativeGeometry interface for BRL-CAD targets. - */ - class DbGeometry : public Interface::INativeGeometry - { - public: - DbGeometry(std::string); - ~DbGeometry(); - - virtual void* getGeometry(); - struct resource* getResource(int); - - virtual void loadGeometry(std::string, int tcount=1); - virtual void cleanupGeometry(); - - virtual double* getGeometryMin(); - virtual double* getGeometryMax(); - - private: - struct rt_i *m_rtip; - }; - - } // namespace DbGeometry - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/BRLCAD/DbTracer.cpp b/src/other/gct/BRLCAD/DbTracer.cpp deleted file mode 100644 index 34e2e22e920..00000000000 --- a/src/other/gct/BRLCAD/DbTracer.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* DbTracer.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 10/02/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the IGeometryTracer interface for shotlining BRL-CAD targets. - */ - -// Local headers -#include "DbTracer.h" - -namespace GeomConversion { - - namespace BRLCAD { - - //******************************************************************* - // NAME hit_func - // - // INPUTS - // ap - application structure - // PartHeadp - pointer to the beginning of the trace list - // - // DESCRIPTION - // Called when a shotline produces a hit. This user defined - // callback copies the in and out hit points into structures and - // stores them in the ray's result list. - //******************************************************************* - static int - hit_func(struct application *ap, struct partition *PartHeadp, struct seg *) - { - /* iterating over partitions, this will keep track of the current - * partition we're working on. - */ - struct partition *pp; - - /* will serve as a pointer for the entry and exit hitpoints */ - struct hit *hitp; - - /* will serve as a pointer to the solid primitive we hit */ - struct soltab *stp; - - /* output variables */ - Interface::ray_results *result = (Interface::ray_results *) ap->a_uptr; - Interface::one_hit singleHit; - - VMOVE(result->origin, ap->a_ray.r_pt); - result->x = ap->a_x; - result->y = ap->a_y; - - /* iterate over each partition until we get back to the head. - * each partition corresponds to a specific homogeneous region of - * material. - */ - for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) - { - /* entry hit point, so we type less */ - hitp = pp->pt_inhit; - - /* primitive we encountered on entry */ - stp = pp->pt_inseg->seg_stp; - - /* clear data struct */ - ONE_HIT_INIT(singleHit); - - /* record IN hit point */ - VJOIN1(singleHit.point, ap->a_ray.r_pt, - hitp->hit_dist, ap->a_ray.r_dir); - - /* calculate IN normal vector */ - /* compute the normal vector at the entry point, flipping the - * normal if necessary. - */ - RT_HIT_NORMAL(singleHit.normal, hitp, stp, - &(ap->a_ray), pp->pt_inflip); - - /* save IN solid and surface numbers */ - /* singleHit.solidNumber = stp->st_bit; */ - singleHit.solidName = stp->st_dp->d_namep; - singleHit.solidSurface = hitp->hit_surfno; - - /* push hit to the result list */ - result->hitData.push_back(singleHit); - - /* exit point, so we type less */ - hitp = pp->pt_outhit; - - /* primitive we exited from */ - stp = pp->pt_outseg->seg_stp; - - /* clear data struct */ - ONE_HIT_INIT(singleHit); - - /* record OUT hit point */ - VJOIN1(singleHit.point, ap->a_ray.r_pt, - hitp->hit_dist, ap->a_ray.r_dir); - - /* calculate OUT normal vector */ - /* compute the normal vector at the exit point, flipping the - * normal if necessary. - */ - RT_HIT_NORMAL(singleHit.normal, hitp, stp, - &(ap->a_ray), pp->pt_outflip); - - /* save OUT solid and surface numbers */ - /* singleHit.solidNumber = stp->st_bit; */ - singleHit.solidName = stp->st_dp->d_namep; - singleHit.solidSurface = hitp->hit_surfno; - - /* push hit to the result list */ - result->hitData.push_back(singleHit); - } - - return 1; - } - - //******************************************************************* - // NAME constructor - // - // INPUTS - // ti - pointer to a target - // cpuID - thread ID - // - // DESCRIPTION - // Construct the object. - //******************************************************************* - DbTracer::DbTracer(Interface::INativeGeometry *ti, int cpuID) - : Interface::IGeometryTracer(ti) - , m_cpuID(cpuID) - { - // set up the application object that will be used - RT_APPLICATION_INIT(&m_ap); - m_ap.a_rt_i = (struct rt_i *) ti->getGeometry(); - m_ap.a_hit = hit_func; - m_ap.a_resource = ((DbGeometry *) ti)->getResource(cpuID); - m_ap.a_user = cpuID; - } - - //******************************************************************* - // NAME destructor - // - // DESCRIPTION - // Cleanup the object. - //******************************************************************* - DbTracer::~DbTracer() - { - } - - //******************************************************************* - // NAME fireRay - // - // INPUTS - // data - pointer to a tracer_ray_data - // - // DESCRIPTION - // Perform a shotline. - //******************************************************************* - void DbTracer::fireRay(Interface::trace_data *ray) - { - // set application data for this ray - VMOVE(m_ap.a_ray.r_pt, ray->point); - VMOVE(m_ap.a_ray.r_dir, ray->direc); - m_ap.a_ray_length = ray->length; - m_ap.a_uptr = (void *) &(ray->results); - m_ap.a_x = ray->results.x; - m_ap.a_y = ray->results.y; - - // perform shot - (void)rt_shootray(&m_ap); - } - - } // namespace BRLCAD - -} // namespace GeomConversion diff --git a/src/other/gct/BRLCAD/DbTracer.h b/src/other/gct/BRLCAD/DbTracer.h deleted file mode 100644 index ea7323daafd..00000000000 --- a/src/other/gct/BRLCAD/DbTracer.h +++ /dev/null @@ -1,80 +0,0 @@ -/* DbTracer.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 10/02/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements the IGeometryTracer interface for shotlining BRL-CAD targets. - */ - -#ifndef BRLCADDBTRACER_H -#define BRLCADDBTRACER_H - -// BRL-CAD libraries -extern "C" { -#include "bu.h" -#include "vmath.h" -#include "raytrace.h" -#include "rt/geom.h" -} - -// Local headers -#include "Interface/IGeometryTracer.h" -#include "DbGeometry.h" - -namespace GeomConversion { - - namespace BRLCAD { - - /** - * DbTracer - * - * Implements the IGeometryTracer interface for BRL-CAD targets. - */ - class DbTracer : public Interface::IGeometryTracer - { - public: - DbTracer(Interface::INativeGeometry*, int); - ~DbTracer(); - - virtual void fireRay(Interface::trace_data*); - - private: - int m_cpuID; - struct application m_ap; - }; - - } // namespace BRLCAD - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/CMakeLists.txt b/src/other/gct/CMakeLists.txt deleted file mode 100644 index e58c912992b..00000000000 --- a/src/other/gct/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Minimum required version of CMake -cmake_minimum_required(VERSION 3.12) - -# set CMake project name -project(GCT) - -# The location in which to install executables. -if(NOT BIN_DIR) - set(BIN_DIR bin) -endif(NOT BIN_DIR) - -# The location in which to install libraries. -if(NOT LIB_DIR) - if(NOT WIN32) - set(LIB_DIR lib) - else(NOT WIN32) - set(LIB_DIR bin) - endif(NOT WIN32) -endif(NOT LIB_DIR) - -CHECK_INCLUDE_FILE(pthread.h PROBE_PTHREAD_H) -if (NOT PROBE_PTHREAD_H) - cmake_push_check_state(RESET) - # pthread.h on FreeBSD 10 and some older Linucies use non-c90 types - set(CMAKE_REQUIRED_DEFINITIONS "-Dclockid_t=clock_t") - set(CMAKE_REQUIRED_FLAGS "-pthread") - CHECK_INCLUDE_FILE(pthread.h PROBE_PTHREAD_H_CLOCKID_T) - if (PROBE_PTHREAD_H_CLOCKID_T) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dclockid_t=clock_t -pthread") - endif (PROBE_PTHREAD_H_CLOCKID_T) -endif (NOT PROBE_PTHREAD_H) - -set(THREADS_PREFER_PTHREAD_FLAG TRUE) -set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -find_package(Threads) - -add_subdirectory(Auxiliary) -add_subdirectory(BRLCAD) -add_subdirectory(Sampler) -add_subdirectory(MeshDecimation) -add_subdirectory(psmain) -add_subdirectory(dcmain) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/src/other/gct/Interface/AppWalkerInterface.h b/src/other/gct/Interface/AppWalkerInterface.h deleted file mode 100644 index 579111fbbf3..00000000000 --- a/src/other/gct/Interface/AppWalkerInterface.h +++ /dev/null @@ -1,56 +0,0 @@ -/* AppWalkerInterface.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/19/13 - * - * Authors(s): - * DRH - * - * Description: - * Interface class that specifies necessary functions to walk a target. - */ - -#ifndef APPWALKERINTERFACE_H -#define APPWALKERINTERFACE_H - -class BrlcadTreeWalker; // necessary forward declaration - -class AppWalkerInterface -{ - public: - virtual void comb_pre_func(struct directory *, - BrlcadTreeWalker *) = 0; - virtual void comb_post_func(struct directory *, - struct rt_comb_internal *, - BrlcadTreeWalker *) = 0; - virtual void primitive_func(struct directory *, - BrlcadTreeWalker *) = 0; -}; - -#endif diff --git a/src/other/gct/Interface/GLoaderInterface.h b/src/other/gct/Interface/GLoaderInterface.h deleted file mode 100644 index 662170fa02e..00000000000 --- a/src/other/gct/Interface/GLoaderInterface.h +++ /dev/null @@ -1,65 +0,0 @@ -/* GLoaderInterface.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/20/13 - * - * Authors(s): - * DRH - * - * Description: - * Interface class that specifies necessary functions to load and query - * for possible geometry names. - */ - -#ifndef GLOADERINTERFACE_H -#define GLOADERINTERFACE_H - -/* Standard libraries */ -#include -#include - -class GLoaderInterface -{ - public: - GLoaderInterface(const std::string filename) - : m_fileName(filename) - , m_status(true) { ; } - - std::string getFileName() const { return m_fileName; } - bool getStatus() { return m_status; } // true = good, false = fail - - virtual std::vector getGeomNames() = 0; - virtual void startLoader() = 0; - - protected: - std::string m_fileName; - bool m_status; -}; - -#endif diff --git a/src/other/gct/Interface/IGeometryTracer.h b/src/other/gct/Interface/IGeometryTracer.h deleted file mode 100644 index bc6f4415598..00000000000 --- a/src/other/gct/Interface/IGeometryTracer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* IGeometryTracer.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 10/02/13 - * - * Authors(s): - * DRH - * - * Description: - * Interface class that specifies necessary functions to define a - * geometry tracer. - */ - -#ifndef IGEOMETRYTRACER_H -#define IGEOMETRYTRACER_H - -// System headers -#include -#include -#include - -// Local headers -#include "INativeGeometry.h" - -namespace GeomConversion { - - namespace Interface { - - //******************************************************************* - // NAME one_hit - // - // DESCRIPTION - // Holds data used to hold a single hit (in or out) along a ray. - //******************************************************************* - struct one_hit - { - double point[3]; - double normal[3]; - // long solidNumber; - std::string solidName; - long solidSurface; - }; -#define ONE_HIT_INIT(onehit) { \ - memset(onehit.point, 0, sizeof(double)*3); \ - memset(onehit.normal, 0, sizeof(double)*3); \ - onehit.solidName = ""; \ - onehit.solidSurface = 0; \ - } - - //******************************************************************* - // NAME ray_result - // - // DESCRIPTION - // Holds data of all hits along a ray. - //******************************************************************* - struct ray_results - { - double origin[3]; - double dir[3]; - int x, y; - std::vector hitData; - }; -#define RAY_RESULTS_INIT(rayres) { \ - memset(rayres.origin, 0, sizeof(double)*3); \ - memset(rayres.dir, 0, sizeof(double)*3); \ - rayres.x = rayres.y = 0; \ - rayres.hitData.clear(); \ - } -#define RAY_RESULTS_COPY(dest, src) { \ - RAY_RESULTS_INIT(dest); \ - memcpy(dest.origin, src.origin, sizeof(double)*3); \ - memcpy(dest.dir, src.dir, sizeof(double)*3); \ - dest.x = src.x; \ - dest.y = src.y; \ - dest.hitData.insert(dest.hitData.end(), src.hitData.begin(), src.hitData.end()); \ - } - - //******************************************************************* - // NAME trace_ray_data - // - // DESCRIPTION - // Holds data info pertaining to a ray, including the results. - //******************************************************************* - struct trace_data - { - double point[3]; - double direc[3]; - double length; - struct ray_results results; - }; -#define TRACE_DATA_INIT(trd) { \ - memset(trd.point, 0, sizeof(double)*3); \ - memset(trd.direc, 0, sizeof(double)*3); \ - trd.length = 0; \ - RAY_RESULTS_INIT(trd.results); \ - } -#define TRACE_DATA_COPY(dest, src) { \ - memcpy(dest.point, src.point, sizeof(double)*3); \ - memcpy(dest.direc, src.direc, sizeof(double)*3); \ - dest.length = src.length; \ - RAY_RESULTS_COPY(dest.results, src.results); \ - } - - /** - * IGeometryTracer - * - * Defines an interface that specifies necessary functions to define a - * geometry tracer. - */ - class IGeometryTracer - { - public: - IGeometryTracer(INativeGeometry *ng) - : m_geometry(ng) { ; } - virtual ~IGeometryTracer() { ; } - - /* User must define how to shoot a ray */ - virtual void fireRay(struct trace_data*) = 0; - - protected: - INativeGeometry *m_geometry; /* pointer to a geometry */ - }; - - } // namespace Interface - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/Interface/INativeGeometry.h b/src/other/gct/Interface/INativeGeometry.h deleted file mode 100644 index 42a2106c16f..00000000000 --- a/src/other/gct/Interface/INativeGeometry.h +++ /dev/null @@ -1,92 +0,0 @@ -/* INativeGeometry.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/20/13 - * - * Authors(s): - * DRH - * - * Description: - * Interface class that specifies necessary functions to load and operate - * with native geometry. - */ - -#ifndef INATIVEGEOMETRY_H -#define INATIVEGEOMETRY_H - -// System headers -#include - -namespace GeomConversion { - - namespace Interface { - // geometry types -- these will increase as more types are added - enum GeometryType { BRLCAD, UNKNOWN }; - - /** - * INativeGeometry - * - * Defines an interface to load and operate with native geometry. - */ - class INativeGeometry - { - public: - INativeGeometry(std::string filename) - : m_filename(filename) - , m_geometryType(UNKNOWN) { ; } - virtual ~INativeGeometry() { ; } - - GeometryType getGeometryType () { return m_geometryType; } - virtual void* getGeometry() = 0; - std::string getGeomtryFilename() { return m_filename; } - - virtual void loadGeometry(std::string, int tcount=1) = 0; - virtual void cleanupGeometry() {;} - - // These are arrays of 3 elements! - virtual double* getGeometryMin() = 0; - virtual double* getGeometryMax() = 0; - - // These are needed for certain geometries, ignored for others - virtual void loadGeometry(std::string, std::string, int tcount=1) {;} - virtual int getMode() {return 2;} - virtual int getMaterial() {return 1;} - virtual float getThickness() {return 1.0;} - virtual int getPosition() {return 2;} - - protected: - std::string m_filename; - GeometryType m_geometryType; - }; - - } // namespace Interface - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/Interface/ISampler.h b/src/other/gct/Interface/ISampler.h deleted file mode 100644 index edefe1da383..00000000000 --- a/src/other/gct/Interface/ISampler.h +++ /dev/null @@ -1,159 +0,0 @@ -/* ISampler.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 10/09/13 - * - * Authors(s): - * DRH - * - * Description: - * Interface class that specifies what is necessary to be a sampler. - */ - -#ifndef ISAMPLER_H -#define ISAMPLER_H - -// System headers -#include - -// Qt headers -#if defined(COMPILE_FOR_VSL) -#define USE_QT 1 -#else -#define USE_QT 0 -#endif -#if USE_QT -#include -#include -#include -#include -#else -/* Pthread libraries */ -#include -#if defined (_GNU_SOURCE) -#include -#endif -#endif - -// Local headers -#include "IGeometryTracer.h" - -// Constructor Parameters are "defined" here (based on -// using Qt or not) so it's more readable later. -// Also, preprocessor for other things -#if USE_QT -#define SAMPLER_CONST_DEF Interface::INativeGeometry *ng, \ - std::vector &tracers, \ - QList &threads, QObject *parent = NULL -#define SAMPLER_CONST_IMP Interface::INativeGeometry *ng, \ - std::vector &tracers, \ - QList &threads, QObject *parent -#define SAMPLER_CONST_PARAMS ng, tracers, threads, parent -#define SAMPLER_CONST_INITS QObject(parent), \ - m_threads(threads), \ - m_canceled(false) -#define SAMPLER_THREAD_EXIT() { ; } -#else -#define SAMPLER_CONST_DEF Interface::INativeGeometry *ng, \ - std::vector &tracers -#define SAMPLER_CONST_IMP Interface::INativeGeometry *ng, \ - std::vector& tracers -#define SAMPLER_CONST_PARAMS ng, tracers -#define SAMPLER_THREAD_EXIT() pthread_exit(0); -#endif - -namespace GeomConversion { - - namespace Interface { - - /** - * ISampler - * - * Defines an interface that specifies what is necessary to be a sampler. - */ - class ISampler -#if USE_QT - : public QObject -#endif - { -#if USE_QT - Q_OBJECT -#endif - - public: - ISampler(SAMPLER_CONST_DEF) - : -#if USE_QT - SAMPLER_CONST_INITS, -#endif - m_geometry(ng) - , m_threadsDone(0) - , m_tracers(tracers) - , m_prepped(false) - { m_threadCount = tracers.size(); } - virtual ~ISampler() {;} - - virtual void setSpacing(float) = 0; - virtual void prepSample() = 0; - virtual void endSample() = 0; - -#if USE_QT - virtual void stopSampling() = 0; - virtual float getProgress() { return 0.0; } - virtual QString getStatusString() { return QString(); } - virtual void updateProgress() { emit updateSamplerProgress(); } - - signals: - void updateSamplerProgress(); - void finished(); - void startWorkers(); - - public slots: - virtual void workerFinished() = 0; -#endif - virtual void runSample() = 0; - - protected: -#if USE_QT - QList &m_threads; - bool m_canceled; -#endif - - INativeGeometry *m_geometry; - int m_threadCount; - int m_threadsDone; - std::vector &m_tracers; - bool m_prepped; - }; - - } // namespace Interface - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/MeshDecimation/CMakeLists.txt b/src/other/gct/MeshDecimation/CMakeLists.txt deleted file mode 100644 index 612de7cfffd..00000000000 --- a/src/other/gct/MeshDecimation/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -set(GCT_DECIMATION_SRCS - meshcorrection.c - meshdecimation.c - meshdecimationSSE2.c - meshdecimationSSE3.c - meshdecimationSSE4p1.c - meshoptimizer.c - meshoptimization.cpp - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../Auxiliary - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../openNURBS - ${CMAKE_CURRENT_SOURCE_DIR}/../../tcl/generic - ) - -add_library(MeshDecimation SHARED ${GCT_DECIMATION_SRCS}) -target_link_libraries(MeshDecimation AUX ${CMAKE_THREAD_LIBS_INIT}) -set_target_properties(MeshDecimation PROPERTIES VERSION 1.1.0 SOVERSION 1) - -install(TARGETS MeshDecimation - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR}) - -if(MSVC) - set_property(TARGET MeshDecimation APPEND PROPERTY COMPILE_DEFINITIONS "DECIMATION_DLL_EXPORTS") -endif(MSVC) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 - diff --git a/src/other/gct/MeshDecimation/meshcorrection.c b/src/other/gct/MeshDecimation/meshcorrection.c deleted file mode 100644 index 068114d30ad..00000000000 --- a/src/other/gct/MeshDecimation/meshcorrection.c +++ /dev/null @@ -1,1227 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -#include "mm.h" -#include "mmhash.h" -#include "mmbitmap.h" -#include "math3d.h" - -#include "mmbinsort.h" -#include "meshcorrection.h" - - - -//// - - - -typedef int mci; -#define MC_SIZEOF_MCI (CPUCONF_INT_SIZE) - - -/* Double precision internal math is recommended */ -/* -typedef float mcf; -*/ -typedef double mcf; - - -/* -#define DEBUG_VERBOSE -#define DEBUG_VERBOSE_TRITEST -*/ - - -#ifdef DEBUG_VERBOSE - #define MC_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);if(f) exit(1);}) -#else - #define MC_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);}) -#endif - - -/* Maximum count of attempts to try avoiding inexact results */ -#define MC_SEED_ATTEMPT_COUNT_MAX (64) - -/* Threshold of attempt count beyond which test only yet unprocessed triangles */ -#define MC_SEED_ATTEMPT_SAFETY_THRESHOLD (MC_SEED_ATTEMPT_COUNT_MAX>>2) - -/* Thresholds to flag operations as inexact, triggering a fresh new attempt */ -#define MC_ENABLE_INEXACTFLAG_SUPPORT -#define MC_INEXACT_VECTOR_THRESHOLD (0.01) -#define MC_INEXACT_SEGMENT_THRESHOLD (0.001) - -/* Multiply thresholds by this factor on each pass */ -#define MC_INEXACT_THRESHOLD_ATTEMPT_FACTOR (0.9) - - - -typedef struct -{ - mci v[2]; - mci triindex; -} mcEdge; - -typedef struct -{ - mci v0, v1; - mci triindex; - mmListNode list; -} mcOp; - - - -//// - - - -static void mcEdgeHashClearEntry( void *entry ) -{ - mcEdge *edge; - edge = entry; - edge->v[0] = -1; - return; -} - -static int mcEdgeHashEntryValid( void *entry ) -{ - mcEdge *edge; - edge = entry; - return ( edge->v[0] >= 0 ? 1 : 0 ); -} - -static uint32_t mcEdgeHashEntryKey( void *entry ) -{ - uint32_t hashkey; - mcEdge *edge; - edge = entry; - -#ifdef MC_CONFIG_FAST_HASH - - hashkey = edge->v[0]; - hashkey += hashkey << 10; - hashkey ^= hashkey >> 6; - hashkey += edge->v[1]; - hashkey += hashkey << 10; - hashkey ^= hashkey >> 6; - hashkey += hashkey << 6; - hashkey ^= hashkey >> 11; - hashkey += hashkey << 15; - -#else - -#if MC_SIZEOF_MCI == 4 - #if CPUCONF_WORD_SIZE == 64 - { - uint64_t *v = (uint64_t *)edge->v; - hashkey = ccHash32Int64Inline( *v ); - } - #else - hashkey = ccHash32Data4Inline( (void *)edge->v ); - #endif -#elif MC_SIZEOF_MCI == 8 - #if CPUCONF_WORD_SIZE == 64 - hashkey = ccHash32Array64( (uint64_t *)edge->v, 2 ); - #else - hashkey = ccHash32Array32( (uint32_t *)edge->v, 4 ); - #endif -#else - hashkey = ccHash32Data( edge->v, 2*sizeof(mci) ); -#endif - -#endif - - return hashkey; -} - -static int mcEdgeHashEntryCmp( void *entry, void *entryref ) -{ - mcEdge *edge, *edgeref; - edge = entry; - edgeref = entryref; - if( edge->v[0] == -1 ) - return MM_HASH_ENTRYCMP_INVALID; - if( ( edge->v[0] == edgeref->v[0] ) && ( edge->v[1] == edgeref->v[1] ) ) - return MM_HASH_ENTRYCMP_FOUND; - return MM_HASH_ENTRYCMP_SKIP; -} - -static mmHashAccess mcEdgeHashEdge = -{ - .clearentry = mcEdgeHashClearEntry, - .entryvalid = mcEdgeHashEntryValid, - .entrykey = mcEdgeHashEntryKey, - .entrycmp = mcEdgeHashEntryCmp -}; - - - -//// - - -typedef struct -{ - size_t vertexcount; - void *vertex; - int vertexwidth; - size_t vertexstride; - size_t tricount; - void *indices; - int indiceswidth; - size_t indicesstride; - long attemptcount; - int flags; - - void *edgehashtable; - mmBitMap tribitmap; - int processcount; - - mmBlockHead opblock; - - void (*indicesUserToNative)( mci *dst, void *src ); - void (*indicesNativeToUser)( void *dst, mci *src ); - void (*vertexUserToNative)( mcf *dst, void *src ); - void (*vertexNativeToUser)( void *dst, mcf *src ); - - ccQuickRandState32 randstate; - -} mcMesh; - - -static void mcIndicesInt8ToNative( mci *dst, void *src ) -{ - uint8_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mcIndicesInt16ToNative( mci *dst, void *src ) -{ - uint16_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mcIndicesInt32ToNative( mci *dst, void *src ) -{ - uint32_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mcIndicesInt64ToNative( mci *dst, void *src ) -{ - uint64_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - - -static void mcIndicesNativeToInt8( void *dst, mci *src ) -{ - uint8_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mcIndicesNativeToInt16( void *dst, mci *src ) -{ - uint16_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mcIndicesNativeToInt32( void *dst, mci *src ) -{ - uint32_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mcIndicesNativeToInt64( void *dst, mci *src ) -{ - uint64_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - - - -static void mcVertexFloatToNative( mcf *dst, void *src ) -{ - float *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mcVertexDoubleToNative( mcf *dst, void *src ) -{ - double *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mcVertexNativeToFloat( void *dst, mcf *src ) -{ - float *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mcVertexNativeToDouble( void *dst, mcf *src ) -{ - double *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - - -//// - - -static void *mcMeshHashInit( size_t trianglecount, mcf hashextrabits, uint32_t lockpageshift ) -{ - size_t edgecount, hashmemsize; - uint32_t hashbits, hashbitsmin, hashbitsmax; - void *edgehashtable; - - edgecount = trianglecount * 3; - - /* Hard minimum count of hash table bits */ -#if CPUCONF_WORD_SIZE == 64 - hashbitsmin = ccLog2Int64( edgecount ) + 1; -#else - hashbitsmin = ccLog2Int32( edgecount ) + 1; -#endif - hashbitsmax = hashbitsmin + 4; - - hashbits = (uint32_t)roundf( log2( (mcf)edgecount ) + hashextrabits ); - if( hashbits < hashbitsmin ) - hashbits = hashbitsmin; - else if( hashbits > hashbitsmax ) - hashbits = hashbitsmax; - - if( hashbits < 12 ) - hashbits = 12; - /* lockpageshift = 7; works great, 128 hash entries per lock page */ - if( lockpageshift < 3 ) - lockpageshift = 3; - else if( lockpageshift > 16 ) - lockpageshift = 16; - - hashmemsize = mmHashRequiredSize( sizeof(mcEdge), hashbits, lockpageshift ); - - edgehashtable = malloc( hashmemsize ); - if( !( edgehashtable ) ) - return 0; - - mmHashInit( edgehashtable, &mcEdgeHashEdge, sizeof(mcEdge), hashbits, lockpageshift, MM_HASH_FLAGS_NO_COUNT ); - - return edgehashtable; -} - - -void mcHashBuild( mcMesh *mesh ) -{ - mci triindex, indices[3]; - void *indsrc; - mcEdge edge; - - /* Build triangles, allow duplicate edges */ - indsrc = mesh->indices; - for( triindex = 0 ; triindex < mesh->tricount ; triindex++, indsrc = ADDRESS( indsrc, mesh->indicesstride ) ) - { - mesh->indicesUserToNative( indices, indsrc ); - edge.v[0] = indices[0]; - edge.v[1] = indices[1]; - edge.triindex = triindex; - if( mmHashDirectAddEntry( mesh->edgehashtable, &mcEdgeHashEdge, &edge, 0 ) != MM_HASH_SUCCESS ) - MC_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[0] = indices[1]; - edge.v[1] = indices[2]; - edge.triindex = triindex; - if( mmHashDirectAddEntry( mesh->edgehashtable, &mcEdgeHashEdge, &edge, 0 ) != MM_HASH_SUCCESS ) - MC_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[0] = indices[2]; - edge.v[1] = indices[0]; - edge.triindex = triindex; - if( mmHashDirectAddEntry( mesh->edgehashtable, &mcEdgeHashEdge, &edge, 0 ) != MM_HASH_SUCCESS ) - MC_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - return; -} - - -//// - - -typedef struct -{ - mcf vectorthreshold; - mcf segmentthreshold; - int inexactflag; -} mcIntersectInexact; - - -static int mcIntersectRayTriangle( mcf *src, mcf *vector, mcf *v0, mcf *v1, mcf *v2, mcf *hit, mcIntersectInexact *inexact ) -{ - mcf u[3], v[3], normal[3], sv0[3], planehit[3], w[3]; - mcf distance, num, denom; - mcf uu, uv, vv, wu, wv, d; - mcf s, t; -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - int inexactflag; -#endif - - M3D_VectorSubStore( u, v1, v0 ); - M3D_VectorSubStore( v, v2, v0 ); - M3D_VectorCrossProduct( normal, u, v ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " V0 : %f %f %f\n", v0[0], v0[1], v0[2] ); -printf( " V1 : %f %f %f\n", v1[0], v1[1], v1[2] ); -printf( " V2 : %f %f %f\n", v2[0], v2[1], v2[2] ); -printf( " Normal : %f %f %f\n", normal[0], normal[1], normal[2] ); -#endif - - denom = M3D_VectorDotProduct( normal, vector ); - -/* Dotproduct of normal,vector should be near mag(normal)*mag(vector) for high accuracy */ -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - mcf accuracy; - accuracy = fabs( denom ) / ( M3D_VectorMagnitude( normal ) * M3D_VectorMagnitude( vector ) ); -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Accuracy : %f\n", accuracy ); -#endif - if( accuracy < inexact->vectorthreshold ) - inexact->inexactflag = 1; -#endif - if( !( denom ) ) /* Ray is parallel to triangle, what about a robust check for near parallel? */ - return 0; - - M3D_VectorSubStore( sv0, src, v0 ); - num = -M3D_VectorDotProduct( normal, sv0 ); - distance = num / denom; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Distance : %f\n", distance ); -#endif - -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - if( distance < -inexact->segmentthreshold ) /* Ray aimed away from triangle plane */ - return 0; - inexactflag = 0; - if( ( distance > -inexact->segmentthreshold ) && ( distance < inexact->segmentthreshold ) ) - inexactflag = 1; -#else - if( distance < 0.0 ) /* Ray aimed away from triangle plane */ - return 0; -#endif - - uu = M3D_VectorDotProduct( u, u ); - uv = M3D_VectorDotProduct( u, v ); - vv = M3D_VectorDotProduct( v, v ); - d = ( uv * uv ) - ( uu * vv ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " D : %f\n", d ); -#endif - - if( !( d ) ) - return 0; - d = 1.0 / d; - - planehit[0] = src[0] + ( distance * vector[0] ); - planehit[1] = src[1] + ( distance * vector[1] ); - planehit[2] = src[2] + ( distance * vector[2] ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Planehit : %f %f %f\n", planehit[0], planehit[1], planehit[2] ); -#endif - - M3D_VectorSubStore( w, planehit, v0 ); - wu = M3D_VectorDotProduct( w, u ); - wv = M3D_VectorDotProduct( w, v ); - s = ( ( uv * wv ) - ( vv * wu ) ) * d; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " S : %f\n", s ); -#endif - - if( ( s < 0.0 ) || ( s > 1.0 ) ) - return 0; - t = ( ( uv * wu ) - ( uu * wv ) ) * d; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " T : %f\n", t ); -#endif - - if( ( t < 0.0 ) || ( ( s + t ) > 1.0 ) ) - return 0; -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - inexact->inexactflag = inexactflag; - if( distance < 0.0 ) /* Ray aimed away from triangle plane */ - return 0; -#endif - M3D_VectorCopy( hit, planehit ); - return 1; -} - - -static int mcIntersectSegmentTriangle( mcf *src, mcf *dst, mcf *v0, mcf *v1, mcf *v2, mcf *hit, mcIntersectInexact *inexact ) -{ - mcf u[3], v[3], normal[3], vector[3], sv0[3], planehit[3], w[3]; - mcf distance, num, denom; - mcf uu, uv, vv, wu, wv, d; - mcf s, t; -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - int inexactflag; -#endif - - M3D_VectorSubStore( u, v1, v0 ); - M3D_VectorSubStore( v, v2, v0 ); - M3D_VectorCrossProduct( normal, u, v ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " V0 : %f %f %f\n", v0[0], v0[1], v0[2] ); -printf( " V1 : %f %f %f\n", v1[0], v1[1], v1[2] ); -printf( " V2 : %f %f %f\n", v2[0], v2[1], v2[2] ); -printf( " Normal : %f %f %f\n", normal[0], normal[1], normal[2] ); -#endif - - M3D_VectorSubStore( vector, dst, src ); - denom = M3D_VectorDotProduct( normal, vector ); - -/* Dotproduct of normal,vector should be near mag(normal)*mag(vector) for high accuracy */ -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - mcf accuracy; - accuracy = fabs( denom ) / ( M3D_VectorMagnitude( normal ) * M3D_VectorMagnitude( vector ) ); -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Accuracy : %f\n", accuracy ); -#endif - if( accuracy < inexact->vectorthreshold ) - inexact->inexactflag = 1; -#endif - if( !( denom ) ) /* Ray is parallel to triangle, what about a robust check for near parallel? */ - return 0; - - M3D_VectorSubStore( sv0, src, v0 ); - num = -M3D_VectorDotProduct( normal, sv0 ); - distance = num / denom; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Distance : %f\n", distance ); -#endif - -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - if( distance < -inexact->segmentthreshold ) /* Ray aimed away from triangle plane */ - return 0; - if( distance > (1.0+inexact->segmentthreshold) ) /* Ray/Plane intersection is beyond segment */ - return 0; - inexactflag = 0; - if( ( distance > -inexact->segmentthreshold ) && ( distance < inexact->segmentthreshold ) ) - inexactflag = 1; - if( ( distance > (1.0-inexact->segmentthreshold) ) && ( distance < (1.0+inexact->segmentthreshold) ) ) - inexactflag = 1; -#else - if( distance < 0.0 ) /* Ray aimed away from triangle plane */ - return 0; - if( distance > 1.0 ) /* Ray/Plane intersection is beyond segment */ - return 0; -#endif - - uu = M3D_VectorDotProduct( u, u ); - uv = M3D_VectorDotProduct( u, v ); - vv = M3D_VectorDotProduct( v, v ); - d = ( uv * uv ) - ( uu * vv ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " D : %f\n", d ); -#endif - - if( !( d ) ) - return 0; - d = 1.0 / d; - - planehit[0] = src[0] + ( distance * vector[0] ); - planehit[1] = src[1] + ( distance * vector[1] ); - planehit[2] = src[2] + ( distance * vector[2] ); - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " Planehit : %f %f %f\n", planehit[0], planehit[1], planehit[2] ); -#endif - - M3D_VectorSubStore( w, planehit, v0 ); - wu = M3D_VectorDotProduct( w, u ); - wv = M3D_VectorDotProduct( w, v ); - s = ( ( uv * wv ) - ( vv * wu ) ) * d; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " S : %f\n", s ); -#endif - - if( ( s < 0.0 ) || ( s > 1.0 ) ) - return 0; - t = ( ( uv * wu ) - ( uu * wv ) ) * d; - -#ifdef DEBUG_VERBOSE_TRITEST -printf( " T : %f\n", t ); -#endif - - if( ( t < 0.0 ) || ( ( s + t ) > 1.0 ) ) - return 0; -#ifdef MC_ENABLE_INEXACTFLAG_SUPPORT - inexact->inexactflag = inexactflag; - if( distance < 0.0 ) /* Ray aimed away from triangle plane */ - return 0; - if( distance > 1.0 ) /* Ray/Plane intersection is beyond segment */ - return 0; -#endif - M3D_VectorCopy( hit, planehit ); - return 1; -} - - -//// - - -#define MC_SEED_TRIBUFFER_SIZE (256) - -static int mcGetSeedtriangle( mcMesh *mesh ) -{ - int attemptcount, tribuffercount, bufferoffset; - mci tribuffer[MC_SEED_TRIBUFFER_SIZE]; - mci triindex, bufferindex, seedindex; - mci indices[3], indtemp, bestvertexindex; - mcf refplane[4]; - mcf distance, bestdistance, worstdistance, midpoint[3], signfactor, middistance, dispdistance; - mcf raysrc[3], raydst[3], rayvector[3]; - void *indsrc; - void *vertex0, *vertex1, *vertex2; - mcf v0f[3], v1f[3], v2f[3]; - mcf vecta[3], vectb[3], normal[3]; - mcIntersectInexact inexact; - -#ifdef DEBUG_VERBOSE -printf( "\nNew Seed Search\n" ); -#endif - - /* Set up initial exactitude thresholds */ - inexact.vectorthreshold = MC_INEXACT_VECTOR_THRESHOLD; - inexact.segmentthreshold = MC_INEXACT_SEGMENT_THRESHOLD; - - /* Attempt multiple times in the rare case where we would detect numerical accuracy issues with the reference plane picked */ - tribuffercount = 0; - for( attemptcount = 0 ; attemptcount < MC_SEED_ATTEMPT_COUNT_MAX ; attemptcount++ ) - { - inexact.inexactflag = 0; - - /* Give up after a certain count of global attempts */ - if( --mesh->attemptcount < 0 ) - return -1; - -#ifdef DEBUG_VERBOSE -printf( "Attempt : %d\n", attemptcount ); -#endif - - for( ; ; ) - { - refplane[0] = ( (mcf)( ccQuickRand32( &mesh->randstate ) & 0xffff ) / 65535.0 ) - 0.5; - refplane[1] = ( (mcf)( ccQuickRand32( &mesh->randstate ) & 0xffff ) / 65535.0 ) - 0.5; - refplane[2] = ( (mcf)( ccQuickRand32( &mesh->randstate ) & 0xffff ) / 65535.0 ) - 0.5; - if( M3D_VectorMagnitude( refplane ) > 0.01 ) - break; - } - M3D_VectorNormalize( refplane ); - refplane[3] = 0.0; - -#ifdef DEBUG_VERBOSE -printf( "Refplane : %f %f %f %f\n", refplane[0], refplane[1], refplane[2], refplane[3] ); -#endif - - /* Loop through all unused triangles, find the right-most vertex and buffer up all triangles that connect to it */ - bestdistance = -FLT_MAX; - worstdistance = FLT_MAX; - bestvertexindex = -1; - for( triindex = 0 ; triindex < mesh->tricount ; triindex++ ) - { - /* Skip triangles that have already been checked */ - if( mmBitMapDirectGet( &mesh->tribitmap, triindex ) ) - continue; - /* Get triangle indices */ - indsrc = ADDRESS( mesh->indices, triindex * mesh->indicesstride ); - mesh->indicesUserToNative( indices, indsrc ); - vertex0 = ADDRESS( mesh->vertex, indices[0] * mesh->vertexstride ); - vertex1 = ADDRESS( mesh->vertex, indices[1] * mesh->vertexstride ); - vertex2 = ADDRESS( mesh->vertex, indices[2] * mesh->vertexstride ); - - /* Find most distant vertex from plane */ - mesh->vertexUserToNative( v0f, vertex0 ); - mesh->vertexUserToNative( v1f, vertex1 ); - mesh->vertexUserToNative( v2f, vertex2 ); - distance = M3D_PlanePoint( refplane, v0f ); - if( distance > bestdistance ) - { - bestdistance = distance; - bestvertexindex = indices[0]; - tribuffercount = 0; - } - worstdistance = fmin( worstdistance, distance ); - distance = M3D_PlanePoint( refplane, v1f ); - if( distance > bestdistance ) - { - bestdistance = distance; - bestvertexindex = indices[1]; - tribuffercount = 0; - } - worstdistance = fmin( worstdistance, distance ); - distance = M3D_PlanePoint( refplane, v2f ); - if( distance > bestdistance ) - { - bestdistance = distance; - bestvertexindex = indices[2]; - tribuffercount = 0; - } - worstdistance = fmin( worstdistance, distance ); - - /* If triangle doesn't connect our bestvertex, do not buffer up */ - if( ( indices[0] != bestvertexindex ) && ( indices[1] != bestvertexindex ) && ( indices[2] != bestvertexindex ) ) - continue; - - /* Accumulate triangles sharing the vertex */ - if( tribuffercount >= MC_SEED_TRIBUFFER_SIZE ) - break; - tribuffer[tribuffercount++] = triindex; - -#ifdef DEBUG_VERBOSE -printf( " Seed Buffer Up %d : %d\n", tribuffercount-1, triindex ); -#endif - } - -#ifdef DEBUG_VERBOSE -printf( "Seed Buffer Count : %d\n", tribuffercount ); -#endif - - /* No buffered triangle means all triangles have been processed */ - if( !( tribuffercount ) ) - return -1; - - /* Trace a ray from outside towards the center of a buffer triangle */ - seedindex = -1; - bufferoffset = ccQuickRand32( &mesh->randstate ) % tribuffercount; - for( bufferindex = 0 ; bufferindex < tribuffercount ; bufferindex++ ) - { - triindex = tribuffer[ ( bufferindex + bufferoffset ) % tribuffercount ]; - indsrc = ADDRESS( mesh->indices, triindex * mesh->indicesstride ); - mesh->indicesUserToNative( indices, indsrc ); - vertex0 = ADDRESS( mesh->vertex, indices[0] * mesh->vertexstride ); - vertex1 = ADDRESS( mesh->vertex, indices[1] * mesh->vertexstride ); - vertex2 = ADDRESS( mesh->vertex, indices[2] * mesh->vertexstride ); - mesh->vertexUserToNative( v0f, vertex0 ); - mesh->vertexUserToNative( v1f, vertex1 ); - mesh->vertexUserToNative( v2f, vertex2 ); - - /* Set the ray origin to midpoint of triangle displaced on target axis */ - midpoint[0] = (1.0/3.0) * ( v0f[0] + v1f[0] + v2f[0] ); - midpoint[1] = (1.0/3.0) * ( v0f[1] + v1f[1] + v2f[1] ); - midpoint[2] = (1.0/3.0) * ( v0f[2] + v1f[2] + v2f[2] ); - -#ifdef DEBUG_VERBOSE -printf( " Target Midpoint : %f %f %f\n", midpoint[0], midpoint[1], midpoint[2] ); -#endif - - /* Define ray origin as beyond plane, perpendicular to plane normal, heading towards midpoint */ - middistance = M3D_PlanePoint( refplane, midpoint ); - dispdistance = bestdistance - middistance; - - /* Displace origin a little beyond the plane */ - dispdistance += fmax( (1.0/16.0) * ( bestdistance - worstdistance ), 0.000001 ); - - raysrc[0] = midpoint[0] + ( dispdistance * refplane[0] ); - raysrc[1] = midpoint[1] + ( dispdistance * refplane[1] ); - raysrc[2] = midpoint[2] + ( dispdistance * refplane[2] ); - - /* Trace ray, store intersection point into raydst */ - rayvector[0] = midpoint[0] - raysrc[0]; - rayvector[1] = midpoint[1] - raysrc[1]; - rayvector[2] = midpoint[2] - raysrc[2]; - -#ifdef DEBUG_VERBOSE -printf( " Ray src : %f %f %f\n", raysrc[0], raysrc[1], raysrc[2] ); -printf( " Vector : %f %f %f\n", rayvector[0], rayvector[1], rayvector[2] ); -#endif - - if( mcIntersectRayTriangle( raysrc, rayvector, v0f, v1f, v2f, raydst, &inexact ) ) - { - seedindex = triindex; - break; - } - } - - /* If no triangle was hit by our ray, try again with a new reference plane */ - if( seedindex == -1 ) - { -#ifdef DEBUG_VERBOSE -printf( " No intersection found in limit vertex!\n" ); -#endif - continue; - } - -#ifdef DEBUG_VERBOSE -printf( " Current Seed : %d\n", triindex ); -#endif - - /* Find the first hit along ray */ - for( triindex = 0 ; triindex < mesh->tricount ; triindex++ ) - { - /* Skip triangles that have already been checked */ - if( ( attemptcount >= MC_SEED_ATTEMPT_SAFETY_THRESHOLD ) && ( mmBitMapDirectGet( &mesh->tribitmap, triindex ) ) ) - continue; - - indsrc = ADDRESS( mesh->indices, triindex * mesh->indicesstride ); - mesh->indicesUserToNative( indices, indsrc ); - vertex0 = ADDRESS( mesh->vertex, indices[0] * mesh->vertexstride ); - vertex1 = ADDRESS( mesh->vertex, indices[1] * mesh->vertexstride ); - vertex2 = ADDRESS( mesh->vertex, indices[2] * mesh->vertexstride ); - mesh->vertexUserToNative( v0f, vertex0 ); - mesh->vertexUserToNative( v1f, vertex1 ); - mesh->vertexUserToNative( v2f, vertex2 ); - - /* Check if that triangle is on top of our current target */ - if( mcIntersectSegmentTriangle( raysrc, raydst, v0f, v1f, v2f, raydst, &inexact ) ) - { -#ifdef DEBUG_VERBOSE -printf( " New Hit %d : %f %f %f\n", triindex, raydst[0], raydst[1], raydst[2] ); -#endif - seedindex = triindex; - } - } - - /* If seedindex has already been processed, try again without modifying thresholds */ - if( mmBitMapDirectGet( &mesh->tribitmap, seedindex ) ) - continue; - -#ifdef DEBUG_VERBOSE -printf( " Seed Found %d ; Inexactflag %d\n", seedindex, inexact.inexactflag ); -#endif - - /* We may hit floating point inaccuracy issues somewhere in our calculations */ - /* If inexactflag is raised, do NOT accept the result, pick a different reference plane and try again */ - if( !( inexact.inexactflag ) ) - break; - - /* For the next pass, reduce accuracy thresholds a little */ - inexact.vectorthreshold *= MC_INEXACT_THRESHOLD_ATTEMPT_FACTOR; - inexact.segmentthreshold *= MC_INEXACT_THRESHOLD_ATTEMPT_FACTOR; -#ifdef DEBUG_VERBOSE -printf( " Inexact Thresholds : %f %f\n", inexact.vectorthreshold, inexact.segmentthreshold ); -#endif - } - - if( seedindex == -1 ) - return -1; - - /* We now know that our target triangle should have a normal looking away from our rayvector */ - mesh->indicesUserToNative( indices, ADDRESS( mesh->indices, seedindex * mesh->indicesstride ) ); - vertex0 = ADDRESS( mesh->vertex, indices[0] * mesh->vertexstride ); - vertex1 = ADDRESS( mesh->vertex, indices[1] * mesh->vertexstride ); - vertex2 = ADDRESS( mesh->vertex, indices[2] * mesh->vertexstride ); - mesh->vertexUserToNative( v0f, vertex0 ); - mesh->vertexUserToNative( v1f, vertex1 ); - mesh->vertexUserToNative( v2f, vertex2 ); - - /* Compute normal of triangle to decide if we need to flip */ - M3D_VectorSubStore( vecta, v1f, v0f ); - M3D_VectorSubStore( vectb, v2f, v0f ); - M3D_VectorCrossProduct( normal, vectb, vecta ); - signfactor = 1.0; - if( mesh->flags & MC_FLAGS_TRIANGLE_WINDING_CCW ) - signfactor = -1.0; - -#ifdef DEBUG_VERBOSE -printf( "Seed Normal : %f %f %f\n", normal[0], normal[1], normal[2] ); -printf( "Ray Vector : %f %f %f\n", rayvector[0], rayvector[1], rayvector[2] ); -#endif - - if( ( signfactor * M3D_VectorDotProduct( normal, rayvector ) ) > 0.0 ) - { -#ifdef DEBUG_VERBOSE -printf( "Seed %d ; %d %d %d, Flip True\n", seedindex, (int)indices[0], (int)indices[1], (int)indices[2] ); -#endif - /* If facing towards ray, seed triangle requires flipping */ - indtemp = indices[2]; - indices[2] = indices[1]; - indices[1] = indtemp; - mesh->indicesNativeToUser( ADDRESS( mesh->indices, seedindex * mesh->indicesstride ), indices ); - } - else - { -#ifdef DEBUG_VERBOSE -printf( "Seed %d ; %d %d %d, Flip False\n", seedindex, (int)indices[0], (int)indices[1], (int)indices[2] ); -#endif - } - mmBitMapDirectSet( &mesh->tribitmap, seedindex ); - - mesh->processcount++; - return seedindex; -} - - -//// - - -typedef struct -{ - int tricount; - int trialloc; - mci *trilist; -} mcEdgeTriBuffer; - -static int mcEdgeTriBufferInit( mcEdgeTriBuffer *tribuffer ) -{ - tribuffer->tricount = 0; - tribuffer->trialloc = 256; - tribuffer->trilist = malloc( tribuffer->trialloc * sizeof(mci) ); - return 1; -} - -static void mcEdgeTriBufferReset( mcEdgeTriBuffer *tribuffer ) -{ - tribuffer->tricount = 0; - return; -} - -static int mcEdgeTriBufferAdd( mcEdgeTriBuffer *tribuffer, mci triindex ) -{ - if( tribuffer->tricount >= tribuffer->trialloc ) - { - tribuffer->trialloc <<= 1; - tribuffer->trilist = realloc( tribuffer->trilist, tribuffer->trialloc * sizeof(mci) ); - } - tribuffer->trilist[tribuffer->tricount++] = triindex; - return 1; -} - -static void mcEdgeTriBufferFree( mcEdgeTriBuffer *tribuffer ) -{ - free( tribuffer->trilist ); - return; -} - - -//// - - -static int mcEdgeHashListBufferAdd( void *opaque, void *entry, void *entryref ) -{ - mcEdge *edge, *edgeref; - mcEdgeTriBuffer *tribuffer; - - edge = entry; - edgeref = entryref; - if( edge->v[0] == -1 ) - return MM_HASH_ENTRYLIST_BREAK; - if( ( edge->v[0] == edgeref->v[0] ) && ( edge->v[1] == edgeref->v[1] ) && ( edge->triindex != edgeref->triindex ) ) - { - tribuffer = opaque; - mcEdgeTriBufferAdd( tribuffer, edge->triindex ); - } - return MM_HASH_ENTRYLIST_CONTINUE; -} - - -static mmHashAccess mcEdgeHashBufferAdd = -{ - .clearentry = mcEdgeHashClearEntry, - .entryvalid = mcEdgeHashEntryValid, - .entrykey = mcEdgeHashEntryKey, - .entrycmp = mcEdgeHashEntryCmp, - .entrylist = mcEdgeHashListBufferAdd -}; - -static void mcQueueNewOp( mcMesh *mesh, void **oplist, mci v0, mci v1, mci triindex ) -{ - mcOp *op; - op = mmBlockAlloc( &mesh->opblock ); - op->v0 = v0; - op->v1 = v1; - op->triindex = triindex; - -#ifdef DEBUG_VERBOSE -printf( " Queue New Op ; Edge %d %d ; Triindex %d\n", v0, v1, triindex ); -#endif - - mmListAdd( oplist, op, offsetof(mcOp,list) ); - return; -} - - -static void mcPerformCorrection( mcMesh *mesh ) -{ - int flipflag; - mci seedindex, triindex; - mcEdge edge; - mcEdgeTriBuffer tribuffer; - mci indices[3], indtemp; - mcOp *op; - void *oplist; - - mcEdgeTriBufferInit( &tribuffer ); - - mesh->processcount = 0; - oplist = 0; - for( ; ; ) - { - /* Find new seed triangles */ - seedindex = mcGetSeedtriangle( mesh ); - if( seedindex == -1 ) - break; - - /* Add the 3 edges of seed to op list */ - mesh->indicesUserToNative( indices, ADDRESS( mesh->indices, seedindex * mesh->indicesstride ) ); - mcQueueNewOp( mesh, &oplist, indices[0], indices[1], seedindex ); - mcQueueNewOp( mesh, &oplist, indices[1], indices[2], seedindex ); - mcQueueNewOp( mesh, &oplist, indices[2], indices[0], seedindex ); - -#ifdef DEBUG_VERBOSE -printf( " Queued Seed %d %d %d\n", (int)indices[0], (int)indices[1], (int)indices[2] ); -#endif - - /* Process all pending edges */ - for( op = oplist ; op ; op = oplist ) - { -#ifdef DEBUG_VERBOSE -printf( " Op %d %d, triindex %d\n", (int)op->v0, (int)op->v1, (int)op->triindex ); -#endif - - /* Accumulate results for edge in both direction */ - mcEdgeTriBufferReset( &tribuffer ); - edge.triindex = op->triindex; - edge.v[0] = op->v0; - edge.v[1] = op->v1; - mmHashDirectListEntry( mesh->edgehashtable, &mcEdgeHashBufferAdd, &edge, &tribuffer ); - edge.v[0] = op->v1; - edge.v[1] = op->v0; - mmHashDirectListEntry( mesh->edgehashtable, &mcEdgeHashBufferAdd, &edge, &tribuffer ); - -#ifdef DEBUG_VERBOSE -printf( " Tribuffercount : %d\n", tribuffer.tricount ); -#endif - - /* If edge is uncertain due to multiple linked edges, do not process */ - if( tribuffer.tricount != 1 ) - goto next; - - /* If linked triangle has already been processed, check */ - triindex = tribuffer.trilist[0]; - - /* Check if we have already processed that edge */ - if( mmBitMapDirectGet( &mesh->tribitmap, triindex ) ) - { -#ifdef DEBUG_VERBOSE -printf( " Skip Triindex %d\n", (int)triindex ); -#endif - goto next; - } - -#ifdef DEBUG_VERBOSE -printf( " Linked Triindex %d\n", (int)triindex ); -#endif - - /* Check the linked triangle, flip if it doesn't face the same way */ - flipflag = 0; - mesh->indicesUserToNative( indices, ADDRESS( mesh->indices, triindex * mesh->indicesstride ) ); - if( indices[0] == op->v0 ) - { - if( indices[1] == op->v1 ) - flipflag = 1; - } - else if( indices[1] == op->v0 ) - { - if( indices[2] == op->v1 ) - flipflag = 1; - } - else if( indices[2] == op->v0 ) - { - if( indices[0] == op->v1 ) - flipflag = 1; - } - else - MC_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - -#ifdef DEBUG_VERBOSE -printf( " Walk %d %d %d, Flipflag %d\n", (int)indices[0], (int)indices[1], (int)indices[2], flipflag ); -#endif - - /* If necessary, flip the indices and write them back */ - mmBitMapDirectSet( &mesh->tribitmap, triindex ); - mesh->processcount++; - if( flipflag ) - { - indtemp = indices[2]; - indices[2] = indices[1]; - indices[1] = indtemp; - mesh->indicesNativeToUser( ADDRESS( mesh->indices, triindex * mesh->indicesstride ), indices ); - } - - /* Add all edges except the one we come from */ - if( ( ( indices[0] != op->v0 ) || ( indices[1] != op->v1 ) ) && ( ( indices[0] != op->v1 ) || ( indices[1] != op->v0 ) ) ) - mcQueueNewOp( mesh, &oplist, indices[0], indices[1], triindex ); - if( ( ( indices[1] != op->v0 ) || ( indices[2] != op->v1 ) ) && ( ( indices[1] != op->v1 ) || ( indices[2] != op->v0 ) ) ) - mcQueueNewOp( mesh, &oplist, indices[1], indices[2], triindex ); - if( ( ( indices[2] != op->v0 ) || ( indices[0] != op->v1 ) ) && ( ( indices[2] != op->v1 ) || ( indices[0] != op->v0 ) ) ) - mcQueueNewOp( mesh, &oplist, indices[2], indices[0], triindex ); - - next: - /* Remove op from list and free */ - mmListRemove( op, offsetof(mcOp,list) ); - mmBlockRelease( &mesh->opblock, op ); - } - } - - mcEdgeTriBufferFree( &tribuffer ); - - return; -} - - -int mcMeshCorrection( size_t vertexcount, void *vertex, int vertexwidth, size_t vertexstride, size_t tricount, void *indices, int indiceswidth, size_t indicesstride, long attemptcount, int flags ) -{ - mcMesh mesh; - - mesh.vertexcount = vertexcount; - mesh.vertex = vertex; - mesh.vertexwidth = vertexwidth; - mesh.vertexstride = vertexstride; - mesh.tricount = tricount; - mesh.indices = indices; - mesh.indiceswidth = indiceswidth; - mesh.indicesstride = indicesstride; - mesh.attemptcount = attemptcount; - mesh.flags = flags; - - switch( indiceswidth ) - { - case sizeof(uint8_t): - mesh.indicesUserToNative = mcIndicesInt8ToNative; - mesh.indicesNativeToUser = mcIndicesNativeToInt8; - break; - case sizeof(uint16_t): - mesh.indicesUserToNative = mcIndicesInt16ToNative; - mesh.indicesNativeToUser = mcIndicesNativeToInt16; - break; - case sizeof(uint32_t): - mesh.indicesUserToNative = mcIndicesInt32ToNative; - mesh.indicesNativeToUser = mcIndicesNativeToInt32; - break; - case sizeof(uint64_t): - mesh.indicesUserToNative = mcIndicesInt64ToNative; - mesh.indicesNativeToUser = mcIndicesNativeToInt64; - break; - default: - return 0; - } - switch( vertexwidth ) - { - case sizeof(float): - mesh.vertexUserToNative = mcVertexFloatToNative; - mesh.vertexNativeToUser = mcVertexNativeToFloat; - break; - case sizeof(double): - mesh.vertexUserToNative = mcVertexDoubleToNative; - mesh.vertexNativeToUser = mcVertexNativeToDouble; - break; - default: - return 0; - } - if( tricount < 1 ) - return 0; - - ccQuickRand32Seed( &mesh.randstate, time(0) + tricount ); - - mesh.edgehashtable = mcMeshHashInit( tricount, 1.5, 7 ); - if( !( mesh.edgehashtable ) ) - return 0; - mmBitMapInit( &mesh.tribitmap, tricount, 0 ); - mmBlockInit( &mesh.opblock, sizeof(mcOp), 16384, 16384, 0x10 ); - - mcHashBuild( &mesh ); - - mcPerformCorrection( &mesh ); - -#ifdef DEBUG_VERBOSE -printf( "Final Process Count : %d\n", mesh.processcount ); -#endif - - free( mesh.edgehashtable ); - mmBitMapFree( &mesh.tribitmap ); - mmBlockFreeAll( &mesh.opblock ); - - return 1; -} - - - - diff --git a/src/other/gct/MeshDecimation/meshcorrection.h b/src/other/gct/MeshDecimation/meshcorrection.h deleted file mode 100644 index 2f705798a4d..00000000000 --- a/src/other/gct/MeshDecimation/meshcorrection.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#ifdef __cplusplus -extern "C" { -#endif - - -int mcMeshCorrection( size_t vertexcount, void *vertex, int vertexwidth, size_t vertexstride, size_t tricount, void *indices, int indiceswidth, size_t indicesstride, long attemptcount, int flags ) -; - -#define MC_FLAGS_TRIANGLE_WINDING_CW (0x1) -#define MC_FLAGS_TRIANGLE_WINDING_CCW (0x2) - - -#ifdef __cplusplus -} -#endif - diff --git a/src/other/gct/MeshDecimation/meshdecimation.c b/src/other/gct/MeshDecimation/meshdecimation.c deleted file mode 100644 index 7cd84ab3408..00000000000 --- a/src/other/gct/MeshDecimation/meshdecimation.c +++ /dev/null @@ -1,4334 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -#include "mm.h" -#include "mmhash.h" -#include "math3d.h" - -#include "mmbinsort.h" -#include "meshdecimation.h" - - -#ifdef __SSE__ - #include -#endif -#ifdef __SSE2__ - #include -#endif -#ifdef __SSE3__ - #include -#endif -#ifdef __SSSE3__ - #include -#endif -#ifdef __SSE4A__ - #include -#endif -#ifdef __SSE4_1__ - #include -#endif - - - - - -/* Define to use double floating point precision */ -/* -#define MD_CONF_DOUBLE_PRECISION -*/ - - -/* Define to use double precision just quadric maths. Very strongly recommended. */ -#define MD_CONF_QUADRICS_DOUBLE_PRECISION - - - -#define MD_CONF_ENABLE_PROGRESS - - - -/* -#define DEBUG_VERBOSE - -#define DEBUG_VERBOSE_QUADRIC -#define DEBUG_VERBOSE_BOUNDARY -#define DEBUG_VERBOSE_COLLISION -#define DEBUG_VERBOSE_PENALTY -#define DEBUG_VERBOSE_COLLAPSE -#define DEBUG_VERBOSE_EVALUATE -#define DEBUG_VERBOSE_MEMORY -*/ - - -/* -#define DEBUG_LIMIT (8000) -*/ -/* -#define DEBUG_LIMIT (1) -*/ -/* -#define DEBUG_DEBUG -*/ - - - -#ifdef DEBUG_VERBOSE - #define MD_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);if(f) exit(1);}) -#else - #define MD_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);}) -#endif - - - - -#ifdef CPUCONF_CORES_COUNT - #define MD_THREAD_COUNT_DEFAULT CPUCONF_CORES_COUNT -#else - #define MD_THREAD_COUNT_DEFAULT (4) -#endif -#define MD_THREAD_COUNT_MAX (64) - - - -/**/ - - - -#define MD_BOUNDARY_WEIGHT (5.0) -/* -#define MD_COLLAPSE_PENALTY_COMPACT_TARGET (0.4) - -#define MD_COLLAPSE_PENALTY_COMPACT_FACTOR (0.025) -*/ -#define MD_COLLAPSE_PENALTY_COMPACT_TARGET (0.25) - -#define MD_COLLAPSE_PENALTY_COMPACT_FACTOR (0.00125) - -#define MD_GLOBAL_LOCK_THRESHOLD (16) - - - -/**/ - - - -/* Required with multithreading! */ -#define MD_CONFIG_DELAYED_OP_REDIRECT - - - -#ifdef MM_ATOMIC_SUPPORT - #define MD_CONFIG_ATOMIC_SUPPORT -#endif - - -#if defined(CPUCONF_ARCH_AMD64) || defined(CPUCONF_ARCH_IA32) - #define MD_CONFIG_SSE_SUPPORT -#endif - - - -#define MD_CONFIG_FAST_HASH - - - -#define MD_CONFIG_HIGH_QUADRICS - - - -#define MD_CONFIG_AREA_QUADRICS - - - - -/**/ - - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - #define RF_ALIGN16 __attribute__((aligned(16))) - #define RF_ALIGN64 __attribute__((aligned(64))) -#elif defined(_MSC_VER) - #define RF_ALIGN16 __declspec(align(16)) - #define RF_ALIGN64 __declspec(align(64)) -#else - #define RF_ALIGN16 - #define RF_ALIGN64 - #ifdef MD_CONFIG_SSE_SUPPORT - #undef MD_CONFIG_SSE_SUPPORT - #endif -#endif - - -#ifdef MD_CONFIG_SSE_SUPPORT -extern int mdPathSSE4p1; -float mdEdgeCollapsePenaltyTriangleSSE4p1f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ); -double mdEdgeCollapsePenaltyTriangleSSE4p1d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ); -extern int mdPathSSE3; -float mdEdgeCollapsePenaltyTriangleSSE3f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ); -double mdEdgeCollapsePenaltyTriangleSSE3d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ); -extern int mdPathSSE2; -float mdEdgeCollapsePenaltyTriangleSSE2f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ); -double mdEdgeCollapsePenaltyTriangleSSE2d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ); -#endif - - -#ifndef M_PI - #define M_PI 3.14159265358979323846264338327 -#endif - - - -/**/ - - -static int mdInitFlag = 0; - -static cpuInfo mdCpuInfo; - - -/**/ - - -#ifdef MD_CONF_DOUBLE_PRECISION -typedef double mdf; - #define mdfmin(x,y) fmin((x),(y)) - #define mdfmax(x,y) fmax((x),(y)) - #define mdffloor(x) floor(x) - #define mdfceil(x) ceil(x) - #define mdfround(x) round(x) - #define mdfsqrt(x) sqrt(x) - #define mdfcbrt(x) cbrt(x) - #define mdfabs(x) fabs(x) - #define mdflog2(x) log2(x) - #define mdfacos(x) acos(x) -#else -typedef float mdf; - #define mdfmin(x,y) fminf((x),(y)) - #define mdfmax(x,y) fmaxf((x),(y)) - #define mdffloor(x) floorf(x) - #define mdfceil(x) ceilf(x) - #define mdfround(x) roundf(x) - #define mdfsqrt(x) sqrtf(x) - #define mdfcbrt(x) cbrtf(x) - #define mdfabs(x) fabsf(x) - #define mdflog2(x) log2f(x) - #define mdfacos(x) acosf(x) -#endif - -#ifdef MD_CONF_DOUBLE_PRECISION - #ifndef MD_CONF_QUADRICS_DOUBLE_PRECISION - #define MD_CONF_QUADRICS_DOUBLE_PRECISION - #endif -#endif - - -#ifdef MD_CONF_QUADRICS_DOUBLE_PRECISION -typedef double mdqf; -#else -typedef float mdqf; -#endif -/* -typedef __float128 mdqf; -*/ -#ifdef MD_CONFIG_HIGH_QUADRICS - #if ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 ) ) && !defined(__INTEL_COMPILER) && ( defined(__i386__) || defined(__x86_64__) || defined(__ia64__) ) -typedef __float128 mdqfhigh; - #else - #undef MD_CONFIG_HIGH_QUADRICS - #endif -#endif - - -#define MD_SIZEOF_MDI (4) -typedef int32_t mdi; - - - -typedef struct -{ - mdqf area; - mdqf a2, ab, ac, ad; - mdqf b2, bc, bd; - mdqf c2, cd; -#ifdef MD_CONFIG_HIGH_QUADRICS - mdqfhigh d2; -#else - mdqf d2; -#endif -} mathQuadric; - -static void mathQuadricInit( mathQuadric *q, mdqf a, mdqf b, mdqf c, mdqf d, mdqf area ) -{ - q->area = area; - - q->a2 = a*a; - q->ab = a*b; - q->ac = a*c; - q->ad = a*d; - q->b2 = b*b; - q->bc = b*c; - q->bd = b*d; - q->c2 = c*c; - q->cd = c*d; -#ifdef MD_CONFIG_HIGH_QUADRICS - q->d2 = (mdqfhigh)d*(mdqfhigh)d; -#else - q->d2 = d*d; -#endif - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Q Init %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)q->area, (double)q->a2, (double)q->ab, (double)q->ac, (double)q->ad, (double)q->b2, (double)q->bc, (double)q->bd, (double)q->c2, (double)q->cd, (double)q->d2 ); -#endif - - return; -} - - - -//// - - - -static mdqf mathMatrix3x3Determinant( mdqf *m ) -{ - mdqf det; - det = m[0*3+0] * ( m[2*3+2] * m[1*3+1] - m[2*3+1] * m[1*3+2] ); - det -= m[1*3+0] * ( m[2*3+2] * m[0*3+1] - m[2*3+1] * m[0*3+2] ); - det += m[2*3+0] * ( m[1*3+2] * m[0*3+1] - m[1*3+1] * m[0*3+2] ); - return det; -} - -static void mathMatrix3x3MulVector( mdqf *vdst, mdqf *m, mdqf *v ) -{ - vdst[0] = v[0] * m[0*3+0] + v[1] * m[1*3+0] + v[2] * m[2*3+0]; - vdst[1] = v[0] * m[0*3+1] + v[1] * m[1*3+1] + v[2] * m[2*3+1]; - vdst[2] = v[0] * m[0*3+2] + v[1] * m[1*3+2] + v[2] * m[2*3+2]; - return; -} - - -static void mathQuadricToMatrix3x3( mdqf *m, mathQuadric *q ) -{ - m[0*3+0] = q->a2; - m[0*3+1] = q->ab; - m[0*3+2] = q->ac; - m[1*3+0] = q->ab; - m[1*3+1] = q->b2; - m[1*3+2] = q->bc; - m[2*3+0] = q->ac; - m[2*3+1] = q->bc; - m[2*3+2] = q->c2; - return; -} - - -static void mathMatrix3x3Invert( mdqf *mdst, mdqf *m, mdqf det ) -{ - mdf detinv; - detinv = 1.0 / det; - mdst[0*3+0] = ( m[2*3+2] * m[1*3+1] - m[2*3+1] * m[1*3+2] ) * detinv; - mdst[0*3+1] = -( m[2*3+2] * m[0*3+1] - m[2*3+1] * m[0*3+2] ) * detinv; - mdst[0*3+2] = ( m[1*3+2] * m[0*3+1] - m[1*3+1] * m[0*3+2] ) * detinv; - mdst[1*3+0] = -( m[2*3+2] * m[1*3+0] - m[2*3+0] * m[1*3+2] ) * detinv; - mdst[1*3+1] = ( m[2*3+2] * m[0*3+0] - m[2*3+0] * m[0*3+2] ) * detinv; - mdst[1*3+2] = -( m[1*3+2] * m[0*3+0] - m[1*3+0] * m[0*3+2] ) * detinv; - mdst[2*3+0] = ( m[2*3+1] * m[1*3+0] - m[2*3+0] * m[1*3+1] ) * detinv; - mdst[2*3+1] = -( m[2*3+1] * m[0*3+0] - m[2*3+0] * m[0*3+1] ) * detinv; - mdst[2*3+2] = ( m[1*3+1] * m[0*3+0] - m[1*3+0] * m[0*3+1] ) * detinv; - return; -} - - - -//// - - - -static int mathQuadricSolve( mathQuadric *q, mdf *v ) -{ - mdqf det, m[9], minv[9], vector[3], vres[3]; - - mathQuadricToMatrix3x3( m, q ); - det = mathMatrix3x3Determinant( m ); - - if( mdfabs( det ) < 0.00001 ) - { -#ifdef DEBUG_VERBOSE_QUADRIC - printf( " Det Fail : %.12f\n", (double)det ); -#endif - return 0; - } - - mathMatrix3x3Invert( minv, m, det ); - vector[0] = -q->ad; - vector[1] = -q->bd; - vector[2] = -q->cd; - mathMatrix3x3MulVector( vres, minv, vector ); - v[0] = vres[0]; - v[1] = vres[1]; - v[2] = vres[2]; - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Vector : %f %f %f : %f %f %f\n", (double)vector[0], (double)vector[1], (double)vector[2], (double)v[0], (double)v[1], (double)v[2] ); -#endif - - return 1; -} - -static void mathQuadricZero( mathQuadric *q ) -{ - q->area = 0.0; - q->a2 = 0.0; - q->ab = 0.0; - q->ac = 0.0; - q->ad = 0.0; - q->b2 = 0.0; - q->bc = 0.0; - q->bd = 0.0; - q->c2 = 0.0; - q->cd = 0.0; - q->d2 = 0.0; - return; -} - - -static void mathQuadricAddStoreQuadric( mathQuadric *qdst, mathQuadric *q0, mathQuadric *q1 ) -{ - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " QAdd Sr0 %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)q0->area, (double)q0->a2, (double)q0->ab, (double)q0->ac, (double)q0->ad, (double)q0->b2, (double)q0->bc, (double)q0->bd, (double)q0->c2, (double)q0->cd, (double)q0->d2 ); -printf( " QAdd Sr1 %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)q1->area, (double)q1->a2, (double)q1->ab, (double)q1->ac, (double)q1->ad, (double)q1->b2, (double)q1->bc, (double)q1->bd, (double)q1->c2, (double)q1->cd, (double)q1->d2 ); -#endif - - qdst->area = q0->area + q1->area; - qdst->a2 = q0->a2 + q1->a2; - qdst->ab = q0->ab + q1->ab; - qdst->ac = q0->ac + q1->ac; - qdst->ad = q0->ad + q1->ad; - qdst->b2 = q0->b2 + q1->b2; - qdst->bc = q0->bc + q1->bc; - qdst->bd = q0->bd + q1->bd; - qdst->c2 = q0->c2 + q1->c2; - qdst->cd = q0->cd + q1->cd; - qdst->d2 = q0->d2 + q1->d2; - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " QSum %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)qdst->area, (double)qdst->a2, (double)qdst->ab, (double)qdst->ac, (double)qdst->ad, (double)qdst->b2, (double)qdst->bc, (double)qdst->bd, (double)qdst->c2, (double)qdst->cd, (double)qdst->d2 ); -#endif - - return; -} - -static void mathQuadricAddQuadric( mathQuadric *qdst, mathQuadric *q ) -{ - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " QAdd Src %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)q->area, (double)q->a2, (double)q->ab, (double)q->ac, (double)q->ad, (double)q->b2, (double)q->bc, (double)q->bd, (double)q->c2, (double)q->cd, (double)q->d2 ); -printf( " QAdd Dst %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)qdst->area, (double)qdst->a2, (double)qdst->ab, (double)qdst->ac, (double)qdst->ad, (double)qdst->b2, (double)qdst->bc, (double)qdst->bd, (double)qdst->c2, (double)qdst->cd, (double)qdst->d2 ); -#endif - - qdst->area += q->area; - qdst->a2 += q->a2; - qdst->ab += q->ab; - qdst->ac += q->ac; - qdst->ad += q->ad; - qdst->b2 += q->b2; - qdst->bc += q->bc; - qdst->bd += q->bd; - qdst->c2 += q->c2; - qdst->cd += q->cd; - qdst->d2 += q->d2; - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " QSum %f ; %f %f %f %f %f %f %f %f %f %f\n", (double)qdst->area, (double)qdst->a2, (double)qdst->ab, (double)qdst->ac, (double)qdst->ad, (double)qdst->b2, (double)qdst->bc, (double)qdst->bd, (double)qdst->c2, (double)qdst->cd, (double)qdst->d2 ); -#endif - - return; -} - -/* A volatile variable is used to force the compiler to do the math strictly in the order specified. */ -static mdf mathQuadricEvaluate( mathQuadric *q, mdf *v ) -{ -#ifdef MD_CONFIG_HIGH_QUADRICS - volatile mdqfhigh d; - mdqfhigh vh[3]; - vh[0] = v[0]; - vh[1] = v[1]; - vh[2] = v[2]; - - d = vh[0]*vh[0]*(mdqfhigh)q->a2 + vh[1]*vh[1]*(mdqfhigh)q->b2 + vh[2]*vh[2]*(mdqfhigh)q->c2; - d += 2.0 * ( vh[0]*vh[1]*(mdqfhigh)q->ab + vh[0]*vh[2]*(mdqfhigh)q->ac + vh[1]*vh[2]*(mdqfhigh)q->bc ); - d += 2.0 * ( vh[0]*(mdqfhigh)q->ad + vh[1]*(mdqfhigh)q->bd + vh[2]*(mdqfhigh)q->cd ); - d += q->d2; -#else - volatile mdqf d; - mdqf vd[3]; - vd[0] = v[0]; - vd[1] = v[1]; - vd[2] = v[2]; - - d = vd[0]*vd[0]*q->a2 + vd[1]*vd[1]*q->b2 + vd[2]*vd[2]*q->c2; - d += 2.0 * ( vd[0]*vd[1]*q->ab + vd[0]*vd[2]*q->ac + vd[1]*vd[2]*q->bc ); - d += 2.0 * ( vd[0]*q->ad + vd[1]*q->bd + vd[2]*q->cd ); - d += q->d2; -#endif - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Q Eval %f ; %f %f %f %f %f %f %f %f %f %f : %.12f\n", (double)q->area, (double)q->a2, (double)q->ab, (double)q->ac, (double)q->ad, (double)q->b2, (double)q->bc, (double)q->bd, (double)q->c2, (double)q->cd, (double)q->d2, (double)d ); -#endif - - return (mdf)d; -} - -static void mathQuadricMul( mathQuadric *qdst, mdf f ) -{ - qdst->a2 *= f; - qdst->ab *= f; - qdst->ac *= f; - qdst->ad *= f; - qdst->b2 *= f; - qdst->bc *= f; - qdst->bd *= f; - qdst->c2 *= f; - qdst->cd *= f; - qdst->d2 *= f; - return; -} - - - -/****/ - - - -typedef struct -{ - mtMutex mutex; - mtSignal signal; - int resetcount; - volatile int index; - volatile int count[2]; -} mdBarrier; - -static void mdBarrierInit( mdBarrier *barrier, int count ) -{ - mtMutexInit( &barrier->mutex ); - mtSignalInit( &barrier->signal ); - barrier->resetcount = count; - barrier->index = 0; - barrier->count[0] = count; - barrier->count[1] = count; - return; -} - -static void mdBarrierDestroy( mdBarrier *barrier ) -{ - mtMutexDestroy( &barrier->mutex ); - mtSignalDestroy( &barrier->signal ); - return; -} - -static int mdBarrierSync( mdBarrier *barrier ) -{ - int index, ret; - mtMutexLock( &barrier->mutex ); - index = barrier->index; - ret = 0; - if( !( --barrier->count[index] ) ) - { - ret = 1; - mtSignalBroadcast( &barrier->signal ); - index ^= 1; - barrier->index = index; - barrier->count[index] = barrier->resetcount; - } - else - { - for( ; barrier->count[index] ; ) - mtSignalWait( &barrier->signal, &barrier->mutex ); - } - mtMutexUnlock( &barrier->mutex ); - return ret; -} - -static int mdBarrierSyncTimeout( mdBarrier *barrier, long miliseconds ) -{ - int index, ret; - mtMutexLock( &barrier->mutex ); - index = barrier->index; - ret = 0; - if( !( --barrier->count[index] ) ) - { - ret = 1; - mtSignalBroadcast( &barrier->signal ); - index ^= 1; - barrier->index = index; - barrier->count[index] = barrier->resetcount; - } - else - { - mtSignalWaitTimeout( &barrier->signal, &barrier->mutex, miliseconds ); - if( !( barrier->count[index] ) ) - ret = 1; - else - barrier->count[index]++; - } - mtMutexUnlock( &barrier->mutex ); - return ret; -} - - - -/****/ - - -/* 16 bytes ; OK */ -typedef struct -{ - mdi v[3]; - union - { - int edgeflags; - mdi redirectindex; - } u; -} mdTriangle; - -typedef struct -{ - mdi v[2]; - mdi triindex; - void *op; -} mdEdge; - -/* 76 bytes, try packing to 64 bytes? */ -typedef struct RF_ALIGN16 -{ -#ifdef MD_CONFIG_SSE_SUPPORT - mdf RF_ALIGN16 point[4]; -#else - mdf point[3]; -#endif -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomic32 atomicowner; -#else - int owner; - mtSpin ownerspinlock; -#endif - mdi trirefbase; - mdi trirefcount; - mdi redirectindex; - mathQuadric quadric; -} mdVertex; - - -typedef struct -{ - int threadcount; - uint32_t operationflags; - int updatestatusflag; - - /* User supplied raw data */ - mdf *point; - size_t pointstride; - void *indices; - size_t indicesstride; - void (*indicesUserToNative)( mdi *dst, void *src ); - void (*indicesNativeToUser)( void *dst, mdi *src ); - void (*vertexUserToNative)( mdf *dst, void *src ); - void (*vertexNativeToUser)( void *dst, mdf *src ); - - /* Per-vertex triangle references */ - mdi *trireflist; - mdi trirefcount; - long trirefalloc; - char paddingA[64]; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomic32 trireflock; -#else - mtSpin trirefspinlock; -#endif - char paddingB[64]; - - /* Synchronization stuff */ - mdBarrier workbarrier; - mdBarrier globalbarrier; - int updatebuffercount; - int updatebuffershift; - - /* List of triangles */ - mdTriangle *trilist; - long tricount; - long tripackcount; - - /* List of vertices */ - mdVertex *vertexlist; - long vertexcount; - long vertexalloc; - long vertexpackcount; - - /* Hash table to locate edges from their vertex indices */ - void *edgehashtable; - - /* Collapse penalty function */ - mdf (*collapsepenalty)( mdf *newpoint, mdf *oldpoint, mdf *leftpoint, mdf *rightpoint, int *denyflag, mdf compactnesstarget ); - - /* Custom vertex attributes besides point position */ - int attribcount; - mdOpAttrib *attrib; - - /* Decimation strength, max cost */ - mdf maxcollapsecost; - - char paddingC[64]; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomic32 globalvertexlock; -#else - mtSpin globalvertexspinlock; -#endif - char paddingD[64]; - - /* Advanced configuration options */ - mdf compactnesstarget; - mdf compactnesspenalty; - int syncstepcount; - mdf normalsearchangle; - - /* Normal recomputation buffers */ - int clonesearchindex; - void *vertexnormal; - void *trinormal; - -} mdMesh; - - -static void mdIndicesInt8ToNative( mdi *dst, void *src ) -{ - uint8_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mdIndicesInt16ToNative( mdi *dst, void *src ) -{ - uint16_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mdIndicesInt32ToNative( mdi *dst, void *src ) -{ - uint32_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mdIndicesInt64ToNative( mdi *dst, void *src ) -{ - uint64_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - - -static void mdIndicesNativeToInt8( void *dst, mdi *src ) -{ - uint8_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mdIndicesNativeToInt16( void *dst, mdi *src ) -{ - uint16_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mdIndicesNativeToInt32( void *dst, mdi *src ) -{ - uint32_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mdIndicesNativeToInt64( void *dst, mdi *src ) -{ - uint64_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - - - -static void mdVertexFloatToNative( mdf *dst, void *src ) -{ - float *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mdVertexDoubleToNative( mdf *dst, void *src ) -{ - double *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void mdVertexNativeToFloat( void *dst, mdf *src ) -{ - float *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void mdVertexNativeToDouble( void *dst, mdf *src ) -{ - double *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - - - -static void mdTriangleComputeQuadric( mdMesh *mesh, mdTriangle *tri, mathQuadric *q ) -{ - mdf area, norm, norminv, vecta[3], vectb[3], plane[4]; - mdVertex *vertex0, *vertex1, *vertex2; - - vertex0 = &mesh->vertexlist[ tri->v[0] ]; - vertex1 = &mesh->vertexlist[ tri->v[1] ]; - vertex2 = &mesh->vertexlist[ tri->v[2] ]; - - M3D_VectorSubStore( vecta, vertex1->point, vertex0->point ); - M3D_VectorSubStore( vectb, vertex2->point, vertex0->point ); - M3D_VectorCrossProduct( plane, vectb, vecta ); - - norm = mdfsqrt( M3D_VectorDotProduct( plane, plane ) ); - if( norm ) - { - area = 0.5 * norm; -#ifdef MD_CONFIG_AREA_QUADRICS - norminv = 0.5; -#else - norminv = 1.0 / norm; -#endif - plane[0] *= norminv; - plane[1] *= norminv; - plane[2] *= norminv; - plane[3] = -M3D_VectorDotProduct( plane, vertex0->point ); - } - else - { - area = 0.0; - plane[0] = 0.0; - plane[1] = 0.0; - plane[2] = 0.0; - plane[3] = 0.0; - } - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Plane %f %f %f %f : Area %f\n", plane[0], plane[1], plane[2], plane[3], area ); -#endif - - mathQuadricInit( q, plane[0], plane[1], plane[2], plane[3], area ); - - return; -} - - -static mdf mdEdgeSolvePoint( mdVertex *vertex0, mdVertex *vertex1, mdf *point ) -{ - mdf cost, bestcost; - mdf midpoint[3]; - mdf *bestpoint; - mathQuadric q; - - mathQuadricAddStoreQuadric( &q, &vertex0->quadric, &vertex1->quadric ); - - if( mathQuadricSolve( &q, point ) ) - bestcost = mathQuadricEvaluate( &q, point ); - else - { - midpoint[0] = 0.5 * ( vertex0->point[0] + vertex1->point[0] ); - midpoint[1] = 0.5 * ( vertex0->point[1] + vertex1->point[1] ); - midpoint[2] = 0.5 * ( vertex0->point[2] + vertex1->point[2] ); - bestcost = mathQuadricEvaluate( &q, midpoint ); - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " MidCost %f %f %f : %f\n", midpoint[0], midpoint[1], midpoint[2], bestcost ); -#endif - - bestpoint = midpoint; - cost = mathQuadricEvaluate( &q, vertex0->point ); - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Vx0Cost %f %f %f : %f\n", vertex0->point[0], vertex0->point[1], vertex0->point[2], cost ); -#endif - - if( cost < bestcost ) - { - bestcost = cost; - bestpoint = vertex0->point; - } - cost = mathQuadricEvaluate( &q, vertex1->point ); - -#ifdef DEBUG_VERBOSE_QUADRIC -printf( " Vx1Cost %f %f %f : %f\n", vertex1->point[0], vertex1->point[1], vertex1->point[2], cost ); -#endif - - if( cost < bestcost ) - { - bestcost = cost; - bestpoint = vertex1->point; - } - - M3D_VectorCopy( point, bestpoint ); - } - - return bestcost; -} - - -//// - - -static void mdMeshAccumulateBoundary( mdVertex *vertex0, mdVertex *vertex1, mdVertex *vertex2 ) -{ - mdf normal[3], sideplane[4], vecta[3], vectb[3], norm, norminv, area; - mathQuadric q; - - M3D_VectorSubStore( vecta, vertex1->point, vertex0->point ); - M3D_VectorSubStore( vectb, vertex2->point, vertex0->point ); - M3D_VectorCrossProduct( normal, vectb, vecta ); - norm = mdfsqrt( normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2] ); - area = 0.5 * norm; - norminv = 1.0 / norm; - M3D_VectorMulScalar( normal, norminv ); - -#ifdef DEBUG_VERBOSE_BOUNDARY -printf( " Vecta %f %f %f\n", vecta[0], vecta[1], vecta[2] ); -printf( " Normal %f %f %f\n", normal[0], normal[1], normal[2] ); -#endif - - M3D_VectorCrossProduct( sideplane, vecta, normal ); - M3D_VectorNormalize( sideplane ); - sideplane[3] = -M3D_VectorDotProduct( sideplane, vertex0->point ); - -#ifdef DEBUG_VERBOSE_BOUNDARY -printf( " Area %f\n", area ); -printf( " Boundary %f %f %f %f\n", sideplane[0], sideplane[1], sideplane[2], sideplane[3] ); -#endif - - mathQuadricInit( &q, sideplane[0], sideplane[1], sideplane[2], sideplane[3], area ); - mathQuadricMul( &q, MD_BOUNDARY_WEIGHT ); -/* - mathQuadricMul( &q, area * MD_BOUNDARY_WEIGHT ); -*/ - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex0->atomicowner, -1, 0xffff ); - mathQuadricAddQuadric( &vertex0->quadric, &q ); - mmAtomicWrite32( &vertex0->atomicowner, -1 ); -#else - mtSpinLock( &vertex0->ownerspinlock ); - mathQuadricAddQuadric( &vertex0->quadric, &q ); - mtSpinUnlock( &vertex0->ownerspinlock ); -#endif - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex1->atomicowner, -1, 0xffff ); - mathQuadricAddQuadric( &vertex1->quadric, &q ); - mmAtomicWrite32( &vertex1->atomicowner, -1 ); -#else - mtSpinLock( &vertex1->ownerspinlock ); - mathQuadricAddQuadric( &vertex1->quadric, &q ); - mtSpinUnlock( &vertex1->ownerspinlock ); -#endif - - return; -} - - -//// - - -static void mdEdgeHashClearEntry( void *entry ) -{ - mdEdge *edge; - edge = entry; - edge->v[0] = -1; - return; -} - -static int mdEdgeHashEntryValid( void *entry ) -{ - mdEdge *edge; - edge = entry; - return ( edge->v[0] >= 0 ? 1 : 0 ); -} - -static uint32_t mdEdgeHashEntryKey( void *entry ) -{ - uint32_t hashkey; - mdEdge *edge; - edge = entry; - -#ifdef MD_CONFIG_FAST_HASH - - hashkey = edge->v[0]; - hashkey += hashkey << 10; - hashkey ^= hashkey >> 6; - hashkey += edge->v[1]; - hashkey += hashkey << 10; - hashkey ^= hashkey >> 6; - hashkey += hashkey << 6; - hashkey ^= hashkey >> 11; - hashkey += hashkey << 15; - -#else - -#if MD_SIZEOF_MDI == 4 - #if CPUCONF_WORD_SIZE == 64 - { - uint64_t *v = (uint64_t *)edge->v; - hashkey = ccHash32Int64Inline( *v ); - } - #else - hashkey = ccHash32Data4Inline( (void *)edge->v ); - #endif -#elif MD_SIZEOF_MDI == 8 - #if CPUCONF_WORD_SIZE == 64 - hashkey = ccHash32Array64( (uint64_t *)edge->v, 2 ); - #else - hashkey = ccHash32Array32( (uint32_t *)edge->v, 4 ); - #endif -#else - hashkey = ccHash32Data( edge->v, 2*sizeof(mdi) ); -#endif - -#endif - - return hashkey; -} - -static int mdEdgeHashEntryCmp( void *entry, void *entryref ) -{ - mdEdge *edge, *edgeref; - edge = entry; - edgeref = entryref; - if( edge->v[0] == -1 ) - return MM_HASH_ENTRYCMP_INVALID; - if( ( edge->v[0] == edgeref->v[0] ) && ( edge->v[1] == edgeref->v[1] ) ) - return MM_HASH_ENTRYCMP_FOUND; - return MM_HASH_ENTRYCMP_SKIP; -} - -static mmHashAccess mdEdgeHashEdge = -{ - .clearentry = mdEdgeHashClearEntry, - .entryvalid = mdEdgeHashEntryValid, - .entrykey = mdEdgeHashEntryKey, - .entrycmp = mdEdgeHashEntryCmp -}; - -static int mdMeshHashInit( mdMesh *mesh, size_t trianglecount, mdf hashextrabits, uint32_t lockpageshift, size_t maxmemorysize ) -{ - size_t edgecount, hashmemsize, meshmemsize, totalmemorysize; - uint32_t hashbits, hashbitsmin, hashbitsmax; - - edgecount = trianglecount * 3; - - /* Hard minimum count of hash table bits */ -#if CPUCONF_WORD_SIZE == 64 - hashbitsmin = ccLog2Int64( edgecount ) + 1; -#else - hashbitsmin = ccLog2Int32( edgecount ) + 1; -#endif - hashbitsmax = hashbitsmin + 4; - - hashbits = (uint32_t)mdfround( mdflog2( (mdf)edgecount ) + hashextrabits ); - if( hashbits < hashbitsmin ) - hashbits = hashbitsmin; - else if( hashbits > hashbitsmax ) - hashbits = hashbitsmax; - - if( hashbits < 12 ) - hashbits = 12; - if( lockpageshift < 3 ) - lockpageshift = 3; - else if( lockpageshift > 16 ) - lockpageshift = 16; - - meshmemsize = ( mesh->tricount * sizeof(mdTriangle) ) + ( mesh->vertexcount * sizeof(mdVertex) ); - for( ; ; hashbits-- ) - { - if( hashbits < hashbitsmin ) - return 0; - hashmemsize = mmHashRequiredSize( sizeof(mdEdge), hashbits, lockpageshift ); - totalmemorysize = hashmemsize + meshmemsize; - - /* Increase estimate of memory consumption by 25% to account for extra stuff not counted here */ - totalmemorysize += totalmemorysize >> 2; - -#ifdef DEBUG_VERBOSE_MEMORY -printf( " Hash bits : %d (%d)\n", hashbits, hashbitsmin ); -printf( " Estimated Memory Requirements : %lld bytes (%lld MB)\n", (long long)totalmemorysize, (long long)totalmemorysize >> 20 ); -printf( " Memory Hard Limit : %lld bytes (%lld MB)\n", (long long)maxmemorysize, (long long)maxmemorysize >> 20 ); -#endif - - if( totalmemorysize > maxmemorysize ) - continue; - mesh->edgehashtable = malloc( hashmemsize ); - if( mesh->edgehashtable ) - break; - } - - mmHashInit( mesh->edgehashtable, &mdEdgeHashEdge, sizeof(mdEdge), hashbits, lockpageshift, MM_HASH_FLAGS_NO_COUNT ); - - return 1; -} - -static void mdMeshHashEnd( mdMesh *mesh ) -{ - free( mesh->edgehashtable ); - return; -} - - -//// - - -typedef struct RF_ALIGN64 -{ - void **opbuffer; - int opcount; - int opalloc; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomic32 atomlock; -#else - mtSpin spinlock; -#endif -} mdUpdateBuffer; - - -/* 56 bytes, try padding to 64? */ -typedef struct -{ -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomic32 flags; -#else - int flags; - mtSpin spinlock; -#endif - mdUpdateBuffer *updatebuffer; - mdi v0, v1; -#ifdef MD_CONFIG_SSE_SUPPORT - mdf RF_ALIGN16 collapsepoint[4]; -#else - mdf collapsepoint[3]; -#endif - mdf collapsecost; - mdf value; - mdf penalty; - mmListNode list; -} mdOp; - -#define MD_OP_FLAGS_DETACHED (0x1) -#define MD_OP_FLAGS_DELETION_PENDING (0x2) -#define MD_OP_FLAGS_UPDATE_QUEUED (0x4) -#define MD_OP_FLAGS_UPDATE_NEEDED (0x8) -#define MD_OP_FLAGS_DELETED (0x10) - - -/* If threadcount exceeds this number, updatebuffers will be shared by nearby cores */ -#define MD_THREAD_UPDATE_BUFFER_COUNTMAX (8) - -typedef struct RF_ALIGN64 -{ - int threadid; - - /* Memory block for ops */ - mmBlockHead opblock; - - /* Hierarchical bucket sort of ops */ - void *binsort; - - /* List of ops flagged by other threads in need of update */ - mdUpdateBuffer updatebuffer[MD_THREAD_UPDATE_BUFFER_COUNTMAX]; - - /* Per-thread status trackers */ - volatile long statusbuildtricount; - volatile long statusbuildrefcount; - volatile long statuspopulatecount; - volatile long statusdeletioncount; - -} mdThreadData; - - -static void mdUpdateBufferInit( mdUpdateBuffer *updatebuffer, int opalloc ) -{ - updatebuffer->opbuffer = malloc( opalloc * sizeof(mdOp *) ); - updatebuffer->opcount = 0; - updatebuffer->opalloc = opalloc; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &updatebuffer->atomlock, 0x0 ); -#else - mtSpinInit( &updatebuffer->spinlock ); -#endif - return; -} - -static void mdUpdateBufferEnd( mdUpdateBuffer *updatebuffer ) -{ -#ifndef MD_CONFIG_ATOMIC_SUPPORT - mtSpinDestroy( &updatebuffer->spinlock ); -#endif - free( updatebuffer->opbuffer ); - return; -} - -static void mdUpdateBufferAdd( mdUpdateBuffer *updatebuffer, mdOp *op, int orflags ) -{ - int32_t flags; - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - - for( ; ; ) - { - flags = mmAtomicRead32( &op->flags ); - if( flags & MD_OP_FLAGS_UPDATE_QUEUED ) - { - if( !( flags & MD_OP_FLAGS_UPDATE_NEEDED ) || ( orflags ) ) - mmAtomicOr32( &op->flags, orflags | MD_OP_FLAGS_UPDATE_NEEDED ); - return; - } - if( mmAtomicCmpReplace32( &op->flags, flags, flags | orflags | MD_OP_FLAGS_UPDATE_QUEUED | MD_OP_FLAGS_UPDATE_NEEDED ) ) - break; - } - /* TODO: Avoid spin lock, use atomic increment for write offset? Careful with this realloc, pointer could become invalid */ - mmAtomicSpin32( &updatebuffer->atomlock, 0x0, 0x1 ); - if( updatebuffer->opcount >= updatebuffer->opalloc ) - { - updatebuffer->opalloc <<= 1; - updatebuffer->opbuffer = realloc( updatebuffer->opbuffer, updatebuffer->opalloc * sizeof(mdOp *) ); - } - updatebuffer->opbuffer[ updatebuffer->opcount++ ] = op; - mmAtomicWrite32( &updatebuffer->atomlock, 0x0 ); - -#else - - mtSpinLock( &op->spinlock ); - op->flags |= orflags; - flags = op->flags; - if( flags & MD_OP_FLAGS_UPDATE_QUEUED ) - { - if( !( flags & MD_OP_FLAGS_UPDATE_NEEDED ) ) - op->flags |= MD_OP_FLAGS_UPDATE_NEEDED; - mtSpinUnlock( &op->spinlock ); - return; - } - op->flags |= MD_OP_FLAGS_UPDATE_QUEUED | MD_OP_FLAGS_UPDATE_NEEDED; - mtSpinUnlock( &op->spinlock ); - mtSpinLock( &updatebuffer->spinlock ); - if( updatebuffer->opcount >= updatebuffer->opalloc ) - { - updatebuffer->opalloc <<= 1; - updatebuffer->opbuffer = realloc( updatebuffer->opbuffer, updatebuffer->opalloc * sizeof(mdOp *) ); - } - updatebuffer->opbuffer[ updatebuffer->opcount++ ] = op; - mtSpinUnlock( &updatebuffer->spinlock ); - -#endif - - return; -} - - - -//// - - - -#define MD_COMPACTNESS_NORMALIZATION_FACTOR (0.5*4.0*1.732050808) - -static mdf mdEdgeCollapsePenaltyTriangle( mdf *newpoint, mdf *oldpoint, mdf *leftpoint, mdf *rightpoint, int *denyflag, mdf compactnesstarget ) -{ - mdf penalty, compactness, oldcompactness, newcompactness, vecta2, norm; - mdf vecta[3], oldvectb[3], oldvectc[3], newvectb[3], newvectc[3], oldnormal[3], newnormal[3]; - - /* Normal of old triangle */ - M3D_VectorSubStore( vecta, rightpoint, leftpoint ); - M3D_VectorSubStore( oldvectb, oldpoint, leftpoint ); - M3D_VectorCrossProduct( oldnormal, vecta, oldvectb ); - - /* Normal of new triangle */ - M3D_VectorSubStore( newvectb, newpoint, leftpoint ); - M3D_VectorCrossProduct( newnormal, vecta, newvectb ); - - /* Detect normal inversion */ - if( M3D_VectorDotProduct( oldnormal, newnormal ) < 0.0 ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta2 = M3D_VectorDotProduct( vecta, vecta ); - M3D_VectorSubStore( newvectc, newpoint, rightpoint ); - newcompactness = MD_COMPACTNESS_NORMALIZATION_FACTOR * mdfsqrt( M3D_VectorDotProduct( newnormal, newnormal ) ); - norm = vecta2 + M3D_VectorDotProduct( newvectb, newvectb ) + M3D_VectorDotProduct( newvectc, newvectc ); - if( newcompactness < ( compactnesstarget * norm ) ) - { - newcompactness /= norm; - M3D_VectorSubStore( oldvectc, oldpoint, rightpoint ); - oldcompactness = ( MD_COMPACTNESS_NORMALIZATION_FACTOR * mdfsqrt( M3D_VectorDotProduct( oldnormal, oldnormal ) ) ) / ( vecta2 + M3D_VectorDotProduct( oldvectb, oldvectb ) + M3D_VectorDotProduct( oldvectc, oldvectc ) ); - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - -static mdf mdEdgeCollapsePenaltyAll( mdMesh *mesh, mdThreadData *tdata, mdi *trireflist, mdi trirefcount, mdi pivotindex, mdi skipindex, mdf *collapsepoint, int *denyflag ) -{ - int index; - mdf penalty; - mdi triindex; - mdTriangle *tri; - mdf (*collapsepenalty)( mdf *newpoint, mdf *oldpoint, mdf *leftpoint, mdf *rightpoint, int *denyflag, mdf compactnesstarget ); - - collapsepenalty = mesh->collapsepenalty; - penalty = 0.0; - for( index = 0 ; index < trirefcount ; index++ ) - { - if( *denyflag ) - break; - triindex = trireflist[ index ]; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - -#ifdef DEBUG_VERBOSE_PENALTY -printf( " Penalty Tri %d,%d,%d ( Pivot %d ; Skip %d )\n", tri->v[0], tri->v[1], tri->v[2], pivotindex, skipindex ); -#endif - -#ifdef DEBUG_DEBUG -mdi triv[3]; -triv[0] = tri->v[0]; -triv[1] = tri->v[1]; -triv[2] = tri->v[2]; -#endif - - if( tri->v[0] == pivotindex ) - { - if( ( tri->v[1] == skipindex ) || ( tri->v[2] == skipindex ) ) - continue; - penalty += collapsepenalty( collapsepoint, mesh->vertexlist[ tri->v[0] ].point, mesh->vertexlist[ tri->v[2] ].point, mesh->vertexlist[ tri->v[1] ].point, denyflag, mesh->compactnesstarget ); - } - else if( tri->v[1] == pivotindex ) - { - if( ( tri->v[2] == skipindex ) || ( tri->v[0] == skipindex ) ) - continue; - penalty += collapsepenalty( collapsepoint, mesh->vertexlist[ tri->v[1] ].point, mesh->vertexlist[ tri->v[0] ].point, mesh->vertexlist[ tri->v[2] ].point, denyflag, mesh->compactnesstarget ); - } - else if( tri->v[2] == pivotindex ) - { - if( ( tri->v[0] == skipindex ) || ( tri->v[1] == skipindex ) ) - continue; - penalty += collapsepenalty( collapsepoint, mesh->vertexlist[ tri->v[2] ].point, mesh->vertexlist[ tri->v[1] ].point, mesh->vertexlist[ tri->v[0] ].point, denyflag, mesh->compactnesstarget ); - } - else - { -#ifdef DEBUG_DEBUG - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - -printf( "CopyV : %d %d %d (%d)\n", triv[0], triv[1], triv[2], pivotindex ); -printf( "TriV : %d %d %d (%d)\n", tri->v[0], tri->v[1], tri->v[2], pivotindex ); -sleep( 1 ); -printf( "CopyV : %d %d %d (%d)\n", triv[0], triv[1], triv[2], pivotindex ); -printf( "TriV : %d %d %d (%d)\n", tri->v[0], tri->v[1], tri->v[2], pivotindex ); -#endif - - } - } - - penalty *= mesh->compactnesspenalty; - -#ifdef DEBUG_VERBOSE_PENALTY -printf( " Penalty Sum : %f\n", penalty ); -#endif - - return penalty; -} - - -static mdf mdEdgeCollapsePenalty( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1, mdf *collapsepoint, int *denyflag ) -{ - mdf penalty, collapsearea, penaltyfactor; - mdVertex *vertex0, *vertex1; - - vertex0 = &mesh->vertexlist[ v0 ]; - vertex1 = &mesh->vertexlist[ v1 ]; - - collapsearea = vertex0->quadric.area + vertex1->quadric.area; - penaltyfactor = collapsearea * collapsearea / ( vertex0->trirefcount + vertex1->trirefcount ); - -#ifdef DEBUG_VERBOSE_PENALTY -printf( " Compute Penalty Edge %d,%d\n", v0, v1 ); -#endif - - *denyflag = 0; - penalty = mdEdgeCollapsePenaltyAll( mesh, tdata, &mesh->trireflist[ vertex0->trirefbase ], vertex0->trirefcount, v0, v1, collapsepoint, denyflag ); - penalty += mdEdgeCollapsePenaltyAll( mesh, tdata, &mesh->trireflist[ vertex1->trirefbase ], vertex1->trirefcount, v1, v0, collapsepoint, denyflag ); - -#ifdef DEBUG_VERBOSE_PENALTY -printf( " Penalty Total : %f * %f -> %f\n", penalty, penaltyfactor, penalty * penaltyfactor ); -#endif - - penalty *= penaltyfactor; - - return penalty; -} - - - -//// - - - -static void mdMeshEdgeOpCallback( void *opaque, void *entry, int newflag ) -{ - mdEdge *edge; - edge = entry; - edge->op = opaque; - return; -} - - -static double mdMeshOpValueCallback( void *item ) -{ - mdOp *op; - op = item; - return (double)op->collapsecost; -} - -static void mdMeshAddOp( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1 ) -{ - int denyflag, opflags; - mdOp *op; - mdEdge edge; - - op = mmBlockAlloc( &tdata->opblock ); - opflags = 0x0; - op->updatebuffer = tdata->updatebuffer; - op->v0 = v0; - op->v1 = v1; - op->value = mdEdgeSolvePoint( &mesh->vertexlist[v0], &mesh->vertexlist[v1], op->collapsepoint ); -#ifdef MD_CONFIG_SSE_SUPPORT - op->collapsepoint[3] = 0.0; -#endif - op->penalty = mdEdgeCollapsePenalty( mesh, tdata, v0, v1, op->collapsepoint, &denyflag ); - op->collapsecost = op->value + op->penalty; - if( ( denyflag ) || ( op->collapsecost > mesh->maxcollapsecost ) ) - opflags |= MD_OP_FLAGS_DETACHED; - else - mmBinSortAdd( tdata->binsort, op, op->collapsecost ); -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &op->flags, opflags ); -#else - op->flags = opflags; - mtSpinInit( &op->spinlock ); -#endif - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - edge.v[0] = v0; - edge.v[1] = v1; - if( mmHashLockCallEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, mdMeshEdgeOpCallback, op, 0 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Solve Edge %d,%d ; Point %f %f %f ; Value %f ; Penalty %f ; Cost %f\n", (int)op->v0, (int)op->v1, op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->value, op->penalty, op->collapsecost ); -#endif - - return; -} - -static void mdMeshPopulateOpList( mdMesh *mesh, mdThreadData *tdata, mdi tribase, mdi tricount ) -{ - mdTriangle *tri, *tristart, *triend; - long populatecount; - - tristart = &mesh->trilist[tribase]; - triend = &tristart[tricount]; - - populatecount = 0; - for( tri = tristart ; tri < triend ; tri++ ) - { -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( "Triangle Edges %d,%d,%d\n", tri->v[0], tri->v[1], tri->v[2] ); -#endif - if( ( tri->v[0] < tri->v[1] ) || ( tri->u.edgeflags & 0x1 ) ) - mdMeshAddOp( mesh, tdata, tri->v[0], tri->v[1] ); - if( ( tri->v[1] < tri->v[2] ) || ( tri->u.edgeflags & 0x2 ) ) - mdMeshAddOp( mesh, tdata, tri->v[1], tri->v[2] ); - if( ( tri->v[2] < tri->v[0] ) || ( tri->u.edgeflags & 0x4 ) ) - mdMeshAddOp( mesh, tdata, tri->v[2], tri->v[0] ); - - populatecount++; - tdata->statuspopulatecount = populatecount; - } - - return; -} - - - -//// - - - -/* Merge vertex attributes of v0 and v1, write to v0 */ -static void mdEdgeCollapseAttrib( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1, mdf *collapsepoint ) -{ - int index; - mdVertex *vertex0, *vertex1; - mdf dist[3], dist0, dist1, weightsum, weightsuminv; - mdf weight0, weight1; - mdOpAttrib *attrib, *attribend; - void *attr0p, *attr1p; - float *attr0pf, *attr1pf, sumf, suminvf; - double *attr0pd, *attr1pd, sumd, suminvd; - - if( !( mesh->attribcount ) ) - return; - - vertex0 = &mesh->vertexlist[ v0 ]; - M3D_VectorSubStore( dist, collapsepoint, vertex0->point ); - dist0 = M3D_VectorMagnitude( dist ); - - vertex1 = &mesh->vertexlist[ v1 ]; - M3D_VectorSubStore( dist, collapsepoint, vertex1->point ); - dist1 = M3D_VectorMagnitude( dist ); - - weight0 = dist1 * vertex0->quadric.area; - weight1 = dist0 * vertex1->quadric.area; - weightsum = weight0 + weight1; - if( weightsum ) - { - weightsuminv = 1.0 / weightsum; - weight0 *= weightsuminv; - weight1 *= weightsuminv; - } - else - { - weight0 = 0.5; - weight1 = 0.5; - } - - attrib = mesh->attrib; - attribend = &attrib[mesh->attribcount]; - for( ; attrib < attribend ; attrib++ ) - { - attr0p = ADDRESS( attrib->base, v0 * attrib->stride ); - attr1p = ADDRESS( attrib->base, v1 * attrib->stride ); - if( attrib->width == sizeof(float) ) - { - attr0pf = attr0p; - attr1pf = attr1p; - for( index = 0 ; index < attrib->count ; index++ ) - attr0pf[index] = ( attr0pf[index] * (float)weight0 ) + ( attr1pf[index] * (float)weight1 ); - if( attrib->flags & MD_ATTRIB_FLAGS_NORMALIZE ) - { - sumf = 0.0; - for( index = 0 ; index < attrib->count ; index++ ) - sumf += attr0pf[index] * attr0pf[index]; - if( sumf ) - { - suminvf = 1.0 / sumf; - for( index = 0 ; index < attrib->count ; index++ ) - attr0pf[index] *= suminvf; - } - } - } - else if( attrib->width == sizeof(double) ) - { - attr0pd = attr0p; - attr1pd = attr1p; - for( index = 0 ; index < attrib->count ; index++ ) - attr0pd[index] = ( attr0pd[index] * (double)weight0 ) + ( attr1pd[index] * (double)weight1 ); - if( attrib->flags & MD_ATTRIB_FLAGS_NORMALIZE ) - { - sumd = 0.0; - for( index = 0 ; index < attrib->count ; index++ ) - sumd += attr0pd[index] * attr0pd[index]; - if( sumd ) - { - suminvd = 1.0 / sumd; - for( index = 0 ; index < attrib->count ; index++ ) - attr0pd[index] *= suminvd; - } - } - } - } - - return; -} - - -/* Delete triangle and return outer vertex */ -static mdi mdEdgeCollapseDeleteTriangle( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1, int *retdelflags ) -{ - int delflags = 0; - mdi outer = 0; - mdEdge edge; - mdTriangle *tri; - mdOp *op; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - *retdelflags = 0x0; - - edge.v[0] = v0; - edge.v[1] = v1; - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - return -1; - op = edge.op; - if( op ) - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, MD_OP_FLAGS_DELETION_PENDING ); - - tri = &mesh->trilist[ edge.triindex ]; - -#ifdef DEBUG_VERBOSE_COLLAPSE - printf( " Delete Triangle %d,%d,%d\n", tri->v[0], tri->v[1], tri->v[2] ); -#endif - - if( tri->v[0] != v0 ) - { - edge.v[0] = tri->v[0]; - edge.v[1] = tri->v[1]; - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - op = edge.op; - if( op ) - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, MD_OP_FLAGS_DELETION_PENDING ); - } - if( tri->v[1] != v0 ) - { - edge.v[0] = tri->v[1]; - edge.v[1] = tri->v[2]; - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - op = edge.op; - if( op ) - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, MD_OP_FLAGS_DELETION_PENDING ); - } - if( tri->v[2] != v0 ) - { - edge.v[0] = tri->v[2]; - edge.v[1] = tri->v[0]; - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - op = edge.op; - if( op ) - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, MD_OP_FLAGS_DELETION_PENDING ); - } - - /* Determine outer vertex */ - /* TODO: Replace branches with bitwise arithmetics */ - if( tri->v[0] == v0 ) - { - outer = tri->v[2]; - delflags = 0x0; - if( tri->u.edgeflags & 0x2 ) - delflags |= 0x1; - if( tri->u.edgeflags & 0x4 ) - delflags |= 0x2; - } - else if( tri->v[1] == v0 ) - { - outer = tri->v[0]; - delflags = 0x0; - if( tri->u.edgeflags & 0x4 ) - delflags |= 0x1; - if( tri->u.edgeflags & 0x1 ) - delflags |= 0x2; - } - else if( tri->v[2] == v0 ) - { - outer = tri->v[1]; - delflags = 0x0; - if( tri->u.edgeflags & 0x1 ) - delflags |= 0x1; - if( tri->u.edgeflags & 0x2 ) - delflags |= 0x2; - } - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - - *retdelflags = delflags; - - /* Invalidate triangle */ - tri->v[0] = -1; - - return outer; -} - - -static void mdEdgeCollapseUpdateTriangle( mdMesh *mesh, mdThreadData *tdata, mdTriangle *tri, mdi newv, int pivot, int left, int right ) -{ - mdEdge edge; - mdOp *op; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Collapse Update %d : Tri %d,%d,%d\n", newv, tri->v[pivot], tri->v[right], tri->v[left] ); -#endif - - edge.v[0] = tri->v[pivot]; - edge.v[1] = tri->v[right]; - if( edge.v[0] == newv ) - { - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - else - { - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[0] = newv; - if( mmHashLockAddEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - op = edge.op; - if( op ) - { -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Update Edge %d,%d Before ; Point %f %f %f ; Cost %f\n", op->v0, op->v1, op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->collapsecost ); -#endif - -#ifdef MD_CONFIG_DELAYED_OP_REDIRECT - op->value = mdEdgeSolvePoint( &mesh->vertexlist[edge.v[0]], &mesh->vertexlist[edge.v[1]], op->collapsepoint ); - #ifdef MD_CONFIG_SSE_SUPPORT - op->collapsepoint[3] = 0.0; - #endif - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, 0x0 ); -#else - op->v0 = newv; - op->value = mdEdgeSolvePoint( &mesh->vertexlist[op->v0], &mesh->vertexlist[op->v1], op->collapsepoint ); - #ifdef MD_CONFIG_SSE_SUPPORT - op->collapsepoint[3] = 0.0; - #endif - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, 0x0 ); -#endif - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Update Edge %d,%d After ; Point %f %f %f ; Cost %f\n", op->v0, op->v1, op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->collapsecost ); -printf( " Edge %d,%d ; Value %f ; Penalty %f ; Cost %f\n", op->v0, op->v1, op->value, op->penalty, op->collapsecost ); -#endif - } - - edge.v[0] = tri->v[left]; - edge.v[1] = tri->v[pivot]; - if( edge.v[1] == newv ) - { - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - else - { - if( mmHashLockDeleteEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[1] = newv; - if( mmHashLockAddEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - op = edge.op; - if( op ) - { -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Update Edge %d,%d Before ; Point %f %f %f ; Cost %f\n", op->v0, op->v1, op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->collapsecost ); -#endif - -#ifdef MD_CONFIG_DELAYED_OP_REDIRECT - op->value = mdEdgeSolvePoint( &mesh->vertexlist[edge.v[0]], &mesh->vertexlist[edge.v[1]], op->collapsepoint ); - #ifdef MD_CONFIG_SSE_SUPPORT - op->collapsepoint[3] = 0.0; - #endif - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, 0x0 ); -#else - op->v1 = newv; - op->value = mdEdgeSolvePoint( &mesh->vertexlist[op->v0], &mesh->vertexlist[op->v1], op->collapsepoint ); - #ifdef MD_CONFIG_SSE_SUPPORT - op->collapsepoint[3] = 0.0; - #endif - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, 0x0 ); -#endif - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Update Edge %d,%d After ; Point %f %f %f ; Cost %f\n", op->v0, op->v1, op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->collapsecost ); -printf( " Edge %d,%d ; Value %f ; Penalty %f ; Cost %f\n", op->v0, op->v1, op->value, op->penalty, op->collapsecost ); -#endif - } - - tri->v[pivot] = newv; - - return; -} - - - -/* -Walk through the list of all triangles attached to a vertex -- Update cost of collapse for other edges of triangles -- Build up the updated list of triangle references for new vertex -*/ -static mdi *mdEdgeCollapseUpdateAll( mdMesh *mesh, mdThreadData *tdata, mdi *trireflist, mdi trirefcount, mdi oldv, mdi newv, mdi *trirefstore ) -{ - int index; - mdi triindex; - mdTriangle *tri; - - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Tri %d : %d %d %d\n", index, tri->v[0], tri->v[1], tri->v[2] ); -#endif - - *trirefstore = triindex; - trirefstore++; - if( tri->v[0] == oldv ) - mdEdgeCollapseUpdateTriangle( mesh, tdata, tri, newv, 0, 2, 1 ); - else if( tri->v[1] == oldv ) - mdEdgeCollapseUpdateTriangle( mesh, tdata, tri, newv, 1, 0, 2 ); - else if( tri->v[2] == oldv ) - mdEdgeCollapseUpdateTriangle( mesh, tdata, tri, newv, 2, 1, 0 ); - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - return trirefstore; -} - - -static void mdVertexInvalidateTri( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1 ) -{ - mdEdge edge; - mdOp *op; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - edge.v[0] = v0; - edge.v[1] = v1; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - op = edge.op; - if( !( op ) ) - return; - - mdUpdateBufferAdd( &op->updatebuffer[ tdata->threadid >> mesh->updatebuffershift ], op, 0x0 ); - - return; -} - -static void mdVertexInvalidate( mdMesh *mesh, mdThreadData *tdata, mdi vertexindex ) -{ - mdi index, triindex, trirefcount; - mdi *trireflist; - mdTriangle *tri; - mdVertex *vertex; - - /* Vertices of the collapsed edge */ - vertex = &mesh->vertexlist[ vertexindex ]; - trireflist = &mesh->trireflist[ vertex->trirefbase ]; - trirefcount = vertex->trirefcount; - - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - if( tri->v[0] == vertexindex ) - { - mdVertexInvalidateTri( mesh, tdata, tri->v[0], tri->v[1] ); - mdVertexInvalidateTri( mesh, tdata, tri->v[2], tri->v[0] ); - } - else if( tri->v[1] == vertexindex ) - { - mdVertexInvalidateTri( mesh, tdata, tri->v[1], tri->v[2] ); - mdVertexInvalidateTri( mesh, tdata, tri->v[0], tri->v[1] ); - } - else if( tri->v[2] == vertexindex ) - { - mdVertexInvalidateTri( mesh, tdata, tri->v[2], tri->v[0] ); - mdVertexInvalidateTri( mesh, tdata, tri->v[1], tri->v[2] ); - } - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - return; -} - -static void mdVertexInvalidateAll( mdMesh *mesh, mdThreadData *tdata, mdi *trireflist, mdi trirefcount, mdi pivotindex ) -{ - int index; - mdi triindex; - mdTriangle *tri; - - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - if( tri->v[0] == pivotindex ) - { - mdVertexInvalidate( mesh, tdata, tri->v[1] ); - mdVertexInvalidate( mesh, tdata, tri->v[2] ); - } - else if( tri->v[1] == pivotindex ) - { - mdVertexInvalidate( mesh, tdata, tri->v[2] ); - mdVertexInvalidate( mesh, tdata, tri->v[0] ); - } - else if( tri->v[2] == pivotindex ) - { - mdVertexInvalidate( mesh, tdata, tri->v[0] ); - mdVertexInvalidate( mesh, tdata, tri->v[1] ); - } - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - return; -} - - -static void mdEdgeCollapseLinkOuter( mdMesh *mesh, mdThreadData *tdata, mdi newv, mdi outer ) -{ - int sideflags; - mdEdge edge; - mdOp *op; - - if( outer == -1 ) - return; - sideflags = 0x0; - - edge.v[0] = newv; - edge.v[1] = outer; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) == MM_HASH_SUCCESS ) - { - sideflags |= 0x1; - op = edge.op; - if( op ) - return; - } - edge.v[0] = outer; - edge.v[1] = newv; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) == MM_HASH_SUCCESS ) - { - sideflags |= 0x2; - op = edge.op; - if( op ) - return; - } - - if( ( newv < outer ) && ( sideflags & 0x1 ) ) - mdMeshAddOp( mesh, tdata, newv, outer ); - else if( sideflags & 0x2 ) - mdMeshAddOp( mesh, tdata, outer, newv ); - - return; -} - - - -static void mdEdgeCollapsePropagateBoundary( mdMesh *mesh, mdi v0, mdi v1 ) -{ - mdEdge edge; - mdTriangle *tri; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - edge.v[0] = v1; - edge.v[1] = v0; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) == MM_HASH_SUCCESS ) - return; - edge.v[0] = v0; - edge.v[1] = v1; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) != MM_HASH_SUCCESS ) - return; - - tri = &mesh->trilist[ edge.triindex ]; - if( tri->v[0] == v0 ) - tri->u.edgeflags |= 0x1; - else if( tri->v[1] == v0 ) - tri->u.edgeflags |= 0x2; - else if( tri->v[2] == v0 ) - tri->u.edgeflags |= 0x4; - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - - /* TODO: Grow the boundary for affected vertex quadrics */ - - return; -} - - - - -#define MD_LOCK_BUFFER_STATIC (512) - -typedef struct -{ - mdi vertexstatic[MD_LOCK_BUFFER_STATIC]; - mdi *vertexlist; - int vertexcount; - int vertexalloc; -} mdLockBuffer; - -static inline void mdLockBufferInit( mdLockBuffer *buffer, int maxvertexcount ) -{ - buffer->vertexlist = buffer->vertexstatic; - buffer->vertexalloc = MD_LOCK_BUFFER_STATIC; - if( maxvertexcount > MD_LOCK_BUFFER_STATIC ) - { - buffer->vertexlist = malloc( maxvertexcount * sizeof(mdi) ); - buffer->vertexalloc = maxvertexcount; - } - buffer->vertexcount = 0; - return; -} - -static inline void mdLockBufferResize( mdLockBuffer *buffer, int maxvertexcount ) -{ - int index; - mdi *vertexlist; - if( maxvertexcount > buffer->vertexalloc ) - { - vertexlist = malloc( maxvertexcount * sizeof(mdi) ); - for( index = 0 ; index < buffer->vertexcount ; index++ ) - vertexlist[index] = buffer->vertexlist[index]; - if( buffer->vertexlist != buffer->vertexstatic ) - free( buffer->vertexlist ); - buffer->vertexlist = vertexlist; - buffer->vertexalloc = maxvertexcount; - } - return; -} - -static inline void mdLockBufferEnd( mdLockBuffer *buffer ) -{ - if( buffer->vertexlist != buffer->vertexstatic ) - free( buffer->vertexlist ); - buffer->vertexlist = buffer->vertexstatic; - buffer->vertexalloc = MD_LOCK_BUFFER_STATIC; - buffer->vertexcount = 0; - return; -} - -void mdLockBufferUnlockAll( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *buffer ) -{ - int index; - mdVertex *vertex; - for( index = 0 ; index < buffer->vertexcount ; index++ ) - { - vertex = &mesh->vertexlist[ buffer->vertexlist[index] ]; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &vertex->atomicowner ) == tdata->threadid ) - mmAtomicCmpXchg32( &vertex->atomicowner, tdata->threadid, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - if( vertex->owner == tdata->threadid ) - vertex->owner = -1; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - buffer->vertexcount = 0; - return; -} - -/* If it fails, release all locks */ -int mdLockBufferTryLock( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *buffer, mdi vertexindex ) -{ - int32_t owner; - mdVertex *vertex; - vertex = &mesh->vertexlist[ vertexindex ]; - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - owner = mmAtomicRead32( &vertex->atomicowner ); - if( owner == tdata->threadid ) - return 1; - if( ( owner != -1 ) || !( mmAtomicCmpReplace32( &vertex->atomicowner, -1, tdata->threadid ) ) ) - { - mdLockBufferUnlockAll( mesh, tdata, buffer ); - return 0; - } -#else - mtSpinLock( &vertex->ownerspinlock ); - owner = vertex->owner; - if( owner == tdata->threadid ) - { - mtSpinUnlock( &vertex->ownerspinlock ); - return 1; - } - if( owner != -1 ) - { - mtSpinUnlock( &vertex->ownerspinlock ); - mdLockBufferUnlockAll( mesh, tdata, buffer ); - return 0; - } - vertex->owner = tdata->threadid; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - - buffer->vertexlist[buffer->vertexcount++] = vertexindex; - return 1; -} - -/* If it fails, release all locks then wait for the desired lock to become available */ -int mdLockBufferLock( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *buffer, mdi vertexindex ) -{ - int32_t owner; - mdVertex *vertex; - vertex = &mesh->vertexlist[ vertexindex ]; - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - owner = mmAtomicRead32( &vertex->atomicowner ); - if( owner == tdata->threadid ) - return 1; - if( ( owner == -1 ) && mmAtomicCmpReplace32( &vertex->atomicowner, -1, tdata->threadid ) ) - { - buffer->vertexlist[buffer->vertexcount++] = vertexindex; - return 1; - } - /* Lock failed, release all locks and wait until we get the lock we got stuck on */ - mdLockBufferUnlockAll( mesh, tdata, buffer ); - mmAtomicSpinWaitEq32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - owner = vertex->owner; - if( owner == tdata->threadid ) - { - mtSpinUnlock( &vertex->ownerspinlock ); - return 1; - } - if( owner == -1 ) - { - vertex->owner = tdata->threadid; - mtSpinUnlock( &vertex->ownerspinlock ); - buffer->vertexlist[buffer->vertexcount++] = vertexindex; - return 1; - } - mtSpinUnlock( &vertex->ownerspinlock ); - /* Lock failed, release all locks */ - mdLockBufferUnlockAll( mesh, tdata, buffer ); -#endif - -/* Alternatively, we could acquire that lock that bugged us */ -/* - for( ; ; ) - { - mmAtomicPause(); - owner = mmAtomicRead32( &vertex->atomicowner ); - if( owner != -1 ) - continue; - if( mmAtomicCmpReplace32( &vertex->atomicowner, -1, tdata->threadid ) ) - break; - } - - buffer->vertexlist[buffer->vertexcount++] = vertexindex; -*/ - - return 0; -} - - -static int mdPivotLockRefs( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *buffer, mdi vertexindex ) -{ - int index; - mdi triindex, iav = 0, ibv = 0, trirefcount; - mdi *trireflist; - mdTriangle *tri; - mdVertex *vertex; - - vertex = &mesh->vertexlist[ vertexindex ]; - trireflist = &mesh->trireflist[ vertex->trirefbase ]; - trirefcount = vertex->trirefcount; - - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - - if( tri->v[0] == vertexindex ) - { - iav = tri->v[1]; - ibv = tri->v[2]; - } - else if( tri->v[1] == vertexindex ) - { - iav = tri->v[2]; - ibv = tri->v[0]; - } - else if( tri->v[2] == vertexindex ) - { - iav = tri->v[0]; - ibv = tri->v[1]; - } - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - - if( !( mdLockBufferLock( mesh, tdata, buffer, iav ) ) ) - return 0; - if( !( mdLockBufferLock( mesh, tdata, buffer, ibv ) ) ) - return 0; - } - - return 1; -} - - -static void mdOpResolveLockEdge( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *lockbuffer, mdOp *op ) -{ - int failcount, globalflag; - mdVertex *vertex0, *vertex1; - - failcount = 0; - globalflag = 0; - for( ; ; ) - { - if( ( failcount > MD_GLOBAL_LOCK_THRESHOLD ) && !( globalflag ) ) - { - mdLockBufferUnlockAll( mesh, tdata, lockbuffer ); -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &mesh->globalvertexlock, 0x0, 0x1 ); -#else - mtSpinLock( &mesh->globalvertexspinlock ); -#endif - globalflag = 1; - } - if( !( mdLockBufferLock( mesh, tdata, lockbuffer, op->v0 ) ) || !( mdLockBufferLock( mesh, tdata, lockbuffer, op->v1 ) ) ) - { - failcount++; - continue; - } - vertex0 = &mesh->vertexlist[ op->v0 ]; - vertex1 = &mesh->vertexlist[ op->v1 ]; -#ifdef MD_CONFIG_DELAYED_OP_REDIRECT - if( vertex0->redirectindex != -1 ) - op->v0 = vertex0->redirectindex; - else if( vertex1->redirectindex != -1 ) - op->v1 = vertex1->redirectindex; - else - break; -#else - break; -#endif - } - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( globalflag ) - mmAtomicWrite32( &mesh->globalvertexlock, 0x0 ); -#else - if( globalflag ) - mtSpinUnlock( &mesh->globalvertexspinlock ); -#endif - - return; -} - -static int mdOpResolveLockEdgeTry( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *lockbuffer, mdOp *op ) -{ - mdVertex *vertex0, *vertex1; - - for( ; ; ) - { - if( !( mdLockBufferTryLock( mesh, tdata, lockbuffer, op->v0 ) ) || !( mdLockBufferTryLock( mesh, tdata, lockbuffer, op->v1 ) ) ) - return 0; - vertex0 = &mesh->vertexlist[ op->v0 ]; - vertex1 = &mesh->vertexlist[ op->v1 ]; -#ifdef MD_CONFIG_DELAYED_OP_REDIRECT - if( vertex0->redirectindex != -1 ) - op->v0 = vertex0->redirectindex; - else if( vertex1->redirectindex != -1 ) - op->v1 = vertex1->redirectindex; - else - break; -#else - break; -#endif - } - - return 1; -} - -static void mdOpResolveLockFull( mdMesh *mesh, mdThreadData *tdata, mdLockBuffer *lockbuffer, mdOp *op ) -{ - int failcount, globalflag; - mdVertex *vertex0, *vertex1; - - failcount = 0; - globalflag = 0; - for( ; ; ) - { - if( ( failcount > MD_GLOBAL_LOCK_THRESHOLD ) && !( globalflag ) ) - { - mdLockBufferUnlockAll( mesh, tdata, lockbuffer ); -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &mesh->globalvertexlock, 0x0, 0x1 ); -#else - mtSpinLock( &mesh->globalvertexspinlock ); -#endif - globalflag = 1; - } - if( !( mdLockBufferLock( mesh, tdata, lockbuffer, op->v0 ) ) || !( mdLockBufferLock( mesh, tdata, lockbuffer, op->v1 ) ) ) - { - failcount++; - continue; - } - vertex0 = &mesh->vertexlist[ op->v0 ]; - vertex1 = &mesh->vertexlist[ op->v1 ]; -#ifdef MD_CONFIG_DELAYED_OP_REDIRECT - if( vertex0->redirectindex != -1 ) - op->v0 = vertex0->redirectindex; - else if( vertex1->redirectindex != -1 ) - op->v1 = vertex1->redirectindex; - else - { - mdLockBufferResize( lockbuffer, 2 + ( ( vertex0->trirefcount + vertex1->trirefcount ) << 1 ) ); - if( !( mdPivotLockRefs( mesh, tdata, lockbuffer, op->v0 ) ) || !( mdPivotLockRefs( mesh, tdata, lockbuffer, op->v1 ) ) ) - { - failcount++; - continue; - } - break; - } -#else - mdLockBufferResize( lockbuffer, 2 + ( ( vertex0->trirefcount + vertex1->trirefcount ) << 1 ) ); - if( !( mdPivotLockRefs( mesh, tdata, lockbuffer, op->v0 ) ) || !( mdPivotLockRefs( mesh, tdata, lockbuffer, op->v1 ) ) ) - { - failcount++; - continue; - } - break; -#endif - } - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( globalflag ) - mmAtomicWrite32( &mesh->globalvertexlock, 0x0 ); -#else - if( globalflag ) - mtSpinUnlock( &mesh->globalvertexspinlock ); -#endif - - return; -} - - - - - -#define MD_EDGE_COLLAPSE_TRIREF_STATIC (512) - -static void mdEdgeCollapse( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1, mdf *collapsepoint ) -{ - int index, delflags0, delflags1; - long deletioncount; - mdi newv, trirefcount, trirefmax, outer0, outer1; - mdi *trireflist, *trirefstore; - mdi trirefstatic[MD_EDGE_COLLAPSE_TRIREF_STATIC]; - mdVertex *vertex0, *vertex1; - - /* Vertices of the collapsed edge */ - vertex0 = &mesh->vertexlist[ v0 ]; - vertex1 = &mesh->vertexlist[ v1 ]; - - /* Collapse other custom vertex attributes */ - mdEdgeCollapseAttrib( mesh, tdata, v0, v1, collapsepoint ); - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( "Collapse %d,%d ; Point %f %f %f ( Overwrite %d ; Delete %d )\n", (int)v0, (int)v1, collapsepoint[0], collapsepoint[1], collapsepoint[2], (int)v0, (int)v1 ); -#endif - - /* New vertex overwriting v0 */ - newv = v0; - - /* Delete the triangles on both sides of the edge and all associated edges */ - outer0 = mdEdgeCollapseDeleteTriangle( mesh, tdata, v0, v1, &delflags0 ); - outer1 = mdEdgeCollapseDeleteTriangle( mesh, tdata, v1, v0, &delflags1 ); - - /* Track count of deletions */ - deletioncount = tdata->statusdeletioncount; - if( outer0 != -1 ) - deletioncount++; - if( outer1 != -1 ) - deletioncount++; - tdata->statusdeletioncount = deletioncount; - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Redirect %d -> %d ; %d -> %d\n", (int)v0, (int)vertex0->redirectindex, (int)v1, (int)vertex1->redirectindex ); -#endif - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( " Move Point %f %f %f ( %f %f %f ) -> %f %f %f\n", vertex0->point[0], vertex0->point[1], vertex0->point[2], vertex1->point[0], vertex1->point[1], vertex1->point[2], collapsepoint[0], collapsepoint[1], collapsepoint[2] ); -#endif - - /* Set up new vertex over v0 */ - M3D_VectorCopy( vertex0->point, collapsepoint ); - mathQuadricAddQuadric( &vertex0->quadric, &vertex1->quadric ); - - /* Propagate boundaries from deleted triangles */ - if( delflags0 ) - { - if( delflags0 & 0x1 ) - mdEdgeCollapsePropagateBoundary( mesh, newv, outer0 ); - if( delflags0 & 0x2 ) - mdEdgeCollapsePropagateBoundary( mesh, outer0, newv ); - } - if( delflags1 ) - { - if( delflags1 & 0x1 ) - mdEdgeCollapsePropagateBoundary( mesh, newv, outer1 ); - if( delflags1 & 0x2 ) - mdEdgeCollapsePropagateBoundary( mesh, outer1, newv ); - } - - /* Redirect vertex1 to vertex0 */ - vertex1->redirectindex = newv; - - /* Maximum theoritical count of triangle references for our new vertex, we need a chunk of memory that big */ - trirefmax = vertex0->trirefcount + vertex1->trirefcount; - - /* Buffer to temporarily store our new trirefs */ - trireflist = trirefstatic; - if( trirefmax > MD_EDGE_COLLAPSE_TRIREF_STATIC ) - trireflist = malloc( trirefmax * sizeof(mdi) ); - - /* Update all triangles connected to vertex0 and vertex1 */ - trirefstore = trireflist; - trirefstore = mdEdgeCollapseUpdateAll( mesh, tdata, &mesh->trireflist[ vertex0->trirefbase ], vertex0->trirefcount, v0, newv, trirefstore ); - trirefstore = mdEdgeCollapseUpdateAll( mesh, tdata, &mesh->trireflist[ vertex1->trirefbase ], vertex1->trirefcount, v1, newv, trirefstore ); - - /* Find where to store the trirefs */ - trirefcount = (int)( trirefstore - trireflist ); - -#ifdef DEBUG_VERBOSE_COLLAPSE - printf( "TriRefCount %d ; Alloc %d\n", trirefcount, trirefmax ); -#endif - - if( trirefcount > vertex0->trirefcount ) - { - if( trirefcount <= vertex1->trirefcount ) - vertex0->trirefbase = vertex1->trirefbase; - else - { - /* Multithreading, acquire lock */ -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &mesh->trireflock, 0x0, 0x1 ); -#else - mtSpinLock( &mesh->trirefspinlock ); -#endif - vertex0->trirefbase = mesh->trirefcount; - mesh->trirefcount += trirefcount; - if( mesh->trirefcount >= mesh->trirefalloc ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &mesh->trireflock, 0x0 ); -#else - mtSpinUnlock( &mesh->trirefspinlock ); -#endif - } - } - - /* Mark vertex1 as unused */ - vertex1->trirefcount = 0; - - /* Store trirefs */ - vertex0->trirefcount = trirefcount; - trirefstore = &mesh->trireflist[ vertex0->trirefbase ]; - for( index = 0 ; index < trirefcount ; index++ ) - { - -#ifdef DEBUG_VERBOSE_COLLAPSE - mdTriangle *tri; - tri = &mesh->trilist[ trireflist[index] ]; - printf( " Triref %d : %d,%d,%d\n", index, tri->v[0], tri->v[1], tri->v[2] ); -#endif - - trirefstore[index] = trireflist[index]; - } - - /* Invalidate all penalty calculations in neighborhood of pivot vertex */ - mdVertexInvalidateAll( mesh, tdata, trireflist, trirefcount, newv ); - - /* If buffer wasn't static, free it */ - if( trireflist != trirefstatic ) - free( trireflist ); - - /* Verify if we should create new ops between newv and outer vertices of deleted triangles */ - mdEdgeCollapseLinkOuter( mesh, tdata, newv, outer0 ); - mdEdgeCollapseLinkOuter( mesh, tdata, newv, outer1 ); - -#ifdef DEBUG_VERBOSE_COLLAPSE -printf( "Collapse End %d,%d\n", (int)v0, (int)v1 ); -#endif - - return; -} - - - -//// - - - -typedef struct -{ - int collisionflag; - mdi trileft; - mdi triright; -} mdEdgeCollisionData; - -static void mdEdgeCollisionCallback( void *opaque, void *entry, int newflag ) -{ - mdEdge *edge; - mdEdgeCollisionData *ecd; - edge = entry; - ecd = opaque; - if( ( edge->triindex != ecd->trileft ) && ( edge->triindex != ecd->triright ) ) - ecd->collisionflag = 1; - return; -} - - -/* -Prevent 2D collapses - -Check all triangles attached to v1 that would have to attach back to v0 -If any of the edge is already present in the hash table, deny the collapse -*/ -static int mdEdgeCollisionCheck( mdMesh *mesh, mdThreadData *tdata, mdi v0, mdi v1 ) -{ - int index, trirefcount, left, right; - mdi triindex, vsrc, vdst; - mdi *trireflist; - mdEdge edge; - mdTriangle *tri; - mdVertex *vertex0, *vertex1; - mdEdgeCollisionData ecd; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - vertex0 = &mesh->vertexlist[ v0 ]; - vertex1 = &mesh->vertexlist[ v1 ]; - if( vertex0->trirefcount < vertex1->trirefcount ) - { - vsrc = v0; - vdst = v1; - trireflist = &mesh->trireflist[ vertex0->trirefbase ]; - trirefcount = vertex0->trirefcount; - } - else - { - vsrc = v1; - vdst = v0; - trireflist = &mesh->trireflist[ vertex1->trirefbase ]; - trirefcount = vertex1->trirefcount; - } - -#ifdef DEBUG_VERBOSE_COLLISION -printf( "Collision Check %d,%d\n", (int)v0, (int)v1 ); -printf( " Src %d ; Dst %d\n", vsrc, vdst ); -#endif - - /* Find the triangles that would be deleted so that we don't detect false collisions with them */ - ecd.collisionflag = 0; - ecd.trileft = -1; - edge.v[0] = v0; - edge.v[1] = v1; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) == MM_HASH_SUCCESS ) - ecd.trileft = edge.triindex; - ecd.triright = -1; - edge.v[0] = v1; - edge.v[1] = v0; - if( mmHashLockReadEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) == MM_HASH_SUCCESS ) - ecd.triright = edge.triindex; - - /* Check all trirefs for collision */ - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - if( ( triindex == ecd.trileft ) || ( triindex == ecd.triright ) ) - continue; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - -#ifdef DEBUG_VERBOSE_COLLISION -printf( " Tri %d : %d,%d,%d\n", index, tri->v[0], tri->v[1], tri->v[2] ); -#endif - - if( tri->v[0] == vsrc ) - { - left = 2; - right = 1; - } - else if( tri->v[1] == vsrc ) - { - left = 0; - right = 2; - } - else if( tri->v[2] == vsrc ) - { - left = 1; - right = 0; - } - else - { - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - continue; - } - - edge.v[0] = vdst; - edge.v[1] = tri->v[right]; - mmHashLockCallEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, mdEdgeCollisionCallback, &ecd, 0 ); - if( ecd.collisionflag ) - return 0; - edge.v[0] = tri->v[left]; - edge.v[1] = vdst; - mmHashLockCallEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, mdEdgeCollisionCallback, &ecd, 0 ); - if( ecd.collisionflag ) - return 0; - } - - return 1; -} - - - -//// - - - -/* Mesh init step 0, allocate, NOT threaded */ -static int mdMeshInit( mdMesh *mesh, size_t maxmemorysize ) -{ - int retval; - - /* Allocate vertices, no extra room for vertices, we overwrite existing ones as we decimate */ - mesh->vertexlist = mmAlignAlloc( mesh->vertexalloc * sizeof(mdVertex), 0x40 ); - - /* Allocate space for per-vertex lists of face references, including future vertices */ - mesh->trirefcount = 0; - mesh->trirefalloc = 2 * 6 * mesh->tricount; - mesh->trireflist = malloc( mesh->trirefalloc * sizeof(mdi) ); - - /* Allocate triangles */ - mesh->trilist = malloc( mesh->tricount * sizeof(mdTriangle) ); - - /* Allocate edge hash table */ - retval = 1; - if( !( mesh->operationflags & MD_FLAGS_NO_DECIMATION ) ) - retval = mdMeshHashInit( mesh, mesh->tricount, 2.0, 7, maxmemorysize ); - - /* Custom vertex attributes besides point position */ - mesh->attribcount = 0; - mesh->attrib = 0; - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &mesh->trireflock, 0x0 ); - mmAtomicWrite32( &mesh->globalvertexlock, 0x0 ); -#else - mtSpinInit( &mesh->trirefspinlock ); - mtSpinInit( &mesh->globalvertexspinlock ); -#endif - - return retval; -} - - -/* Mesh init step 1, initialize vertices, threaded */ -static void mdMeshInitVertices( mdMesh *mesh, mdThreadData *tdata, int threadcount ) -{ - int vertexindex, vertexindexmax, vertexperthread; - mdVertex *vertex; - void *point; - - vertexperthread = ( mesh->vertexcount / threadcount ) + 1; - vertexindex = tdata->threadid * vertexperthread; - vertexindexmax = vertexindex + vertexperthread; - if( vertexindexmax > mesh->vertexcount ) - vertexindexmax = mesh->vertexcount; - - vertex = &mesh->vertexlist[vertexindex]; - point = ADDRESS( mesh->point, vertexindex * mesh->pointstride ); - for( ; vertexindex < vertexindexmax ; vertexindex++, vertex++ ) - { -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - vertex->owner = -1; - mtSpinInit( &vertex->ownerspinlock ); -#endif - mesh->vertexUserToNative( vertex->point, point ); -#ifdef MD_CONFIG_SSE_SUPPORT - vertex->point[3] = 0.0; -#endif - vertex->trirefcount = 0; - vertex->redirectindex = -1; - - mathQuadricZero( &vertex->quadric ); - point = ADDRESS( point, mesh->pointstride ); - } - - return; -} - - -/* Mesh init step 2, initialize triangles, threaded */ -static void mdMeshInitTriangles( mdMesh *mesh, mdThreadData *tdata, int threadcount ) -{ - int i, triperthread, triindex, triindexmax; - long buildtricount; - void *indices; - mdTriangle *tri; - mdVertex *vertex; - mdEdge edge; - mathQuadric q; - - memset (&edge, 0, sizeof (mdEdge)); //DRH added so it's initialized - triperthread = ( mesh->tricount / threadcount ) + 1; - triindex = tdata->threadid * triperthread; - triindexmax = triindex + triperthread; - if( triindexmax > mesh->tricount ) - triindexmax = mesh->tricount; - - /* Initialize triangles */ - buildtricount = 0; - indices = ADDRESS( mesh->indices, triindex * mesh->indicesstride ); - tri = &mesh->trilist[triindex]; - edge.op = 0; - for( ; triindex < triindexmax ; triindex++, indices = ADDRESS( indices, mesh->indicesstride ), tri++ ) - { - mesh->indicesUserToNative( tri->v, indices ); -#ifdef DEBUG_VERBOSE_QUADRIC - printf( "Triangle %d,%d,%d\n", (int)tri->v[0], (int)tri->v[1], (int)tri->v[2] ); -#endif - mdTriangleComputeQuadric( mesh, tri, &q ); - - for( i = 0 ; i < 3 ; i++ ) - { - vertex = &mesh->vertexlist[ tri->v[i] ]; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - mathQuadricAddQuadric( &vertex->quadric, &q ); - vertex->trirefcount++; - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - mathQuadricAddQuadric( &vertex->quadric, &q ); - vertex->trirefcount++; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - - if( !( mesh->operationflags & MD_FLAGS_NO_DECIMATION ) ) - { - edge.triindex = triindex; - edge.v[0] = tri->v[0]; - edge.v[1] = tri->v[1]; - if( mmHashLockAddEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[0] = tri->v[1]; - edge.v[1] = tri->v[2]; - if( mmHashLockAddEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - edge.v[0] = tri->v[2]; - edge.v[1] = tri->v[0]; - if( mmHashLockAddEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge, 1 ) != MM_HASH_SUCCESS ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - buildtricount++; - tdata->statusbuildtricount = buildtricount; - } - - return; -} - - -/* Mesh init step 3, initialize vertex trirefbase, NOT threaded */ -static void mdMeshInitTrirefs( mdMesh *mesh ) -{ - mdi vertexindex, trirefcount; - mdVertex *vertex; - - /* Compute base of vertex triangle references */ - trirefcount = 0; - vertex = mesh->vertexlist; - for( vertexindex = 0 ; vertexindex < mesh->vertexcount ; vertexindex++, vertex++ ) - { - vertex->trirefbase = trirefcount; - trirefcount += vertex->trirefcount; - vertex->trirefcount = 0; - } - mesh->trirefcount = trirefcount; - - return; -} - - -/* Mesh init step 4, store vertex trirefs and accumulate boundary quadrics, threaded */ -static void mdMeshBuildTrirefs( mdMesh *mesh, mdThreadData *tdata, int threadcount ) -{ - int i, triperthread, triindex, triindexmax; - long buildrefcount; - mdTriangle *tri; - mdVertex *vertex, *trivertex[3]; - mdEdge edge; - - triperthread = ( mesh->tricount / threadcount ) + 1; - triindex = tdata->threadid * triperthread; - triindexmax = triindex + triperthread; - if( triindexmax > mesh->tricount ) - triindexmax = mesh->tricount; - - /* Store vertex triangle references and accumulate boundary quadrics */ - buildrefcount = 0; - tri = &mesh->trilist[triindex]; - for( ; triindex < triindexmax ; triindex++, tri++ ) - { - for( i = 0 ; i < 3 ; i++ ) - { - vertex = &mesh->vertexlist[ tri->v[i] ]; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - mesh->trireflist[ vertex->trirefbase + vertex->trirefcount++ ] = triindex; - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - mesh->trireflist[ vertex->trirefbase + vertex->trirefcount++ ] = triindex; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - trivertex[i] = vertex; - } - - if( !( mesh->operationflags & MD_FLAGS_NO_DECIMATION ) ) - { - tri->u.edgeflags = 0; - edge.v[0] = tri->v[1]; - edge.v[1] = tri->v[0]; - if( !( mmHashLockFindEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) ) ) - { -#ifdef DEBUG_VERBOSE_BOUNDARY -printf( "Boundary %d,%d (%d)\n", tri->v[1], tri->v[0], tri->v[2] ); -#endif - mdMeshAccumulateBoundary( trivertex[0], trivertex[1], trivertex[2] ); - tri->u.edgeflags |= 1; - } - edge.v[0] = tri->v[2]; - edge.v[1] = tri->v[1]; - if( !( mmHashLockFindEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) ) ) - { -#ifdef DEBUG_VERBOSE_BOUNDARY -printf( "Boundary %d,%d (%d)\n", tri->v[2], tri->v[1], tri->v[0] ); -#endif - mdMeshAccumulateBoundary( trivertex[1], trivertex[2], trivertex[0] ); - tri->u.edgeflags |= 2; - } - edge.v[0] = tri->v[0]; - edge.v[1] = tri->v[2]; - if( !( mmHashLockFindEntry( mesh->edgehashtable, &mdEdgeHashEdge, &edge ) ) ) - { -#ifdef DEBUG_VERBOSE_BOUNDARY -printf( "Boundary %d,%d (%d)\n", tri->v[0], tri->v[2], tri->v[1] ); -#endif - mdMeshAccumulateBoundary( trivertex[2], trivertex[0], trivertex[1] ); - tri->u.edgeflags |= 4; - } - } - - buildrefcount++; - tdata->statusbuildrefcount = buildrefcount; - } - - return; -} - - -/* Mesh clean up */ -static void mdMeshEnd( mdMesh *mesh ) -{ -#ifndef MD_CONFIG_ATOMIC_SUPPORT - mdi index; - mdVertex *vertex; - vertex = mesh->vertexlist; - for( index = 0 ; index < mesh->vertexcount ; index++, vertex++ ) - mtSpinDestroy( &vertex->ownerspinlock ); - mtSpinDestroy( &mesh->trirefspinlock ); - mtSpinDestroy( &mesh->globalvertexspinlock ); -#endif - mmAlignFree( mesh->vertexlist ); - free( mesh->trireflist ); - free( mesh->trilist ); - return; -} - - - -//// - - - -static void mdSortOp( mdMesh *mesh, mdThreadData *tdata, mdOp *op, int denyflag ) -{ - mdf collapsecost; - collapsecost = op->value + op->penalty; - if( ( denyflag ) || ( collapsecost > mesh->maxcollapsecost ) ) - { -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( !( mmAtomicRead32( &op->flags ) & MD_OP_FLAGS_DETACHED ) ) - { - mmBinSortRemove( tdata->binsort, op, op->collapsecost ); - mmAtomicOr32( &op->flags, MD_OP_FLAGS_DETACHED ); - } -#else - mtSpinLock( &op->spinlock ); - if( !( op->flags & MD_OP_FLAGS_DETACHED ) ) - { - mmBinSortRemove( tdata->binsort, op, op->collapsecost ); - op->flags |= MD_OP_FLAGS_DETACHED; - } - mtSpinUnlock( &op->spinlock ); -#endif - } - else - { -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &op->flags ) & MD_OP_FLAGS_DETACHED ) - { - mmBinSortAdd( tdata->binsort, op, collapsecost ); - mmAtomicAnd32( &op->flags, ~MD_OP_FLAGS_DETACHED ); - } - else if( op->collapsecost != collapsecost ) - mmBinSortUpdate( tdata->binsort, op, op->collapsecost, collapsecost ); -#else - mtSpinLock( &op->spinlock ); - if( op->flags & MD_OP_FLAGS_DETACHED ) - { - mmBinSortAdd( tdata->binsort, op, collapsecost ); - op->flags &= ~MD_OP_FLAGS_DETACHED; - } - else if( op->collapsecost != collapsecost ) - mmBinSortUpdate( tdata->binsort, op, op->collapsecost, collapsecost ); - mtSpinUnlock( &op->spinlock ); -#endif - op->collapsecost = collapsecost; - } - - return; -} - - -static void mdUpdateOp( mdMesh *mesh, mdThreadData *tdata, mdOp *op, int32_t opflagsmask ) -{ - int denyflag, flags; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - for( ; ; ) - { - flags = mmAtomicRead32( &op->flags ); - if( mmAtomicCmpReplace32( &op->flags, flags, flags & opflagsmask ) ) - break; - } -#else - mtSpinLock( &op->spinlock ); - flags = op->flags; - op->flags &= opflagsmask; - mtSpinUnlock( &op->spinlock ); -#endif - if( !( flags & MD_OP_FLAGS_UPDATE_NEEDED ) ) - return; - if( flags & MD_OP_FLAGS_DELETED ) - return; - if( flags & MD_OP_FLAGS_DELETION_PENDING ) - { - if( !( flags & MD_OP_FLAGS_DETACHED ) ) - mmBinSortRemove( tdata->binsort, op, op->collapsecost ); - -/* Race condition, flag the op as deleted but don't free it. Meh, free them all at the end with FreeAll(). */ -/* - mmBlockFree( &tdata->opblock, op ); -*/ -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicOr32( &op->flags, MD_OP_FLAGS_DELETED ); -#else - mtSpinLock( &op->spinlock ); - op->flags |= MD_OP_FLAGS_DELETED; - mtSpinUnlock( &op->spinlock ); -#endif - } - else - { - op->penalty = mdEdgeCollapsePenalty( mesh, tdata, op->v0, op->v1, op->collapsepoint, &denyflag ); - mdSortOp( mesh, tdata, op, denyflag ); - } - return; -} - -static void mdUpdateBufferOps( mdMesh *mesh, mdThreadData *tdata, mdUpdateBuffer *updatebuffer, mdLockBuffer *lockbuffer ) -{ - int index; - mdOp *op; - -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &updatebuffer->atomlock, 0x0, 0x1 ); -#else - mtSpinLock( &updatebuffer->spinlock ); -#endif - for( index = 0 ; index < updatebuffer->opcount ; index++ ) - { - op = updatebuffer->opbuffer[index]; - if( mdOpResolveLockEdgeTry( mesh, tdata, lockbuffer, op ) ) - { - mdUpdateOp( mesh, tdata, op, ~( MD_OP_FLAGS_UPDATE_QUEUED | MD_OP_FLAGS_UPDATE_NEEDED ) ); - mdLockBufferUnlockAll( mesh, tdata, lockbuffer ); - } - else - { -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &updatebuffer->atomlock, 0x0 ); -#else - mtSpinUnlock( &updatebuffer->spinlock ); -#endif - mdOpResolveLockEdge( mesh, tdata, lockbuffer, op ); - mdUpdateOp( mesh, tdata, op, ~( MD_OP_FLAGS_UPDATE_QUEUED | MD_OP_FLAGS_UPDATE_NEEDED ) ); - mdLockBufferUnlockAll( mesh, tdata, lockbuffer ); -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &updatebuffer->atomlock, 0x0, 0x1 ); -#else - mtSpinLock( &updatebuffer->spinlock ); -#endif - } - } - updatebuffer->opcount = 0; -#ifdef MD_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &updatebuffer->atomlock, 0x0 ); -#else - mtSpinUnlock( &updatebuffer->spinlock ); -#endif - - return; -} - - -static int mdMeshProcessQueue( mdMesh *mesh, mdThreadData *tdata ) -{ - int index, decimationcount, stepindex; - int32_t opflags; - mdf maxcost; - mdOp *op; - mdLockBuffer lockbuffer; -#ifdef DEBUG_LIMIT - int limit = DEBUG_LIMIT; -#endif - - mdLockBufferInit( &lockbuffer, 2 ); - - stepindex = 0; - maxcost = 0.0; - - decimationcount = 0; - for( ; ; ) - { - /* Update all ops flagged as requiring update */ - if( mesh->operationflags & MD_FLAGS_CONTINUOUS_UPDATE ) - { - for( index = 0 ; index < mesh->updatebuffercount ; index++ ) - mdUpdateBufferOps( mesh, tdata, &tdata->updatebuffer[index], &lockbuffer ); - } - - /* Acquire first op */ - op = mmBinSortGetFirstItem( tdata->binsort, maxcost ); - if( !( op ) ) - { - if( ++stepindex >= mesh->syncstepcount ) - break; - maxcost = mesh->maxcollapsecost * ( (mdf)stepindex / (mdf)mesh->syncstepcount ); - mdBarrierSync( &mesh->workbarrier ); - /* Update all ops flagged as requiring update */ - if( !( mesh->operationflags & MD_FLAGS_CONTINUOUS_UPDATE ) ) - { - for( index = 0 ; index < mesh->updatebuffercount ; index++ ) - mdUpdateBufferOps( mesh, tdata, &tdata->updatebuffer[index], &lockbuffer ); - } - continue; - } - -#ifdef DEBUG_VERBOSE -printf( "Op %p ; Edge %d,%d (0x%x) ; Point %f %f %f ; Value %f ; Penalty %f ; Cost %f\n", op, op->v0, op->v1, mmAtomicRead32( &op->flags ), op->collapsepoint[0], op->collapsepoint[1], op->collapsepoint[2], op->value, op->penalty, op->collapsecost ); -#endif - - /* Acquire lock for op edge and all trirefs vertices */ - mdOpResolveLockFull( mesh, tdata, &lockbuffer, op ); - - /* If our op was flagged for update between mdUpdateBufferOps() and before we acquired lock, no big deal, catch the update */ -#ifdef MD_CONFIG_ATOMIC_SUPPORT - opflags = mmAtomicRead32( &op->flags ); -#else - mtSpinLock( &op->spinlock ); - opflags = op->flags; - mtSpinUnlock( &op->spinlock ); -#endif - if( opflags & MD_OP_FLAGS_UPDATE_NEEDED ) - { - mdLockBufferUnlockAll( mesh, tdata, &lockbuffer ); - mdUpdateOp( mesh, tdata, op, ~MD_OP_FLAGS_UPDATE_NEEDED ); - continue; - } - -#if DEBUG_PENALTY_CHECK - int denyflag; - mdf penalty; - penalty = mdEdgeCollapsePenalty( mesh, tdata, op->v0, op->v1, op->collapsepoint, &denyflag ); - if( fabs( penalty - op->penalty ) > 0.001 * fmax( penalty, op->penalty ) ) - printf( "CRAP : %f %f\n", penalty, op->penalty ); -#endif - - if( !( mdEdgeCollisionCheck( mesh, tdata, op->v0, op->v1 ) ) ) - { -#ifdef MD_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &op->flags ) & MD_OP_FLAGS_DETACHED ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - mmAtomicOr32( &op->flags, MD_OP_FLAGS_DETACHED ); - mmBinSortRemove( tdata->binsort, op, op->collapsecost ); -#else - mtSpinLock( &op->spinlock ); - if( op->flags & MD_OP_FLAGS_DETACHED ) - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - op->flags |= MD_OP_FLAGS_DETACHED; - mtSpinUnlock( &op->spinlock ); - mmBinSortRemove( tdata->binsort, op, op->collapsecost ); -#endif - goto opdone; - } - - mdEdgeCollapse( mesh, tdata, op->v0, op->v1, op->collapsepoint ); - decimationcount++; - -#ifdef DEBUG_LIMIT - if( decimationcount >= limit ) - break; -#endif - - opdone: - /* Release all locks for op */ - mdLockBufferUnlockAll( mesh, tdata, &lockbuffer ); - } - - mdLockBufferEnd( &lockbuffer ); - -#ifdef DEBUG_VERBOSE - printf( "Final Count of Collapses : %d\n", decimationcount ); -#endif - - return decimationcount; -} - - - -/****/ - - - -typedef struct -{ - mdf normal[3]; - mdf factor[3]; -} mdTriNormal; - - -static mdi mdMeshPackCountTriangles( mdMesh *mesh ) -{ - mdi tricount; - mdTriangle *tri, *triend; - - tricount = 0; - tri = mesh->trilist; - triend = &tri[ mesh->tricount ]; - for( ; tri < triend ; tri++ ) - { - if( tri->v[0] == -1 ) - continue; - tri->u.redirectindex = tricount; - tricount++; - } - - mesh->tripackcount = tricount; - return tricount; -} - -static mdf mdMeshAngleFactor( mdf dotangle ) -{ - mdf factor; - if( dotangle >= 1.0 ) - factor = 0.0; - else if( dotangle <= -1.0 ) - factor = 0.5 * M_PI; - else - { - factor = mdfacos( dotangle ); - if( isnan( factor ) ) - factor = 0.0; - } - return factor; -} - -static void mdMeshBuildTriangleNormals( mdMesh *mesh ) -{ - mdTriangle *tri, *triend; - mdVertex *vertex0, *vertex1, *vertex2; - mdf vecta[3], vectb[3], vectc[3], normalfactor, magna, magnb, magnc, norm, norminv; - mdTriNormal *trinormal; - - trinormal = mesh->trinormal; - - normalfactor = 1.0; - if( mesh->operationflags & MD_FLAGS_TRIANGLE_WINDING_CCW ) - normalfactor = -1.0; - - tri = mesh->trilist; - triend = &tri[ mesh->tricount ]; - for( ; tri < triend ; tri++ ) - { - if( tri->v[0] == -1 ) - continue; - - /* Compute triangle normal */ - vertex0 = &mesh->vertexlist[ tri->v[0] ]; - vertex1 = &mesh->vertexlist[ tri->v[1] ]; - vertex2 = &mesh->vertexlist[ tri->v[2] ]; - M3D_VectorSubStore( vecta, vertex1->point, vertex0->point ); - M3D_VectorSubStore( vectb, vertex2->point, vertex0->point ); - M3D_VectorCrossProduct( trinormal->normal, vectb, vecta ); - - norm = mdfsqrt( M3D_VectorDotProduct( trinormal->normal, trinormal->normal ) ); - if( norm ) - { - norminv = normalfactor / norm; - trinormal->normal[0] *= norminv; - trinormal->normal[1] *= norminv; - trinormal->normal[2] *= norminv; - } - - M3D_VectorSubStore( vectc, vertex2->point, vertex1->point ); - magna = M3D_VectorMagnitude( vecta ); - magnb = M3D_VectorMagnitude( vectb ); - magnc = M3D_VectorMagnitude( vectc ); - trinormal->factor[0] = norm * mdMeshAngleFactor( M3D_VectorDotProduct( vecta, vectb ) / ( magna * magnb ) ); - trinormal->factor[1] = norm * mdMeshAngleFactor( -M3D_VectorDotProduct( vecta, vectc ) / ( magna * magnc ) ); - trinormal->factor[2] = norm * mdMeshAngleFactor( M3D_VectorDotProduct( vectb, vectc ) / ( magnb * magnc ) ); - - trinormal++; - } - - return; -} - - -static int mdMeshVertexComputeNormal( mdMesh *mesh, mdi vertexindex, mdi *trireflist, int trirefcount, mdf *normal ) -{ - int index, pivot, validflag; - mdi triindex; - mdf norm, norminv; - mdTriangle *tri; - mdTriNormal *trinormal, *tn; - - trinormal = mesh->trinormal; - - /* Loop through all trirefs associated with the vertex */ - validflag = 0; - M3D_VectorZero( normal ); - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - if( triindex == -1 ) - continue; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - - if( tri->v[0] == vertexindex ) - pivot = 0; - else if( tri->v[1] == vertexindex ) - pivot = 1; - else if( tri->v[2] == vertexindex ) - pivot = 2; - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - - tn = &trinormal[ tri->u.redirectindex ]; - M3D_VectorAddMulScalar( normal, tn->normal, tn->factor[pivot] ); - validflag = 1; - } - - if( !( validflag ) ) - return 0; - - norm = mdfsqrt( M3D_VectorDotProduct( normal, normal ) ); - if( norm ) - { - norminv = 1.0 / norm; - normal[0] *= norminv; - normal[1] *= norminv; - normal[2] *= norminv; - } - - return 1; -} - - -static mdi mdMeshCloneVertex( mdMesh *mesh, mdi cloneindex, mdf *point ) -{ - mdi vertexindex, retindex; - mdVertex *vertex; - mdOpAttrib *attrib, *attribend; - void *attrsrc, *attrdst; - - retindex = -1; - vertex = &mesh->vertexlist[ mesh->clonesearchindex ]; - for( vertexindex = mesh->clonesearchindex ; vertexindex < mesh->vertexalloc ; vertexindex++, vertex++ ) - { - if( ( vertexindex < mesh->vertexcount ) && ( vertex->trirefcount ) ) - continue; - vertex->trirefcount = -1; - vertex->redirectindex = -1; - /* Copy the point from the cloned vertex */ - M3D_VectorCopy( vertex->point, point ); - /* Copy generic vertex attributes from the cloned vertex */ - if( mesh->attribcount ) - { - attrib = mesh->attrib; - attribend = &mesh->attrib[mesh->attribcount]; - for( attrib = mesh->attrib ; attrib < attribend ; attrib++ ) - { - attrsrc = ADDRESS( attrib->base, cloneindex * attrib->stride ); - attrdst = ADDRESS( attrib->base, vertexindex * attrib->stride ); - memcpy( attrdst, attrsrc, attrib->count * attrib->width ); - } - } - retindex = vertexindex; - if( vertexindex >= mesh->vertexcount ) - mesh->vertexcount = vertexindex+1; - break; - } - -/* -printf( "CLONE REQUEST %d ( %d %d )\n", retindex, mesh->vertexcount, mesh->vertexalloc ); -*/ - - mesh->clonesearchindex = vertexindex; - return retindex; -} - - -static void mdMeshVertexRedirectTriRefs( mdMesh *mesh, mdi vertexindex, mdi newvertexindex, mdi *trireflist, int trirefcount ) -{ - int index; - mdi triindex; - mdTriangle *tri; - - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - if( triindex == -1 ) - continue; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - if( tri->v[0] == vertexindex ) - tri->v[0] = newvertexindex; - else if( tri->v[1] == vertexindex ) - tri->v[1] = newvertexindex; - else if( tri->v[2] == vertexindex ) - tri->v[2] = newvertexindex; - else - MD_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - } - - return; -} - - -/* Find a target normal */ -static int mdMeshVertexFindTarget( mdMesh *mesh, mdi *trireflist, int trirefcount, mdf **targetnormal ) -{ - int i0, i1; - mdi triindex0, triindex1; - mdf dotangle, bestdotangle; - mdTriangle *tri0, *tri1; - mdTriNormal *trinormal, *tn0, *tn1; - - /* Of all triangles, find the most diverging pair, pick one */ - targetnormal[0] = 0; - targetnormal[1] = 0; - trinormal = mesh->trinormal; - bestdotangle = mesh->normalsearchangle; - for( i0 = 0 ; i0 < trirefcount ; i0++ ) - { - triindex0 = trireflist[ i0 ]; - if( triindex0 == -1 ) - continue; - tri0 = &mesh->trilist[ triindex0 ]; - if( tri0->v[0] == -1 ) - continue; - tn0 = &trinormal[ tri0->u.redirectindex ]; - for( i1 = i0+1 ; i1 < trirefcount ; i1++ ) - { - triindex1 = trireflist[ i1 ]; - if( triindex1 == -1 ) - continue; - tri1 = &mesh->trilist[ triindex1 ]; - if( tri1->v[0] == -1 ) - continue; - tn1 = &trinormal[ tri1->u.redirectindex ]; - dotangle = M3D_VectorDotProduct( tn0->normal, tn1->normal ); - if( dotangle < bestdotangle ) - { - bestdotangle = dotangle; - targetnormal[0] = tn0->normal; - targetnormal[1] = tn1->normal; - } - } - } - - return ( targetnormal[0] != 0 ); -} - - - -#define MD_MESH_TRIREF_MAX (256) - -static int mdMeshVertexBuildNormal( mdMesh *mesh, mdi vertexindex, mdi *trireflist, int trirefcount, mdf *point, mdf *normal ) -{ - int index, trirefbuffercount; - mdi triindex, newvertexindex; - mdi trirefbuffer[MD_MESH_TRIREF_MAX]; - mdf dotangle0, dotangle1; - mdf *newnormal, *targetnormal[2]; - mdTriangle *tri; - mdTriNormal *trinormal, *tn; - - if( trirefcount > MD_MESH_TRIREF_MAX ) - return 1; - - /* Loop to repeat as we retire trirefs from the list */ - trinormal = mesh->trinormal; - for( ; ; ) - { - /* Compute normal for vertex */ - if( !( mdMeshVertexComputeNormal( mesh, vertexindex, trireflist, trirefcount, normal ) ) ) - return 0; - - /* If user doesn't allow vertex splitting, take the normal as it is */ - if( !( mesh->operationflags & MD_FLAGS_NORMAL_VERTEX_SPLITTING ) ) - break; - - /* Find a pair of target normals */ - if( !( mdMeshVertexFindTarget( mesh, trireflist, trirefcount, targetnormal ) ) ) - break; - - /* Find all trirefs that agree with targetnormal[1] and store them independently */ - trirefbuffercount = 0; - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - if( triindex == -1 ) - continue; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - tn = &trinormal[ tri->u.redirectindex ]; - dotangle1 = M3D_VectorDotProduct( targetnormal[1], tn->normal ); - if( dotangle1 < mesh->normalsearchangle ) - continue; - dotangle0 = M3D_VectorDotProduct( targetnormal[0], tn->normal ); - if( dotangle0 > dotangle1 ) - continue; - trirefbuffer[trirefbuffercount++] = triindex; - trireflist[ index ] = -1; - } - if( !( trirefbuffercount ) ) - break; - - /* Find an unused vertex, bail out if none can be found */ - newvertexindex = mdMeshCloneVertex( mesh, vertexindex, point ); - if( newvertexindex == -1 ) - break; - - /* Correct all trirefs to new vertex */ - mdMeshVertexRedirectTriRefs( mesh, vertexindex, newvertexindex, trirefbuffer, trirefbuffercount ); - - /* Spawn a new vertex */ - newnormal = ADDRESS( mesh->vertexnormal, newvertexindex * 3 * sizeof(mdf) ); - mdMeshVertexBuildNormal( mesh, newvertexindex, trirefbuffer, trirefbuffercount, point, newnormal ); - } - - return 1; -} - - -/* In some rare circumstances, a vertex can be unused even with redirectindex = -1 and trirefs leading to deleted triangles */ -static int mdMeshVertexCheckUse( mdMesh *mesh, mdi *trireflist, int trirefcount ) -{ - int index; - mdi triindex; - mdTriangle *tri; - for( index = 0 ; index < trirefcount ; index++ ) - { - triindex = trireflist[ index ]; - if( triindex == -1 ) - continue; - tri = &mesh->trilist[ triindex ]; - if( tri->v[0] == -1 ) - continue; - return 1; - } - return 0; -} - - -static void mdMeshWriteVertices( mdMesh *mesh, mdOpAttrib *normalattrib, mdf *vertexnormal ) -{ - mdi vertexindex, writeindex; - mdf *point, *normal; - mdVertex *vertex; - mdOpAttrib *attrib, *attribend; - void *attrsrc, *attrdst; - void (*writenormal)( void *dst, mdf *src ); - - writenormal = 0; - if( ( vertexnormal ) && ( normalattrib ) && ( normalattrib->count >= 3 ) ) - { - if( normalattrib->width == sizeof(float) ) - writenormal = mdVertexNativeToFloat; - else if( normalattrib->width == sizeof(double) ) - writenormal = mdVertexNativeToDouble; - } - - point = mesh->point; - writeindex = 0; - vertex = mesh->vertexlist; - attrib = mesh->attrib; - attribend = &mesh->attrib[mesh->attribcount]; - for( vertexindex = 0 ; vertexindex < mesh->vertexcount ; vertexindex++, vertex++ ) - { - if( !( mesh->operationflags & MD_FLAGS_NO_VERTEX_PACKING ) ) - { - if( vertex->redirectindex != -1 ) - continue; - if( !( vertex->trirefcount ) ) - continue; - /* The whole mdMeshRecomputeNormals() process already strips unused vertices */ - if( !( vertexnormal ) && ( vertex->trirefcount != -1 ) && !( mdMeshVertexCheckUse( mesh, &mesh->trireflist[ vertex->trirefbase ], vertex->trirefcount ) ) ) - continue; - } - vertex->redirectindex = writeindex; - mesh->vertexNativeToUser( point, vertex->point ); - if( writenormal ) - { - normal = ADDRESS( vertexnormal, vertexindex * 3 * sizeof(mdf) ); - attrdst = ADDRESS( normalattrib->base, writeindex * normalattrib->stride ); - writenormal( attrdst, normal ); - } - if( vertexindex != writeindex ) - { - for( attrib = mesh->attrib ; attrib < attribend ; attrib++ ) - { - attrsrc = ADDRESS( attrib->base, vertexindex * attrib->stride ); - attrdst = ADDRESS( attrib->base, writeindex * attrib->stride ); - memcpy( attrdst, attrsrc, attrib->count * attrib->width ); - } - } - point = ADDRESS( point, mesh->pointstride ); - writeindex++; - } - - mesh->vertexpackcount = writeindex; - if( mesh->operationflags & MD_FLAGS_NO_VERTEX_PACKING ) - mesh->vertexpackcount = mesh->vertexcount; - - return; -} - - -static void mdMeshWriteIndices( mdMesh *mesh ) -{ - mdi finaltricount, v[3]; - mdTriangle *tri, *triend; - mdVertex *vertex0, *vertex1, *vertex2; - void *indices; - - indices = mesh->indices; - finaltricount = 0; - tri = mesh->trilist; - triend = &tri[ mesh->tricount ]; - for( ; tri < triend ; tri++ ) - { - if( tri->v[0] == -1 ) - continue; - vertex0 = &mesh->vertexlist[ tri->v[0] ]; - v[0] = vertex0->redirectindex; - vertex1 = &mesh->vertexlist[ tri->v[1] ]; - v[1] = vertex1->redirectindex; - vertex2 = &mesh->vertexlist[ tri->v[2] ]; - v[2] = vertex2->redirectindex; - mesh->indicesNativeToUser( indices, v ); - indices = ADDRESS( indices, mesh->indicesstride ); - finaltricount++; - } - - mesh->tripackcount = finaltricount; - return; -} - - -/* Recompute normals, store them along with vertices and indices at once */ -static void mdMeshRecomputeNormals( mdMesh *mesh, mdOpAttrib *normalattrib ) -{ - // 2012-10-22 ch3: vertexcount set but never used, so commented - mdi vertexindex /*, vertexcount*/; - mdf *normal; - mdVertex *vertex; - - /* Start search for free vertices to clone at 0 */ - mesh->clonesearchindex = 0; - - /* Count triangles and assign redirectindex to each in sequence */ - mdMeshPackCountTriangles( mesh ); - - mesh->vertexnormal = malloc( mesh->vertexalloc * 3 * sizeof(normal) ); - mesh->trinormal = malloc( mesh->tripackcount * sizeof(mdTriNormal) ); - - /* Build up mesh->trinormal, store normals, area and vertex angles of each triangle */ - mdMeshBuildTriangleNormals( mesh ); - - /* Build each vertex normal */ - vertex = mesh->vertexlist; - for( vertexindex = 0 ; vertexindex < mesh->vertexcount ; vertexindex++, vertex++ ) - { - if( !( vertex->trirefcount ) || ( vertex->trirefcount == -1 ) ) - continue; - normal = ADDRESS( mesh->vertexnormal, vertexindex * 3 * sizeof(mdf) ); - if( !( mdMeshVertexBuildNormal( mesh, vertexindex, &mesh->trireflist[ vertex->trirefbase ], vertex->trirefcount, vertex->point, normal ) ) ) - vertex->trirefcount = 0; - } - - /* Write vertices along with normals and other attributes */ - mdMeshWriteVertices( mesh, normalattrib, mesh->vertexnormal ); - mdMeshWriteIndices( mesh ); - - free( mesh->vertexnormal ); - free( mesh->trinormal ); - - return; -} - - - -/****/ - - - -typedef struct -{ - int threadid; - mdMesh *mesh; - int deletioncount; - int decimationcount; - mdThreadData *tdata; - int stage; -} mdThreadInit; - -#ifndef MD_CONFIG_ATOMIC_SUPPORT -int mdFreeOpCallback( void *chunk, void *userpointer ) -{ - mdOp *op; - op = chunk; - mtSpinDestroy( &op->spinlock ); -} -#endif - - -static void *mdThreadMain( void *value ) -{ - int index, tribase, trimax, triperthread, nodeindex; - int groupthreshold; - mdThreadInit *tinit; - mdThreadData tdata; - mdMesh *mesh; - - tinit = value; - mesh = tinit->mesh; - tinit->tdata = &tdata; - - /* Thread memory initialization */ - tdata.threadid = tinit->threadid; - tdata.statusbuildtricount = 0; - tdata.statusbuildrefcount = 0; - tdata.statuspopulatecount = 0; - tdata.statusdeletioncount = 0; - groupthreshold = mesh->tricount >> 9; - if( groupthreshold < 256 ) - groupthreshold = 256; - - nodeindex = -1; - if( mmcontext.numaflag ) - { - mmThreadBindToCpu( tdata.threadid ); - nodeindex = mmCpuGetNode( tdata.threadid ); - mmBlockNodeInit( &tdata.opblock, nodeindex, sizeof(mdOp), 16384, 16384, 0x10 ); - } - else - mmBlockInit( &tdata.opblock, sizeof(mdOp), 16384, 16384, 0x10 ); - - tdata.binsort = mmBinSortInit( offsetof(mdOp,list), 64, 16, -0.2 * mesh->maxcollapsecost, 1.2 * mesh->maxcollapsecost, groupthreshold, mdMeshOpValueCallback, 6, nodeindex ); - for( index = 0 ; index < mesh->updatebuffercount ; index++ ) - mdUpdateBufferInit( &tdata.updatebuffer[index], 4096 ); - - /* Wait until all threads have properly initialized */ - if( mesh->updatestatusflag ) - mdBarrierSync( &mesh->globalbarrier ); - - /* Build mesh step 1 */ - if( !( tdata.threadid ) ) - tinit->stage = MD_STATUS_STAGE_BUILDVERTICES; - mdMeshInitVertices( mesh, &tdata, mesh->threadcount ); - mdBarrierSync( &mesh->workbarrier ); - - /* Build mesh step 2 */ - if( !( tdata.threadid ) ) - tinit->stage = MD_STATUS_STAGE_BUILDTRIANGLES; - mdMeshInitTriangles( mesh, &tdata, mesh->threadcount ); - mdBarrierSync( &mesh->globalbarrier ); - - /* Build mesh step 3 is not parallel, have the main thread run it */ - if( !( tdata.threadid ) ) - tinit->stage = MD_STATUS_STAGE_BUILDTRIREFS; - mdBarrierSync( &mesh->globalbarrier ); - - /* Build mesh step 4 */ - mdMeshBuildTrirefs( mesh, &tdata, mesh->threadcount ); - mdBarrierSync( &mesh->workbarrier ); - - if( !( mesh->operationflags & MD_FLAGS_NO_DECIMATION ) ) - { - /* Initialize the thread's op queue */ - if( !( tdata.threadid ) ) - tinit->stage = MD_STATUS_STAGE_BUILDQUEUE; - triperthread = ( mesh->tricount / mesh->threadcount ) + 1; - tribase = tdata.threadid * triperthread; - trimax = tribase + triperthread; - if( trimax > mesh->tricount ) - trimax = mesh->tricount; - mdMeshPopulateOpList( mesh, &tdata, tribase, trimax - tribase ); - - /* Wait for all threads to reach this point */ - mdBarrierSync( &mesh->workbarrier ); - - /* Process the thread's op queue */ - if( !( tdata.threadid ) ) - tinit->stage = MD_STATUS_STAGE_DECIMATION; - tinit->decimationcount = mdMeshProcessQueue( mesh, &tdata ); - } - - /* Wait for all threads to reach this point */ - tinit->deletioncount = tdata.statusdeletioncount; - mdBarrierSync( &mesh->globalbarrier ); - - /* If we didn't use atomic operations, we have spinlocks to destroy in each op */ -#ifndef MD_CONFIG_ATOMIC_SUPPORT - mmBlockProcessList( &tdata.opblock, 0, mdFreeOpCallback ); -#endif - - /* Free thread memory allocations */ - mmBlockFreeAll( &tdata.opblock ); - for( index = 0 ; index < mesh->updatebuffercount ; index++ ) - mdUpdateBufferEnd( &tdata.updatebuffer[index] ); - mmBinSortFree( tdata.binsort ); - - return 0; -} - - - -/********/ - - - -static const char *mdStatusStageName[] = -{ - [MD_STATUS_STAGE_INIT] = "Initializing", - [MD_STATUS_STAGE_BUILDVERTICES] = "Building Vertices", - [MD_STATUS_STAGE_BUILDTRIANGLES] = "Building Triangles", - [MD_STATUS_STAGE_BUILDTRIREFS] = "Building Trirefs", - [MD_STATUS_STAGE_BUILDQUEUE] = "Building Queues", - [MD_STATUS_STAGE_DECIMATION] = "Decimating Mesh", - [MD_STATUS_STAGE_STORE] = "Storing Geometry", - [MD_STATUS_STAGE_DONE] = "Done" -}; - -static double mdStatusStageProgress[] = -{ - [MD_STATUS_STAGE_INIT] = 0.0, - [MD_STATUS_STAGE_BUILDVERTICES] = 2.0, - [MD_STATUS_STAGE_BUILDTRIANGLES] = 6.0, - [MD_STATUS_STAGE_BUILDTRIREFS] = 6.0, - [MD_STATUS_STAGE_BUILDQUEUE] = 8.0, - [MD_STATUS_STAGE_DECIMATION] = 75.0, - [MD_STATUS_STAGE_STORE] = 3.0, - [MD_STATUS_STAGE_DONE] = 0.0 -}; - -static void mdUpdateStatus( mdMesh *mesh, mdThreadInit *threadinit, int stage, mdStatus *status ) -{ - int threadid, stageindex; - long buildtricount, buildrefcount, populatecount, deletioncount; - double progress, subprogress; - mdThreadInit *tinit; - mdThreadData *tdata; - - subprogress = 0.0; - if( !( threadinit ) ) - status->stage = stage; - else - { - tinit = &threadinit[0]; - status->stage = tinit->stage; - - tdata = tinit->tdata; - if( (unsigned)status->stage >= MD_STATUS_STAGE_COUNT ) - return; - buildtricount = 0; - buildrefcount = 0; - populatecount = 0; - deletioncount = 0; - for( threadid = 0 ; threadid < mesh->threadcount ; threadid++ ) - { - tinit = &threadinit[threadid]; - tdata = tinit->tdata; - buildtricount += tdata->statusbuildtricount; - buildrefcount += tdata->statusbuildrefcount; - populatecount += tdata->statuspopulatecount; - deletioncount += tdata->statusdeletioncount; - } - status->trianglecount = mesh->tricount - deletioncount; - if( status->stage == MD_STATUS_STAGE_DECIMATION ) - subprogress = 1.0 - ( (double)status->trianglecount / (double)mesh->tricount ); - else if( status->stage == MD_STATUS_STAGE_BUILDQUEUE ) - subprogress = (double)populatecount / (double)mesh->tricount; - else if( status->stage == MD_STATUS_STAGE_BUILDTRIANGLES ) - subprogress = (double)buildtricount / (double)mesh->tricount; - else if( status->stage == MD_STATUS_STAGE_BUILDTRIREFS ) - subprogress = (double)buildrefcount / (double)mesh->tricount; - subprogress = fmax( 0.0, fmin( 1.0, subprogress ) ); - } - - progress = 0.0; - status->stagename = mdStatusStageName[status->stage]; - for( stageindex = 0 ; stageindex < status->stage ; stageindex++ ) - progress += mdStatusStageProgress[stageindex]; - - progress += subprogress * mdStatusStageProgress[status->stage]; - if( progress > status->progress ) - status->progress = progress; - - return; -} - - - -/********/ - - - -void mdInit() -{ - mmInit(); - cpuGetInfo( &mdCpuInfo ); - mdInitFlag = 1; - return; -} - -void mdOperationInit( mdOperation *op ) -{ - /* Input */ - op->vertexcount = 0; - op->vertex = 0; - op->vertexstride = 0; - op->vertexalloc = 0; - op->indices = 0; - op->indiceswidth = 0; - op->indicesstride = 0; - op->tricount = 0; - op->decimationstrength = 0.0; - op->attribcount = 0; - op->normalattrib.base = 0; - - /* Status callback */ - op->statusmiliseconds = 0; - op->statusopaquepointer = 0; - op->statuscallback = 0; - - /* Advanced settings, default values */ - op->compactnesstarget = MD_COLLAPSE_PENALTY_COMPACT_TARGET; - op->compactnesspenalty = MD_COLLAPSE_PENALTY_COMPACT_FACTOR; - op->syncstepcount = 32; - op->normalsearchangle = 45.0; - mmInit(); - op->maxmemorysize = ((long long)2)*1024*1024*1024; - if( mmcontext.sysmemory ) - { - op->maxmemorysize = ( mmcontext.sysmemory >> 1 ) + ( mmcontext.sysmemory >> 2 ); /* By default, allow to allocate up to 75% of system memory */ - if( op->maxmemorysize < 1024*1024*1024 ) - op->maxmemorysize = 1024*1024*1024; - } - - return; -} - -void mdOperationData( mdOperation *op, size_t vertexcount, void *vertex, int vertexwidth, size_t vertexstride, size_t tricount, void *indices, int indiceswidth, size_t indicesstride ) -{ - op->vertexcount = vertexcount; - op->vertex = vertex; - op->vertexwidth = vertexwidth; - op->vertexstride = vertexstride; - op->indices = indices; - op->indiceswidth = indiceswidth; - op->indicesstride = indicesstride; - op->tricount = tricount; - return; -} - -int mdOperationAddAttrib( mdOperation *op, void *base, int width, size_t count, size_t stride, int flags ) -{ - mdOpAttrib *attrib; - - if( flags & MD_ATTRIB_FLAGS_COMPUTE_NORMALS ) - attrib = &op->normalattrib; - else - { - if( op->attribcount >= MD_ATTRIB_MAX ) - return 0; - attrib = &op->attrib[op->attribcount++]; - } - attrib->base = base; - attrib->width = width; - attrib->count = count; - attrib->stride = stride; - attrib->flags = flags; - - return 1; -} - -void mdOperationStrength( mdOperation *op, double decimationstrength ) -{ - /* pow( decimationstrength/4.0, 4.0 ) */ - decimationstrength *= 0.25; - decimationstrength *= decimationstrength; - op->decimationstrength = decimationstrength * decimationstrength; - return; -} - -void mdOperationStatusCallback( mdOperation *op, void (*statuscallback)( void *opaquepointer, const mdStatus *status ), void *opaquepointer, long miliseconds ) -{ - op->statusmiliseconds = miliseconds; - op->statusopaquepointer = opaquepointer; - op->statuscallback = statuscallback; - return; -} - - - -/****/ - - - -int mdMeshDecimation( mdOperation *operation, int threadcount, int flags ) -{ - int threadid, maxthreadcount; - long statuswait; - mdMesh mesh; - mtThread thread[MD_THREAD_COUNT_MAX]; - mdThreadInit threadinit[MD_THREAD_COUNT_MAX]; - mdThreadInit *tinit; - mdStatus status; -#ifdef MD_CONF_ENABLE_PROGRESS - long deletioncount; -#endif - - operation->decimationcount = 0; - operation->msecs = 0; - - if( !( mdInitFlag ) ) - { - mdInitFlag = 1; - /* Initialization of the memory manager, filling struct mmcontext with info about CPUs and NUMA */ - mmInit(); - /* Retrieve processor capability */ - cpuGetInfo( &mdCpuInfo ); - } - - maxthreadcount = operation->tricount / 1024; - if( threadcount > maxthreadcount ) - threadcount = maxthreadcount; - if( threadcount <= 0 ) - { - threadcount = mmcontext.cpucount; - if( threadcount <= 0 ) - threadcount = MD_THREAD_COUNT_DEFAULT; - } - if( threadcount > MD_THREAD_COUNT_MAX ) - threadcount = MD_THREAD_COUNT_MAX; - - /* Get operation general settings */ - mesh.point = operation->vertex; - mesh.pointstride = operation->vertexstride; - mesh.vertexcount = operation->vertexcount; - mesh.indices = operation->indices; - mesh.indicesstride = operation->indicesstride; - switch( operation->indiceswidth ) - { - case sizeof(uint8_t): - mesh.indicesUserToNative = mdIndicesInt8ToNative; - mesh.indicesNativeToUser = mdIndicesNativeToInt8; - break; - case sizeof(uint16_t): - mesh.indicesUserToNative = mdIndicesInt16ToNative; - mesh.indicesNativeToUser = mdIndicesNativeToInt16; - break; - case sizeof(uint32_t): - mesh.indicesUserToNative = mdIndicesInt32ToNative; - mesh.indicesNativeToUser = mdIndicesNativeToInt32; - break; - case sizeof(uint64_t): - mesh.indicesUserToNative = mdIndicesInt64ToNative; - mesh.indicesNativeToUser = mdIndicesNativeToInt64; - break; - default: - return 0; - } - switch( operation->vertexwidth ) - { - case sizeof(float): - mesh.vertexUserToNative = mdVertexFloatToNative; - mesh.vertexNativeToUser = mdVertexNativeToFloat; - break; - case sizeof(double): - mesh.vertexUserToNative = mdVertexDoubleToNative; - mesh.vertexNativeToUser = mdVertexNativeToDouble; - break; - default: - return 0; - } - mesh.tricount = operation->tricount; - if( mesh.tricount < 2 ) - return 0; - mesh.maxcollapsecost = operation->decimationstrength; - - /* Record start time */ - operation->msecs = mmGetMillisecondsTime(); - - mesh.threadcount = threadcount; - mesh.operationflags = flags; - - /* Custom vertex attributes besides point position */ - mesh.attribcount = operation->attribcount; - mesh.attrib = operation->attrib; - - /* Advanced configuration options */ - mesh.compactnesstarget = operation->compactnesstarget; - mesh.compactnesspenalty = operation->compactnesspenalty; - mesh.syncstepcount = operation->syncstepcount; - if( mesh.syncstepcount < 1 ) - mesh.syncstepcount = 1; - if( mesh.syncstepcount > 1024 ) - mesh.syncstepcount = 1024; - mesh.normalsearchangle = cos( 1.0 * operation->normalsearchangle * (M_PI/180.0) ); - if( mesh.normalsearchangle > 0.9 ) - mesh.normalsearchangle = 0.9; - - /* Synchronization */ - mdBarrierInit( &mesh.workbarrier, threadcount ); - mdBarrierInit( &mesh.globalbarrier, threadcount+1 ); - - /* Determine update buffer shift required, find the count of updatebuffers */ - for( mesh.updatebuffershift = 0 ; ( threadcount >> mesh.updatebuffershift ) > MD_THREAD_UPDATE_BUFFER_COUNTMAX ; mesh.updatebuffershift++ ); - mesh.updatebuffercount = ( ( threadcount - 1 ) >> mesh.updatebuffershift ) + 1; - - /* Runtime picking of collapse penalty computation path */ - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangle; - -#ifdef MD_CONFIG_SSE_SUPPORT - #ifndef MD_CONF_DOUBLE_PRECISION - if( ( mdCpuInfo.capsse4p1 ) && ( mdPathSSE4p1 & 0x1 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE4.1 Float\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE4p1f; - } - else if( ( mdCpuInfo.capsse3 ) && ( mdPathSSE3 & 0x1 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE3 Float\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE3f; - } - else if( ( mdCpuInfo.capsse2 ) && ( mdPathSSE2 & 0x1 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE2 Float\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE2f; - } - #else - if( ( mdCpuInfo.capsse4p1 ) && ( mdPathSSE4p1 & 0x2 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE4.1 Double\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE4p1d; - } - else if( ( mdCpuInfo.capsse3 ) && ( mdPathSSE3 & 0x2 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE3 Double\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE3d; - } - else if( ( mdCpuInfo.capsse2 ) && ( mdPathSSE2 & 0x2 ) ) - { - #ifdef DEBUG_VERBOSE - printf( "PATH : SSE2 Double\n" ); - #endif - mesh.collapsepenalty = mdEdgeCollapsePenaltyTriangleSSE2d; - } - #endif -#endif - - - /* Initialize entire mesh storage */ - mesh.vertexalloc = operation->vertexalloc; - if( mesh.vertexalloc < mesh.vertexcount ) - mesh.vertexalloc = mesh.vertexcount; - if( !( mdMeshInit( &mesh, operation->maxmemorysize ) ) ) - goto error; - - mesh.updatestatusflag = 0; - status.progress = 0.0; - statuswait = ( operation->statusmiliseconds > 10 ? operation->statusmiliseconds : 10 ); - status.trianglecount = 0; - if( operation->statuscallback ) - { - mesh.updatestatusflag = 1; - mdUpdateStatus( &mesh, 0, MD_STATUS_STAGE_INIT, &status ); - operation->statuscallback( operation->statusopaquepointer, &status ); - } - - /* Launch threads! */ - tinit = threadinit; - for( threadid = 0 ; threadid < threadcount ; threadid++, tinit++ ) - { - tinit->threadid = threadid; - tinit->mesh = &mesh; - tinit->stage = MD_STATUS_STAGE_INIT; - mtThreadCreate( &thread[threadid], mdThreadMain, tinit, MT_THREAD_FLAGS_JOINABLE, 0, 0 ); - } - - /* Wait until all threads have properly initialized */ - if( mesh.updatestatusflag ) - mdBarrierSync( &mesh.globalbarrier ); - - /* Wait for all threads to reach step 3 */ -#ifdef MD_CONF_ENABLE_PROGRESS - if( !( mesh.updatestatusflag ) ) - mdBarrierSync( &mesh.globalbarrier ); - else - { - for( ; !( mdBarrierSyncTimeout( &mesh.globalbarrier, statuswait ) ) ; ) - { - mdUpdateStatus( &mesh, threadinit, 0, &status ); - operation->statuscallback( operation->statusopaquepointer, &status ); - } - } -#else - mdBarrierSync( &mesh.globalbarrier ); -#endif - - /* Build mesh step 3 is not parallel, have the main thread run it */ - mdMeshInitTrirefs( &mesh ); - - /* Wake up all threads */ - mdBarrierSync( &mesh.globalbarrier ); - - /* Wait for all threads to complete */ -#ifdef MD_CONF_ENABLE_PROGRESS - if( !( mesh.updatestatusflag ) ) - mdBarrierSync( &mesh.globalbarrier ); - else - { - for( ; !( mdBarrierSyncTimeout( &mesh.globalbarrier, statuswait ) ) ; ) - { - mdUpdateStatus( &mesh, threadinit, 0, &status ); - operation->statuscallback( operation->statusopaquepointer, &status ); - } - } - deletioncount = 0; - for( threadid = 0 ; threadid < threadcount ; threadid++ ) - { - deletioncount += threadinit[threadid].deletioncount; - mtThreadJoin( &thread[threadid] ); - } - status.trianglecount = mesh.tricount - deletioncount; -#else - mdBarrierSync( &mesh.globalbarrier ); - for( threadid = 0 ; threadid < threadcount ; threadid++ ) - mtThreadJoin( &thread[threadid] ); -#endif - - /* Count sums of all threads */ - operation->decimationcount = 0; - tinit = threadinit; - for( threadid = 0 ; threadid < threadcount ; threadid++, tinit++ ) - operation->decimationcount += tinit->decimationcount; - - if( mesh.updatestatusflag ) - { - mdUpdateStatus( &mesh, 0, MD_STATUS_STAGE_STORE, &status ); - operation->statuscallback( operation->statusopaquepointer, &status ); - } - - /* Write out the final mesh */ - if( operation->normalattrib.base ) - mdMeshRecomputeNormals( &mesh, &operation->normalattrib ); - else - { - mdMeshWriteVertices( &mesh, 0, 0 ); - mdMeshWriteIndices( &mesh ); - } - operation->vertexcount = mesh.vertexpackcount; - operation->tricount = mesh.tripackcount; - - if( mesh.updatestatusflag ) - { - mdUpdateStatus( &mesh, 0, MD_STATUS_STAGE_DONE, &status ); - operation->statuscallback( operation->statusopaquepointer, &status ); - } - - /* Requires mmhash.c compiled with MM_HASH_DEBUG_STATISTICS */ -#ifdef MM_HASH_DEBUG_STATISTICS - { - long accesscount, collisioncount, relocationcount; - long entrycount, entrycountmax, hashsizemax; - - mmHashStatistics( mesh.edgehashtable, &accesscount, &collisioncount, &relocationcount, &entrycount, &entrycountmax, &hashsizemax ); - - printf( "Hash Access : %ld\n", accesscount ); - printf( "Hash Collision : %ld\n", collisioncount ); - printf( "Hash Relocation : %ld\n", relocationcount ); - printf( "Entry Count : %ld\n", entrycount ); - printf( "Entry Count Max : %ld\n", entrycountmax ); - printf( "Hash Size Max : %ld\n", hashsizemax ); - } -#endif - - /* Free all global data */ - error: - if( !( mesh.operationflags & MD_FLAGS_NO_DECIMATION ) ) - mdMeshHashEnd( &mesh ); - mdMeshEnd( &mesh ); - mdBarrierDestroy( &mesh.workbarrier ); - mdBarrierDestroy( &mesh.globalbarrier ); - - /* Store total processing time */ - operation->msecs = mmGetMillisecondsTime() - operation->msecs; - - return 1; -} - - - - diff --git a/src/other/gct/MeshDecimation/meshdecimation.h b/src/other/gct/MeshDecimation/meshdecimation.h deleted file mode 100644 index bf7b3d84132..00000000000 --- a/src/other/gct/MeshDecimation/meshdecimation.h +++ /dev/null @@ -1,148 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#ifdef __cplusplus -extern "C" { -#endif - - -#define MD_ATTRIB_MAX (16) - - -typedef struct -{ - void *base; - int width; - size_t count; - size_t stride; - int flags; -} mdOpAttrib; - - -typedef struct -{ - double progress; - int stage; - const char *stagename; - long trianglecount; -} mdStatus; - -enum -{ - MD_STATUS_STAGE_INIT, - MD_STATUS_STAGE_BUILDVERTICES, - MD_STATUS_STAGE_BUILDTRIANGLES, - MD_STATUS_STAGE_BUILDTRIREFS, - MD_STATUS_STAGE_BUILDQUEUE, - MD_STATUS_STAGE_DECIMATION, - MD_STATUS_STAGE_STORE, - MD_STATUS_STAGE_DONE, - - MD_STATUS_STAGE_COUNT -}; - - -typedef struct -{ - size_t vertexcount; - void *vertex; - int vertexwidth; - size_t vertexstride; - size_t vertexalloc; - - void *indices; - int indiceswidth; - size_t indicesstride; - size_t tricount; - - double decimationstrength; - int decimationcount; - - int attribcount; - mdOpAttrib attrib[MD_ATTRIB_MAX]; - mdOpAttrib normalattrib; - - long msecs; - - /* Status callback */ - long statusmiliseconds; - void *statusopaquepointer; - void (*statuscallback)( void *opaquepointer, const mdStatus *status ); - - /* Advanced configuration options */ - double compactnesstarget; - double compactnesspenalty; - int syncstepcount; - double normalsearchangle; - size_t maxmemorysize; - -} mdOperation; - - -/* - * This function exists only to read CPUID and NUMA information once in a thread safe - * manner, in case you want to launch multiple mdMeshDecimation() simultaneously. - */ -void mdInit(); - - -/* - * Set up the mdOperation struct to configure a mesh decimation task. - */ -void mdOperationInit( mdOperation *op ); -void mdOperationData( mdOperation *op, size_t vertexcount, void *vertex, int vertexwidth, size_t vertexstride, size_t tricount, void *indices, int indiceswidth, size_t indicesstride ); -int mdOperationAddAttrib( mdOperation *op, void *base, int width, size_t count, size_t stride, int flags ); -void mdOperationStrength( mdOperation *op, double decimationstrength ); -void mdOperationStatusCallback( mdOperation *op, void (*statuscallback)( void *opaquepointer, const mdStatus *status ), void *opaquepointer, long miliseconds ); - -#define MD_ATTRIB_FLAGS_NORMALIZE (0x1) -#define MD_ATTRIB_FLAGS_COMPUTE_NORMALS (0x2) - - -/* - * Decimate the mesh specifed by the mdOperation struct. - */ -int mdMeshDecimation( mdOperation *operation, int threadcount, int flags ); - -/* Slightly increases the quality of the mesh decimation */ -#define MD_FLAGS_CONTINUOUS_UPDATE (0x1) -/* Do not pack vertices */ -#define MD_FLAGS_NO_VERTEX_PACKING (0x2) -/* Allow cloning/splitting of vertices with diverging normals when recomputing normals */ -#define MD_FLAGS_NORMAL_VERTEX_SPLITTING (0x4) -/* Define orientation of triangles when rebuilding normals */ -#define MD_FLAGS_TRIANGLE_WINDING_CW (0x8) -#define MD_FLAGS_TRIANGLE_WINDING_CCW (0x10) -/* Do not actually do any decimation, in case all you actually want to do is to recompute normals */ -#define MD_FLAGS_NO_DECIMATION (0x20) - - - -#ifdef __cplusplus -} -#endif - diff --git a/src/other/gct/MeshDecimation/meshdecimationSSE2.c b/src/other/gct/MeshDecimation/meshdecimationSSE2.c deleted file mode 100644 index 1336a10e400..00000000000 --- a/src/other/gct/MeshDecimation/meshdecimationSSE2.c +++ /dev/null @@ -1,275 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -#include "mm.h" -#include "mmhash.h" -#include "math3d.h" - -#include "mmbinsort.h" -#include "meshdecimation.h" - - -#ifdef __SSE__ - #include -#endif -#ifdef __SSE2__ - #include -#endif -#ifdef __SSE3__ - #include -#endif -#ifdef __SSSE3__ - #include -#endif -#ifdef __SSE4A__ - #include -#endif -#ifdef __SSE4_1__ - #include -#endif - - -/****/ - - -#ifdef __SSE2__ - #define MD_CONFIG_SSE2_SUPPORT -#else - #warning "SSE2 wasn't enabled to compile this file." -#endif - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - #define RF_ALIGN16 __attribute__((aligned(16))) -#elif defined(_MSC_VER) - #define RF_ALIGN16 __declspec(align(16)) -#else - #define RF_ALIGN16 - #warning "SSE Disabled: Unsupported Compiler." - #ifdef MD_CONFIG_SSE2_SUPPORT - #undef MD_CONFIG_SSE2_SUPPORT - #endif -#endif - - - -#define MD_CONFIG_SSE_APPROX - - - -#ifdef MD_CONFIG_SSE2_SUPPORT - -typedef union -{ - __m128 v; - float f[4]; -} m128f; - -int mdPathSSE2 = 0x1 | 0x2; - - -#define MD_COMPACTNESS_NORMALIZATION_FACTOR (0.5*4.0*1.732050808) - -float mdEdgeCollapsePenaltyTriangleSSE2f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ) -{ - float penalty, compactness, oldcompactness, newcompactness, vectadp, norm; - __m128 left; - m128f vecta, oldvectb, oldvectc, newvectb, newvectc, oldnormal, newnormal; - - /* Normal of old triangle */ - left = _mm_load_ps( leftpoint ); - vecta.v = _mm_sub_ps( _mm_load_ps( rightpoint ), left ); - oldvectb.v = _mm_sub_ps( _mm_load_ps( oldpoint ), left ); - oldnormal.v = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta.v, vecta.v, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( oldvectb.v, oldvectb.v, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta.v, vecta.v, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( oldvectb.v, oldvectb.v, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Normal of new triangle */ - newvectb.v = _mm_sub_ps( _mm_load_ps( newpoint ), left ); - newnormal.v = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta.v, vecta.v, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( newvectb.v, newvectb.v, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta.v, vecta.v, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( newvectb.v, newvectb.v, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Detect normal inversion */ - if( M3D_VectorDotProduct( oldnormal.f, newnormal.f ) < 0.0 ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vectadp = M3D_VectorDotProduct( vecta.f, vecta.f ); - newvectc.v = _mm_sub_ps( _mm_load_ps( newpoint ), _mm_load_ps( rightpoint ) ); -#ifdef MD_CONFIG_SSE_APPROX - norm = vectadp + M3D_VectorDotProduct( newvectb.f, newvectb.f ) + M3D_VectorDotProduct( newvectc.f, newvectc.f ); - newcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( _mm_set_ss( M3D_VectorDotProduct( newnormal.f, newnormal.f ) ) ), _mm_set_ss( norm ) ) ) ) ); - if( newcompactness < compactnesstarget ) - { -#else - newcompactness = MD_COMPACTNESS_NORMALIZATION_FACTOR * sqrtf( M3D_VectorDotProduct( newnormal.f, newnormal.f ) ); - norm = vectadp + M3D_VectorDotProduct( newvectb.f, newvectb.f ) + M3D_VectorDotProduct( newvectc.f, newvectc.f ); - if( newcompactness < ( compactnesstarget * norm ) ) - { - newcompactness /= norm; -#endif - oldvectc.v = _mm_sub_ps( _mm_load_ps( oldpoint ), _mm_load_ps( rightpoint ) ); -#ifdef MD_CONFIG_SSE_APPROX - norm = vectadp + M3D_VectorDotProduct( oldvectb.f, oldvectb.f ) + M3D_VectorDotProduct( oldvectc.f, oldvectc.f ); - oldcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( _mm_set_ss( M3D_VectorDotProduct( oldnormal.f, oldnormal.f ) ) ), _mm_set_ss( norm ) ) ) ) ); -#else - oldcompactness = ( MD_COMPACTNESS_NORMALIZATION_FACTOR * sqrtf( M3D_VectorDotProduct( oldnormal.f, oldnormal.f ) ) ) / ( vectadp + M3D_VectorDotProduct( oldvectb.f, oldvectb.f ) + M3D_VectorDotProduct( oldvectc.f, oldvectc.f ) ); -#endif - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - - - -double mdEdgeCollapsePenaltyTriangleSSE2d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ) -{ - __m128d vecta0, vecta1, oldvectb0, oldvectb1, oldvectc0, oldvectc1, newvectb0, newvectb1, newvectc0, newvectc1; - __m128d oldnormal0, oldnormal1, newnormal0, newnormal1; - __m128d dotprsum; - __m128d left0, left1; - double newcompactness, oldcompactness, compactness, penalty, norm; - static double zero = 0.0; - - /* Normal of old triangle */ - left0 = _mm_load_pd( leftpoint+0 ); - left1 = _mm_load_sd( leftpoint+2 ); - vecta0 = _mm_sub_pd( _mm_load_pd( rightpoint+0 ), left0 ); - vecta1 = _mm_sub_pd( _mm_load_pd( rightpoint+2 ), left1 ); - oldvectb0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), left0 ); - oldvectb1 = _mm_sub_pd( _mm_load_pd( oldpoint+2 ), left1 ); - oldnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( oldvectb1, oldvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( oldvectb0, oldvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - oldnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( oldvectb0, oldvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), oldvectb0 ) - ); - - /* Normal of new triangle */ - newvectb0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), left0 ); - newvectb1 = _mm_sub_pd( _mm_load_pd( newpoint+2 ), left1 ); - newnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( newvectb1, newvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( newvectb0, newvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - newnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( newvectb0, newvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), newvectb0 ) - ); - - /* Detect normal inversion */ - dotprsum = _mm_mul_pd( oldnormal0, newnormal0 ); - dotprsum = _mm_add_sd( _mm_add_sd( dotprsum, _mm_unpackhi_pd( dotprsum, dotprsum ) ), _mm_mul_sd( oldnormal1, newnormal1 ) ); - if( _mm_comilt_sd( dotprsum, _mm_load_sd( &zero ) ) ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta0 = _mm_mul_pd( vecta0, vecta0 ); - vecta0 = _mm_add_sd( _mm_add_sd( vecta0, _mm_unpackhi_pd( vecta0, vecta0 ) ), _mm_mul_sd( vecta1, vecta1 ) ); - newvectc0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - newvectc1 = _mm_sub_sd( _mm_load_sd( newpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - newnormal0 = _mm_mul_pd( newnormal0, newnormal0 ); - newnormal0 = _mm_add_sd( _mm_add_sd( newnormal0, _mm_unpackhi_pd( newnormal0, newnormal0 ) ), _mm_mul_sd( newnormal1, newnormal1 ) ); - newvectb0 = _mm_mul_pd( newvectb0, newvectb0 ); - newvectb0 = _mm_add_sd( _mm_add_sd( newvectb0, _mm_unpackhi_pd( newvectb0, newvectb0 ) ), _mm_mul_sd( newvectb1, newvectb1 ) ); - newvectc0 = _mm_mul_pd( newvectc0, newvectc0 ); - newvectc0 = _mm_add_sd( _mm_add_sd( newvectc0, _mm_unpackhi_pd( newvectc0, newvectc0 ) ), _mm_mul_sd( newvectc1, newvectc1 ) ); - norm = _mm_cvtsd_f64( _mm_add_sd( vecta0, _mm_add_sd( newvectb0, newvectc0 ) ) ); - newcompactness = _mm_cvtsd_f64( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( newnormal0, newnormal0 ) ) ); - if( newcompactness < ( compactnesstarget * norm ) ) - { - newcompactness /= norm; - oldvectc0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - oldvectc1 = _mm_sub_sd( _mm_load_sd( oldpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - oldnormal0 = _mm_mul_pd( oldnormal0, oldnormal0 ); - oldnormal0 = _mm_add_sd( _mm_add_sd( oldnormal0, _mm_unpackhi_pd( oldnormal0, oldnormal0 ) ), _mm_mul_sd( oldnormal1, oldnormal1 ) ); - oldvectb0 = _mm_mul_pd( oldvectb0, oldvectb0 ); - oldvectb0 = _mm_add_sd( _mm_add_sd( oldvectb0, _mm_unpackhi_pd( oldvectb0, oldvectb0 ) ), _mm_mul_sd( oldvectb1, oldvectb1 ) ); - oldvectc0 = _mm_mul_pd( oldvectc0, oldvectc0 ); - oldvectc0 = _mm_add_sd( _mm_add_sd( oldvectc0, _mm_unpackhi_pd( oldvectc0, oldvectc0 ) ), _mm_mul_sd( oldvectc1, oldvectc1 ) ); - oldcompactness = _mm_cvtsd_f64( _mm_div_sd( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( oldnormal0, oldnormal0 ) ), _mm_add_sd( vecta0, _mm_add_sd( oldvectb0, oldvectc0 ) ) ) ); - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - -#else - - -int mdPathSSE2 = 0x0; - -float mdEdgeCollapsePenaltyTriangleSSE2f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag ) -{ - return 0.0; -} - -double mdEdgeCollapsePenaltyTriangleSSE2d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag ) -{ - return 0.0; -} - - -#endif - - - - diff --git a/src/other/gct/MeshDecimation/meshdecimationSSE3.c b/src/other/gct/MeshDecimation/meshdecimationSSE3.c deleted file mode 100644 index aeb23437dc0..00000000000 --- a/src/other/gct/MeshDecimation/meshdecimationSSE3.c +++ /dev/null @@ -1,286 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -#include "mm.h" -#include "mmhash.h" -#include "math3d.h" - -#include "mmbinsort.h" -#include "meshdecimation.h" - - -#ifdef __SSE__ - #include -#endif -#ifdef __SSE2__ - #include -#endif -#ifdef __SSE3__ - #include -#endif -#ifdef __SSSE3__ - #include -#endif -#ifdef __SSE4A__ - #include -#endif -#ifdef __SSE4_1__ - #include -#endif - - -/****/ - - -#ifdef __SSE3__ - #define MD_CONFIG_SSE3_SUPPORT -#else - #warning "SSE3 wasn't enabled to compile this file." -#endif - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - #define RF_ALIGN16 __attribute__((aligned(16))) -#elif defined(_MSC_VER) - #define RF_ALIGN16 __declspec(align(16)) -#else - #define RF_ALIGN16 - #warning "SSE Disabled: Unsupported Compiler." - #ifdef MD_CONFIG_SSE3_SUPPORT - #undef MD_CONFIG_SSE3_SUPPORT - #endif -#endif - - - -#define MD_CONFIG_SSE_APPROX - - - -#ifdef MD_CONFIG_SSE3_SUPPORT - - -int mdPathSSE3 = 0x1 | 0x2; - - -#define MD_COMPACTNESS_NORMALIZATION_FACTOR (0.5*4.0*1.732050808) - -float mdEdgeCollapsePenaltyTriangleSSE3f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ) -{ - float penalty, compactness, oldcompactness, newcompactness; - static float zero = 0.0; - __m128 left, vecta, oldvectb, oldvectc, newvectb, newvectc, oldnormal, newnormal, dotproduct; - - /* Normal of old triangle */ - left = _mm_load_ps( leftpoint ); - vecta = _mm_sub_ps( _mm_load_ps( rightpoint ), left ); - oldvectb = _mm_sub_ps( _mm_load_ps( oldpoint ), left ); - oldnormal = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( oldvectb, oldvectb, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( oldvectb, oldvectb, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Normal of new triangle */ - newvectb = _mm_sub_ps( _mm_load_ps( newpoint ), left ); - newnormal = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( newvectb, newvectb, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( newvectb, newvectb, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Detect normal inversion */ - dotproduct = _mm_mul_ps( oldnormal, newnormal ); - dotproduct = _mm_hadd_ps( dotproduct, dotproduct ); - dotproduct = _mm_hadd_ps( dotproduct, dotproduct ); - if( _mm_comilt_ss( dotproduct, _mm_load_ss( &zero ) ) ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta = _mm_mul_ps( vecta, vecta ); - vecta = _mm_hadd_ps( vecta, vecta ); - vecta = _mm_hadd_ps( vecta, vecta ); - newvectc = _mm_sub_ps( _mm_load_ps( newpoint ), _mm_load_ps( rightpoint ) ); - newnormal = _mm_mul_ps( newnormal, newnormal ); - newnormal = _mm_hadd_ps( newnormal, newnormal ); - newnormal = _mm_hadd_ps( newnormal, newnormal ); - newvectb = _mm_mul_ps( newvectb, newvectb ); - newvectb = _mm_hadd_ps( newvectb, newvectb ); - newvectb = _mm_hadd_ps( newvectb, newvectb ); - newvectc = _mm_mul_ps( newvectc, newvectc ); - newvectc = _mm_hadd_ps( newvectc, newvectc ); - newvectc = _mm_hadd_ps( newvectc, newvectc ); -#ifdef MD_CONFIG_SSE_APPROX - newcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( newnormal ), _mm_add_ss( _mm_add_ss( vecta, newvectb ), newvectc ) ) ) ) ); -#else - newcompactness = _mm_cvtss_f32( _mm_div_ss( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_ss( newnormal ) ), _mm_add_ss( _mm_add_ss( vecta, newvectb ), newvectc ) ) ); -#endif - if( newcompactness < compactnesstarget ) - { - oldvectc = _mm_sub_ps( _mm_load_ps( oldpoint ), _mm_load_ps( rightpoint ) ); - oldnormal = _mm_mul_ps( oldnormal, oldnormal ); - oldnormal = _mm_hadd_ps( oldnormal, oldnormal ); - oldnormal = _mm_hadd_ps( oldnormal, oldnormal ); - oldvectb = _mm_mul_ps( oldvectb, oldvectb ); - oldvectb = _mm_hadd_ps( oldvectb, oldvectb ); - oldvectb = _mm_hadd_ps( oldvectb, oldvectb ); - oldvectc = _mm_mul_ps( oldvectc, oldvectc ); - oldvectc = _mm_hadd_ps( oldvectc, oldvectc ); - oldvectc = _mm_hadd_ps( oldvectc, oldvectc ); -#ifdef MD_CONFIG_SSE_APPROX - oldcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( oldnormal ), _mm_add_ss( _mm_add_ss( vecta, oldvectb ), oldvectc ) ) ) ) ); -#else - oldcompactness = _mm_cvtss_f32( _mm_div_ss( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_ss( oldnormal ) ), _mm_add_ss( _mm_add_ss( vecta, oldvectb ), oldvectc ) ) ); -#endif - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - - -double mdEdgeCollapsePenaltyTriangleSSE3d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ) -{ - __m128d vecta0, vecta1, oldvectb0, oldvectb1, oldvectc0, oldvectc1, newvectb0, newvectb1, newvectc0, newvectc1; - __m128d oldnormal0, oldnormal1, newnormal0, newnormal1; - __m128d dotprsum; - __m128d left0, left1; - double newcompactness, oldcompactness, compactness, penalty, norm; - static double zero = 0.0; - - /* Normal of old triangle */ - left0 = _mm_load_pd( leftpoint+0 ); - left1 = _mm_load_sd( leftpoint+2 ); - vecta0 = _mm_sub_pd( _mm_load_pd( rightpoint+0 ), left0 ); - vecta1 = _mm_sub_pd( _mm_load_pd( rightpoint+2 ), left1 ); - oldvectb0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), left0 ); - oldvectb1 = _mm_sub_pd( _mm_load_pd( oldpoint+2 ), left1 ); - oldnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( oldvectb1, oldvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( oldvectb0, oldvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - oldnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( oldvectb0, oldvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), oldvectb0 ) - ); - - /* Normal of new triangle */ - newvectb0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), left0 ); - newvectb1 = _mm_sub_pd( _mm_load_pd( newpoint+2 ), left1 ); - newnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( newvectb1, newvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( newvectb0, newvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - newnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( newvectb0, newvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), newvectb0 ) - ); - - /* Detect normal inversion */ - dotprsum = _mm_mul_pd( oldnormal0, newnormal0 ); - dotprsum = _mm_add_sd( _mm_hadd_pd( dotprsum, dotprsum ), _mm_mul_sd( oldnormal1, newnormal1 ) ); - if( _mm_comilt_sd( dotprsum, _mm_load_sd( &zero ) ) ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta0 = _mm_mul_pd( vecta0, vecta0 ); - vecta0 = _mm_add_sd( _mm_hadd_pd( vecta0, vecta0 ), _mm_mul_sd( vecta1, vecta1 ) ); - newvectc0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - newvectc1 = _mm_sub_sd( _mm_load_sd( newpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - newnormal0 = _mm_mul_pd( newnormal0, newnormal0 ); - newnormal0 = _mm_add_sd( _mm_hadd_pd( newnormal0, newnormal0 ), _mm_mul_sd( newnormal1, newnormal1 ) ); - newvectb0 = _mm_mul_pd( newvectb0, newvectb0 ); - newvectb0 = _mm_add_sd( _mm_hadd_pd( newvectb0, newvectb0 ), _mm_mul_sd( newvectb1, newvectb1 ) ); - newvectc0 = _mm_mul_pd( newvectc0, newvectc0 ); - newvectc0 = _mm_add_sd( _mm_hadd_pd( newvectc0, newvectc0 ), _mm_mul_sd( newvectc1, newvectc1 ) ); - norm = _mm_cvtsd_f64( _mm_add_sd( vecta0, _mm_add_sd( newvectb0, newvectc0 ) ) ); - newcompactness = _mm_cvtsd_f64( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( newnormal0, newnormal0 ) ) ); - if( newcompactness < ( compactnesstarget * norm ) ) - { - newcompactness /= norm; - oldvectc0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - oldvectc1 = _mm_sub_sd( _mm_load_sd( oldpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - oldnormal0 = _mm_mul_pd( oldnormal0, oldnormal0 ); - oldnormal0 = _mm_add_sd( _mm_hadd_pd( oldnormal0, oldnormal0 ), _mm_mul_sd( oldnormal1, oldnormal1 ) ); - oldvectb0 = _mm_mul_pd( oldvectb0, oldvectb0 ); - oldvectb0 = _mm_add_sd( _mm_hadd_pd( oldvectb0, oldvectb0 ), _mm_mul_sd( oldvectb1, oldvectb1 ) ); - oldvectc0 = _mm_mul_pd( oldvectc0, oldvectc0 ); - oldvectc0 = _mm_add_sd( _mm_hadd_pd( oldvectc0, oldvectc0 ), _mm_mul_sd( oldvectc1, oldvectc1 ) ); - oldcompactness = _mm_cvtsd_f64( _mm_div_sd( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( oldnormal0, oldnormal0 ) ), _mm_add_sd( vecta0, _mm_add_sd( oldvectb0, oldvectc0 ) ) ) ); - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - -#else - - -int mdPathSSE3 = 0x0; - -float mdEdgeCollapsePenaltyTriangleSSE3f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag ) -{ - return 0.0; -} - -double mdEdgeCollapsePenaltyTriangleSSE3d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag ) -{ - return 0.0; -} - - -#endif - - - - diff --git a/src/other/gct/MeshDecimation/meshdecimationSSE4p1.c b/src/other/gct/MeshDecimation/meshdecimationSSE4p1.c deleted file mode 100644 index 6b202028115..00000000000 --- a/src/other/gct/MeshDecimation/meshdecimationSSE4p1.c +++ /dev/null @@ -1,261 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -#include "mm.h" -#include "mmhash.h" -#include "math3d.h" - -#include "mmbinsort.h" -#include "meshdecimation.h" - - -#ifdef __SSE__ - #include -#endif -#ifdef __SSE2__ - #include -#endif -#ifdef __SSE3__ - #include -#endif -#ifdef __SSSE3__ - #include -#endif -#ifdef __SSE4A__ - #include -#endif -#ifdef __SSE4_1__ - #include -#endif - - -/****/ - - -#ifdef __SSE4_1__ - #define MD_CONFIG_SSE4_1_SUPPORT -#else - #warning "SSE4.1 wasn't enabled to compile this file." -#endif - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - #define RF_ALIGN16 __attribute__((aligned(16))) -#elif defined(_MSC_VER) - #define RF_ALIGN16 __declspec(align(16)) -#else - #define RF_ALIGN16 - #warning "SSE Disabled: Unsupported Compiler." - #ifdef MD_CONFIG_SSE4_1_SUPPORT - #undef MD_CONFIG_SSE4_1_SUPPORT - #endif -#endif - - - -#define MD_CONFIG_SSE_APPROX - - - -#ifdef MD_CONFIG_SSE4_1_SUPPORT - - -int mdPathSSE4p1 = 0x1 | 0x2; - - -#define MD_COMPACTNESS_NORMALIZATION_FACTOR (0.5*4.0*1.732050808) - -float mdEdgeCollapsePenaltyTriangleSSE4p1f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag, float compactnesstarget ) -{ - float penalty, compactness, oldcompactness, newcompactness; - static float zero = 0.0; - __m128 left, vecta, oldvectb, oldvectc, newvectb, newvectc, oldnormal, newnormal; - - /* Normal of old triangle */ - left = _mm_load_ps( leftpoint ); - vecta = _mm_sub_ps( _mm_load_ps( rightpoint ), left ); - oldvectb = _mm_sub_ps( _mm_load_ps( oldpoint ), left ); - oldnormal = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( oldvectb, oldvectb, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( oldvectb, oldvectb, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Normal of new triangle */ - newvectb = _mm_sub_ps( _mm_load_ps( newpoint ), left ); - newnormal = _mm_sub_ps( - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,0,2,1) ), _mm_shuffle_ps( newvectb, newvectb, _MM_SHUFFLE(3,1,0,2) ) ), - _mm_mul_ps( _mm_shuffle_ps( vecta, vecta, _MM_SHUFFLE(3,1,0,2) ), _mm_shuffle_ps( newvectb, newvectb, _MM_SHUFFLE(3,0,2,1) ) ) - ); - - /* Detect normal inversion */ - if( _mm_comilt_ss( _mm_dp_ps( oldnormal, newnormal, 0x1 | 0x70 ), _mm_load_ss( &zero ) ) ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta = _mm_dp_ps( vecta, vecta, 0x1 | 0x70 ); - newvectc = _mm_sub_ps( _mm_load_ps( newpoint ), _mm_load_ps( rightpoint ) ); - newnormal = _mm_dp_ps( newnormal, newnormal, 0x1 | 0x70 ); - newvectb = _mm_dp_ps( newvectb, newvectb, 0x1 | 0x70 ); - newvectc = _mm_dp_ps( newvectc, newvectc, 0x1 | 0x70 ); -#ifdef MD_CONFIG_SSE_APPROX - newcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( newnormal ), _mm_add_ss( _mm_add_ss( vecta, newvectb ), newvectc ) ) ) ) ); -#else - newcompactness = _mm_cvtss_f32( _mm_div_ss( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_ss( newnormal ) ), _mm_add_ss( _mm_add_ss( vecta, newvectb ), newvectc ) ) ); -#endif - if( newcompactness < compactnesstarget ) - { - oldvectc = _mm_sub_ps( _mm_load_ps( oldpoint ), _mm_load_ps( rightpoint ) ); - oldnormal = _mm_dp_ps( oldnormal, oldnormal, 0x1 | 0x70 ); - oldvectb = _mm_dp_ps( oldvectb, oldvectb, 0x1 | 0x70 ); - oldvectc = _mm_dp_ps( oldvectc, oldvectc, 0x1 | 0x70 ); -#ifdef MD_CONFIG_SSE_APPROX - oldcompactness = _mm_cvtss_f32( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_rcp_ss( _mm_mul_ss( _mm_rsqrt_ss( oldnormal ), _mm_add_ss( _mm_add_ss( vecta, oldvectb ), oldvectc ) ) ) ) ); -#else - oldcompactness = _mm_cvtss_f32( _mm_div_ss( _mm_mul_ss( _mm_set_ss( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_ss( oldnormal ) ), _mm_add_ss( _mm_add_ss( vecta, oldvectb ), oldvectc ) ) ); -#endif - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - - -double mdEdgeCollapsePenaltyTriangleSSE4p1d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag, double compactnesstarget ) -{ - __m128d vecta0, vecta1, oldvectb0, oldvectb1, oldvectc0, oldvectc1, newvectb0, newvectb1, newvectc0, newvectc1; - __m128d oldnormal0, oldnormal1, newnormal0, newnormal1; - __m128d dotprsum; - __m128d left0, left1; - double newcompactness, oldcompactness, compactness, penalty, norm; - static double zero = 0.0; - - /* Normal of old triangle */ - left0 = _mm_load_pd( leftpoint+0 ); - left1 = _mm_load_sd( leftpoint+2 ); - vecta0 = _mm_sub_pd( _mm_load_pd( rightpoint+0 ), left0 ); - vecta1 = _mm_sub_pd( _mm_load_pd( rightpoint+2 ), left1 ); - oldvectb0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), left0 ); - oldvectb1 = _mm_sub_pd( _mm_load_pd( oldpoint+2 ), left1 ); - oldnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( oldvectb1, oldvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( oldvectb0, oldvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - oldnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( oldvectb0, oldvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), oldvectb0 ) - ); - - /* Normal of new triangle */ - newvectb0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), left0 ); - newvectb1 = _mm_sub_pd( _mm_load_pd( newpoint+2 ), left1 ); - newnormal0 = _mm_sub_pd( - _mm_mul_pd( _mm_shuffle_pd( vecta0, vecta1, _MM_SHUFFLE2(0,1) ), _mm_unpacklo_pd( newvectb1, newvectb0 ) ), - _mm_mul_pd( _mm_unpacklo_pd( vecta1, vecta0 ), _mm_shuffle_pd( newvectb0, newvectb1, _MM_SHUFFLE2(0,1) ) ) - ); - newnormal1 = _mm_sub_sd( - _mm_mul_sd( vecta0, _mm_unpackhi_pd( newvectb0, newvectb0 ) ), - _mm_mul_sd( _mm_unpackhi_pd( vecta0, vecta0 ), newvectb0 ) - ); - - /* Detect normal inversion */ - dotprsum = _mm_add_sd( _mm_dp_pd( oldnormal0, oldnormal0, 0x1 | 0x30 ), _mm_mul_sd( oldnormal1, newnormal1 ) ); - if( _mm_comilt_sd( dotprsum, _mm_load_sd( &zero ) ) ) - { - *denyflag = 1; - return 0.0; - } - - /* Penalize long thin triangles */ - penalty = 0.0; - vecta0 = _mm_add_sd( _mm_dp_pd( vecta0, vecta0, 0x1 | 0x30 ), _mm_mul_sd( vecta1, vecta1 ) ); - newvectc0 = _mm_sub_pd( _mm_load_pd( newpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - newvectc1 = _mm_sub_sd( _mm_load_sd( newpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - newnormal0 = _mm_add_sd( _mm_dp_pd( newnormal0, newnormal0, 0x1 | 0x30 ), _mm_mul_sd( newnormal1, newnormal1 ) ); - newvectb0 = _mm_add_sd( _mm_dp_pd( newvectb0, newvectb0, 0x1 | 0x30 ), _mm_mul_sd( newvectb1, newvectb1 ) ); - newvectc0 = _mm_add_sd( _mm_dp_pd( newvectc0, newvectc0, 0x1 | 0x30 ), _mm_mul_sd( newvectc1, newvectc1 ) ); - norm = _mm_cvtsd_f64( _mm_add_sd( vecta0, _mm_add_sd( newvectb0, newvectc0 ) ) ); - newcompactness = _mm_cvtsd_f64( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( newnormal0, newnormal0 ) ) ); - if( newcompactness < ( compactnesstarget * norm ) ) - { - newcompactness /= norm; - oldvectc0 = _mm_sub_pd( _mm_load_pd( oldpoint+0 ), _mm_load_pd( rightpoint+0 ) ); - oldvectc1 = _mm_sub_sd( _mm_load_sd( oldpoint+2 ), _mm_load_sd( rightpoint+2 ) ); - oldnormal0 = _mm_add_sd( _mm_dp_pd( oldnormal0, oldnormal0, 0x1 | 0x30 ), _mm_mul_sd( oldnormal1, oldnormal1 ) ); - oldvectb0 = _mm_add_sd( _mm_dp_pd( oldvectb0, oldvectb0, 0x1 | 0x30 ), _mm_mul_sd( oldvectb1, oldvectb1 ) ); - oldvectc0 = _mm_add_sd( _mm_dp_pd( oldvectc0, oldvectc0, 0x1 | 0x30 ), _mm_mul_sd( oldvectc1, oldvectc1 ) ); - oldcompactness = _mm_cvtsd_f64( _mm_div_sd( _mm_mul_sd( _mm_set_sd( MD_COMPACTNESS_NORMALIZATION_FACTOR ), _mm_sqrt_sd( oldnormal0, oldnormal0 ) ), _mm_add_sd( vecta0, _mm_add_sd( oldvectb0, oldvectc0 ) ) ) ); - compactness = fmin( compactnesstarget, oldcompactness ) - newcompactness; - if( compactness > 0.0 ) - penalty = compactness; - } - - return penalty; -} - - -#else - - -int mdPathSSE4p1 = 0x0; - -float mdEdgeCollapsePenaltyTriangleSSE4p1f( float *newpoint, float *oldpoint, float *leftpoint, float *rightpoint, int *denyflag ) -{ - return 0.0; -} - -double mdEdgeCollapsePenaltyTriangleSSE4p1d( double *newpoint, double *oldpoint, double *leftpoint, double *rightpoint, int *denyflag ) -{ - return 0.0; -} - - -#endif - - - - diff --git a/src/other/gct/MeshDecimation/meshoptimization.cpp b/src/other/gct/MeshDecimation/meshoptimization.cpp deleted file mode 100644 index 22764d12a82..00000000000 --- a/src/other/gct/MeshDecimation/meshoptimization.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* meshoptimization.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/26/13 - * - * Authors(s): - * DRH - * - * Description: - * Mesh optimization routine. - * - */ - -// System headers -#include - -// Local headers -#include "meshoptimization.h" - -void -mesh_optimization (long vertexcount, - long tricount, - void *indices, - int indiceswidth, - int threadcount, - int optimizationlevel -#if DEBUG_MESH_OPTIMIZATION_VERBOSE - , std::string rname -#endif - ) -{ - int depth, flags, maxthreadcount; - switch( optimizationlevel ) - { - case 3: - depth = 32; - flags = 0; - break; - case 2: - depth = 32; - flags = OPTIMIZATION_FLAGS; - break; - case 1: - depth = 16; - flags = OPTIMIZATION_FLAGS; - break; - case 0: - default: - return; - } - maxthreadcount = tricount / 16384; - if( threadcount > maxthreadcount ) - threadcount = maxthreadcount; -#if DEBUG_MESH_OPTIMIZATION_VERBOSE - fprintf (stderr, "Optimizing %s...", rname.c_str()); -#endif - moOptimizeMesh (vertexcount, - tricount, - indices, indiceswidth, - 3*indiceswidth, 0, 0, - depth, - threadcount, - flags); -#if DEBUG_MESH_OPTIMIZATION_VERBOSE - fprintf (stderr, "Done.\n"); -#endif -} diff --git a/src/other/gct/MeshDecimation/meshoptimization.h b/src/other/gct/MeshDecimation/meshoptimization.h deleted file mode 100644 index bdd3eeb14ed..00000000000 --- a/src/other/gct/MeshDecimation/meshoptimization.h +++ /dev/null @@ -1,74 +0,0 @@ -/* meshoptimization.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/26/13 - * - * Authors(s): - * DRH - * - * Description: - * Mesh optimization routine. - * - */ - -#ifndef MESHOPTIMIZATION_H -#define MESHOPTIMIZATION_H - -// Standard headers -#include - -// Local headers -#include "meshoptimizer.h" - -#define OPTIMIZATION_FLAGS MO_FLAGS_DISABLE_LOOK_AHEAD | \ - MO_FLAGS_ENABLE_LAZY_SEARCH | \ - MO_FLAGS_FAST_SEED_SELECT -#define DEBUG_MESH_OPTIMIZATION_VERBOSE 0 - -#ifdef __cplusplus -extern "C" { -#endif - -void -mesh_optimization (long vertexcount, - long tricount, - void *indices, - int indiceswidth, - int threadcount, - int optimizationlevel -#if DEBUG_MESH_OPTIMIZATION_VERBOSE - , std::string rname -#endif - ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/other/gct/MeshDecimation/meshoptimizer.c b/src/other/gct/MeshDecimation/meshoptimizer.c deleted file mode 100644 index 4f002c9e937..00000000000 --- a/src/other/gct/MeshDecimation/meshoptimizer.c +++ /dev/null @@ -1,1668 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include - - -#include "cpuconfig.h" - -#include "cpuinfo.h" - -#include "cc.h" -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#include "mm.h" -#include "mmhash.h" -#include "math3d.h" - -#include "meshoptimizer.h" - - - -#ifdef MM_ATOMIC_SUPPORT - #define MO_CONFIG_ATOMIC_SUPPORT -#endif - - - -/* -#define DEBUG_VERBOSE -#define DEBUG_VERBOSE_TIME -*/ - - - -#ifdef DEBUG_VERBOSE - #define MO_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);if(f) exit(1);}) -#else - #define MO_ERROR(s,f,...) ({fprintf(stderr,s,__VA_ARGS__);}) -#endif - - -#ifdef CPUCONF_CORES_COUNT - #define MO_THREAD_COUNT_DEFAULT CPUCONF_CORES_COUNT -#else - #define MO_THREAD_COUNT_DEFAULT (4) -#endif -#define MO_THREAD_COUNT_MAX (64) - - -//// - - -typedef int moi; -typedef float mof; - - -#define MO_VERTEX_CACHE_SIZE_MAX (64+1) -#define MO_TRIREFSCORE_COUNT (64) - - -#define MO_CACHE_HASH_SIZE_MAX (0x100) - - -//// - - -typedef struct -{ - mtMutex mutex; - mtSignal signal; - int resetcount; - volatile int index; - volatile int count[2]; -} moBarrier; - -static void moBarrierInit( moBarrier *barrier, int count ) -{ - mtMutexInit( &barrier->mutex ); - mtSignalInit( &barrier->signal ); - barrier->resetcount = count; - barrier->index = 0; - barrier->count[0] = count; - barrier->count[1] = count; - return; -} - -static void moBarrierDestroy( moBarrier *barrier ) -{ - mtMutexDestroy( &barrier->mutex ); - mtSignalDestroy( &barrier->signal ); - return; -} - -static int moBarrierSync( moBarrier *barrier ) -{ - int index, ret; - mtMutexLock( &barrier->mutex ); - index = barrier->index; - ret = 0; - if( !( --barrier->count[index] ) ) - { - ret = 1; - mtSignalBroadcast( &barrier->signal ); - index ^= 1; - barrier->index = index; - barrier->count[index] = barrier->resetcount; - } - else - { - for( ; barrier->count[index] ; ) - mtSignalWait( &barrier->signal, &barrier->mutex ); - } - mtMutexUnlock( &barrier->mutex ); - return ret; -} - -#if 0 // 2012-10-22 ch3: this function not currently used, so commented -static int moBarrierSyncTimeout( moBarrier *barrier, long miliseconds ) -{ - int index, ret; - mtMutexLock( &barrier->mutex ); - index = barrier->index; - ret = 0; - if( !( --barrier->count[index] ) ) - { - ret = 1; - mtSignalBroadcast( &barrier->signal ); - index ^= 1; - barrier->index = index; - barrier->count[index] = barrier->resetcount; - } - else - { - mtSignalWaitTimeout( &barrier->signal, &barrier->mutex, miliseconds ); - if( !( barrier->count[index] ) ) - ret = 1; - else - barrier->count[index]++; - } - mtMutexUnlock( &barrier->mutex ); - return ret; -} -#endif - - -//// - - -typedef struct -{ -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomic32 atomicowner; - mmAtomic32 atomictrirefcount; -#else - int owner; - mtSpin ownerspinlock; - moi trirefcount; -#endif - moi trirefbase; - moi redirectindex; -} moVertex; - -typedef struct -{ - moi v[3]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomic32 atomictrinext; -#else - moi trinext; - mtSpin spinlock; -#endif -} moTriangle; - -#define MO_TRINEXT_ENDOFLIST (-1) -#define MO_TRINEXT_PENDING (-2) - -typedef struct -{ - int threadcount; - uint32_t operationflags; - - void *indices; - size_t indicesstride; - void (*indicesUserToNative)( moi *dst, void *src ); - void (*indicesNativeToUser)( void *dst, moi *src ); - - moVertex *vertexlist; - moi vertexcount; - - moTriangle *trilist; - moi tricount; - - moi *trireflist; - moi trirefcount; - - /* Vertex shuffle */ - void *shuffleopaquepointer; - void (*shufflecallback)( void *opaquepointer, long newvertexindex, long oldvertexindex ); - - /* Score tables */ - mof lookaheadfactor; - int vertexcachesize; - mof cachescore[MO_VERTEX_CACHE_SIZE_MAX]; - mof trirefscore[MO_TRIREFSCORE_COUNT]; - - /* Synchronization stuff */ - moBarrier workbarrier; - moBarrier globalbarrier; - -} moMesh; - -typedef struct -{ - moi vertexindex; - int cacheorder; -} moCacheEntry; - -typedef struct -{ - int threadid; - - moi tricount; - moi trifirst; - moi trilast; - - int32_t hashsize; - int32_t hashmask; - moCacheEntry cachehash[MO_CACHE_HASH_SIZE_MAX]; - - ccQuickRandState32 randstate; - -} moThreadData; - - -//// - - -static void moIndicesInt8ToNative( moi *dst, void *src ) -{ - uint8_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void moIndicesInt16ToNative( moi *dst, void *src ) -{ - uint16_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void moIndicesInt32ToNative( moi *dst, void *src ) -{ - uint32_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - -static void moIndicesInt64ToNative( moi *dst, void *src ) -{ - uint64_t *s = src; - dst[0] = s[0]; - dst[1] = s[1]; - dst[2] = s[2]; - return; -} - - -static void moIndicesNativeToInt8( void *dst, moi *src ) -{ - uint8_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void moIndicesNativeToInt16( void *dst, moi *src ) -{ - uint16_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void moIndicesNativeToInt32( void *dst, moi *src ) -{ - uint32_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - -static void moIndicesNativeToInt64( void *dst, moi *src ) -{ - uint64_t *d = dst; - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - return; -} - - -//// - - -/* Mesh init step 1, initialize vertices, threaded */ -static void moMeshInitVertices( moMesh *mesh, moThreadData *tdata, int threadcount ) -{ - int vertexindex, vertexindexmax, vertexperthread; - moVertex *vertex; - - vertexperthread = ( mesh->vertexcount / threadcount ) + 1; - vertexindex = tdata->threadid * vertexperthread; - vertexindexmax = vertexindex + vertexperthread; - if( vertexindexmax > mesh->vertexcount ) - vertexindexmax = mesh->vertexcount; - - vertex = &mesh->vertexlist[vertexindex]; - for( ; vertexindex < vertexindexmax ; vertexindex++, vertex++ ) - { -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); - mmAtomicWrite32( &vertex->atomictrirefcount, 0 ); -#else - vertex->owner = -1; - mtSpinInit( &vertex->ownerspinlock ); - vertex->trirefcount = 0; -#endif - vertex->redirectindex = -1; - } - - return; -} - - -/* Mesh init step 2, initialize triangles, threaded */ -static void moMeshInitTriangles( moMesh *mesh, moThreadData *tdata, int threadcount ) -{ - int i, triperthread, triindex, triindexmax; - void *indices; - moTriangle *tri; - moVertex *vertex; - - triperthread = ( mesh->tricount / threadcount ) + 1; - triindex = tdata->threadid * triperthread; - triindexmax = triindex + triperthread; - if( triindexmax > mesh->tricount ) - triindexmax = mesh->tricount; - - /* Initialize triangles */ - indices = ADDRESS( mesh->indices, triindex * mesh->indicesstride ); - tri = &mesh->trilist[triindex]; - for( ; triindex < triindexmax ; triindex++, indices = ADDRESS( indices, mesh->indicesstride ), tri++ ) - { - mesh->indicesUserToNative( tri->v, indices ); -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &tri->atomictrinext, MO_TRINEXT_PENDING ); -#else - tri->trinext = MO_TRINEXT_PENDING; - mtSpinInit( &tri->spinlock ); -#endif - for( i = 0 ; i < 3 ; i++ ) - { - vertex = &mesh->vertexlist[ tri->v[i] ]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicAdd32( &vertex->atomictrirefcount, 1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->trirefcount++; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - } - - return; -} - - -/* Mesh init step 3, initialize vertex trirefbase, compute vertex scores, NOT threaded */ -static void moMeshInitTrirefs( moMesh *mesh ) -{ - moi vertexindex, trirefcount; - moVertex *vertex; - - /* Compute base of vertex triangle references */ - trirefcount = 0; - vertex = mesh->vertexlist; - for( vertexindex = 0 ; vertexindex < mesh->vertexcount ; vertexindex++, vertex++ ) - { -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trirefcount += mmAtomicRead32( &vertex->atomictrirefcount ); -#else - trirefcount += vertex->trirefcount; -#endif - vertex->trirefbase = trirefcount; - } - mesh->trirefcount = trirefcount; - - return; -} - - -/* Mesh init step 4, store vertex trirefs, compute triangle scores, return highest score triindex, threaded */ -static moi moMeshBuildTrirefs( moMesh *mesh, moThreadData *tdata, int threadcount ) -{ - int i, triperthread, triindex, triindexmax, besttriindex = 0; - moi trirefcount; - mof score, bestscore; - moTriangle *tri; - moVertex *vertex; - - triperthread = ( mesh->tricount / threadcount ) + 1; - triindex = tdata->threadid * triperthread; - triindexmax = triindex + triperthread; - if( triindexmax > mesh->tricount ) - triindexmax = mesh->tricount; - - /* Store vertex triangle references */ - bestscore = 0.0; - tri = &mesh->trilist[triindex]; - for( ; triindex < triindexmax ; triindex++, tri++ ) - { - score = 0.0; - for( i = 0 ; i < 3 ; i++ ) - { - vertex = &mesh->vertexlist[ tri->v[i] ]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - mesh->trireflist[ --vertex->trirefbase ] = triindex; - mmAtomicWrite32( &vertex->atomicowner, -1 ); - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - mesh->trireflist[ --vertex->trirefbase ] = triindex; - mtSpinUnlock( &vertex->ownerspinlock ); - trirefcount = vertex->trirefcount; -#endif - if( trirefcount < MO_TRIREFSCORE_COUNT ) - score += mesh->trirefscore[ trirefcount ]; - } - if( score > bestscore ) - { - bestscore = score; - besttriindex = triindex; - } - } - - return besttriindex; -} - - -//// - - -static inline uint32_t moCacheHashKey( moi index ) -{ - uint32_t hashkey; - hashkey = index; - hashkey += hashkey << 10; - hashkey ^= hashkey >> 6; - hashkey += hashkey << 6; - hashkey ^= hashkey >> 11; - return hashkey; -} - -static void moCacheInit( moMesh *mesh, moThreadData *tdata, int minimumcount ) -{ - int entryindex; - moCacheEntry *cache; - tdata->hashsize = ccPow2Round32( minimumcount ); - if( tdata->hashsize > MO_CACHE_HASH_SIZE_MAX ) - tdata->hashsize = MO_CACHE_HASH_SIZE_MAX; - tdata->hashmask = tdata->hashsize - 1; - for( entryindex = 0 ; entryindex < tdata->hashsize ; entryindex++ ) - { - cache = &tdata->cachehash[entryindex]; - cache->vertexindex = -1; - cache->cacheorder = 0; - } - return; -} - -static int moCacheGetOrder( moMesh *mesh, moThreadData *tdata, moi vertexindex ) -{ - int cacheorder; - uint32_t hashkey; - moCacheEntry *cache; - cacheorder = mesh->vertexcachesize; - hashkey = moCacheHashKey( vertexindex ) & tdata->hashmask; - for( ; ; hashkey = ( hashkey + 1 ) & tdata->hashmask ) - { - cache = &tdata->cachehash[hashkey]; - if( cache->vertexindex == -1 ) - break; - if( cache->vertexindex == vertexindex ) - { - cacheorder = cache->cacheorder; - break; - } - } - return cacheorder; -} - -static int moCacheSetOrder( moMesh *mesh, moThreadData *tdata, moi vertexindex, int cacheorder ) -{ - int retcacheorder; - uint32_t hashkey; - moCacheEntry *cache; - hashkey = moCacheHashKey( vertexindex ) & tdata->hashmask; - for( ; ; hashkey = ( hashkey + 1 ) & tdata->hashmask ) - { - cache = &tdata->cachehash[hashkey]; - if( cache->vertexindex == -1 ) - { - cache->vertexindex = vertexindex; - retcacheorder = -1; - cache->cacheorder = cacheorder; - break; - } - if( cache->vertexindex == vertexindex ) - { - retcacheorder = cache->cacheorder; - cache->cacheorder = cacheorder; - break; - } - } - return retcacheorder; -} - -static void moCacheDelete( moMesh *mesh, moThreadData *tdata, moi vertexindex ) -{ - uint32_t hashkey, delbase, targetkey, sourcekey, targetindex = 0, sourceindex; - moCacheEntry *cache, *cachesource, *cachetarget; - hashkey = moCacheHashKey( vertexindex ) & tdata->hashmask; - for( ; ; hashkey = ( hashkey + 1 ) & tdata->hashmask ) - { - cache = &tdata->cachehash[hashkey]; - if( cache->vertexindex == -1 ) - { - MO_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - return; - } - if( cache->vertexindex == vertexindex ) - break; - } - for( delbase = hashkey ; ; ) - { - delbase = ( delbase - 1 ) & tdata->hashmask; - if( tdata->cachehash[delbase].vertexindex == -1 ) - break; - } - delbase = ( delbase + 1 ) & tdata->hashmask; - for( ; ; ) - { - targetkey = hashkey; - cachetarget = 0; - for( sourceindex = hashkey ; ; ) - { - sourceindex = ( sourceindex + 1 ) & tdata->hashmask; - cachesource = &tdata->cachehash[sourceindex]; - if( cachesource->vertexindex == -1 ) - break; - sourcekey = moCacheHashKey( cachesource->vertexindex ) & tdata->hashmask; - /* Check if moving the entry backwards is allowed without breaking chain */ - if( targetkey >= delbase ) - { - if( ( sourcekey < delbase ) || ( sourcekey > targetkey ) ) - continue; - } - else if( ( sourcekey > targetkey ) && ( sourcekey < delbase ) ) - continue; - cachetarget = cachesource; - targetkey = sourcekey; - targetindex = sourceindex; - } - cache = &tdata->cachehash[hashkey]; - if( !( cachetarget ) ) - { - cache->vertexindex = -1; - break; - } - cache->vertexindex = cachetarget->vertexindex; - cache->cacheorder = cachetarget->cacheorder; - hashkey = targetindex; - } - return; -} - - -//// - - -static mof moTriangleScore( moMesh *mesh, moThreadData *tdata, moTriangle *tri ) -{ - int axisindex, cacheorder, trirefcount; -#ifndef MO_CONFIG_ATOMIC_SUPPORT - int32_t owner; -#endif - moi vertexindex; - mof score; - moVertex *vertex; - - score = 0.0; - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - { - vertexindex = tri->v[axisindex]; - cacheorder = moCacheGetOrder( mesh, tdata, vertexindex ); - score += mesh->cachescore[ cacheorder ]; - vertex = &mesh->vertexlist[ vertexindex ]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - owner = vertex->owner; - trirefcount = vertex->trirefcount; - mtSpinUnlock( &vertex->ownerspinlock ); - if( ( owner != tdata->threadid ) && ( owner != -1 ) ) - continue; -#endif - if( trirefcount < MO_TRIREFSCORE_COUNT ) - score += mesh->trirefscore[ trirefcount ]; - } - - return score; -} - - -static mof moTriangleNextScore( moMesh *mesh, moThreadData *tdata, moTriangle *tri, moi *prevtriv ) -{ - int axisindex, cacheorder, trirefcount; -#ifndef MO_CONFIG_ATOMIC_SUPPORT - int32_t owner; -#endif - moi vertexindex; - mof score; - moVertex *vertex; - - score = 0.0; - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - { - vertexindex = tri->v[axisindex]; - cacheorder = 0; - if( ( vertexindex != prevtriv[0] ) && ( vertexindex != prevtriv[1] ) && ( vertexindex != prevtriv[2] ) ) - { - cacheorder = moCacheGetOrder( mesh, tdata, vertexindex ) + 3; - if( cacheorder > mesh->vertexcachesize ) - cacheorder = mesh->vertexcachesize; - } - score += mesh->cachescore[ cacheorder ]; - vertex = &mesh->vertexlist[ vertexindex ]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - owner = vertex->owner; - trirefcount = vertex->trirefcount; - mtSpinUnlock( &vertex->ownerspinlock ); - if( ( owner != tdata->threadid ) && ( owner != -1 ) ) - continue; -#endif - if( trirefcount < MO_TRIREFSCORE_COUNT ) - score += mesh->trirefscore[ trirefcount ]; - } - - return score; -} - - -static mof moLookAheadScore( moMesh *mesh, moThreadData *tdata, moTriangle *tri ) -{ - int axisindex, cacheorder, trirefindex, trirefcount; - moi vertexindex, triindex; - mof score, bestscore; - moi *trireflist; - moVertex *vertex; - moTriangle *tricheck; - - bestscore = 0.0; - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - { - vertexindex = tri->v[axisindex]; - vertex = &mesh->vertexlist[ vertexindex ]; - trireflist = &mesh->trireflist[vertex->trirefbase]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = tdata->threadid; - mtSpinUnlock( &vertex->ownerspinlock ); - trirefcount = vertex->trirefcount; -#endif - for( trirefindex = 0 ; trirefindex < trirefcount ; trirefindex++ ) - { - triindex = trireflist[trirefindex]; - tricheck = &mesh->trilist[triindex]; - if( tricheck == tri ) - continue; - score = moTriangleNextScore( mesh, tdata, tricheck, tri->v ); - if( score > bestscore ) - bestscore = score; - } -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = -1; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - cacheorder = moCacheGetOrder( mesh, tdata, vertexindex ); - score += mesh->cachescore[ cacheorder ]; - vertex = &mesh->vertexlist[ vertexindex ]; - } - - return bestscore; -} - - -static void moDetachTriangle( moMesh *mesh, moThreadData *tdata, moi detachtriindex ) -{ - int axisindex, trirefindex, trirefcount; - moi vertexindex, triindex; - moi *trireflist; - moVertex *vertex; - moTriangle *tri; - - tri = &mesh->trilist[detachtriindex]; - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - { - /* Adjust triref lists and count for the 3 vertices */ - vertexindex = tri->v[axisindex]; - vertex = &mesh->vertexlist[vertexindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = tdata->threadid; -#endif - trireflist = &mesh->trireflist[vertex->trirefbase]; - for( trirefindex = 0 ; ; trirefindex++ ) - { -#ifdef DEBUG_VERBOSE - #ifdef MO_CONFIG_ATOMIC_SUPPORT - if( trirefindex >= mmAtomicRead32( &vertex->atomictrirefcount ) ) - MO_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - #else - if( trirefindex >= vertex->trirefcount ) - MO_ERROR( "SHOULD NOT HAPPEN %s:%d\n", 1, __FILE__, __LINE__ ); - #endif -#endif - triindex = trireflist[trirefindex]; - if( triindex != detachtriindex ) - continue; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ) - 1; - mmAtomicWrite32( &vertex->atomictrirefcount, trirefcount ); -#else - trirefcount = vertex->trirefcount - 1; - vertex->trirefcount = trirefcount; -#endif - for( ; trirefindex < trirefcount ; trirefindex++ ) - trireflist[trirefindex] = trireflist[trirefindex+1]; - break; - } -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - vertex->owner = -1; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - - return; -} - -static moi moFindSeedTriangle( moMesh *mesh, moThreadData *tdata ) -{ - int testcount; - moi seedindex, triindex, triindexstart, triindexend; - mof score, bestscore; - moTriangle *tri; -#ifndef MO_CONFIG_ATOMIC_SUPPORT - moi trinext; -#endif - - testcount = 16384; - if( mesh->operationflags & MO_FLAGS_FAST_SEED_SELECT ) - testcount = 256; - if( testcount > mesh->tricount ) - testcount = mesh->tricount; - - triindexstart = ccQuickRand32( &tdata->randstate ) % mesh->tricount; - triindexend = mesh->tricount; - bestscore = 0; - seedindex = -1; - for( ; ; ) - { - tri = &mesh->trilist[triindexstart]; - for( triindex = triindexstart ; triindex < triindexend ; triindex++, tri++ ) - { - if( ( --testcount < 0 ) && ( seedindex != -1 ) ) - goto done; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &tri->atomictrinext ) != MO_TRINEXT_PENDING ) - continue; -#else - mtSpinLock( &tri->spinlock ); - trinext = tri->trinext; - mtSpinUnlock( &tri->spinlock ); - if( trinext != MO_TRINEXT_PENDING ) - continue; -#endif - score = moTriangleScore( mesh, tdata, tri ); - if( score > bestscore ) - { - bestscore = score; - seedindex = triindex; - } - } - if( !( triindexstart ) ) - break; - triindexend = triindexstart; - triindexstart = 0; - } - - done: - - return seedindex; -} - - -//// - - -static moi moFindNextStep( moMesh *mesh, moThreadData *tdata ) -{ - int trirefindex, trirefcount, cacheordercap; - uint32_t hashkey; - moi triindex, besttriindex; - mof score, bestscore; - moi *trireflist; - moCacheEntry *cache; - moVertex *vertex; - moTriangle *tri; -#ifndef MO_CONFIG_ATOMIC_SUPPORT - moi trinext; -#endif - - cacheordercap = mesh->vertexcachesize; - if( mesh->operationflags & MO_FLAGS_ENABLE_LAZY_SEARCH ) - cacheordercap = 4; - - bestscore = 0.0; - besttriindex = -1; - for( ; ; ) - { - cache = tdata->cachehash; - for( hashkey = 0 ; hashkey < tdata->hashsize ; hashkey++, cache++ ) - { - if( cache->vertexindex == -1 ) - continue; - if( ( cacheordercap < mesh->vertexcachesize ) && ( moCacheGetOrder( mesh, tdata, cache->vertexindex ) > cacheordercap ) ) - continue; - vertex = &mesh->vertexlist[cache->vertexindex]; - trireflist = &mesh->trireflist[vertex->trirefbase]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = tdata->threadid; - mtSpinUnlock( &vertex->ownerspinlock ); - trirefcount = vertex->trirefcount; -#endif - for( trirefindex = 0 ; trirefindex < trirefcount ; trirefindex++ ) - { - triindex = trireflist[trirefindex]; - tri = &mesh->trilist[triindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &tri->atomictrinext ) != MO_TRINEXT_PENDING ) - continue; -#else - mtSpinLock( &tri->spinlock ); - trinext = tri->trinext; - mtSpinUnlock( &tri->spinlock ); - if( trinext != MO_TRINEXT_PENDING ) - continue; -#endif - score = moTriangleScore( mesh, tdata, tri ); - if( score < bestscore ) - continue; - bestscore = score; - besttriindex = triindex; - } -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = -1; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - if( besttriindex != -1 ) - break; - if( cacheordercap >= mesh->vertexcachesize ) - return -1; - cacheordercap <<= 1; - } - - /* Add score bonus for triangle strip continuity ? */ - -#ifdef DEBUG_VERBOSE -tri = &mesh->trilist[besttriindex]; -printf( " Tri %d : %d,%d,%d ( %f )\n", besttriindex, tri->v[0], tri->v[1], tri->v[2], bestscore ); -#endif - - return besttriindex; -} - - -#define MO_LOOK_AHEAD_BEST_BUFFER_SIZE (4) - -typedef struct -{ - moi triindex; - mof score; -} moScoreEntry; - -static inline void moBufferRegisterScore( moScoreEntry *entry, moi triindex, mof score ) -{ - int bufferindex, targetindex; - if( score < entry[0].score ) - return; - targetindex = 0; - for( bufferindex = 1 ; bufferindex < MO_LOOK_AHEAD_BEST_BUFFER_SIZE ; bufferindex++ ) - { - if( score < entry[bufferindex].score ) - break; - if( triindex == entry[bufferindex].triindex ) - return; - targetindex = bufferindex; - } - for( bufferindex = 0 ; bufferindex < targetindex ; bufferindex++ ) - entry[bufferindex+0] = entry[bufferindex+1]; - entry[targetindex].triindex = triindex; - entry[targetindex].score = score; - return; -} - -static moi moFindNextStepLookAhead( moMesh *mesh, moThreadData *tdata ) -{ - int trirefindex, trirefcount, cacheordercap; - uint32_t hashkey; - moi triindex, besttriindex; - mof score, nextscore, bestscore; - moi *trireflist; - moCacheEntry *cache; - moVertex *vertex; - moTriangle *tri; - moScoreEntry scorebuffer[MO_LOOK_AHEAD_BEST_BUFFER_SIZE]; - moScoreEntry *entry, *entrynext; -#ifndef MO_CONFIG_ATOMIC_SUPPORT - moi trinext; -#endif - - for( entry = &scorebuffer[MO_LOOK_AHEAD_BEST_BUFFER_SIZE-1] ; entry >= scorebuffer ; entry-- ) - { - entry->triindex = -1; - entry->score = 0.0; - } - - cacheordercap = mesh->vertexcachesize; - if( mesh->operationflags & MO_FLAGS_ENABLE_LAZY_SEARCH ) - cacheordercap = 4; - - bestscore = 0.0; - besttriindex = -1; - for( ; ; ) - { - cache = tdata->cachehash; - for( hashkey = 0 ; hashkey < tdata->hashsize ; hashkey++, cache++ ) - { - if( cache->vertexindex == -1 ) - continue; - if( ( cacheordercap < mesh->vertexcachesize ) && ( moCacheGetOrder( mesh, tdata, cache->vertexindex ) > cacheordercap ) ) - continue; - vertex = &mesh->vertexlist[cache->vertexindex]; - trireflist = &mesh->trireflist[vertex->trirefbase]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicSpin32( &vertex->atomicowner, -1, tdata->threadid ); - trirefcount = mmAtomicRead32( &vertex->atomictrirefcount ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = tdata->threadid; - mtSpinUnlock( &vertex->ownerspinlock ); - trirefcount = vertex->trirefcount; -#endif - for( trirefindex = 0 ; trirefindex < trirefcount ; trirefindex++ ) - { - triindex = trireflist[trirefindex]; - tri = &mesh->trilist[triindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - if( mmAtomicRead32( &tri->atomictrinext ) != MO_TRINEXT_PENDING ) - continue; -#else - mtSpinLock( &tri->spinlock ); - trinext = tri->trinext; - mtSpinUnlock( &tri->spinlock ); - if( trinext != MO_TRINEXT_PENDING ) - continue; -#endif - score = moTriangleScore( mesh, tdata, tri ); - moBufferRegisterScore( scorebuffer, triindex, score ); - } -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &vertex->atomicowner, -1 ); -#else - mtSpinLock( &vertex->ownerspinlock ); - vertex->owner = -1; - mtSpinUnlock( &vertex->ownerspinlock ); -#endif - } - if( scorebuffer[MO_LOOK_AHEAD_BEST_BUFFER_SIZE-1].triindex != -1 ) - break; - if( cacheordercap >= mesh->vertexcachesize ) - return -1; - cacheordercap <<= 1; - } - - bestscore = 0.0; - besttriindex = -1; - for( entry = &scorebuffer[MO_LOOK_AHEAD_BEST_BUFFER_SIZE-1] ; entry >= scorebuffer ; entry-- ) - { -#ifdef DEBUG_VERBOSE - printf( "Result[%d] = %d : %f\n", (int)(entry-scorebuffer), entry->triindex, entry->score ); -#endif - if( entry->triindex == -1 ) - break; - tri = &mesh->trilist[entry->triindex]; - nextscore = moLookAheadScore( mesh, tdata, tri ); - for( entrynext = &scorebuffer[MO_LOOK_AHEAD_BEST_BUFFER_SIZE-1] ; entrynext >= scorebuffer ; entrynext-- ) - { - if( entrynext->triindex == -1 ) - break; - if( entrynext == entry ) - continue; - score = moTriangleNextScore( mesh, tdata, &mesh->trilist[entrynext->triindex], tri->v ); - if( score > nextscore ) - nextscore = score; - } - score = entry->score + ( mesh->lookaheadfactor * nextscore ); - if( score < bestscore ) - continue; - bestscore = score; - besttriindex = entry->triindex; - } - - /* Add score bonus for triangle strip continuity ? */ - -#ifdef DEBUG_VERBOSE -tri = &mesh->trilist[besttriindex]; -printf( " Tri %d : %d,%d,%d ( %f )\n", besttriindex, tri->v[0], tri->v[1], tri->v[2], bestscore ); -#endif - - return besttriindex; -} - - -//// - - -static void moRebuildMesh( moMesh *mesh, moThreadData *tdata, moi seedindex ) -{ - int axisindex, cacheorder, caheorderaddglobal; - uint32_t hashkey; - moi besttriindex = -1; - moCacheEntry *cache; - moTriangle *tri, *trilast; - int cacheorderadd[MO_VERTEX_CACHE_SIZE_MAX]; - moi delindex, delcount; - moi delbuffer[8]; - moi (*findnextstep)( moMesh *mesh, moThreadData *tdata ); -#ifndef MO_CONFIG_ATOMIC_SUPPORT - moi trinext; -#endif - - for( ; ; ) - { - if( seedindex == -1 ) - { - /* Exhaustive search for a new seed triangle */ - seedindex = moFindSeedTriangle( mesh, tdata ); - if( seedindex == -1 ) - return; - } - tri = &mesh->trilist[seedindex]; - -#ifdef DEBUG_VERBOSE -printf( "Seed %d : %d,%d,%d\n", seedindex, tri->v[0], tri->v[1], tri->v[2] ); -#endif - - /* Add triangle to list */ -#ifdef MO_CONFIG_ATOMIC_SUPPORT - if( mmAtomicCmpReplace32( &tri->atomictrinext, MO_TRINEXT_PENDING, MO_TRINEXT_ENDOFLIST ) ) - break; -#else - mtSpinLock( &tri->spinlock ); - trinext = tri->trinext; - if( tri->trinext == MO_TRINEXT_PENDING ) - tri->trinext = MO_TRINEXT_ENDOFLIST; - mtSpinUnlock( &tri->spinlock ); - if( trinext == MO_TRINEXT_PENDING ) - break; -#endif - seedindex = -1; - } - tdata->trifirst = seedindex; - tdata->trilast = seedindex; - - /* Adjust triref lists and count for the 3 vertices */ - moDetachTriangle( mesh, tdata, seedindex ); - - /* Adjust cache */ - moCacheSetOrder( mesh, tdata, tri->v[0], 0 ); - moCacheSetOrder( mesh, tdata, tri->v[1], 0 ); - moCacheSetOrder( mesh, tdata, tri->v[2], 0 ); - - /* Select step pipeline */ - findnextstep = moFindNextStepLookAhead; - if( mesh->operationflags & MO_FLAGS_DISABLE_LOOK_AHEAD ) - findnextstep = moFindNextStep; - - for( ; ; ) - { - /* Find highest score triangle of all the triangles linked to vertices present in cache */ - besttriindex = findnextstep( mesh, tdata ); - - if( besttriindex == -1 ) - { -#ifdef DEBUG_VERBOSE -printf( "Strip Dead End\n" ); -#endif - - /* Exhaustive search for a new seed triangle */ - besttriindex = moFindSeedTriangle( mesh, tdata ); - if( besttriindex == -1 ) - return; - -#ifdef DEBUG_VERBOSE -printf( "Seed %d\n", besttriindex ); -#endif - } - - /* If triangle has already been added by the time we got here, we have to start over... */ - tri = &mesh->trilist[besttriindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - if( !( mmAtomicCmpReplace32( &tri->atomictrinext, MO_TRINEXT_PENDING, MO_TRINEXT_ENDOFLIST ) ) ) - continue; -#else - mtSpinLock( &tri->spinlock ); - trinext = tri->trinext; - if( tri->trinext == MO_TRINEXT_PENDING ) - tri->trinext = MO_TRINEXT_ENDOFLIST; - mtSpinUnlock( &tri->spinlock ); - if( trinext != MO_TRINEXT_PENDING ) - continue; -#endif - - /* Add triangle to list */ - trilast = &mesh->trilist[tdata->trilast]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - mmAtomicWrite32( &trilast->atomictrinext, besttriindex ); -#else - mtSpinLock( &tri->spinlock ); - trilast->trinext = besttriindex; - mtSpinUnlock( &tri->spinlock ); -#endif - tdata->trilast = besttriindex; - tdata->tricount++; - - /* Adjust triref lists and count for the 3 vertices */ - moDetachTriangle( mesh, tdata, besttriindex ); - - /* Build the shift table */ - caheorderaddglobal = 3; - for( cacheorder = 0 ; cacheorder < mesh->vertexcachesize ; cacheorder++ ) - cacheorderadd[cacheorder] = 0; - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - { - cacheorder = moCacheGetOrder( mesh, tdata, tri->v[axisindex] ); - if( cacheorder != -1 ) - { - caheorderaddglobal--; - for( ; cacheorder >= 0 ; cacheorder-- ) - cacheorderadd[cacheorder]++; - } - } - - /* Update cache entries */ - delcount = 0; - cache = tdata->cachehash; - for( hashkey = 0 ; hashkey < tdata->hashsize ; hashkey++, cache++ ) - { - if( cache->vertexindex == -1 ) - continue; - cache->cacheorder += caheorderaddglobal + cacheorderadd[cache->cacheorder]; - if( cache->cacheorder >= mesh->vertexcachesize ) - delbuffer[ delcount++ ] = cache->vertexindex; - } - for( delindex = 0 ; delindex < delcount ; delindex++ ) - moCacheDelete( mesh, tdata, delbuffer[delindex] ); - - /* Set new cache entries */ - for( axisindex = 0 ; axisindex < 3 ; axisindex++ ) - moCacheSetOrder( mesh, tdata, tri->v[axisindex], 0 ); - } - - return; -} - - -//// - - -typedef struct -{ - int threadid; - moMesh *mesh; - moThreadData *tdata; - moi trifirst; -} moThreadInit; - -static void *moThreadMain( void *value ) -{ - moi seedindex; - moMesh *mesh; - moThreadInit *tinit; - moThreadData tdata; - - tinit = value; - mesh = tinit->mesh; - tinit->tdata = &tdata; - - tdata.threadid = tinit->threadid; - moCacheInit( mesh, &tdata, mesh->vertexcachesize + ( mesh->vertexcachesize >> 1 ) + 3 ); - tdata.trifirst = MO_TRINEXT_ENDOFLIST; - tdata.trilast = -1; - tdata.tricount = 0; -/* - ccQuickRand32Seed( &tdata.randstate, (int)((uintptr_t)&tdata) + tdata.threadid ); -*/ - ccQuickRand32Seed( &tdata.randstate, 2 ); - - - /* Step 1 */ - moMeshInitVertices( mesh, &tdata, mesh->threadcount ); - moBarrierSync( &mesh->workbarrier ); - - /* Step 2 */ - moMeshInitTriangles( mesh, &tdata, mesh->threadcount ); - moBarrierSync( &mesh->workbarrier ); - - /* Step 3 is done by a single thread */ - if( tdata.threadid == 0 ) - moMeshInitTrirefs( mesh ); - moBarrierSync( &mesh->workbarrier ); - - /* Step 4 */ - seedindex = moMeshBuildTrirefs( mesh, &tdata, mesh->threadcount ); - moBarrierSync( &mesh->workbarrier ); - - /* Step 5, threads rebuild the mesh */ - moRebuildMesh( mesh, &tdata, seedindex ); - moBarrierSync( &mesh->workbarrier ); - - /* Set the linked list's first item for main thread to access */ - tinit->trifirst = tdata.trifirst; - - /* Sync all and wake up main thread */ - moBarrierSync( &mesh->globalbarrier ); - - return 0; -} - - -//// - - -static void moWriteIndices( moMesh *mesh, moThreadInit *threadinit ) -{ - int threadindex; - moi triindex, trinext; - moThreadInit *tinit; - moTriangle *tri; - void *indices; - - indices = mesh->indices; - for( threadindex = 0 ; threadindex < mesh->threadcount ; threadindex++ ) - { - tinit = &threadinit[threadindex]; - for( triindex = tinit->trifirst ; triindex != MO_TRINEXT_ENDOFLIST ; triindex = trinext ) - { - tri = &mesh->trilist[triindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trinext = mmAtomicRead32( &tri->atomictrinext ); -#else - trinext = tri->trinext; -#endif - -#ifdef DEBUG_VERBOSE -printf( "Tri %d,%d,%d\n", tri->v[0], tri->v[1], tri->v[2] ); -#endif - - mesh->indicesNativeToUser( indices, tri->v ); - indices = ADDRESS( indices, mesh->indicesstride ); - } - } - - return; -} - - -static void moBuildRedirection( moMesh *mesh, moThreadInit *threadinit ) -{ - int threadindex, redirectindex; - moi triindex, trinext; - moThreadInit *tinit; - moVertex *vertex; - moTriangle *tri; - - redirectindex = 0; - for( threadindex = 0 ; threadindex < mesh->threadcount ; threadindex++ ) - { - tinit = &threadinit[threadindex]; - for( triindex = tinit->trifirst ; triindex != MO_TRINEXT_ENDOFLIST ; triindex = trinext ) - { - tri = &mesh->trilist[triindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trinext = mmAtomicRead32( &tri->atomictrinext ); -#else - trinext = tri->trinext; -#endif - vertex = &mesh->vertexlist[tri->v[0]]; - if( vertex->redirectindex < 0 ) - { - mesh->shufflecallback( mesh->shuffleopaquepointer, redirectindex, tri->v[0] ); - vertex->redirectindex = redirectindex++; - } - vertex = &mesh->vertexlist[tri->v[1]]; - if( vertex->redirectindex < 0 ) - { - mesh->shufflecallback( mesh->shuffleopaquepointer, redirectindex, tri->v[1] ); - vertex->redirectindex = redirectindex++; - } - vertex = &mesh->vertexlist[tri->v[2]]; - if( vertex->redirectindex < 0 ) - { - mesh->shufflecallback( mesh->shuffleopaquepointer, redirectindex, tri->v[2] ); - vertex->redirectindex = redirectindex++; - } - } - } - - return; -} - - -static void moWriteRedirectIndices( moMesh *mesh, moThreadInit *threadinit ) -{ - int threadindex; - moi triindices[3]; - moi triindex, trinext; - moThreadInit *tinit; - moVertex *vertex; - moTriangle *tri; - void *indices; - - indices = mesh->indices; - for( threadindex = 0 ; threadindex < mesh->threadcount ; threadindex++ ) - { - tinit = &threadinit[threadindex]; - for( triindex = tinit->trifirst ; triindex != MO_TRINEXT_ENDOFLIST ; triindex = trinext ) - { - tri = &mesh->trilist[triindex]; -#ifdef MO_CONFIG_ATOMIC_SUPPORT - trinext = mmAtomicRead32( &tri->atomictrinext ); -#else - trinext = tri->trinext; -#endif - vertex = &mesh->vertexlist[tri->v[0]]; - triindices[0] = vertex->redirectindex; - vertex = &mesh->vertexlist[tri->v[1]]; - triindices[1] = vertex->redirectindex; - vertex = &mesh->vertexlist[tri->v[2]]; - triindices[2] = vertex->redirectindex; - -#ifdef DEBUG_VERBOSE -printf( "Tri %d,%d,%d\n", triindices[0], triindices[1], triindices[2] ); -#endif - - mesh->indicesNativeToUser( indices, triindices ); - indices = ADDRESS( indices, mesh->indicesstride ); - } - } - - return; -} - - -//// - - -int moOptimizeMesh( size_t vertexcount, size_t tricount, void *indices, int indiceswidth, size_t indicesstride, void (*shufflecallback)( void *opaquepointer, long newvertexindex, long oldvertexindex ), void *shuffleopaquepointer, int vertexcachesize, int threadcount, int flags ) -{ - int a, threadid, maxthreadcount; - mof factor; - moMesh mesh; - mtThread thread[MO_THREAD_COUNT_MAX]; - moThreadInit threadinit[MO_THREAD_COUNT_MAX]; - moThreadInit *tinit; - -#ifdef DEBUG_VERBOSE_TIME - long long msecs; - msecs = mmGetMilisecondsTime(); -#endif - - if( tricount < 3 ) - return 1; - - maxthreadcount = tricount / 1024; - if( threadcount > maxthreadcount ) - threadcount = maxthreadcount; - if( threadcount <= 0 ) - { - threadcount = mmcontext.cpucount; - if( threadcount <= 0 ) - threadcount = MO_THREAD_COUNT_DEFAULT; - } - if( threadcount > MO_THREAD_COUNT_MAX ) - threadcount = MO_THREAD_COUNT_MAX; - - mesh.vertexcount = vertexcount; - mesh.tricount = tricount; - mesh.indices = indices; - switch( indiceswidth ) - { - case sizeof(uint8_t): - mesh.indicesUserToNative = moIndicesInt8ToNative; - mesh.indicesNativeToUser = moIndicesNativeToInt8; - break; - case sizeof(uint16_t): - mesh.indicesUserToNative = moIndicesInt16ToNative; - mesh.indicesNativeToUser = moIndicesNativeToInt16; - break; - case sizeof(uint32_t): - mesh.indicesUserToNative = moIndicesInt32ToNative; - mesh.indicesNativeToUser = moIndicesNativeToInt32; - break; - case sizeof(uint64_t): - mesh.indicesUserToNative = moIndicesInt64ToNative; - mesh.indicesNativeToUser = moIndicesNativeToInt64; - break; - default: - return 0; - } - mesh.indicesstride = indicesstride; - mesh.shuffleopaquepointer = shuffleopaquepointer; - mesh.shufflecallback = shufflecallback; - mesh.threadcount = threadcount; - mesh.operationflags = flags; - - /* Synchronization */ - moBarrierInit( &mesh.workbarrier, threadcount ); - moBarrierInit( &mesh.globalbarrier, threadcount+1 ); - -#ifdef DEBUG_VERBOSE -printf( "Mesh Optimization ; %d vertices ; %d triangles\n", (int)vertexcount, (int)tricount ); -#endif - - /* Score look-up tables */ - mesh.lookaheadfactor = 0.5; - if( vertexcachesize < 12 ) - vertexcachesize = 12; - else if( vertexcachesize > MO_VERTEX_CACHE_SIZE_MAX-1 ) - vertexcachesize = MO_VERTEX_CACHE_SIZE_MAX-1; - mesh.vertexcachesize = vertexcachesize; - mesh.cachescore[0] = 0.85; - if( mesh.operationflags & MO_FLAGS_FIXED_CACHE_SIZE ) - mesh.cachescore[0] = 0.75; - mesh.cachescore[mesh.vertexcachesize] = 0.0; - factor = 1.0 / (mof)( mesh.vertexcachesize - 3 ); - if( mesh.operationflags & MO_FLAGS_FIXED_CACHE_SIZE ) - factor *= 0.25; - for( a = 3 ; a < mesh.vertexcachesize ; a++ ) - mesh.cachescore[a] = powf( 1.0 - ( (mof)(a-3) * factor ), 1.5 ); - if( mesh.operationflags & MO_FLAGS_FIXED_CACHE_SIZE ) - { - if( mesh.vertexcachesize > 1 ) - mesh.cachescore[mesh.vertexcachesize-1] *= 0.50; - if( mesh.vertexcachesize > 2 ) - mesh.cachescore[mesh.vertexcachesize-2] *= 0.75; - } - mesh.trirefscore[0] = -256.0; - for( a = 1 ; a < MO_TRIREFSCORE_COUNT ; a++ ) - mesh.trirefscore[a] = 2.0 * powf( (float)a, -0.5 ); - - /* Allocation */ - mesh.vertexlist = mmAlignAlloc( mesh.vertexcount * sizeof(moVertex), 0x40 ); - mesh.trilist = mmAlignAlloc( mesh.tricount * sizeof(moTriangle), 0x40 ); - mesh.trirefcount = 0; - mesh.trireflist = malloc( 3 * mesh.tricount * sizeof(moi) ); - - /* Launch threads! */ - tinit = threadinit; - for( threadid = 0 ; threadid < threadcount ; threadid++, tinit++ ) - { - tinit->threadid = threadid; - tinit->mesh = &mesh; - mtThreadCreate( &thread[threadid], moThreadMain, tinit, MT_THREAD_FLAGS_JOINABLE, 0, 0 ); - } - - /* Wait for all threads to be done */ - moBarrierSync( &mesh.globalbarrier ); - for( threadid = 0 ; threadid < threadcount ; threadid++ ) - mtThreadJoin( &thread[threadid] ); - - /* Read the linked list of each thread and rebuild the new indices */ - if( !( mesh.shufflecallback ) ) - moWriteIndices( &mesh, threadinit ); - else - { - moBuildRedirection( &mesh, threadinit ); - moWriteRedirectIndices( &mesh, threadinit ); - } - - /* Free all global data */ - mmAlignFree( mesh.vertexlist ); - mmAlignFree( mesh.trilist ); - free( mesh.trireflist ); - moBarrierDestroy( &mesh.workbarrier ); - moBarrierDestroy( &mesh.globalbarrier ); - -#ifdef DEBUG_VERBOSE_TIME - msecs = mmGetMilisecondsTime() - msecs; - printf( "Mesh Optimization : %lld msecs\n", (long long)msecs ); -#endif - - return 1; -} - - -//// - - -#define MO_EVAL_VERTEX_CACHE_MAX (256) - -static int moEvalCacheInsert( moi *vertexcache, int vertexcachesize, moi vertexindex ) -{ - int cacheindex, pushlimit, cachemiss; - pushlimit = vertexcachesize-1; - cachemiss = 1; - for( cacheindex = 0 ; cacheindex < vertexcachesize ; cacheindex++ ) - { - if( vertexcache[cacheindex] != vertexindex ) - continue; - pushlimit = cacheindex; - cachemiss = 0; - break; - } - for( cacheindex = pushlimit-1 ; cacheindex >= 0 ; cacheindex-- ) - vertexcache[cacheindex+1] = vertexcache[cacheindex+0]; - vertexcache[0] = vertexindex; - return cachemiss; -} - -/* -Returns the ACMR (Average Cache Miss Rate) for the mesh. -ACMR is the sum of vertex cache miss divided by the number of triangles in the mesh. -*/ -double moEvaluateMesh( size_t tricount, void *indices, int indiceswidth, size_t indicesstride, int vertexcachesize, int flags ) -{ - int cacheindex, cachemiss; - moi triindex; - void (*indicesUserToNative)( moi *dst, void *src ); - moi vertexcache[MO_EVAL_VERTEX_CACHE_MAX]; - moi triv[3]; - - switch( indiceswidth ) - { - case sizeof(uint8_t): - indicesUserToNative = moIndicesInt8ToNative; - break; - case sizeof(uint16_t): - indicesUserToNative = moIndicesInt16ToNative; - break; - case sizeof(uint32_t): - indicesUserToNative = moIndicesInt32ToNative; - break; - case sizeof(uint64_t): - indicesUserToNative = moIndicesInt64ToNative; - break; - default: - return 0; - } - - if( vertexcachesize > MO_EVAL_VERTEX_CACHE_MAX ) - vertexcachesize = MO_EVAL_VERTEX_CACHE_MAX; - for( cacheindex = 0 ; cacheindex < vertexcachesize ; cacheindex++ ) - vertexcache[cacheindex] = -1; - - cachemiss = 0; - for( triindex = 0 ; triindex < tricount ; triindex++ ) - { - indicesUserToNative( triv, indices ); - indices = ADDRESS( indices, indicesstride ); - cachemiss += moEvalCacheInsert( vertexcache, vertexcachesize, triv[0] ); - cachemiss += moEvalCacheInsert( vertexcache, vertexcachesize, triv[1] ); - cachemiss += moEvalCacheInsert( vertexcache, vertexcachesize, triv[2] ); - } - -/* -printf( "Cache Miss : %d / %d\n", cachemiss, (int)tricount*3 ); -printf( "ACMR : %f\n", (double)cachemiss / (double)tricount ); -*/ - - return (double)cachemiss / (double)tricount; -} - - - diff --git a/src/other/gct/MeshDecimation/meshoptimizer.h b/src/other/gct/MeshDecimation/meshoptimizer.h deleted file mode 100644 index 299350b9697..00000000000 --- a/src/other/gct/MeshDecimation/meshoptimizer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ***************************************************************************** - * - * Copyright (c) 2014 Alexis Naveros. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ***************************************************************************** - */ - -#ifdef __cplusplus -extern "C" { -#endif - - -int moOptimizeMesh( size_t vertexcount, size_t tricount, void *indices, int indiceswidth, size_t indicesstride, void (*shufflecallback)( void *opaquepointer, long newvertexindex, long oldvertexindex ), void *shuffleopaquepointer, int vertexcachesize, int threadcount, int flags ); - -#define MO_FLAGS_FIXED_CACHE_SIZE (0x1) -#define MO_FLAGS_DISABLE_LOOK_AHEAD (0x2) -#define MO_FLAGS_ENABLE_LAZY_SEARCH (0x4) -#define MO_FLAGS_FAST_SEED_SELECT (0x8) - - -double moEvaluateMesh( size_t tricount, void *indices, int indiceswidth, size_t indicesstride, int vertexcachesize, int flags ); - - -#ifdef __cplusplus -} -#endif - diff --git a/src/other/gct/Sampler/CMakeLists.txt b/src/other/gct/Sampler/CMakeLists.txt deleted file mode 100644 index 0df07129407..00000000000 --- a/src/other/gct/Sampler/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -set(GCT_SAMPLER_SRCS - PointSampler.cpp - MarchingCubesSampler.cpp - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../openNURBS - ${CMAKE_CURRENT_SOURCE_DIR}/../../tcl/generic - ) - -add_library(Sampler SHARED ${GCT_SAMPLER_SRCS}) -set_target_properties(Sampler PROPERTIES VERSION 1.1.0 SOVERSION 1) - -install(TARGETS Sampler - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR}) - -if(MSVC) - set_property(TARGET Sampler APPEND PROPERTY COMPILE_DEFINITIONS "SAMPLER_DLL_EXPORTS") -endif(MSVC) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 - diff --git a/src/other/gct/Sampler/MarchingCubesSampler.cpp b/src/other/gct/Sampler/MarchingCubesSampler.cpp deleted file mode 100644 index ff441d8e525..00000000000 --- a/src/other/gct/Sampler/MarchingCubesSampler.cpp +++ /dev/null @@ -1,1726 +0,0 @@ -/* MarchingCubesSampler.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/22/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements a marching cubes technique to create a faceted representation - * of a piece of geometry. - */ - -#define MC_DEBUG 0 - -// System heades -#include -#if MC_DEBUG -#include -#endif -#include - -// Local headers -#include "MarchingCubesSampler.h" -#include "Auxiliary/gctcommon.h" - -namespace GeomConversion { - - namespace Sampler { - -#if USE_QT -#define MC_MUTEX_INIT() { ; } -#define MC_MUTX_DESTROY() { ; } -#define MC_MUTEX_LOCK(mcs) mcs->m_threadData->threadMutex.lock() -#define MC_MUTEX_UNLOCK(mcs) mcs->m_threadData->threadMutex.unlock() -#define MC_CHECK_CANCEL() (! mcs->m_keepGoing) -#define MC_STATUS_STR(str) m_statusStr = QString(str) -#define MC_INCREMENT(s) { \ - if (s > 1) { \ - m_doneSteps += s; \ - } \ - incrementStep(); \ - } -#else -#define MC_MUTEX_INIT() pthread_mutex_init(&m_threadData.threadMutex, NULL); -#define MC_MUTX_DESTROY() pthread_mutex_destroy(&m_threadData.threadMutex); -#define MC_MUTEX_LOCK(mcs) pthread_mutex_lock(&(mcs->m_threadData->threadMutex)) -#define MC_MUTEX_UNLOCK(mcs) pthread_mutex_unlock(&(mcs->m_threadData->threadMutex)) -#define MC_CHECK_CANCEL() (0) -#define MC_STATUS_STR(str) { ; } -#define MC_INCREMENT(s) { ; } -#endif - - /* constants */ - /* the edge table tells which edges are intersected based on - * index determined during the vertex check process */ - const int cEdgeTable[256] = { - 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, - 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, - 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, - 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, - 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, - 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, - 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, - 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, - 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, - 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, - 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, - 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, - 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, - 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, - 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , - 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, - 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, - 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, - 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, - 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, - 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, - 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, - 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, - 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, - 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, - 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, - 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, - 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, - 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, - 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, - 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, - 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 - }; - /* The tri table is the stitching table used to make the facets necessary - * to represent the surface that passes through the referencing cube. */ - const int cTriTable[256][16] = { - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, - {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, - {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, - {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, - {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, - {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, - {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, - {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, - {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, - {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, - {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, - {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, - {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, - {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, - {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, - {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, - {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, - {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, - {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, - {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, - {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, - {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, - {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, - {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, - {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, - {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, - {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, - {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, - {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, - {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, - {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, - {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, - {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, - {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, - {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, - {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, - {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, - {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, - {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, - {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, - {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, - {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, - {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, - {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, - {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, - {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, - {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, - {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, - {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, - {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, - {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, - {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, - {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, - {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, - {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, - {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, - {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, - {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, - {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, - {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, - {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, - {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, - {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, - {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, - {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, - {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, - {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, - {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, - {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, - {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, - {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, - {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, - {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, - {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, - {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, - {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, - {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, - {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, - {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, - {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, - {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, - {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, - {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, - {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, - {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, - {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, - {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, - {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, - {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, - {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, - {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, - {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, - {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, - {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, - {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, - {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, - {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} - }; - - /* structures */ - - //******************************************************************* - // NAME vertex_struct - // - // DESCRIPTION - // Structure that marries a point and normal together. - //******************************************************************* - struct vertex_struct - { - float point[3]; - float normal[3]; - }; - std::vectorgVerList; // list of vertices - - //******************************************************************* - // NAME find_vertex - // - // INPUTS - // pt - 3D point - // nrm - normal for the point - // - // DESCRIPTION - // Locate the point/normal combo in the vertex list. If found the index - // in the list is returned, otherwise it returns -1. - //******************************************************************* - static int - find_vertex (float *pt, float *nrm) - { - if (gVerList.size() > 0) - { - for (unsigned i=0; ipoint, pt) && VEQUAL(vs->normal, nrm)) - return i; - } - } - - return -1; - } - - //******************************************************************* - // NAME add_vertex - // - // INPUTS - // x, y, z - 3D point - // dx, dy, dz - normal for the point - // - // DESCRIPTION - // Add a point/normal combo if it does not already exist in the list. - // Returns 1 if successful, 0 if memory failed. - //******************************************************************* - static short - add_vertex (float x, float y, float z, - float dx, float dy, float dz) - { - float pt[3]; - float nrm[3]; - - pt[X] = x; pt[Y] = y; pt[Z] = z; - nrm[X] = dx; nrm[Y] = dy; nrm[Z] = dz; - if (find_vertex (pt, nrm) > -1) - return 1; - - struct vertex_struct *vs = (struct vertex_struct *) malloc (sizeof (struct vertex_struct)); - if (!vs) return 0; - - memset (vs, 0, sizeof (struct vertex_struct)); - VMOVE(vs->point, pt); - VMOVE(vs->normal, nrm); - gVerList.push_back(vs); - return 1; - } - - //******************************************************************* - // NAME segment_check - // - // INPUTS - // lower, upper - bounds of a cell - // inloc, outloc - in/out locations of a trace segment - // - // DESCRIPTION - // Checks to see what case of the trace vs. the cell you currently have. - //******************************************************************* - static int - segment_check (float lower, float upper, float inloc, float outloc) - { - /* Possible cases: - * 1) Both entry and exit are before the front cube face - no facets. - * 2) Both entry and exit are behind the back cube face - no facets. - * 3) The entry is before the front cube face and the exit is behind the back cube face - no facets. - * 4) The entry is behind the front cube face and the exit is before the back cube face - no facets. - * 5) The entry is before the front cube face and the exit is before the back cube face - facets. - * 6) The entry is before the back cube face and the exit is behind the back cube face - facets. - */ - if (inloc < lower) - { - if (outloc <= lower) return 1; - - if (outloc > upper) return 3; - - return 5; - } - else if (inloc > upper) - return 2; - - if (outloc <= upper) return 4; - - return 6; - } - - //******************************************************************* - // NAME get_cube_index - // - // INPUTS - // mcs - worker class for the thread - // cube - cube being inspected - // - // DESCRIPTION - // Determines which vertices of the cube are in/out of the geometry and - // returns an index into the cEdgeTable to reflect that. - //******************************************************************* - static int - get_cube_index (MarchingCubesWorker *mcs, struct cube_def &cube) - { - Interface::ray_results *currResults; - int cubeindex = 0; - -#if MC_DEBUG - fprintf (stderr, "\t\tGetting Cube Index\n"); -#endif - - for (int i=0; i<4; i++) - { - int cube_in=0; - - /* determine which partition list you need */ - switch (i) - { - case 0: - currResults = &((mcs->m_threadData->rayGrid[cube.ll[0]][cube.ll[1]]).results); - break; - case 1: - currResults = &((mcs->m_threadData->rayGrid[cube.lr[0]][cube.lr[1]]).results); - break; - case 2: - currResults = &((mcs->m_threadData->rayGrid[cube.ul[0]][cube.ul[1]]).results); - break; - case 3: - currResults = &((mcs->m_threadData->rayGrid[cube.ur[0]][cube.ur[1]]).results); - break; - } - - if (currResults->hitData.size() > 0) - { - /* run the partition list for this ray to get the state of the vertices */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tHit Size: %d\n", (int) currResults->hitData.size()); -#endif - for (unsigned p = 0; p < currResults->hitData.size(); p+=2) - { - Interface::one_hit &ihit = currResults->hitData[p]; - Interface::one_hit &ohit = currResults->hitData[p+1]; - int state; - - /* determine if there is a partition overlap with the cube */ - state = segment_check (cube.ymin, cube.ymax, (float) ihit.point[Y], - (float) ohit.point[Y]); -#if MC_DEBUG - fprintf (stderr, "\t\t\tRAY: %d IN: %g OUT: %g LOW: %g UP: %g\n", - i, ihit.point[Y], ohit.point[Y], cube.ymin, cube.ymax); - fprintf (stderr, "\t\t\tSTATE -- %d\n", state); -#endif - - if (state == 3 || state == 5 || state == 6) - { - cube_in = 1; - -#if MC_DEBUG - if (state == 3) - fprintf (stderr, "\t\t\tPartition is inside geometry!\n"); - else - fprintf (stderr, "\t\t\tFound a partiton intersecting the cube!\n"); -#endif - /* only cases 5 & 6 require one of the vertices along this ray - * to be marked in or out */ - switch (i) - { - case 0: - { - switch (state) - { - case 5: - cubeindex |= 1; - break; - case 6: - cubeindex |= 8; - break; - } - } - break; - case 1: - { - switch (state) - { - case 5: - cubeindex |= 2; - break; - case 6: - cubeindex |= 4; - break; - } - } - break; - case 2: - { - switch (state) - { - case 5: - cubeindex |= 16; - break; - case 6: - cubeindex |= 128; - break; - } - } - break; - case 3: - { - switch (state) - { - case 5: - cubeindex |= 32; - break; - case 6: - cubeindex |= 64; - break; - } - } - break; - } - } - - /* if you got a segment inside the cube you only want to look at the 1st one */ - if (cube_in) - break; - } - } - - if (currResults->hitData.size() == 0 || cube_in == 0) - { - /* there were no partitons that intersected this cube for this ray.... - * mark both the vertices along the ray as out */ -#if MC_DEBUG - if (currResults->hitData.size() == 0) - fprintf (stderr, "\t\t\tPointer %d is NULL\n", i); - else - fprintf (stderr, "\t\t\tNo partitions along this line intersect the cube.\n"); -#endif - switch (i) - { - case 0: - cubeindex |= 1; - cubeindex |= 8; - break; - case 1: - cubeindex |= 2; - cubeindex |= 4; - break; - case 2: - cubeindex |= 16; - cubeindex |= 128; - break; - case 3: - cubeindex |= 32; - cubeindex |= 64; - break; - } - } - } - -#if MC_DEBUG - fprintf (stderr, "\t\tReturning Cube Index of %d\n", cubeindex); -#endif - return cubeindex; - } - - //******************************************************************* - // NAME get_edge_intersections - // - // INPUTS - // mcs - worker class for the thread - // cube - cube being inspected - // cubeindex - index into the cEdgeTable - // edgePts - storage of points/normals along the cube edges - // - // DESCRIPTION - // Perform shotlining along the cube edges to get where geometry boundaries - // are crossed. - //******************************************************************* - static void - get_edge_intersections (MarchingCubesWorker *mcs, - struct cube_def &cube, - int cubeindex, - struct edge_int *edgePts) - { - int i; - Interface::ray_results edge_hits[12]; - Interface::trace_data rdata; - - double xmin = mcs->m_threadData->rayGrid[cube.ll[0]][cube.ll[1]].point[X]; - double ymin = cube.ymin; - double zmin = mcs->m_threadData->rayGrid[cube.ll[0]][cube.ll[1]].point[Z]; - double xmax = xmin + mcs->m_threadData->cellsize; - double ymax = cube.ymax; - double zmax = zmin + mcs->m_threadData->cellsize; - -#if MC_DEBUG - fprintf (stderr, "\t\tEntering Intersections Routine\n"); -#endif - -#define OFFSET 0.125 - TRACE_DATA_INIT(rdata); - rdata.length = mcs->m_threadData->cellsize * (1 + (4.0 * OFFSET)); // length of cellsize - - /* Cube is entirely in/out of the component */ - if (cEdgeTable[cubeindex] == 0) - return; - - /* shoot necessary rays to get intersections */ - if (cEdgeTable[cubeindex] & 1) - { - /* shotline Edge0 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 0\n"); -#endif - rdata.point[X] = xmin-OFFSET; rdata.point[Y] = ymax; rdata.point[Z] = zmin; - rdata.direc[X] = 1.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[0], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 2) - { - /* shotline Edge1 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 1\n"); -#endif - rdata.point[X] = xmax; rdata.point[Y] = ymin-OFFSET; rdata.point[Z] = zmin; - rdata.direc[X] = 0.0; rdata.direc[Y] = 1.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[1], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 4) - { - /* shotline Edge2 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 2\n"); -#endif - rdata.point[X] = xmin-OFFSET; rdata.point[Y] = ymin; rdata.point[Z] = zmin; - rdata.direc[X] = 1.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[2], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 8) - { - /* shotline Edge3 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 3\n"); -#endif - rdata.point[X] = xmin; rdata.point[Y] = ymin-OFFSET; rdata.point[Z] = zmin; - rdata.direc[X] = 0.0; rdata.direc[Y] = 1.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[3], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 16) - { - /* shotline Edge4 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 4\n"); -#endif - rdata.point[X] = xmin-OFFSET; rdata.point[Y] = ymax; rdata.point[Z] = zmax; - rdata.direc[X] = 1.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[4], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 32) - { - /* shotline Edge5 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 5\n"); -#endif - rdata.point[X] = xmax; rdata.point[Y] = ymin-OFFSET; rdata.point[Z] = zmax; - rdata.direc[X] = 0.0; rdata.direc[Y] = 1.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[5], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 64) - { - /* shotline Edge6 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 6\n"); -#endif - rdata.point[X] = xmin-OFFSET; rdata.point[Y] = ymin; rdata.point[Z] = zmax; - rdata.direc[X] = 1.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[6], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 128) - { - /* shotline Edge7 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 7\n"); -#endif - rdata.point[X] = xmin; rdata.point[Y] = ymin-OFFSET; rdata.point[Z] = zmax; - rdata.direc[X] = 0.0; rdata.direc[Y] = 1.0; rdata.direc[Z] = 0.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[7], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 256) - { - /* shotline Edge8 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 8\n"); -#endif - rdata.point[X] = xmin; rdata.point[Y] = ymax; rdata.point[Z] = zmin-OFFSET; - rdata.direc[X] = 0.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 1.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[8], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 512) - { - /* shotline Edge9 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 9\n"); -#endif - rdata.point[X] = xmax; rdata.point[Y] = ymax; rdata.point[Z] = zmin-OFFSET; - rdata.direc[X] = 0.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 1.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[9], rdata.results); - rdata.results.hitData.clear(); - } - - if (cEdgeTable[cubeindex] & 1024) - { - /* shotline Edge10 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 10\n"); -#endif - rdata.point[X] = xmax; rdata.point[Y] = ymin; rdata.point[Z] = zmin-OFFSET; - rdata.direc[X] = 0.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 1.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[10], rdata.results); - rdata.results.hitData.clear(); - } std::vector index; - - - if (cEdgeTable[cubeindex] & 2048) - { - /* shotline Edge11 */ -#if MC_DEBUG - fprintf (stderr, "\t\t\tShooting Edge 11\n"); -#endif - rdata.point[X] = xmin; rdata.point[Y] = ymin; rdata.point[Z] = zmin-OFFSET; - rdata.direc[X] = 0.0; rdata.direc[Y] = 0.0; rdata.direc[Z] = 1.0; - mcs->tracer->fireRay(&rdata); - RAY_RESULTS_COPY (edge_hits[11], rdata.results); - rdata.results.hitData.clear(); - } - - /* run partitons and get the edge hit locations and normals */ - for (i=0; i<12; i++) - { - float in, out; - float low, upp; - float off = 0; /* used to extend the edge of a cube in the event that a hit - * is not reported when it should be. this is mostly likely - * due to a hit right on the vertex of a cube. */ - - if (edge_hits[i].hitData.size() == 0) continue; - - do - { -#if MC_DEBUG - fprintf (stderr, "\t\t\t%ld Hits Along Edge\n", edge_hits[i].hitData.size()); -#endif - for (unsigned p = 0; p < edge_hits[i].hitData.size(); p+=2) - { - Interface::one_hit &ihit = edge_hits[i].hitData[p]; - Interface::one_hit &ohit = edge_hits[i].hitData[p+1]; - int state; - - switch (i) - { - case 0: - case 2: - case 4: - case 6: - in = (float) ihit.point[X]; - out = (float) ohit.point[X]; - - low = xmin; - upp = xmax; - break; - case 1: - case 3: - case 5: - case 7: - in = (float) ihit.point[Y]; - out = (float) ohit.point[Y]; - - low = ymin; - upp = ymax; - break; - case 8: - case 9: - case 10: - case 11: - in = (float) ihit.point[Z]; - out = (float) ohit.point[Z]; - - low = zmin; - upp = zmax; - break; - } - - /* check to see if the segment is inbounds and store point/normal and in/out */ - state = segment_check (low-off, upp+off, in, out); -#if MC_DEBUG - fprintf (stderr, "\t\t\tRAY: %d OFF: %g IN: %g OUT: %g LOW: %g UP: %g\n", - i, off, in, out, low-off, upp+off); - fprintf (stderr, "\t\t\tSTATE -- %d\n", state); -#endif - - /* only worried about the 1st intersection on an edge */ - if ((state == 5 || state == 6)) - { -#if MC_DEBUG - fprintf (stderr, "\t\t\tEDGE %d\n", i); -#endif - switch (state) - { - case 5: - for (int j=0; j<3; j++) - { - edgePts[i].pt[j] = (float) ohit.point[j]; - edgePts[i].norm[j] = (float) ohit.normal[j]; - } - edgePts[i].set = 1; -#if MC_DEBUG - fprintf (stderr,"\t\t\tOUT PT (%g, %g, %g)\n", - edgePts[i].pt[X], edgePts[i].pt[Y], edgePts[i].pt[Z]); - fprintf (stderr,"\t\t\tOUT NM (%g, %g, %g)\n", - edgePts[i].norm[X], edgePts[i].norm[Y], edgePts[i].norm[Z]); -#endif - break; - - case 6: - for (int j=0; j<3; j++) - { - edgePts[i].pt[j] = (float) ihit.point[j]; - edgePts[i].norm[j] = (float) ihit.normal[j]; - } - edgePts[i].set = 1; -#if MC_DEBUG - fprintf (stderr,"\t\t\tIN PT (%g, %g, %g)\n", - edgePts[i].pt[X], edgePts[i].pt[Y], edgePts[i].pt[Z]); - fprintf (stderr,"\t\t\tIN NM (%g, %g, %g)\n", - edgePts[i].norm[X], edgePts[i].norm[Y], edgePts[i].norm[Z]); -#endif - break; - } - - break; - } -#if MC_DEBUG - else if (state == 4) - { - fprintf (stderr,"\t\t\tIN PT (%g, %g, %g)\n", - ihit.point[X], ihit.point[Y], ihit.point[Z]); - fprintf (stderr,"\t\t\tOUT PT (%g, %g, %g)\n", - ohit.point[X], ohit.point[Y], ohit.point[Z]); - } -#endif - } - off += (mcs->m_threadData->cellsize * OFFSET); - } - while (!edgePts[i].set && off < (mcs->m_threadData->cellsize * OFFSET * 3.0)); - - /* cleanup the temporary edge partitions */ - edge_hits[i].hitData.clear(); - } - -#if MC_DEBUG - fprintf (stderr, "\t\tLeaving Intersections Routine\n"); -#endif - } - - //******************************************************************* - // NAME construct_triangles - // - // INPUTS - // cube - cube being inspected - // cubeindex - index into the cEdgeTable - // edgePts - points/normals along the cube edges - // - // DESCRIPTION - // Use the edgePts and cubeindex to determine and construct the triangles - // for the given cube. - //******************************************************************* - static void - construct_triangles (struct cube_def *cube, - int cubeindex, - struct edge_int *edgePts) - { - /* create triangles */ - for (int i=0; cTriTable[cubeindex][i]!=-1; i+=3) - { - int pt1 = cTriTable[cubeindex][i]; - int pt2 = cTriTable[cubeindex][i+1]; - int pt3 = cTriTable[cubeindex][i+2]; - -#if MC_DEBUG - if (!edgePts[pt1].set) - fprintf (stderr, "PROBLEM: edge point 1 (%d) was not set!\n", pt1); - if (!edgePts[pt2].set) - fprintf (stderr, "PROBLEM: edge point 2 (%d) was not set!\n", pt2); - if (!edgePts[pt3].set) - fprintf (stderr, "PROBLEM: edge point 3 (%d) was not set!\n", pt3); -#endif - - /* This is a check in case for some reason that an edge hit - * was not set. It happens, and in that event there will just - * be a whole were the triangle(s) belong. But it's better that - * having a triangle edge go arbitraily to the origin. */ - if (!edgePts[pt1].set) continue; - if (!edgePts[pt2].set) continue; - if (!edgePts[pt3].set) continue; - - /* check for denerate triangles */ - if ((edgePts[pt1].pt[X] == edgePts[pt2].pt[X]) && - (edgePts[pt1].pt[Y] == edgePts[pt2].pt[Y]) && - (edgePts[pt1].pt[Z] == edgePts[pt2].pt[Z])) continue; /* pt1 & pt2 */ - if ((edgePts[pt1].pt[X] == edgePts[pt3].pt[X]) && - (edgePts[pt1].pt[Y] == edgePts[pt3].pt[Y]) && - (edgePts[pt1].pt[Z] == edgePts[pt3].pt[Z])) continue; /* pt1 & pt3 */ - if ((edgePts[pt2].pt[X] == edgePts[pt3].pt[X]) && - (edgePts[pt2].pt[Y] == edgePts[pt3].pt[Y]) && - (edgePts[pt2].pt[Z] == edgePts[pt3].pt[Z])) continue; /* pt2 & pt3 */ - - /* add points and normals to the lists */ - cube->points.push_back(edgePts[pt1].pt[X]); - cube->points.push_back(edgePts[pt1].pt[Y]); - cube->points.push_back(edgePts[pt1].pt[Z]); - - cube->normals.push_back(edgePts[pt1].norm[X]); - cube->normals.push_back(edgePts[pt1].norm[Y]); - cube->normals.push_back(edgePts[pt1].norm[Z]); - - cube->points.push_back(edgePts[pt3].pt[X]); - cube->points.push_back(edgePts[pt3].pt[Y]); - cube->points.push_back(edgePts[pt3].pt[Z]); - - cube->normals.push_back(edgePts[pt3].norm[X]); - cube->normals.push_back(edgePts[pt3].norm[Y]); - cube->normals.push_back(edgePts[pt3].norm[Z]); - - cube->points.push_back(edgePts[pt2].pt[X]); - cube->points.push_back(edgePts[pt2].pt[Y]); - cube->points.push_back(edgePts[pt2].pt[Z]); - - cube->normals.push_back(edgePts[pt2].norm[X]); - cube->normals.push_back(edgePts[pt2].norm[Y]); - cube->normals.push_back(edgePts[pt2].norm[Z]); - } - } - - //******************************************************************* - // NAME analyze_voxel - // - // INPUTS - // mcs - worker class for the thread - // idx - cube index - // - // DESCRIPTION - // Perform all the necessary operations on a cube. - //******************************************************************* - static void - analyze_voxel (MarchingCubesWorker *mcs, int idx) - { - int cubeindex = 0; - struct cube_def &cube = mcs->m_threadData->cubes[idx];; - struct edge_int edge_pts[12]; - -#if MC_DEBUG - double xmin = mcs->m_threadData->rayGrid[cube.ll[0]][cube.ll[1]].point[X]; - double ymin = cube.ymin; - double zmin = mcs->m_threadData->rayGrid[cube.ll[0]][cube.ll[1]].point[Z]; - double xmax = xmin + mcs->m_threadData->cellsize; - double ymax = cube.ymax; - double zmax = zmin + mcs->m_threadData->cellsize; - fprintf (stderr, "\tAnalyzing Voxel (%.3f, %.3f, %.3f) -> (%.3f, %.3f, %.3f)\n", - xmin, ymin, zmin, xmax, ymax, zmax); -#endif - - /* Step 1: Determine which cube vertices are in/out of the component. */ - cubeindex = get_cube_index (mcs, cube); - mcs->incrementStep(); - - /* Step 2: Based on which vertices are in/out of the component, determine - * what other edges you must shotline to get intersections */ - for (int i=0; i<12; i++) - memset (&(edge_pts[i]), 0, sizeof (struct edge_int)); - - get_edge_intersections (mcs, cube, cubeindex, edge_pts); - mcs->incrementStep(); - - /* Step 3: Construct triangles. */ - construct_triangles (&cube, cubeindex, edge_pts); - mcs->incrementStep(); - } - - //******************************************************************* - // NAME process_shotlines - // - // INPUTS - // mcs - worker class for the thread - // - // DESCRIPTION - // Process any shotlines in the grid. - //******************************************************************* - static int - process_shotlines (MarchingCubesWorker *mcs) - { - int i, j; - - /* get the index of the next ray */ - MC_MUTEX_LOCK(mcs); - i = mcs->m_threadData->currRow; j = mcs->m_threadData->currCol; - mcs->m_threadData->currRow++; - if (mcs->m_threadData->currRow >= mcs->m_threadData->rowCount) - { - mcs->m_threadData->currCol++; - mcs->m_threadData->currRow = 0; - } - MC_MUTEX_UNLOCK(mcs); - - if (j < mcs->m_threadData->colCount) - { - while (1) - { - /* process the ray */ - mcs->tracer->fireRay(&(mcs->m_threadData->rayGrid[i][j])); - mcs->incrementStep(); - - /* get the index of the next ray */ - MC_MUTEX_LOCK(mcs); - -#if MC_DEBUG - fprintf (stderr, "THREAD %ld -- process [%d,%d]\n", mcs->m_ID, i, j); - if (mcs->m_threadData->rayGrid[i][j].results.hitData.size() > 0) - fprintf (stderr, "\t hit something\n"); - else - fprintf (stderr, "\t hit nothing\n"); -#endif - - mcs->m_threadData->doneRays++; - - i = mcs->m_threadData->currRow; j = mcs->m_threadData->currCol; - mcs->m_threadData->currRow++; - if (mcs->m_threadData->currRow >= mcs->m_threadData->rowCount) - { - mcs->m_threadData->currCol++; - mcs->m_threadData->currRow = 0; - } - MC_MUTEX_UNLOCK(mcs); - - if (j >= mcs->m_threadData->colCount) break; - if (MC_CHECK_CANCEL()) break; - } - } - - return 0; - } - - //******************************************************************* - // NAME process_cubes - // - // INPUTS - // mcs - worker class for the thread - // - // DESCRIPTION - // Process any cubes in the list. - //******************************************************************* - static int - process_cubes (MarchingCubesWorker *mcs) - { - int i; - - /* get the index of the next cube */ - MC_MUTEX_LOCK(mcs); - i = mcs->m_threadData->currCube; - mcs->m_threadData->currCube++; - MC_MUTEX_UNLOCK(mcs); - - if ((unsigned long)i < mcs->m_threadData->cubes.size()) - { - while (1) - { -#if MC_DEBUG - struct cube_def cube = mcs->m_threadData->cubes[i]; - fprintf (stderr, "THREAD %ld -- process cube %d\n", mcs->m_ID, i); - fprintf (stderr, "\tLL: [%d,%d] LR: [%d,%d] UL: [%d,%d] UR: [%d,%d]\n", - cube.ll[0], cube.ll[1], - cube.lr[0], cube.lr[1], - cube.ul[0], cube.ul[1], - cube.ur[0], cube.ur[1]); -#endif - - /* anlyze this cube */ - analyze_voxel (mcs, i); - - /* get the index of the next cube */ - MC_MUTEX_LOCK(mcs); - i = mcs->m_threadData->currCube; - mcs->m_threadData->currCube++; - MC_MUTEX_UNLOCK(mcs); - - if ((unsigned long)i >= mcs->m_threadData->cubes.size()) break; - if (MC_CHECK_CANCEL()) break; - } - } - - return 0; - } - - //******************************************************************* - // NAME marchcubes_worker - // - // INPUTS - // mcs - MarchingCubesWorker does the work of 1 thread - // - // DESCRIPTION - // Function called to perform work for each thread. - //******************************************************************* - void * - marchcubes_worker (void *td) - { - MarchingCubesWorker *mcs = (MarchingCubesWorker *) td; - - if (MC_CHECK_CANCEL()) goto endWorker; - - /* Algorithm: - * This is needs to happen in 2 phases of parallelism. Here are - * the steps. - * - * 1) Shotline grid for the XZ plane. - * 2) Synchronize threads. - * 3) Process the cubes. - * 4) Cleanup shotline memory. - */ - - /* STEP 1: process shotlines */ - process_shotlines(mcs); - if (MC_CHECK_CANCEL()) goto endWorker; - - /* STEP 2: Synchronize threads to make sure ALL rays are processed */ - while (1) - { - if (mcs->m_threadData->doneRays == mcs->m_threadData->rayCount) - break; - - sleep(1); // sleep for a second - } - -#if MC_DEBUG - MC_MUTEX_LOCK(mcs); - fprintf (stderr, "THREAD %ld synchronized... \n", mcs->m_ID); - for (int i = 0; i < mcs->m_threadData->rowCount; i++) - for (int j = 0; j < mcs->m_threadData->colCount; j++) - fprintf (stderr, "[%d][%d]: %ld\n", i, j, mcs->m_threadData->rayGrid[i][j].results.hitData.size()); - MC_MUTEX_UNLOCK(mcs); -#endif - if (MC_CHECK_CANCEL()) goto endWorker; - - /* STEP 3: process the cubes */ - process_cubes(mcs); - - endWorker: - SAMPLER_THREAD_EXIT(); - return NULL; - } - -#if USE_QT - //******************************************************************* - // NAME run - // - // INPUTS - // none - // - // DESCRIPTION - // Start the worker. - //******************************************************************* - void MarchingCubesWorker::run() - { - marchcubes_worker((void *) this); - emit finished(); - } -#endif - - //******************************************************************* - // NAME constructor - // - // INPUTS - // ti - pointer to a target - // tracers - list of tracer objects - // threads - list of already instantiated QThreads (Qt only) - // parent - parent QObject (Qt only, should be NULL) - // - // DESCRIPTION - // Construct the object. - //******************************************************************* - MarchingCubesSampler::MarchingCubesSampler(SAMPLER_CONST_IMP) - : Interface::ISampler(SAMPLER_CONST_PARAMS) - { - m_threadData.cellsize = 1.0; - m_threadData.rayGrid = NULL; - m_threadData.rowCount = 0; - m_threadData.colCount = 0; - m_threadData.rayCount = 0; - m_vertex.clear(); - m_normal.clear(); - m_index.clear(); - MC_MUTEX_INIT(); - } - - //******************************************************************* - // NAME destructor - // - // DESCRIPTION - // Cleanup the object. - //******************************************************************* - MarchingCubesSampler::~MarchingCubesSampler() - { - m_vertex.clear(); - m_normal.clear(); - m_index.clear(); - - if (m_threadData.rayGrid) - { - for (int i=0; igetGeometryMin(); - tmax = m_geometry->getGeometryMax(); - - for (int i=0; i<3; i++) - { - min[i] = tmin[i]; - span[i] = tmax[i] - tmin[i]; - } - - /* set the 2D grid of rays */ - z = min[Z]; - y = min[Y]; - // add 2 so it covers the 1st row and anything not evenly divisible - m_threadData.rowCount = (int) (span[Z] / (double) m_threadData.cellsize) + 2; - m_threadData.colCount = (int) (span[X] / (double) m_threadData.cellsize) + 2; - m_threadData.rayCount = m_threadData.rowCount * m_threadData.colCount; - m_threadData.rayGrid = (Interface::trace_data**) malloc (sizeof (Interface::trace_data*) * - m_threadData.rowCount); - if (! m_threadData.rayGrid) return; - memset (m_threadData.rayGrid, 0, sizeof(Interface::trace_data*) * m_threadData.rowCount); - - for (int i=0; i < m_threadData.rowCount; i++) - { - m_threadData.rayGrid[i] = - (Interface::trace_data*) malloc (sizeof (Interface::trace_data) * m_threadData.colCount); - if (! m_threadData.rayGrid[i]) return; - memset (m_threadData.rayGrid[i], 0, sizeof(Interface::trace_data) * m_threadData.colCount); - - x = min[X]; - for (int j=0; j < m_threadData.colCount; j++) - { - TRACE_DATA_INIT(m_threadData.rayGrid[i][j]); - - // set ray info here - m_threadData.rayGrid[i][j].point[X] = x; - m_threadData.rayGrid[i][j].point[Y] = y; - m_threadData.rayGrid[i][j].point[Z] = z; - - m_threadData.rayGrid[i][j].direc[X] = 0.0; - m_threadData.rayGrid[i][j].direc[Y] = 1.0; - m_threadData.rayGrid[i][j].direc[Z] = 0.0; - - // increase X - x += m_threadData.cellsize; - } - - // increase Z - z += m_threadData.cellsize; - } - m_threadData.currRow = m_threadData.currCol = m_threadData.doneRays = 0; - - /* create list of cubes */ - int ycount = (int) (span[Y] / (double) m_threadData.cellsize) + 2; - for (int i=1; i < m_threadData.rowCount; i++) - { - for (int j=1; j < m_threadData.colCount; j++) - { - y = min[Y]; - - for (int k=0; k < ycount; k++) - { - struct cube_def cube; - - /* set pointers to ray grid */ - cube.ll[0] = i-1; cube.ll[1] = j-1; - cube.lr[0] = i-1; cube.lr[1] = j; - cube.ul[0] = i; cube.ul[1] = j-1; - cube.ur[0] = i; cube.ur[1] = j; - - /* set Y depth for cube */ - cube.ymin = y; - y += m_threadData.cellsize; - cube.ymax = y; - - cube.points.clear(); - cube.normals.clear(); - - m_threadData.cubes.push_back(cube); - } - } - } - m_threadData.currCube = 0; - - -#if USE_QT - m_statusStr = QString(); - m_doneSteps = 0; - m_totalSteps = m_threadData.rayCount; // # of rays - m_totalSteps += (m_threadData.cubes.size() * 4); // # of cubes - m_totalSteps += 4; // steps for creating indexed lists -#endif - - for (int i=0; im_ID = (unsigned long) i; - - /* assign tracer object */ - worker->tracer = m_tracers[i]; - - m_workers.push_back(worker); - -#if USE_QT - // move the worker to it's thread - worker->moveToThread(m_threads.at(i)); - - // connect signals - connect(worker, SIGNAL(finished()), - this, SLOT(workerFinished()), - Qt::QueuedConnection); - connect(worker, SIGNAL(doneStep()), - this, SLOT(incrementStep()), - Qt::QueuedConnection); - connect(this, SIGNAL(startWorkers()), - worker, SLOT(run()), - Qt::QueuedConnection); -#endif - } - - m_threadsDone = 0; - m_prepped = true; - } - - //******************************************************************* - // NAME runSample - // - // INPUTS - // none - // - // DESCRIPTION - // Does the work to perform the marching cubes algorithm, including - // subdividing the work amongst a desired number of threads. - //******************************************************************* - void MarchingCubesSampler::runSample() - { - if (m_prepped) - { - MC_STATUS_STR("Sampling Geometry"); -#if USE_QT - emit startWorkers(); -#else - // set up threading data - pthread_attr_t attr; - pthread_t *ptid = NULL; - - pthread_attr_init (&attr); - ptid = (pthread_t *) malloc (sizeof (pthread_t) * m_threadCount); - if (! ptid) return; - memset (ptid, 0, sizeof (pthread_t) * m_threadCount); - - /* start the threading */ - for (int i=0; i points; - std::vector normals; - -#if MC_DEBUG - fprintf (stderr, "Entering End Sample\n"); -#endif - MC_STATUS_STR("Transferring Cube Points"); - - /* worker cleanup */ -#if MC_DEBUG - fprintf (stderr, "\tWorker Cleanup\n"); -#endif - for (int i=0; i *pts = &(m_threadData.cubes[i]).points; - const std::vector *nrms = &(m_threadData.cubes[i]).normals; - -#if MC_DEBUG - fprintf (stderr, "\tTransfering Points & Normals to Local Lists\n"); - fprintf (stderr, "\t\tCube: %ld -- points: %ld\n", i, pts->size() / 3); -#endif - points.insert(points.end(), pts->begin(), pts->end()); - normals.insert(normals.end(), nrms->begin(), nrms->end()); - - /* increment progress bar */ - MC_INCREMENT(1); - } - - /* create vectors of fused vertices, normals, and indices */ - MC_STATUS_STR("Building Vertex/Normal Lists"); - if (points.size () > 0) - { -#if MC_DEBUG - fprintf (stderr, "\tCreate Index Vertice List\n"); -#endif - for (unsigned i=0; ipoint[X]); - m_vertex.push_back (vs->point[Y]); - m_vertex.push_back (vs->point[Z]); - - m_normal.push_back (vs->normal[X]); - m_normal.push_back (vs->normal[Y]); - m_normal.push_back (vs->normal[Z]); - } - - /* increment progress bar */ - MC_INCREMENT(1); - -#if MC_DEBUG - fprintf (stderr, "\tCreate Class Index List\n"); -#endif - MC_STATUS_STR("Building Index List"); - for (unsigned i=0; i -1) - m_index.push_back(index); - } - - /* increment progress bar */ - MC_INCREMENT(1); - -#if MC_DEBUG - fprintf (stderr, "\tCleanup Temp Vert List\n"); -#endif - while (gVerList.size()) - { - struct vertex_struct *vs = gVerList.back(); - gVerList.pop_back(); - free (vs); - } - /* increment progress bar */ - MC_INCREMENT(1); - } - else - { -#if MC_DEBUG - fprintf (stderr, "\tPoints Array is emtpy!\n"); -#endif - MC_INCREMENT(3); - } -#if MC_DEBUG - fprintf (stderr, "Leaving End Sample\n"); -#endif - } - -#if USE_QT - //******************************************************************* - // NAME workerFinished - // - // INPUTS - // none - // - // DESCRIPTION - // Returns here when a worker is done it's part. Once all are done it - // does the finishing work. - //******************************************************************* - void MarchingCubesSampler::workerFinished() - { - // wait for the threads to finish - m_threadsDone++; - if (m_threadsDone < m_threadCount) - return; - - if (!m_canceled) - endSample(); - - emit finished(); - } - - //******************************************************************* - // NAME getProgress - // - // INPUTS - // none - // - // DESCRIPTION - // Return the overall progress of the workers - //******************************************************************* - float MarchingCubesSampler::getProgress() - { - float progress = 0.0; - - progress = (((float) m_doneSteps) / ((float) m_totalSteps)) * 100.0; - return progress; - } - - //******************************************************************* - // NAME stopSampling - // - // INPUTS - // none - // - // DESCRIPTION - // Tell all the workers to stop - //******************************************************************* - void MarchingCubesSampler::stopSampling() - { - m_canceled = true; - for (unsigned i=0; ipleaseStop(); - } - } -#endif - - } // namespace Sampler - -} // namespace GeomConversion diff --git a/src/other/gct/Sampler/MarchingCubesSampler.h b/src/other/gct/Sampler/MarchingCubesSampler.h deleted file mode 100644 index 6edcfb20ab5..00000000000 --- a/src/other/gct/Sampler/MarchingCubesSampler.h +++ /dev/null @@ -1,204 +0,0 @@ -/* MarchingCubesSampler.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/22/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements a marching cubes technique to create a faceted representation - * of a piece of geometry. - */ - -#ifndef MARCHINGCUBESSAMPLER_H -#define MARCHINGCUBESSAMPLER_H - -// System headers -#include - -// Local headers -#include "Interface/ISampler.h" - -namespace GeomConversion { - - namespace Sampler { - - // Structures - struct edge_int - { - float pt[3]; - float norm[3]; - int set; - }; - - struct cube_def - { - int ll[2], lr[2], ul[2], ur[2]; - double ymin, ymax; - - /* output lists */ - std::vector points; - std::vector normals; - }; - - struct mc_thread_data - { - double cellsize; - - /* intermediate data */ - Interface::trace_data **rayGrid; - int rowCount, colCount, rayCount; - int currRow, currCol, doneRays; -#if USE_QT - QMutex threadMutex; -#else - pthread_mutex_t threadMutex; -#endif - - std::vector cubes; - int currCube; - }; - - //******************************************************************* - // NAME MarchingCubesWorker - // - // DESCRIPTION - // Holds data used/created on a per thread basis. - // - // NOTE - // Glorified structure declared as a class for Qt threading model. - //******************************************************************* - class MarchingCubesWorker -#if USE_QT - : public QObject -#endif - { -#if USE_QT - Q_OBJECT -#endif - - public: - MarchingCubesWorker(struct mc_thread_data *td -#if USE_QT - , QObject *parent = NULL) : QObject(parent) , -#else - ) : -#endif - m_threadData(td) - { -#if USE_QT - m_keepGoing = true; -#endif - } - - /* thread data */ - unsigned long m_ID; - struct mc_thread_data *m_threadData; - - /* input data */ - Interface::IGeometryTracer *tracer; - - void incrementStep() - { -#if USE_QT - emit doneStep(); -#endif - } - -#if USE_QT - bool m_keepGoing; - void pleaseStop() { m_keepGoing = false; } - - signals: - void doneStep(); - void finished(); - - public slots: - void run(); -#endif - }; - - /** - * MarchingCubesSampler - * - * Implements a marching cubes technique to create a faceted representation - * of a piece of geometry. - */ - class MarchingCubesSampler : public Interface::ISampler - { -#if USE_QT - Q_OBJECT -#endif - - public: - MarchingCubesSampler(SAMPLER_CONST_DEF); - ~MarchingCubesSampler(); - - virtual void setSpacing(float s) { m_threadData.cellsize = s; } - virtual void prepSample(); - virtual void endSample(); - - std::vector getVertices() { return m_vertex; } - std::vector getNormals() { return m_normal; } - std::vector getIndices() { return m_index; } - -#if USE_QT - virtual void stopSampling(); - virtual float getProgress(); - virtual QString getStatusString() { return m_statusStr; } - - public slots: - void incrementStep() { m_doneSteps++; updateProgress(); } - virtual void workerFinished(); -#endif - virtual void runSample(); - - private: - /* threading data */ - std::vector m_workers; - struct mc_thread_data m_threadData; - - /* output storage */ - std::vector m_vertex; - std::vector m_normal; - std::vector m_index; - -#if USE_QT - long m_doneSteps; - long m_totalSteps; - QString m_statusStr; -#endif - }; - - } // namespace Sampler - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/Sampler/PointSampler.cpp b/src/other/gct/Sampler/PointSampler.cpp deleted file mode 100644 index cd0f0e68d43..00000000000 --- a/src/other/gct/Sampler/PointSampler.cpp +++ /dev/null @@ -1,692 +0,0 @@ -/* PointSampler.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/21/13 - * - * Authors(s): - * DRH - * LB - * - * Description: - * Implements a point sample technique to get (x, y, z) locations on - * a piece of geometry. - */ - -// System headers -#include - -// Local headers -#include "PointSampler.h" -#include "Auxiliary/gctcommon.h" - -namespace GeomConversion { - - namespace Sampler { - -#if USE_QT -#define PS_CHECK_CANCEL() (! twd->m_keepGoing) -#else -#define PS_CHECK_CANCEL() (0) -#endif - - //******************************************************************* - // NAME ray_results_differ - // - // INPUTS - // previousRayResults, currentRayResults - the ray results for the rays - // - // DESCRIPTION - // Check to see if the results of two rays are different. - // true = different. - //******************************************************************* - bool - ray_results_differ(const Interface::ray_results &previousRayResults, - const Interface::ray_results ¤tRayResults) - { - // If the list sizes differ that is a dead give-away - if (previousRayResults.hitData.size() != currentRayResults.hitData.size()) - return true; - - for (unsigned i=0 ; i < previousRayResults.hitData.size() ; i++) - { - const Interface::one_hit &prevHit = previousRayResults.hitData[i]; - const Interface::one_hit &currHit = currentRayResults.hitData[i]; - - // compare things in relative order of difficulty of the comparison - - if (prevHit.solidSurface != currHit.solidSurface ) - return true; - - if (prevHit.solidName.compare(currHit.solidName)) - return true; - } - - return false; - } - - //******************************************************************* - // NAME sub_sample - // - // INPUTS - // thisThreadResults - all the ray results for the current thread - // twd - pointer to the current thread's thread_worker_data - // prevResults - results from the previously shot ray - // currResults - results from the current ray - // depth, limit - variables to control depth of recursion - // - // DESCRIPTION - // Function performs sub sampling to determine if/where an edge occurs - // between 2 rays. - //******************************************************************* - void - sub_sample (std::vector &thisThreadResults, - const PointSamplerWorker *twd, - const Interface::ray_results &prevResults, - const Interface::ray_results &currResults, - const int depth, const int limit) - { - if (depth >= limit) - return; - - Interface::trace_data middle_ray; - TRACE_DATA_INIT(middle_ray); - - VADD2(middle_ray.point, currResults.origin, prevResults.origin); - VSCALE(middle_ray.point, middle_ray.point, 0.5); - VMOVE(middle_ray.direc, currResults.dir); - middle_ray.results.x = -1; // note that this is a sub-sampling ray - middle_ray.results.y = -1; - VMOVE(middle_ray.results.origin, middle_ray.point); - VMOVE(middle_ray.results.dir, middle_ray.direc); - - twd->tracer->fireRay(&middle_ray); - - bool diffLeft = ray_results_differ(prevResults, middle_ray.results); - bool diffRight = ray_results_differ(middle_ray.results, currResults); - unsigned remember = thisThreadResults.size(); - - if (diffLeft && diffRight) - { - sub_sample(thisThreadResults, twd, - prevResults, middle_ray.results, - depth+1, limit); - sub_sample(thisThreadResults, twd, - middle_ray.results, currResults, - depth+1, limit); - thisThreadResults.push_back(middle_ray.results); - } - else if (diffLeft) - { - sub_sample(thisThreadResults, twd, - prevResults, middle_ray.results, - depth+1, limit); - for (unsigned pos=remember; pos < thisThreadResults.size(); pos++) - { - Interface::ray_results &newerResults = thisThreadResults[pos]; - if (!ray_results_differ(newerResults, currResults)) - { - // somethig to my left also matches right so I am not needed - goto rightFound; - } - } - thisThreadResults.push_back(middle_ray.results); - - rightFound: - ; - } - else if (diffRight) - { - sub_sample(thisThreadResults, twd, - middle_ray.results, currResults, - depth+1, limit); - for (unsigned pos=remember ; pos < thisThreadResults.size() ; pos++) - { - Interface::ray_results &newerResults = thisThreadResults[pos]; - if (!ray_results_differ(newerResults, prevResults)) - { - // somethig to my right also matches left so I am not needed - goto leftFound; - } - } - thisThreadResults.push_back(middle_ray.results); - leftFound: - ; - } - } - - //******************************************************************* - // NAME check_subsample - // - // INPUTS - // twd - pointer to the current thread's thread_worker_data - // j - ??? - // currResults - results from the current ray - // prevResults - results from the previously shot ray - // thisThreadResults - all the ray results for the current thread - // - // DESCRIPTION - // Check whether there is any sub-sampling needed and perform it if so. - //******************************************************************* - void - check_subsample(const PointSamplerWorker *twd, - const int j, - const Interface::ray_results &currResults, - const Interface::ray_results &prevResults, - std::vector &thisThreadResults) - { - Interface::ray_results lowerRowRayResults, diagonalRayResults; - - RAY_RESULTS_INIT(lowerRowRayResults); - RAY_RESULTS_INIT(diagonalRayResults); - - // look to see if we crossed a physical boundary - // along the i_axis and should sub-sample - if (ray_results_differ(prevResults, currResults)) - { - sub_sample(thisThreadResults, twd, - prevResults, currResults, - 0, twd->model->sub_division); - } - - // look to see if we crossed a physical boundary - // along the j_axis and should sub-sample - if (j == 0) - return; - - // look backwards for matching x,y-1 entry - for (int prevIdx=thisThreadResults.size()-1; prevIdx >= 0; prevIdx--) - { - if (thisThreadResults.at(prevIdx).x == currResults.x && - thisThreadResults.at(prevIdx).y ==(currResults.y-1)) - { - // found it - RAY_RESULTS_COPY(lowerRowRayResults, thisThreadResults[prevIdx]); - if (ray_results_differ(lowerRowRayResults, currResults)) - { - sub_sample(thisThreadResults, twd, - lowerRowRayResults, currResults, - 0, twd->model->sub_division); - } - - // sample diagonally across the "cell" - if (ray_results_differ(prevResults, lowerRowRayResults)) - { - sub_sample(thisThreadResults, twd, - prevResults, lowerRowRayResults, - 0, twd->model->sub_division); - } - - // now go looking back for the x-1,y-1 entry - // so we can sample along the other diagonal - for (int diagIdx=thisThreadResults.size()-1; diagIdx >= 0; - diagIdx--) - { - if (thisThreadResults.at(diagIdx).x ==(currResults.x-1) && - thisThreadResults.at(diagIdx).y ==(currResults.y-1)) - { - // found it - RAY_RESULTS_COPY(diagonalRayResults, - thisThreadResults[diagIdx]); - if (ray_results_differ(diagonalRayResults, currResults)) - { - sub_sample(thisThreadResults, twd, - diagonalRayResults, currResults, - 0, twd->model->sub_division); - } - - break; - } // found x-1, y-1 - } - break; - } // found x, y-1 - } - } - - //******************************************************************* - // NAME pointsample_worker - // - // INPUTS - // td - pointer to PointSamplerWorker - // - // DESCRIPTION - // Function called to perform work for each thread. - //******************************************************************* - void * - pointsample_worker (void *td) - { - PointSamplerWorker *twd = (PointSamplerWorker *) td; - Interface::trace_data prevRay, currentRay; - std::vector thisViewResults; // the results for the current view - std::vector thisThreadResults; // the total results for this thread - - // make sure everythign is clear - thisThreadResults.clear(); - TRACE_DATA_INIT(prevRay); - - /* We shoot rays in the shootAxis direction, - * we step from bounding box min..max along the i_axis. - * we step from slabStartLineNumber..slabEndLineNumber along j_axis - * - * Conceptually, the bounding box of the object is divided into slabs - * along the j_axis. Each thread of computation handles one - * slab. Within a slab, the thread shoots rays along the individal - * lines (rows) stepping from mdl_min[i_axis]..mdl_max[i_axis]. - */ - for (int shootAxis = 0; shootAxis < 3; shootAxis++) - { - if (PS_CHECK_CANCEL()) goto endWorker; - - // make sure everything is clear - thisViewResults.clear(); - TRACE_DATA_INIT(currentRay); - - /* set direction vector */ - int i_axis = (shootAxis + 1) % 3; // the axis we step between rays - int j_axis = (shootAxis + 2) % 3; // the slab axis - - currentRay.point[shootAxis] = twd->model->model_min[shootAxis]; - currentRay.direc[shootAxis] = 1.0; - currentRay.direc[i_axis] = 0.0; - currentRay.direc[j_axis] = 0.0; - - // compute the dimensions of the slab along the j_axis dimension - float slabBottom = twd->cpuID * twd->model->perCpuSlabWidth[j_axis]; - float slabTop = (twd->cpuID+1) * twd->model->perCpuSlabWidth[j_axis]; - - int slabStartLineNumber = ceil(slabBottom / twd->model->spacing); - int slabEndLineNumber = ceil(slabTop / twd->model->spacing); - - for (long j=slabStartLineNumber ; j <= slabEndLineNumber ; j++) - { - if (PS_CHECK_CANCEL()) goto endWorker; - currentRay.point[j_axis] = twd->model->model_min[j_axis] + (j * twd->model->spacing); - - prevRay.results.hitData.clear(); - prevRay.results.x = -1; - prevRay.results.y = -1; - - long iAxisSteps = ceil(twd->model->model_span[i_axis] / twd->model->spacing); - - for (long i=0 ; i <= iAxisSteps ; i++) - { - if (PS_CHECK_CANCEL()) goto endWorker; - currentRay.point[i_axis] = twd->model->model_min[i_axis] + (i * twd->model->spacing); - - currentRay.results.x = i; - currentRay.results.y = j; - VMOVE(currentRay.results.origin, currentRay.point); - VMOVE(currentRay.results.dir, currentRay.direc); - currentRay.results.hitData.clear(); - - // fire the ray - twd->tracer->fireRay(¤tRay); - - if (j < slabEndLineNumber || (twd->cpuID+1) == twd->model->total_threads) - { - // record results - thisViewResults.push_back(currentRay.results); - } - - if (twd->model->do_subsample && twd->model->sub_division > 0) - { - if (i > 0) - { - check_subsample(twd, j, currentRay.results, - prevRay.results, thisViewResults); - } - } - - twd->completedRays++; - TRACE_DATA_COPY(prevRay, currentRay); - } - } - - // copy the view results to the overall results - thisThreadResults.insert(thisThreadResults.end(), - thisViewResults.begin(), - thisViewResults.end()); - } - - thisViewResults.clear(); // not needed anymore - - if (PS_CHECK_CANCEL()) goto endWorker; - - // move all points to proper lists - for (unsigned i = 0; i < thisThreadResults.size(); i++) - { - std::vector *points = &(twd->points); - std::vector *normals = &(twd->normals); - std::vector *solNumber = &(twd->solidNumber); - std::vector *surfNumber = &(twd->surfNumber); - - for (unsigned j = 0; j < thisThreadResults[i].hitData.size(); j++) - { - Interface::one_hit &hit = thisThreadResults[i].hitData[j]; - - /* save points and normals */ - for (int a=0; a<3; a++) - { - points->push_back(hit.point[a]); - normals->push_back(hit.normal[a]); - } - - /* save surface numbers and solid numbers */ - solNumber->push_back(hit.solidName); - surfNumber->push_back(hit.solidSurface); - } - } - - endWorker: - thisThreadResults.clear(); - - //fprintf (stderr, "Ending CPU %d\n", twd->cpuID); - SAMPLER_THREAD_EXIT(); - return NULL; - } - -#if USE_QT - //******************************************************************* - // NAME run - // - // INPUTS - // none - // - // DESCRIPTION - // Start the worker. - //******************************************************************* - void PointSamplerWorker::run() - { - pointsample_worker((void *) this); - emit finished(); - } -#endif - - //******************************************************************* - // NAME constructor - // - // INPUTS - // ti - pointer to a target - // tracers - list of tracer objects - // threads - list of already instantiated QThreads (Qt only) - // parent - parent QObject (Qt only, should be NULL) - // - // DESCRIPTION - // Construct the object. - //******************************************************************* - PointSampler::PointSampler(SAMPLER_CONST_IMP) - : Interface::ISampler(SAMPLER_CONST_PARAMS) - , m_spacing(1.0) - , m_subdivision(4) - { - m_points.clear(); - m_normals.clear(); - m_surfNumber.clear(); - m_solidNumber.clear(); - } - - //******************************************************************* - // NAME destructor - // - // DESCRIPTION - // Cleanup the object. - //******************************************************************* - PointSampler::~PointSampler() - { - m_points.clear(); - m_normals.clear(); - m_surfNumber.clear(); - m_solidNumber.clear(); - } - - //******************************************************************* - // NAME prepSample - // - // INPUTS - // none - // - // DESCRIPTION - // Preps data used across the entire model. - //******************************************************************* - void PointSampler::prepSample() - { - memset (&m_model, 0, sizeof (struct thread_model_data)); - - // load geometry and determine overall model data - VMOVE(m_model.model_min, m_geometry->getGeometryMin()); - VMOVE(m_model.model_max, m_geometry->getGeometryMax()); - VSUB2(m_model.model_span, m_model.model_max, m_model.model_min); - m_model.total_threads = m_threadCount; - m_model.sub_division = m_subdivision; - m_model.do_subsample = true; // always set to true - m_model.spacing = m_spacing; - - for (int currentAxis = 0; currentAxis < 3; currentAxis++) - { - m_model.perCpuSlabWidth[currentAxis] = m_model.model_span[currentAxis] / m_threadCount; - m_model.ray_total += m_model.model_span[currentAxis] / m_spacing; - } - - for (int i=0; itracer = m_tracers[i]; - - // set pointer to model data - worker->model = &m_model; - - // set completed rays - worker->completedRays = 0; - - // set cpu ID - worker->cpuID = i; - - // make sure output vectors are empty - worker->points.clear(); - worker->normals.clear(); - worker->surfNumber.clear(); - worker->solidNumber.clear(); - - m_workers.push_back(worker); - -#if USE_QT - // move the worker to it's thread - worker->moveToThread(m_threads.at(i)); - - // connect signals - connect(worker, SIGNAL(finished()), - this, SLOT(workerFinished()), - Qt::QueuedConnection); - connect(this, SIGNAL(startWorkers()), - worker, SLOT(run()), - Qt::QueuedConnection); -#endif - } - - m_threadsDone = 0; - m_prepped = true; - } - - //******************************************************************* - // NAME runSample - // - // INPUTS - // none - // - // DESCRIPTION - // Does the work to perform the point sampling, including subdividing - // the work amongst a desired number of threads. - //******************************************************************* - void PointSampler::runSample() - { - if (m_prepped) - { -#if USE_QT - emit startWorkers(); -#else - // set up threading data - pthread_attr_t attr; - pthread_t *ptid = NULL; - - pthread_attr_init (&attr); - ptid = (pthread_t *) malloc (sizeof (pthread_t) * m_threadCount); - memset (ptid, 0, sizeof (pthread_t) * m_threadCount); - - /* start threading */ - for (int i=0; i *points = &(worker->points); - std::vector *normals = &(worker->normals); - - m_points.insert(m_points.end(), points->begin(), points->end()); - m_normals.insert(m_normals.end(), normals->begin(), normals->end()); - - std::vector *solNum = &(worker->solidNumber); - std::vector *surfNum = &(worker->surfNumber); - - m_surfNumber.insert(m_surfNumber.end(), surfNum->begin(), surfNum->end()); - m_solidNumber.insert(m_solidNumber.end(), solNum->begin(), solNum->end()); - - /* cleanup */ - worker->tracer = NULL; - worker->points.clear(); - worker->normals.clear(); - worker->surfNumber.clear(); - worker->solidNumber.clear(); - delete worker; - } - m_workers.clear(); - m_prepped = false; - } - -#if USE_QT - //******************************************************************* - // NAME workerFinished - // - // INPUTS - // none - // - // DESCRIPTION - // Returns here when a worker is done it's part. Once all are done it - // does the finishing work. - //******************************************************************* - void PointSampler::workerFinished() - { - // wait for the threads to finish - m_threadsDone++; - updateProgress(); - if (m_threadsDone < m_threadCount) - return; - - if (!m_canceled) - endSample(); - emit finished(); - } - - //******************************************************************* - // NAME getProgress - // - // INPUTS - // none - // - // DESCRIPTION - // Return the overall progress of the workers - //******************************************************************* - float PointSampler::getProgress() - { - int done_rays = 0; - float progress = 0.0; - - for (unsigned i=0; i < m_workers.size(); i++) - done_rays += (m_workers[i])->completedRays; - - if (m_model.ray_total) - progress = (float) done_rays / (float) m_model.ray_total; - if( progress > 100.0 ) - progress = 100.0; - - return progress; - } - - //******************************************************************* - // NAME stopSampling - // - // INPUTS - // none - // - // DESCRIPTION - // Tell all the workers to stop - //******************************************************************* - void PointSampler::stopSampling() - { - m_canceled = true; - for (unsigned i=0; ipleaseStop(); - } - } -#endif - - } // namespace Sampler - -} // namespace GeomConversion diff --git a/src/other/gct/Sampler/PointSampler.h b/src/other/gct/Sampler/PointSampler.h deleted file mode 100644 index d3e7f99fba5..00000000000 --- a/src/other/gct/Sampler/PointSampler.h +++ /dev/null @@ -1,179 +0,0 @@ -/* PointSampler.h - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/21/13 - * - * Authors(s): - * DRH - * - * Description: - * Implements a point sample technique to get (x, y, z) locations on - * a piece of geometry. - */ - -#ifndef POINTSAMPLER_H -#define POINTSAMPLER_H - -// System headers -#include - -// Local headers -#include "Interface/ISampler.h" - -namespace GeomConversion { - - namespace Sampler { - - // Structures - - //******************************************************************* - // NAME thread_model_data - // - // DESCRIPTION - // Holds data used across the entire geometric model. - //******************************************************************* - struct thread_model_data - { - int total_threads; - int sub_division; - bool do_subsample; - double spacing; - double model_min[3]; - double model_max[3]; - double model_span[3]; - double perCpuSlabWidth[3]; - int ray_total; - }; - - //******************************************************************* - // NAME PointSamplerWorker - // - // DESCRIPTION - // Holds data used/created on a per thread basis. - // - // NOTE - // Glorified structure declared as a class for Qt threading model. - //******************************************************************* - class PointSamplerWorker -#if USE_QT - : public QObject -#endif - { -#if USE_QT - Q_OBJECT -#endif - - public: -#if USE_QT - PointSamplerWorker(QObject *parent = NULL) : QObject(parent) { m_keepGoing = true; } -#endif - - /* input data */ - Interface::IGeometryTracer *tracer; - struct thread_model_data *model; - int cpuID; - - /* intermediate data */ - int completedRays; - - /* output data */ - std::vector points; - std::vector normals; - std::vector solidNumber; - std::vector surfNumber; - -#if USE_QT - bool m_keepGoing; - - void pleaseStop() { m_keepGoing = false; } - - signals: - void finished(); - - public slots: - void run(); -#endif - }; - - - /** - * PointSampler - * - * Implements a point sample technique to get (x, y, z) locations on - * a piece of geometry. - */ - class PointSampler : public Interface::ISampler - { -#if USE_QT - Q_OBJECT -#endif - - public: - PointSampler(SAMPLER_CONST_DEF); - ~PointSampler(); - - void setSubdivisionDepth(int d) { m_subdivision = d; } - - virtual void setSpacing(float s) { m_spacing = s; } - virtual void prepSample(); - virtual void endSample(); - - std::vector getPoints() { return m_points; } - std::vector getNormals() { return m_normals; } - std::vector getSolidNumbers() { return m_solidNumber; } - std::vector getSurfNumbers() { return m_surfNumber; } - -#if USE_QT - virtual void stopSampling(); - virtual float getProgress(); - - public slots: - virtual void workerFinished(); -#endif - virtual void runSample(); - - private: - /* necessary inputs */ - float m_spacing; - int m_subdivision; - struct thread_model_data m_model; - std::vector m_workers; - - /* output storage */ - std::vector m_points; - std::vector m_normals; - std::vector m_solidNumber; - std::vector m_surfNumber; - }; - - } // namespace Sampler - -} // namespace GeomConversion - -#endif diff --git a/src/other/gct/dcmain/CMakeLists.txt b/src/other/gct/dcmain/CMakeLists.txt deleted file mode 100644 index 66fe2d06025..00000000000 --- a/src/other/gct/dcmain/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../openNURBS - ${CMAKE_CURRENT_SOURCE_DIR}/../../tcl/generic - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../Auxiliary -) - -add_executable(dcmain main.cpp) -target_link_libraries(dcmain librt libbu libbn AUX MeshDecimation ${M_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) - diff --git a/src/other/gct/dcmain/main.cpp b/src/other/gct/dcmain/main.cpp deleted file mode 100644 index d3565960c96..00000000000 --- a/src/other/gct/dcmain/main.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* main.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/26/13 - * - * Authors(s): - * DRH - * - * Description: - * This is the standalone mesh decimation application. - * - */ - -/* Standard C/C++ libraries */ -#include -#include -#include -#include -#include - -/* Custom libraries */ -#include "gctcommon.h" -#include "MeshDecimation/meshdecimation.h" -#include "MeshDecimation/meshoptimizer.h" -#include "MeshDecimation/meshoptimization.h" - -#if 0 - #define DECIMATION_FLAGS MD_ATTRIB_FLAGS_NORMALIZE -#else - #define DECIMATION_FLAGS MD_ATTRIB_FLAGS_COMPUTE_NORMALS -#endif -#define OPTLEVEL 3 // 0=none, 1=low, 2=medium, 3=high - -/* globals */ -std::vector gVertex; -std::vector gNormal; -std::vector gNewVertex; -std::vector gNewNormal; -std::vector gNewVIndex; -std::vector gGeom; -std::vector gOffset; - -/*============ STATIC FUNCTIONS ============*/ - -//****************************************************************************** -// NAME mesh_decimate -// -// INPUTS -// points - initial list of non-decimated vertices -// normals - initial list of non-decimated normals -// indexes - initial list of non-decimated indices -// featuresize - the smallest feature size to keep undecimated -// optlevel - optimization level -// -// DESCRIPTION -// Function that actually performs the mesh decimation routines. -//****************************************************************************** -static void -mesh_decimate(std::vector &points, - std::vector &normals, - std::vector &indexes, - float featuresize, - int optlevel) -{ - int threadcount; - long pointcount = points.size() / 3; - long tricount = indexes.size() / 3; - float *vertex = &points[0]; - float *normal = &normals[0]; - int *indices = &indexes[0]; - int *triindices, isize = (int) sizeof(int); - mdOperation mdop; - - if (points.size() < 1) return; - - threadcount = (int) ideal_thread_count (); - - mdOperationInit(&mdop); - mdOperationData(&mdop, pointcount, vertex, sizeof(float), 3*sizeof(float), - tricount, indices, isize, 3*isize); - mdOperationStrength(&mdop, featuresize); - mdOperationAddAttrib(&mdop, normal, sizeof(float), 3, 3*sizeof(float), DECIMATION_FLAGS); - -#if DEBUG_MESH_DECIMATION_VERBOSE - fprintf( stderr, "Mesh Decimation Start, %d vertices, %d triangles, %f featuresize\n", - (int)pointcount, (int)tricount, featuresize ); -#endif - mdMeshDecimation(&mdop, threadcount, - MD_FLAGS_NORMAL_VERTEX_SPLITTING|MD_FLAGS_TRIANGLE_WINDING_CCW); -#if DEBUG_MESH_DECIMATION_VERBOSE - fprintf( stderr, "Mesh Decimation End, %d vertices, %d triangles, %.3f seconds\n", - (int)mdop.vertexcount, (int)mdop.tricount, (double)mdop.msecs / 1000.0 ); -#endif - - pointcount = mdop.vertexcount; - tricount = mdop.tricount; - - mesh_optimization (pointcount, tricount, indices, isize, threadcount, optlevel); - - /* indices need to be offset by the vertices already present */ - long offset = gNewVertex.size()/3; - - for( long i = pointcount, j = 0 ; i ; i--, j += 3 ) - { - gNewVertex.push_back(vertex[j+0]); - gNewVertex.push_back(vertex[j+1]); - gNewVertex.push_back(vertex[j+2]); - - gNewNormal.push_back(normal[j+0]); - gNewNormal.push_back(normal[j+1]); - gNewNormal.push_back(normal[j+2]); - } - - triindices = indices; - for( long i = tricount ; i ; i--, triindices += 3 ) - { - gNewVIndex.push_back( triindices[0] + offset ); - gNewVIndex.push_back( triindices[1] + offset ); - gNewVIndex.push_back( triindices[2] + offset ); - } -} - -/*============ MAIN FUNCTION ============*/ - -//****************************************************************************** -// NAME main -// -// INPUTS -// argc - commandline argument count -// argv - array of commandline arguments -// -// DESCRIPTION -// Perform mesh decimation on an ".obj" file generated from the -// ballpivot (Ball Pivoting) or march (Marching Cubes) application. -//****************************************************************************** -int -main (int argc, char **argv) -{ - FILE *fp1 = NULL, *fp2 = NULL; - char buffer[255], ch, gname[100]; - float fsize = 0.25; - std::vector indexes; - - if (argc < 3) - { - fprintf (stderr, "Usage: %s infile outfile [featuresize]\n", argv[0]); - exit (1); - } - - if (argc == 4) - fsize = (float) atof (argv[3]); - - if (!(fp1 = fopen (argv[1], "r"))) - { - fprintf (stderr, "Error opening infile(%s).\n", argv[1]); - exit(2); - } - - memset (gname, 0, sizeof (gname)); - - long low = 0; - long high = 0; - long offset = 0; - - ch = fgetc (fp1); - while (!feof(fp1)) - { - ungetc (ch, fp1); - memset (buffer, 0, sizeof (buffer)); - fgets (buffer, 255, fp1); - - int len = strlen(buffer); - if (buffer[len-1] == '\n') buffer[len-1] = '\0'; - - if (buffer[0] == 'g') - { - if (buffer[1] != '\0') - { - if (low > 0 && high > 0) - { - std::vector points, normals; - - /* set grouping info */ - gOffset.push_back(gNewVIndex.size()); - gGeom.push_back(gname); - -#if DEBUG - fprintf (stdout, "Decimating %s...\n", gname); -#endif - - /* stick current element's points into temp vectors */ - for (long i = (low -1); i <= (high -1); i++) - { - long idx = i*3; - - points.push_back (gVertex[idx+0]); - points.push_back (gVertex[idx+1]); - points.push_back (gVertex[idx+2]); - - normals.push_back (gNormal[idx+0]); - normals.push_back (gNormal[idx+1]); - normals.push_back (gNormal[idx+2]); - } - - /* do the mesh decimation */ - mesh_decimate(points, normals, indexes, fsize, OPTLEVEL); - - /* reset indices */ - offset = high; - low = high = -1; - } - - /* grab region name */ - char *tok = strtok (buffer, " \n\r"); /* eat 'g' */ - tok = strtok (NULL, " \n\r"); - sprintf (gname, "%s", tok); - - indexes.clear(); - } - } - else if (buffer[0] == 'v') - { - if (buffer[1] == ' ') /* vertex */ - { - float x, y, z; - sscanf (buffer+2, "%f %f %f", &x, &y, &z); - gVertex.push_back (x); - gVertex.push_back (y); - gVertex.push_back (z); - } - else if (buffer[1] == 'n') /* normal */ - { - float x, y, z; - sscanf (buffer+3, "%f %f %f", &x, &y, &z); - gNormal.push_back (x); - gNormal.push_back (y); - gNormal.push_back (z); - } - } - else if (buffer[0] == 'f') - { - long idx[3]; - char *tok = strtok(buffer, " \n"); - tok = strtok(NULL, " \n"); sscanf(tok, "%ld", &idx[0]); - tok = strtok(NULL, " \n"); sscanf(tok, "%ld", &idx[1]); - tok = strtok(NULL, " \n"); sscanf(tok, "%ld", &idx[2]); - - for (int i=0; i<3; i++) - { - int j = idx[i]; - if (low < 1) low = j; - else if (j < low) low = j; - - if (high < 1) high = j; - else if (j > high) high = j; - - indexes.push_back (idx[i] - offset - 1); - } - } - - ch = fgetc (fp1); - while (ch == '\n' || ch == '\r') ch = fgetc (fp1); - } - fclose (fp1); - fp1 = NULL; - - if (low > 0 && high > 0) - { - std::vector points, normals; - - /* set grouping info */ - gOffset.push_back(gNewVIndex.size()); - gGeom.push_back(gname); - -#if DEBUG - fprintf (stdout, "Decimating %s...\n", gname); -#endif - - /* stick current element's points into temp vectors */ - for (long i = (low -1); i <= (high -1); i++) - { - long idx = i*3; - - points.push_back (gVertex[idx+0]); - points.push_back (gVertex[idx+1]); - points.push_back (gVertex[idx+2]); - - normals.push_back (gNormal[idx+0]); - normals.push_back (gNormal[idx+1]); - normals.push_back (gNormal[idx+2]); - } - - /* do the mesh decimation */ - mesh_decimate(points, normals, indexes, fsize, OPTLEVEL); - } - - /* output obj file */ - if (!(fp2 = fopen (argv[2], "w"))) - { - fprintf (stderr, "Error opening OBJ file(%s).\n", argv[2]); - exit(3); - } - -#if DEBUG - fprintf (stdout, "Outputting OBJ file.\n", gname); -#endif - /* output OBJ file */ - output_obj (fp2, gNewVertex, gNewNormal, gNewVIndex, gGeom, gOffset); - - /* close mesh file */ - fclose (fp2); - fp2 = NULL; - - return 0; -} diff --git a/src/other/gct/psmain/CMakeLists.txt b/src/other/gct/psmain/CMakeLists.txt deleted file mode 100644 index 6e994ec9572..00000000000 --- a/src/other/gct/psmain/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include - ${CMAKE_CURRENT_SOURCE_DIR}/../../openNURBS - ${CMAKE_CURRENT_SOURCE_DIR}/../../tcl/generic - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../Auxiliary -) - -add_executable(psmain main.cpp) -target_link_libraries(psmain librt libbu libbn AUX Sampler BrlcadGCT ${CMAKE_THREAD_LIBS_INIT}) - diff --git a/src/other/gct/psmain/main.cpp b/src/other/gct/psmain/main.cpp deleted file mode 100644 index 582379250d1..00000000000 --- a/src/other/gct/psmain/main.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* main.cpp - * - * ---------------------------------------------------------------------- - * - * Copyright (c) 2014 SURVICE Engineering. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ---------------------------------------------------------------------- - * - * Revision Date: - * 08/22/13 - * - * Authors(s): - * DRH - * - * Description: - * This is the standalone point sampling application. - * - */ - -/* Standard C/C++ libraries */ -#include -#include - -/* BRL-CAD libraries */ -#include "bu.h" - -/* Custom libraries */ -#include "BRLCAD/BrlcadLoader.h" -#include "BRLCAD/DbGeometry.h" -#include "BRLCAD/DbTracer.h" -#include "Sampler/PointSampler.h" - -#include // this has to be behind the brlcad headers!!! - -/*============ MAIN FUNCTION ============*/ - -//****************************************************************************** -// NAME main -// -// INPUTS -// argc - commandline argument count -// argv - array of commandline arguments -// -// DESCRIPTION -// Perform point sampling on BRL-CAD geometry. -//****************************************************************************** -int -main (int argc, char **argv) -{ - int i, thread_count = (int) ideal_thread_count(); - float csize = 0.0; - GLoaderInterface *loader = NULL; - std::vector gnames; - - if (argc < 3) - bu_exit(1, "Usage: %s model.g cellsize [item0 ...]\n", argv[0]); - - /* get the cube size */ - csize = (float) atof (argv[2]); - if (csize <= 0.0) - bu_exit(2, "Cube size (%s) needs to be a float greater than 0.0.", argv[2]); - - if (argc > 3) - { - /* user specified piece(s) of geometry */ - for (i=3; istartLoader(); - - if (loader->getStatus()) - { - /* get region names */ - gnames = loader->getGeomNames(); - } - - /* cleanup loader */ - delete loader; - loader = NULL; - } - - FILE *fp = NULL; - char fname[100]; - memset (fname, 0, sizeof (char) * 100); - sprintf (fname, "%s.psamp", argv[1]); - if (!(fp = fopen (fname, "w"))) - bu_exit(5, "Opening output PSAMP file failed.\n"); - - /* print cellsize */ - fprintf (fp, "%.4f\n", csize); - - /* create target & tracers -- right now assume BRLCAD */ - GeomConversion::Interface::INativeGeometry *target = new GeomConversion::BRLCAD::DbGeometry(argv[1]); - std::vector tracers; - for (i=0; iloadGeometry(gnames.at(i), thread_count); - psamp->setSpacing(csize); - psamp->prepSample(); - psamp->runSample(); - target->cleanupGeometry(); - - /* Get points and normals for this geometry */ - std::vector points = psamp->getPoints(); - std::vector normals = psamp->getNormals(); -#if SURF_SOL_CAPTURE - std::vector sols = psamp->getSolidNumbers(); - std::vector surfs = psamp->getSurfNumbers(); -#endif - - /* cleanup sampler */ - delete psamp; - psamp = NULL; - - /* output points & normals */ - fprintf (fp, "# %s\n", gnames.at(i).c_str()); - for (int j=0; j 0) - { - GeomConversion::Interface::IGeometryTracer *ti = tracers.back(); - tracers.pop_back(); - delete ti; - } - delete target; - target = NULL; - - return 0; -} diff --git a/src/other/libosmesa.dist b/src/other/libosmesa.dist index 664ad7f2096..887cd35c4b5 100644 --- a/src/other/libosmesa.dist +++ b/src/other/libosmesa.dist @@ -47,7 +47,6 @@ src/main/clip.h src/main/colormac.h src/main/colortab.c src/main/colortab.h -src/main/config.h src/main/context.c src/main/context.h src/main/convolve.c @@ -70,7 +69,6 @@ src/main/enums.c src/main/enums.h src/main/eval.c src/main/eval.h -src/main/execmem.c src/main/extensions.c src/main/extensions.h src/main/fbobject.c @@ -85,6 +83,7 @@ src/main/get.c src/main/get.h src/main/getstring.c src/main/glheader.h +src/main/gllimits.h src/main/hash.c src/main/hash.h src/main/hint.c diff --git a/src/other/libosmesa/CMakeLists.txt b/src/other/libosmesa/CMakeLists.txt index e0f3f16fb91..a6e40f90277 100644 --- a/src/other/libosmesa/CMakeLists.txt +++ b/src/other/libosmesa/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.18) project(OSMESA) include(CheckCXXCompilerFlag) -check_cxx_compiler_flag(-O3 O3_COMPILER_FLAG) +check_cxx_compiler_flag(-O2 O2_COMPILER_FLAG) find_package(Threads REQUIRED) if (CMAKE_USE_PTHREADS_INIT) @@ -23,7 +23,7 @@ endif (HAVE_M_LIBRARY) # prefixing add_definitions(-DUSE_MGL_NAMESPACE) -# The primarly libosmesa library +# The primary libosmesa library add_subdirectory(src) # For testing purposes, the build defines a number diff --git a/src/other/libosmesa/include/OSMesa/osmesa.h b/src/other/libosmesa/include/OSMesa/osmesa.h index d7e96740dd3..fd1f700a3f2 100644 --- a/src/other/libosmesa/include/OSMesa/osmesa.h +++ b/src/other/libosmesa/include/OSMesa/osmesa.h @@ -42,7 +42,7 @@ * * * The limits on the width and height of an image buffer are MAX_WIDTH and - * MAX_HEIGHT as defined in src/main/config.h. Defaults are 4096 and 4096. + * MAX_HEIGHT as defined in src/main/gllimits.h. Defaults are 4096 and 4096. * You can increase them as needed but beware that many temporary arrays in * Mesa are dimensioned by MAX_WIDTH or MAX_HEIGHT. */ diff --git a/src/other/libosmesa/src/CMakeLists.txt b/src/other/libosmesa/src/CMakeLists.txt index bde4852a059..6684a1109b8 100644 --- a/src/other/libosmesa/src/CMakeLists.txt +++ b/src/other/libosmesa/src/CMakeLists.txt @@ -40,7 +40,6 @@ set(osmesa_srcs main/enable.c main/enums.c main/eval.c - main/execmem.c main/extensions.c main/fbobject.c main/feedback.c @@ -197,10 +196,10 @@ set_property(TARGET osmesa APPEND PROPERTY COMPILE_DEFINITIONS "UTIL_ARCH_LITTLE set_property(TARGET osmesa APPEND PROPERTY COMPILE_DEFINITIONS "LIBRARYBUILD") set_property(TARGET osmesa APPEND PROPERTY COMPILE_DEFINITIONS "GL_DLL_EXPORTS") set_property(TARGET osmesa APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "GL_DLL_IMPORTS") -if (O3_COMPILER_FLAG) - # If we have the O3 flag, use it - target_compile_options(osmesa PRIVATE "-O3") -endif (O3_COMPILER_FLAG) +if (O2_COMPILER_FLAG) + # If we have the O2 flag, use it + target_compile_options(osmesa PRIVATE "-O2") +endif (O2_COMPILER_FLAG) # Local Variables: # tab-width: 8 diff --git a/src/other/libosmesa/src/drivers/common/driverfuncs.c b/src/other/libosmesa/src/drivers/common/driverfuncs.c index 338476f5f37..f74ce303b4b 100644 --- a/src/other/libosmesa/src/drivers/common/driverfuncs.c +++ b/src/other/libosmesa/src/drivers/common/driverfuncs.c @@ -114,7 +114,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->FreeTexImageData = _mesa_free_texture_image_data; driver->MapTexture = NULL; driver->UnmapTexture = NULL; - driver->TextureMemCpy = _mesa_memcpy; + driver->TextureMemCpy = memcpy; driver->IsTextureResident = NULL; driver->PrioritizeTexture = NULL; driver->ActiveTexture = NULL; diff --git a/src/other/libosmesa/src/drivers/osmesa/osmesa.c b/src/other/libosmesa/src/drivers/osmesa/osmesa.c index 6ae03d67d3f..289f0a8f0be 100644 --- a/src/other/libosmesa/src/drivers/osmesa/osmesa.c +++ b/src/other/libosmesa/src/drivers/osmesa/osmesa.c @@ -814,7 +814,7 @@ compute_row_addresses(OSMesaContext osmesa) static void osmesa_delete_renderbuffer(struct gl_renderbuffer *rb) { - _mesa_free(rb); + free(rb); } @@ -1176,7 +1176,7 @@ OSMesaCreateContextExt(GLenum format, GLint depthBits, GLint stencilBits, 1 /* num samples */ ); if (!osmesa->gl_visual) { - _mesa_free(osmesa); + free(osmesa); return NULL; } @@ -1193,7 +1193,7 @@ OSMesaCreateContextExt(GLenum format, GLint depthBits, GLint stencilBits, : (GLcontext *) NULL, &functions, (void *) osmesa)) { _mesa_destroy_visual(osmesa->gl_visual); - _mesa_free(osmesa); + free(osmesa); return NULL; } @@ -1206,7 +1206,7 @@ OSMesaCreateContextExt(GLenum format, GLint depthBits, GLint stencilBits, if (!osmesa->gl_buffer) { _mesa_destroy_visual(osmesa->gl_visual); _mesa_free_context_data(&osmesa->mesa); - _mesa_free(osmesa); + free(osmesa); return NULL; } @@ -1243,7 +1243,7 @@ OSMesaCreateContextExt(GLenum format, GLint depthBits, GLint stencilBits, !_swsetup_CreateContext(ctx)) { _mesa_destroy_visual(osmesa->gl_visual); _mesa_free_context_data(ctx); - _mesa_free(osmesa); + free(osmesa); return NULL; } @@ -1286,7 +1286,7 @@ OSMesaDestroyContext(OSMesaContext osmesa) _mesa_unreference_framebuffer(&osmesa->gl_buffer); _mesa_free_context_data(&osmesa->mesa); - _mesa_free(osmesa); + free(osmesa); } } @@ -1556,7 +1556,7 @@ OSMesaGetProcAddress(const char *funcName) { int i; for (i = 0; functions[i].Name; i++) { - if (_mesa_strcmp(functions[i].Name, funcName) == 0) + if (strcmp(functions[i].Name, funcName) == 0) return functions[i].Function; } return _glapi_get_proc_address(funcName); diff --git a/src/other/libosmesa/src/glapi/glapi.c b/src/other/libosmesa/src/glapi/glapi.c index 0dae4c0d73c..4305f509e69 100644 --- a/src/other/libosmesa/src/glapi/glapi.c +++ b/src/other/libosmesa/src/glapi/glapi.c @@ -31,10 +31,6 @@ * current thread and to manage registration/dispatch of dynamically * added extension functions. * - * It's intended that this file and the other glapi*.[ch] files are - * flexible enough to be reused in several places: XFree86, DRI- - * based libGL.so, and perhaps the SGI SI. - * * NOTE: There are no dependencies on Mesa in this code. * * Versions (API changes): @@ -166,19 +162,6 @@ static GLint NoOpUnused(void) * between TLS enabled loaders and non-TLS DRI drivers. */ /*@{*/ -#if defined(GLX_USE_TLS) - -PUBLIC __thread struct _glapi_table * _glapi_tls_Dispatch -__attribute__((tls_model("initial-exec"))) - = (struct _glapi_table *) __glapi_noop_table; - -PUBLIC __thread void * _glapi_tls_Context -__attribute__((tls_model("initial-exec"))); - -PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL; -PUBLIC const void *_glapi_Context = NULL; - -#else #if defined(THREADS) @@ -201,7 +184,6 @@ PUBLIC struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table; PUBLIC void *_glapi_Context = NULL; -#endif /* defined(GLX_USE_TLS) */ /*@}*/ @@ -259,9 +241,7 @@ PUBLIC void _glapi_set_context(void *context) { (void) __unused_noop_functions; /* silence a warning */ -#if defined(GLX_USE_TLS) - _glapi_tls_Context = context; -#elif defined(THREADS) +#if defined(THREADS) _glthread_SetTSD(&ContextTSD, context); _glapi_Context = (ThreadSafe) ? NULL : context; #else @@ -279,9 +259,7 @@ _glapi_set_context(void *context) PUBLIC void * _glapi_get_context(void) { -#if defined(GLX_USE_TLS) - return _glapi_tls_Context; -#elif defined(THREADS) +#if defined(THREADS) if (ThreadSafe) { return _glthread_GetTSD(&ContextTSD); } else { @@ -311,15 +289,8 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) /* use the no-op functions */ dispatch = (struct _glapi_table *) __glapi_noop_table; } -#ifdef DEBUG - else { - _glapi_check_table(dispatch); - } -#endif -#if defined(GLX_USE_TLS) - _glapi_tls_Dispatch = dispatch; -#elif defined(THREADS) +#if defined(THREADS) _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch; #else /*THREADS*/ @@ -336,9 +307,7 @@ PUBLIC struct _glapi_table * _glapi_get_dispatch(void) { struct _glapi_table * api; -#if defined(GLX_USE_TLS) - api = _glapi_tls_Dispatch; -#elif defined(THREADS) +#if defined(THREADS) api = (ThreadSafe) ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD) : _glapi_Dispatch; @@ -354,20 +323,7 @@ _glapi_get_dispatch(void) *** The rest of this file is pretty much concerned with GetProcAddress *** functionality. ***/ - -#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS) -# define DISPATCH_FUNCTION_SIZE 16 -#elif defined(USE_X86_ASM) -# if defined(THREADS) && !defined(GLX_USE_TLS) -# define DISPATCH_FUNCTION_SIZE 32 -# else -# define DISPATCH_FUNCTION_SIZE 16 -# endif -#endif - -#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer) -# define NEED_FUNCTION_POINTER -#endif +#define NEED_FUNCTION_POINTER /* The code in this file is auto-generated with Python */ #include "glprocs.h" @@ -405,20 +361,6 @@ get_static_proc_offset(const char *funcName) return -1; } - -#if !defined(XFree86Server) && !defined(XGLServer) -#ifdef USE_X86_ASM - -#if defined( GLX_USE_TLS ) -extern GLubyte gl_dispatch_functions_start[]; -extern GLubyte gl_dispatch_functions_end[]; -#else -extern const GLubyte gl_dispatch_functions_start[]; -#endif - -#endif /* USE_X86_ASM */ - - /** * Return dispatch function address for the named static (built-in) function. * Return NULL if function not found. @@ -444,10 +386,6 @@ get_static_proc_address(const char *funcName) } } -#endif /* !defined(XFree86Server) && !defined(XGLServer) */ - - - /** * Return the name of the function at the given offset in the dispatch * table. For debugging only. @@ -475,16 +413,6 @@ get_static_proc_name(GLuint offset) */ #define MAX_EXTENSION_FUNCS 300 - -/* - * The dispatch table size (number of entries) is the size of the - * _glapi_table struct plus the number of dynamic entries we can add. - * The extra slots can be filled in by DRI drivers that register new extension - * functions. - */ -#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS) - - /** * Track information about a function added to the GL API. */ @@ -533,9 +461,6 @@ struct _glapi_function { static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; static GLuint NumExtEntryPoints = 0; -#ifdef USE_SPARC_ASM -extern void __glapi_sparc_icache_flush(unsigned int *); -#endif /** * Generate a dispatch function (entrypoint) which jumps through @@ -545,75 +470,8 @@ extern void __glapi_sparc_icache_flush(unsigned int *); static _glapi_proc generate_entrypoint(GLuint functionOffset) { -#if defined(USE_X86_ASM) - /* 32 is chosen as something of a magic offset. For x86, the dispatch - * at offset 32 is the first one where the offset in the - * "jmp OFFSET*4(%eax)" can't be encoded in a single byte. - */ - const GLubyte * const template_func = gl_dispatch_functions_start - + (DISPATCH_FUNCTION_SIZE * 32); - GLubyte * const code = (GLubyte *) malloc(DISPATCH_FUNCTION_SIZE); - - - if (code != NULL) { - (void) memcpy(code, template_func, DISPATCH_FUNCTION_SIZE); - fill_in_entrypoint_offset((_glapi_proc) code, functionOffset); - } - - return (_glapi_proc) code; -#elif defined(USE_SPARC_ASM) - -#ifdef __arch64__ - static const unsigned int insn_template[] = { - 0x05000000, /* sethi %uhi(_glapi_Dispatch), %g2 */ - 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ - 0x8410a000, /* or %g2, %ulo(_glapi_Dispatch), %g2 */ - 0x82106000, /* or %g1, %lo(_glapi_Dispatch), %g1 */ - 0x8528b020, /* sllx %g2, 32, %g2 */ - 0xc2584002, /* ldx [%g1 + %g2], %g1 */ - 0x05000000, /* sethi %hi(8 * glapioffset), %g2 */ - 0x8410a000, /* or %g2, %lo(8 * glapioffset), %g2 */ - 0xc6584002, /* ldx [%g1 + %g2], %g3 */ - 0x81c0c000, /* jmpl %g3, %g0 */ - 0x01000000 /* nop */ - }; -#else - static const unsigned int insn_template[] = { - 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ - 0xc2006000, /* ld [%g1 + %lo(_glapi_Dispatch)], %g1 */ - 0xc6006000, /* ld [%g1 + %lo(4*glapioffset)], %g3 */ - 0x81c0c000, /* jmpl %g3, %g0 */ - 0x01000000 /* nop */ - }; -#endif /* __arch64__ */ - unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); - unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; - if (code) { - memcpy(code, insn_template, sizeof(insn_template)); - -#ifdef __arch64__ - code[0] |= (glapi_addr >> (32 + 10)); - code[1] |= ((glapi_addr & 0xffffffff) >> 10); - __glapi_sparc_icache_flush(&code[0]); - code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1)); - code[3] |= (glapi_addr & ((1 << 10) - 1)); - __glapi_sparc_icache_flush(&code[2]); - code[6] |= ((functionOffset * 8) >> 10); - code[7] |= ((functionOffset * 8) & ((1 << 10) - 1)); - __glapi_sparc_icache_flush(&code[6]); -#else - code[0] |= (glapi_addr >> 10); - code[1] |= (glapi_addr & ((1 << 10) - 1)); - __glapi_sparc_icache_flush(&code[0]); - code[2] |= (functionOffset * 4); - __glapi_sparc_icache_flush(&code[2]); -#endif /* __arch64__ */ - } - return (_glapi_proc) code; -#else (void) functionOffset; return NULL; -#endif /* USE_*_ASM */ } @@ -624,43 +482,11 @@ generate_entrypoint(GLuint functionOffset) static void fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset) { -#if defined(USE_X86_ASM) - GLubyte * const code = (GLubyte *) entrypoint; - -#if DISPATCH_FUNCTION_SIZE == 32 - *((unsigned int *)(code + 11)) = 4 * offset; - *((unsigned int *)(code + 22)) = 4 * offset; -#elif DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS ) - *((unsigned int *)(code + 8)) = 4 * offset; -#elif DISPATCH_FUNCTION_SIZE == 16 - *((unsigned int *)(code + 7)) = 4 * offset; -#else -# error Invalid DISPATCH_FUNCTION_SIZE! -#endif - -#elif defined(USE_SPARC_ASM) - - /* XXX this hasn't been tested! */ - unsigned int *code = (unsigned int *) entrypoint; -#ifdef __arch64__ - code[6] = 0x05000000; /* sethi %hi(8 * glapioffset), %g2 */ - code[7] = 0x8410a000; /* or %g2, %lo(8 * glapioffset), %g2 */ - code[6] |= ((offset * 8) >> 10); - code[7] |= ((offset * 8) & ((1 << 10) - 1)); - __glapi_sparc_icache_flush(&code[6]); -#else /* __arch64__ */ - code[2] = 0xc6006000; /* ld [%g1 + %lo(4*glapioffset)], %g3 */ - code[2] |= (offset * 4); - __glapi_sparc_icache_flush(&code[2]); -#endif /* __arch64__ */ - -#else /* an unimplemented architecture */ (void) entrypoint; (void) offset; -#endif /* USE_*_ASM */ } @@ -887,14 +713,12 @@ _glapi_get_proc_address(const char *funcName) } } -#if !defined( XFree86Server ) && !defined( XGLServer ) /* search static functions */ { const _glapi_proc func = get_static_proc_address(funcName); if (func) return func; } -#endif /* !defined( XFree86Server ) */ entry = add_function_name(funcName); return (entry == NULL) ? NULL : entry->dispatch_stub; @@ -927,100 +751,6 @@ _glapi_get_proc_name(GLuint offset) return NULL; } - - -/** - * Return size of dispatch table struct as number of functions (or - * slots). - */ -PUBLIC GLuint -_glapi_get_dispatch_table_size(void) -{ - return DISPATCH_TABLE_SIZE; -} - - - -/** - * Make sure there are no NULL pointers in the given dispatch table. - * Intended for debugging purposes. - */ -void -_glapi_check_table(const struct _glapi_table *table) -{ -#ifdef DEBUG - const GLuint entries = _glapi_get_dispatch_table_size(); - const void **tab = (const void **) table; - GLuint i; - for (i = 1; i < entries; i++) { - assert(tab[i]); - } - - /* Do some spot checks to be sure that the dispatch table - * slots are assigned correctly. - */ - { - GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); - char *BeginFunc = (char*) &table->Begin; - GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); - assert(BeginOffset == _gloffset_Begin); - assert(BeginOffset == offset); - } - { - GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); - char *viewportFunc = (char*) &table->Viewport; - GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); - assert(viewportOffset == _gloffset_Viewport); - assert(viewportOffset == offset); - } - { - GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); - char *VertexPointerFunc = (char*) &table->VertexPointer; - GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); - assert(VertexPointerOffset == _gloffset_VertexPointer); - assert(VertexPointerOffset == offset); - } - { - GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); - char *ResetMinMaxFunc = (char*) &table->ResetMinmax; - GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); - assert(ResetMinMaxOffset == _gloffset_ResetMinmax); - assert(ResetMinMaxOffset == offset); - } - { - GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); - char *blendColorFunc = (char*) &table->BlendColor; - GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); - assert(blendColorOffset == _gloffset_BlendColor); - assert(blendColorOffset == offset); - } - { - GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); - char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; - GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); - assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); - assert(secondaryColor3fOffset == offset); - } - { - GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); - char *pointParameterivFunc = (char*) &table->PointParameterivNV; - GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); - assert(pointParameterivOffset == _gloffset_PointParameterivNV); - assert(pointParameterivOffset == offset); - } - { - GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); - char *setFenceFunc = (char*) &table->SetFenceNV; - GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); - assert(setFenceOffset == _gloffset_SetFenceNV); - assert(setFenceOffset == offset); - } -#else - (void) table; -#endif -} - - #if defined(PTHREADS) || defined(GLX_USE_TLS) /** * Perform platform-specific GL API entry-point fixups. @@ -1028,21 +758,6 @@ _glapi_check_table(const struct _glapi_table *table) static void init_glapi_relocs(void) { -#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT) - extern unsigned long _x86_get_dispatch(void); - char run_time_patch[] = { - 0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */ - }; - GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */ - const GLubyte * const get_disp = (const GLubyte *) run_time_patch; - GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start; - - *offset = _x86_get_dispatch(); - while (curr_func != (GLubyte *) gl_dispatch_functions_end) { - (void) memcpy(curr_func, get_disp, sizeof(run_time_patch)); - curr_func += DISPATCH_FUNCTION_SIZE; - } -#endif } #endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */ diff --git a/src/other/libosmesa/src/glapi/glapi.h b/src/other/libosmesa/src/glapi/glapi.h index a3d41b70a05..46e8c052b84 100644 --- a/src/other/libosmesa/src/glapi/glapi.h +++ b/src/other/libosmesa/src/glapi/glapi.h @@ -65,17 +65,6 @@ typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); ** Define the GET_CURRENT_CONTEXT() macro. ** \param C local variable which will hold the current context. **/ -#if defined (GLX_USE_TLS) - -const extern void *_glapi_Context; -const extern struct _glapi_table *_glapi_Dispatch; - -extern __thread void * _glapi_tls_Context -__attribute__((tls_model("initial-exec"))); - -# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_tls_Context - -#else extern void *_glapi_Context; extern struct _glapi_table *_glapi_Dispatch; @@ -86,7 +75,6 @@ extern struct _glapi_table *_glapi_Dispatch; # define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_Context # endif -#endif /* defined (GLX_USE_TLS) */ /** @@ -131,14 +119,6 @@ struct _glapi_table * _glapi_get_override_dispatch(int layer); -extern GLuint -_glapi_get_dispatch_table_size(void); - - -extern void -_glapi_check_table(const struct _glapi_table *table); - - extern int _glapi_add_dispatch(const char * const * function_names, const char * parameter_signature); diff --git a/src/other/libosmesa/src/glapi/glapitemp.h b/src/other/libosmesa/src/glapi/glapitemp.h index 1908ebdefd3..8363c25d707 100644 --- a/src/other/libosmesa/src/glapi/glapitemp.h +++ b/src/other/libosmesa/src/glapi/glapitemp.h @@ -2539,7 +2539,7 @@ KEYWORD1 void KEYWORD2 NAME(UniformMatrix4x3fv)(GLint location, GLsizei count, G DISPATCH(UniformMatrix4x3fv, (location, count, transpose, value), (F, "glUniformMatrix4x3fv(%d, %d, %d, %p);\n", location, count, transpose, (const void *) value)); } -KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixd)(const GLdouble * m) +KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixd)(const GLdouble m[16]) { DISPATCH(LoadTransposeMatrixdARB, (m), (F, "glLoadTransposeMatrixd(%p);\n", (const void *) m)); } @@ -2549,7 +2549,7 @@ KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixdARB)(const GLdouble * m) DISPATCH(LoadTransposeMatrixdARB, (m), (F, "glLoadTransposeMatrixdARB(%p);\n", (const void *) m)); } -KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixf)(const GLfloat * m) +KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixf)(const GLfloat m[16]) { DISPATCH(LoadTransposeMatrixfARB, (m), (F, "glLoadTransposeMatrixf(%p);\n", (const void *) m)); } @@ -2559,7 +2559,7 @@ KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixfARB)(const GLfloat * m) DISPATCH(LoadTransposeMatrixfARB, (m), (F, "glLoadTransposeMatrixfARB(%p);\n", (const void *) m)); } -KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixd)(const GLdouble * m) +KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixd)(const GLdouble m[16]) { DISPATCH(MultTransposeMatrixdARB, (m), (F, "glMultTransposeMatrixd(%p);\n", (const void *) m)); } @@ -2569,7 +2569,7 @@ KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixdARB)(const GLdouble * m) DISPATCH(MultTransposeMatrixdARB, (m), (F, "glMultTransposeMatrixdARB(%p);\n", (const void *) m)); } -KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixf)(const GLfloat * m) +KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixf)(const GLfloat m[16]) { DISPATCH(MultTransposeMatrixfARB, (m), (F, "glMultTransposeMatrixf(%p);\n", (const void *) m)); } diff --git a/src/other/libosmesa/src/glapi/glthread.h b/src/other/libosmesa/src/glapi/glthread.h index 26a7213e902..2cfdaf9636a 100644 --- a/src/other/libosmesa/src/glapi/glthread.h +++ b/src/other/libosmesa/src/glapi/glthread.h @@ -294,14 +294,7 @@ _glthread_GetTSD(_glthread_TSD *); extern void _glthread_SetTSD(_glthread_TSD *, void *); -#if defined(GLX_USE_TLS) - -extern __thread struct _glapi_table * _glapi_tls_Dispatch -__attribute__((tls_model("initial-exec"))); - -#define GET_DISPATCH() _glapi_tls_Dispatch - -#elif !defined(GL_CALL) +#if !defined(GL_CALL) # if defined(THREADS) # define GET_DISPATCH() \ ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ diff --git a/src/other/libosmesa/src/main/api_arrayelt.c b/src/other/libosmesa/src/main/api_arrayelt.c index 2fbacdc4c13..608c10d4ce4 100644 --- a/src/other/libosmesa/src/main/api_arrayelt.c +++ b/src/other/libosmesa/src/main/api_arrayelt.c @@ -1051,7 +1051,7 @@ GLboolean _ae_create_context(GLcontext *ctx) FogCoordFuncs[6] = _gloffset_FogCoordfvEXT; FogCoordFuncs[7] = _gloffset_FogCoorddvEXT; - ctx->aelt_context = CALLOC(sizeof(AEcontext)); + ctx->aelt_context = calloc(1,sizeof(AEcontext)); if (!ctx->aelt_context) return GL_FALSE; @@ -1063,7 +1063,7 @@ GLboolean _ae_create_context(GLcontext *ctx) void _ae_destroy_context(GLcontext *ctx) { if (AE_CONTEXT(ctx)) { - FREE(ctx->aelt_context); + free(ctx->aelt_context); ctx->aelt_context = NULL; } } diff --git a/src/other/libosmesa/src/main/arrayobj.c b/src/other/libosmesa/src/main/arrayobj.c index 04dae23aedc..a9e71b65a1e 100644 --- a/src/other/libosmesa/src/main/arrayobj.c +++ b/src/other/libosmesa/src/main/arrayobj.c @@ -94,7 +94,7 @@ void _mesa_delete_array_object(GLcontext *ctx, struct gl_array_object *obj) { (void) ctx; - _mesa_free(obj); + free(obj); } diff --git a/src/other/libosmesa/src/main/attrib.c b/src/other/libosmesa/src/main/attrib.c index 5d81c0efb1f..5945f160f90 100644 --- a/src/other/libosmesa/src/main/attrib.c +++ b/src/other/libosmesa/src/main/attrib.c @@ -115,7 +115,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_ACCUM_BUFFER_BIT) { struct gl_accum_attrib *attr; attr = MALLOC_STRUCT(gl_accum_attrib); - MEMCPY(attr, &ctx->Accum, sizeof(struct gl_accum_attrib)); + memcpy(attr, &ctx->Accum, sizeof(struct gl_accum_attrib)); newnode = new_attrib_node(GL_ACCUM_BUFFER_BIT); newnode->data = attr; newnode->next = head; @@ -125,7 +125,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_COLOR_BUFFER_BIT) { struct gl_colorbuffer_attrib *attr; attr = MALLOC_STRUCT(gl_colorbuffer_attrib); - MEMCPY(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib)); + memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib)); newnode = new_attrib_node(GL_COLOR_BUFFER_BIT); newnode->data = attr; newnode->next = head; @@ -136,7 +136,7 @@ _mesa_PushAttrib(GLbitfield mask) struct gl_current_attrib *attr; FLUSH_CURRENT(ctx, 0); attr = MALLOC_STRUCT(gl_current_attrib); - MEMCPY(attr, &ctx->Current, sizeof(struct gl_current_attrib)); + memcpy(attr, &ctx->Current, sizeof(struct gl_current_attrib)); newnode = new_attrib_node(GL_CURRENT_BIT); newnode->data = attr; newnode->next = head; @@ -146,7 +146,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_DEPTH_BUFFER_BIT) { struct gl_depthbuffer_attrib *attr; attr = MALLOC_STRUCT(gl_depthbuffer_attrib); - MEMCPY(attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib)); + memcpy(attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib)); newnode = new_attrib_node(GL_DEPTH_BUFFER_BIT); newnode->data = attr; newnode->next = head; @@ -192,7 +192,7 @@ _mesa_PushAttrib(GLbitfield mask) attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; - MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib)); + memcpy(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib)); attr->Map2Color4 = ctx->Eval.Map2Color4; attr->Map2Index = ctx->Eval.Map2Index; attr->Map2Normal = ctx->Eval.Map2Normal; @@ -202,7 +202,7 @@ _mesa_PushAttrib(GLbitfield mask) attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; - MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib)); + memcpy(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib)); attr->Normalize = ctx->Transform.Normalize; attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped; attr->PointSmooth = ctx->Point.SmoothFlag; @@ -239,7 +239,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_EVAL_BIT) { struct gl_eval_attrib *attr; attr = MALLOC_STRUCT(gl_eval_attrib); - MEMCPY(attr, &ctx->Eval, sizeof(struct gl_eval_attrib)); + memcpy(attr, &ctx->Eval, sizeof(struct gl_eval_attrib)); newnode = new_attrib_node(GL_EVAL_BIT); newnode->data = attr; newnode->next = head; @@ -249,7 +249,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_FOG_BIT) { struct gl_fog_attrib *attr; attr = MALLOC_STRUCT(gl_fog_attrib); - MEMCPY(attr, &ctx->Fog, sizeof(struct gl_fog_attrib)); + memcpy(attr, &ctx->Fog, sizeof(struct gl_fog_attrib)); newnode = new_attrib_node(GL_FOG_BIT); newnode->data = attr; newnode->next = head; @@ -259,7 +259,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_HINT_BIT) { struct gl_hint_attrib *attr; attr = MALLOC_STRUCT(gl_hint_attrib); - MEMCPY(attr, &ctx->Hint, sizeof(struct gl_hint_attrib)); + memcpy(attr, &ctx->Hint, sizeof(struct gl_hint_attrib)); newnode = new_attrib_node(GL_HINT_BIT); newnode->data = attr; newnode->next = head; @@ -270,7 +270,7 @@ _mesa_PushAttrib(GLbitfield mask) struct gl_light_attrib *attr; FLUSH_CURRENT(ctx, 0); /* flush material changes */ attr = MALLOC_STRUCT(gl_light_attrib); - MEMCPY(attr, &ctx->Light, sizeof(struct gl_light_attrib)); + memcpy(attr, &ctx->Light, sizeof(struct gl_light_attrib)); newnode = new_attrib_node(GL_LIGHTING_BIT); newnode->data = attr; newnode->next = head; @@ -280,7 +280,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_LINE_BIT) { struct gl_line_attrib *attr; attr = MALLOC_STRUCT(gl_line_attrib); - MEMCPY(attr, &ctx->Line, sizeof(struct gl_line_attrib)); + memcpy(attr, &ctx->Line, sizeof(struct gl_line_attrib)); newnode = new_attrib_node(GL_LINE_BIT); newnode->data = attr; newnode->next = head; @@ -290,7 +290,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_LIST_BIT) { struct gl_list_attrib *attr; attr = MALLOC_STRUCT(gl_list_attrib); - MEMCPY(attr, &ctx->List, sizeof(struct gl_list_attrib)); + memcpy(attr, &ctx->List, sizeof(struct gl_list_attrib)); newnode = new_attrib_node(GL_LIST_BIT); newnode->data = attr; newnode->next = head; @@ -300,7 +300,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_PIXEL_MODE_BIT) { struct gl_pixel_attrib *attr; attr = MALLOC_STRUCT(gl_pixel_attrib); - MEMCPY(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib)); + memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib)); /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; newnode = new_attrib_node(GL_PIXEL_MODE_BIT); @@ -312,7 +312,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_POINT_BIT) { struct gl_point_attrib *attr; attr = MALLOC_STRUCT(gl_point_attrib); - MEMCPY(attr, &ctx->Point, sizeof(struct gl_point_attrib)); + memcpy(attr, &ctx->Point, sizeof(struct gl_point_attrib)); newnode = new_attrib_node(GL_POINT_BIT); newnode->data = attr; newnode->next = head; @@ -322,7 +322,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_POLYGON_BIT) { struct gl_polygon_attrib *attr; attr = MALLOC_STRUCT(gl_polygon_attrib); - MEMCPY(attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib)); + memcpy(attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib)); newnode = new_attrib_node(GL_POLYGON_BIT); newnode->data = attr; newnode->next = head; @@ -331,8 +331,8 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_POLYGON_STIPPLE_BIT) { GLuint *stipple; - stipple = (GLuint *) MALLOC(32*sizeof(GLuint)); - MEMCPY(stipple, ctx->PolygonStipple, 32*sizeof(GLuint)); + stipple = (GLuint *) malloc(32*sizeof(GLuint)); + memcpy(stipple, ctx->PolygonStipple, 32*sizeof(GLuint)); newnode = new_attrib_node(GL_POLYGON_STIPPLE_BIT); newnode->data = stipple; newnode->next = head; @@ -342,7 +342,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_SCISSOR_BIT) { struct gl_scissor_attrib *attr; attr = MALLOC_STRUCT(gl_scissor_attrib); - MEMCPY(attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib)); + memcpy(attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib)); newnode = new_attrib_node(GL_SCISSOR_BIT); newnode->data = attr; newnode->next = head; @@ -352,7 +352,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_STENCIL_BUFFER_BIT) { struct gl_stencil_attrib *attr; attr = MALLOC_STRUCT(gl_stencil_attrib); - MEMCPY(attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib)); + memcpy(attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib)); newnode = new_attrib_node(GL_STENCIL_BUFFER_BIT); newnode->data = attr; newnode->next = head; @@ -371,7 +371,7 @@ _mesa_PushAttrib(GLbitfield mask) _mesa_lock_context_textures(ctx); /* copy/save the bulk of texture state here */ - _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture)); + memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture)); /* Save references to the currently bound texture objects so they don't * accidentally get deleted while referenced in the attribute stack. @@ -409,7 +409,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_TRANSFORM_BIT) { struct gl_transform_attrib *attr; attr = MALLOC_STRUCT(gl_transform_attrib); - MEMCPY(attr, &ctx->Transform, sizeof(struct gl_transform_attrib)); + memcpy(attr, &ctx->Transform, sizeof(struct gl_transform_attrib)); newnode = new_attrib_node(GL_TRANSFORM_BIT); newnode->data = attr; newnode->next = head; @@ -419,7 +419,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_VIEWPORT_BIT) { struct gl_viewport_attrib *attr; attr = MALLOC_STRUCT(gl_viewport_attrib); - MEMCPY(attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib)); + memcpy(attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib)); newnode = new_attrib_node(GL_VIEWPORT_BIT); newnode->data = attr; newnode->next = head; @@ -430,7 +430,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_MULTISAMPLE_BIT_ARB) { struct gl_multisample_attrib *attr; attr = MALLOC_STRUCT(gl_multisample_attrib); - MEMCPY(attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib)); + memcpy(attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib)); newnode = new_attrib_node(GL_MULTISAMPLE_BIT_ARB); newnode->data = attr; newnode->next = head; @@ -955,7 +955,7 @@ _mesa_PopAttrib(void) break; case GL_CURRENT_BIT: FLUSH_CURRENT(ctx, 0); - MEMCPY(&ctx->Current, attr->data, + memcpy(&ctx->Current, attr->data, sizeof(struct gl_current_attrib)); break; case GL_DEPTH_BUFFER_BIT: { @@ -975,7 +975,7 @@ _mesa_PopAttrib(void) } break; case GL_EVAL_BIT: - MEMCPY(&ctx->Eval, attr->data, sizeof(struct gl_eval_attrib)); + memcpy(&ctx->Eval, attr->data, sizeof(struct gl_eval_attrib)); ctx->NewState |= _NEW_EVAL; break; case GL_FOG_BIT: { @@ -1053,7 +1053,7 @@ _mesa_PopAttrib(void) _mesa_set_enable(ctx, GL_COLOR_MATERIAL, light->ColorMaterialEnabled); /* materials */ - MEMCPY(&ctx->Light.Material, &light->Material, + memcpy(&ctx->Light.Material, &light->Material, sizeof(struct gl_material)); } break; @@ -1067,10 +1067,10 @@ _mesa_PopAttrib(void) } break; case GL_LIST_BIT: - MEMCPY(&ctx->List, attr->data, sizeof(struct gl_list_attrib)); + memcpy(&ctx->List, attr->data, sizeof(struct gl_list_attrib)); break; case GL_PIXEL_MODE_BIT: - MEMCPY(&ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib)); + memcpy(&ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib)); /* XXX what other pixel state needs to be set by function calls? */ _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); ctx->NewState |= _NEW_PIXEL; @@ -1127,7 +1127,7 @@ _mesa_PopAttrib(void) } break; case GL_POLYGON_STIPPLE_BIT: - MEMCPY(ctx->PolygonStipple, attr->data, 32*sizeof(GLuint)); + memcpy(ctx->PolygonStipple, attr->data, 32*sizeof(GLuint)); ctx->NewState |= _NEW_POLYGONSTIPPLE; if (ctx->Driver.PolygonStipple) ctx->Driver.PolygonStipple(ctx, (const GLubyte *) attr->data); @@ -1231,8 +1231,8 @@ _mesa_PopAttrib(void) } next = attr->next; - FREE(attr->data); - FREE(attr); + free(attr->data); + free(attr); attr = next; } } @@ -1293,14 +1293,14 @@ _mesa_PushClientAttrib(GLbitfield mask) #endif /* packing attribs */ attr = MALLOC_STRUCT(gl_pixelstore_attrib); - MEMCPY(attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib)); + memcpy(attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib)); newnode = new_attrib_node(GL_CLIENT_PACK_BIT); newnode->data = attr; newnode->next = head; head = newnode; /* unpacking attribs */ attr = MALLOC_STRUCT(gl_pixelstore_attrib); - MEMCPY(attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib)); + memcpy(attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib)); newnode = new_attrib_node(GL_CLIENT_UNPACK_BIT); newnode->data = attr; newnode->next = head; @@ -1319,8 +1319,8 @@ _mesa_PushClientAttrib(GLbitfield mask) ctx->Array.ElementArrayBufferObj->RefCount++; #endif - MEMCPY(attr, &ctx->Array, sizeof(struct gl_array_attrib)); - MEMCPY(obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object)); + memcpy(attr, &ctx->Array, sizeof(struct gl_array_attrib)); + memcpy(obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object)); attr->ArrayObj = obj; @@ -1365,7 +1365,7 @@ _mesa_PopClientAttrib(void) (*ctx->Driver.DeleteBuffer)(ctx, ctx->Pack.BufferObj); } #endif - MEMCPY(&ctx->Pack, attr->data, + memcpy(&ctx->Pack, attr->data, sizeof(struct gl_pixelstore_attrib)); ctx->NewState |= _NEW_PACKUNPACK; break; @@ -1377,7 +1377,7 @@ _mesa_PopClientAttrib(void) (*ctx->Driver.DeleteBuffer)(ctx, ctx->Unpack.BufferObj); } #endif - MEMCPY(&ctx->Unpack, attr->data, + memcpy(&ctx->Unpack, attr->data, sizeof(struct gl_pixelstore_attrib)); ctx->NewState |= _NEW_PACKUNPACK; break; @@ -1400,10 +1400,10 @@ _mesa_PopClientAttrib(void) data->ElementArrayBufferObj->Name); #endif - MEMCPY(ctx->Array.ArrayObj, data->ArrayObj, + memcpy(ctx->Array.ArrayObj, data->ArrayObj, sizeof(struct gl_array_object)); - FREE(data->ArrayObj); + free(data->ArrayObj); /* FIXME: Should some bits in ctx->Array->NewState also be set * FIXME: here? It seems like it should be set to inclusive-or @@ -1419,8 +1419,8 @@ _mesa_PopClientAttrib(void) } next = attr->next; - FREE(attr->data); - FREE(attr); + free(attr->data); + free(attr); attr = next; } } @@ -1452,8 +1452,8 @@ _mesa_free_attrib_data(GLcontext *ctx) } next = attr->next; - _mesa_free(attr->data); - _mesa_free(attr); + free(attr->data); + free(attr); attr = next; } } diff --git a/src/other/libosmesa/src/main/bitset.h b/src/other/libosmesa/src/main/bitset.h index 0f7bb83788d..edcc9ecfc34 100644 --- a/src/other/libosmesa/src/main/bitset.h +++ b/src/other/libosmesa/src/main/bitset.h @@ -42,10 +42,10 @@ /* bitset operations */ -#define BITSET_COPY(x, y) _mesa_memcpy( (x), (y), sizeof (x) ) -#define BITSET_EQUAL(x, y) (_mesa_memcmp( (x), (y), sizeof (x) ) == 0) -#define BITSET_ZERO(x) _mesa_memset( (x), 0, sizeof (x) ) -#define BITSET_ONES(x) _mesa_memset( (x), 0xff, sizeof (x) ) +#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) ) +#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0) +#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) ) +#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) #define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) #define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) diff --git a/src/other/libosmesa/src/main/bufferobj.c b/src/other/libosmesa/src/main/bufferobj.c index 064885bf1b6..77097af7af9 100644 --- a/src/other/libosmesa/src/main/bufferobj.c +++ b/src/other/libosmesa/src/main/bufferobj.c @@ -165,8 +165,8 @@ _mesa_delete_buffer_object(GLcontext *ctx, struct gl_buffer_object *bufObj) (void) ctx; if (bufObj->Data) - _mesa_free(bufObj->Data); - _mesa_free(bufObj); + free(bufObj->Data); + free(bufObj); } @@ -266,7 +266,7 @@ _mesa_buffer_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size, bufObj->Usage = usage; if (data) { - _mesa_memcpy(bufObj->Data, data, size); + memcpy(bufObj->Data, data, size); } } } @@ -302,7 +302,7 @@ _mesa_buffer_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, ASSERT(size + offset <= bufObj->Size); if (bufObj->Data) { - _mesa_memcpy((GLubyte *) bufObj->Data + offset, data, size); + memcpy((GLubyte *) bufObj->Data + offset, data, size); } } @@ -334,7 +334,7 @@ _mesa_buffer_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, (void) target; if (bufObj->Data && ((GLsizeiptrARB)(size + offset) <= bufObj->Size)) { - _mesa_memcpy(data, (GLubyte *) bufObj->Data + offset, size); + memcpy(data, (GLubyte *) bufObj->Data + offset, size); } } diff --git a/src/other/libosmesa/src/main/colormac.h b/src/other/libosmesa/src/main/colormac.h index 666f2ebca1b..b49fe8be4fc 100644 --- a/src/other/libosmesa/src/main/colormac.h +++ b/src/other/libosmesa/src/main/colormac.h @@ -34,7 +34,7 @@ #include "imports.h" -#include "config.h" +#include "gllimits.h" #include "macros.h" diff --git a/src/other/libosmesa/src/main/colortab.c b/src/other/libosmesa/src/main/colortab.c index ce30e63dd29..9b128cf4552 100644 --- a/src/other/libosmesa/src/main/colortab.c +++ b/src/other/libosmesa/src/main/colortab.c @@ -448,8 +448,8 @@ _mesa_ColorTable(GLenum target, GLenum internalFormat, _mesa_free_colortable_data(table); if (width > 0) { - table->TableF = (GLfloat *) _mesa_malloc(comps * width * sizeof(GLfloat)); - table->TableUB = (GLubyte *) _mesa_malloc(comps * width * sizeof(GLubyte)); + table->TableF = (GLfloat *) malloc(comps * width * sizeof(GLfloat)); + table->TableUB = (GLubyte *) malloc(comps * width * sizeof(GLubyte)); if (!table->TableF || !table->TableUB) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); @@ -732,7 +732,7 @@ _mesa_GetColorTable(GLenum target, GLenum format, } break; case GL_RGBA: - _mesa_memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat)); + memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat)); break; default: _mesa_problem(ctx, "bad table format in glGetColorTable"); @@ -1194,11 +1194,11 @@ void _mesa_free_colortable_data(struct gl_color_table *p) { if (p->TableF) { - _mesa_free(p->TableF); + free(p->TableF); p->TableF = NULL; } if (p->TableUB) { - _mesa_free(p->TableUB); + free(p->TableUB); p->TableUB = NULL; } } diff --git a/src/other/libosmesa/src/main/config.h b/src/other/libosmesa/src/main/config.h deleted file mode 100644 index 8c695bd591c..00000000000 --- a/src/other/libosmesa/src/main/config.h +++ /dev/null @@ -1,333 +0,0 @@ -/** - * \file config.h - * Tunable configuration parameters. - */ - -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef MESA_CONFIG_H_INCLUDED -#define MESA_CONFIG_H_INCLUDED - -/** - * \name OpenGL implementation limits - */ -/*@{*/ - -/** Maximum modelview matrix stack depth */ -#define MAX_MODELVIEW_STACK_DEPTH 32 - -/** Maximum projection matrix stack depth */ -#define MAX_PROJECTION_STACK_DEPTH 32 - -/** Maximum texture matrix stack depth */ -#define MAX_TEXTURE_STACK_DEPTH 10 - -/** Maximum color matrix stack depth */ -#define MAX_COLOR_STACK_DEPTH 4 - -/** Maximum attribute stack depth */ -#define MAX_ATTRIB_STACK_DEPTH 16 - -/** Maximum client attribute stack depth */ -#define MAX_CLIENT_ATTRIB_STACK_DEPTH 16 - -/** Maximum recursion depth of display list calls */ -#define MAX_LIST_NESTING 64 - -/** Maximum number of lights */ -#define MAX_LIGHTS 8 - -/** Maximum user-defined clipping planes */ -#define MAX_CLIP_PLANES 6 - -/** Maximum pixel map lookup table size */ -#define MAX_PIXEL_MAP_TABLE 256 - -/** Maximum number of auxillary color buffers */ -#define MAX_AUX_BUFFERS 4 - -/** Maximum order (degree) of curves */ -#ifdef AMIGA -# define MAX_EVAL_ORDER 12 -#else -# define MAX_EVAL_ORDER 30 -#endif - -/** Maximum Name stack depth */ -#define MAX_NAME_STACK_DEPTH 64 - -/** Minimum point size */ -#define MIN_POINT_SIZE 1.0 -/** Maximum point size */ -#define MAX_POINT_SIZE 20.0 -/** Point size granularity */ -#define POINT_SIZE_GRANULARITY 0.1 - -/** Minimum line width */ -#define MIN_LINE_WIDTH 1.0 -/** Maximum line width */ -#define MAX_LINE_WIDTH 10.0 -/** Line width granularity */ -#define LINE_WIDTH_GRANULARITY 0.1 - -/** Max texture palette / color table size */ -#define MAX_COLOR_TABLE_SIZE 256 - -/** Number of 1D/2D texture mipmap levels */ -#define MAX_TEXTURE_LEVELS 12 - -/** Number of 3D texture mipmap levels */ -#define MAX_3D_TEXTURE_LEVELS 9 - -/** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */ -#define MAX_CUBE_TEXTURE_LEVELS 12 - -/** Maximum rectangular texture size - GL_NV_texture_rectangle */ -#define MAX_TEXTURE_RECT_SIZE 2048 - -/** Number of texture units - GL_ARB_multitexture - * This needs to be the larger of MAX_TEXTURE_COORD_UNITS and - * MAX_TEXTURE_IMAGE_UNITS seen below, since MAX_TEXTURE_UNITS is used - * to dimension some arrays that store both coord and image data. -*/ -#define MAX_TEXTURE_UNITS 8 - -/*@}*/ - - -/** - * \name Separate numbers of texture coordinates and texture image units. - * - * These values will eventually replace most instances of MAX_TEXTURE_UNITS. - * We should always have MAX_TEXTURE_COORD_UNITS <= MAX_TEXTURE_IMAGE_UNITS. - * And, GL_MAX_TEXTURE_UNITS <= MAX_TEXTURE_COORD_UNITS. - */ -/*@{*/ -#define MAX_TEXTURE_COORD_UNITS 8 -#define MAX_TEXTURE_IMAGE_UNITS 8 -/*@}*/ - -/** - * Maximum viewport/image width. Must accomodate all texture sizes too. - */ -#define MAX_WIDTH 4096 -/** Maximum viewport/image height */ -#define MAX_HEIGHT 4096 - -/** Maxmimum size for CVA. May be overridden by the drivers. */ -#define MAX_ARRAY_LOCK_SIZE 3000 - -/** Subpixel precision for antialiasing, window coordinate snapping */ -#define SUB_PIXEL_BITS 4 - -/** Size of histogram tables */ -#define HISTOGRAM_TABLE_SIZE 256 - -/** Max convolution filter width */ -#define MAX_CONVOLUTION_WIDTH 9 -/** Max convolution filter height */ -#define MAX_CONVOLUTION_HEIGHT 9 - -/** For GL_ARB_texture_compression */ -#define MAX_COMPRESSED_TEXTURE_FORMATS 25 - -/** For GL_EXT_texture_filter_anisotropic */ -#define MAX_TEXTURE_MAX_ANISOTROPY 16.0 - -/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */ -#define MAX_TEXTURE_LOD_BIAS 11.0 - -/** For GL_NV_vertex_program */ -/*@{*/ -#define MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS 128 -#define MAX_NV_VERTEX_PROGRAM_TEMPS 12 -#define MAX_NV_VERTEX_PROGRAM_PARAMS 128 /* KW: power of two */ -#define MAX_NV_VERTEX_PROGRAM_INPUTS 16 -#define MAX_NV_VERTEX_PROGRAM_OUTPUTS 15 -/*@}*/ - -/** For GL_NV_fragment_program */ -/*@{*/ -#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */ -#define MAX_NV_FRAGMENT_PROGRAM_TEMPS 96 -#define MAX_NV_FRAGMENT_PROGRAM_PARAMS 64 -#define MAX_NV_FRAGMENT_PROGRAM_INPUTS 12 -#define MAX_NV_FRAGMENT_PROGRAM_OUTPUTS 3 -#define MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS 2 -/*@}*/ - -/** For GL_ARB_vertex_program */ -/*@{*/ -#define MAX_VERTEX_PROGRAM_ADDRESS_REGS 1 -#define MAX_VERTEX_PROGRAM_ATTRIBS 16 -/*@}*/ - -/** For GL_ARB_fragment_program */ -/*@{*/ -#define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0 -#define MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS 48 -#define MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS 24 -#define MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS 4 -/*@}*/ - -/** For any program target/extension */ -/*@{*/ -#define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */ -#define MAX_PROGRAM_ENV_PARAMS 128 -#define MAX_PROGRAM_MATRICES 8 -#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 -#define MAX_PROGRAM_CALL_DEPTH 8 -#define MAX_PROGRAM_TEMPS 128 -#define MAX_PROGRAM_ADDRESS_REGS 2 -#define MAX_UNIFORMS 128 -#define MAX_VARYING 8 -/*@}*/ - -/** For GL_ARB_vertex_shader */ -/*@{*/ -#define MAX_VERTEX_ATTRIBS 16 -#define MAX_VERTEX_TEXTURE_IMAGE_UNITS MAX_TEXTURE_UNITS -#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS) -/*@}*/ - - -/** For GL_ARB_draw_buffers */ -/*@{*/ -#define MAX_DRAW_BUFFERS 4 -/*@}*/ - - -/** For GL_EXT_framebuffer_object */ -/*@{*/ -#define MAX_COLOR_ATTACHMENTS 8 -/*@}*/ - - - -/** - * \name Mesa-specific parameters - */ -/*@{*/ - - -/** - * If non-zero use GLdouble for walking triangle edges, for better accuracy. - */ -#define TRIANGLE_WALK_DOUBLE 0 - - -/** - * Bits per depth buffer value (max is 32). - */ -#ifndef DEFAULT_SOFTWARE_DEPTH_BITS -#define DEFAULT_SOFTWARE_DEPTH_BITS 16 -#endif -/** Depth buffer data type */ -#if DEFAULT_SOFTWARE_DEPTH_BITS <= 16 -#define DEFAULT_SOFTWARE_DEPTH_TYPE GLushort -#else -#define DEFAULT_SOFTWARE_DEPTH_TYPE GLuint -#endif - - -/** - * Bits per stencil value: 8 - */ -#define STENCIL_BITS 8 - - -/** - * Bits per color channel: 8, 16 or 32 - */ -#ifndef CHAN_BITS -#define CHAN_BITS 8 -#endif - - -/* - * Color channel component order - * - * \note Changes will almost certainly cause problems at this time. - */ -#define RCOMP 0 -#define GCOMP 1 -#define BCOMP 2 -#define ACOMP 3 - - -/* - * Enable/disable features (blocks of code) by setting FEATURE_xyz to 0 or 1. - */ -#ifndef _HAVE_FULL_GL -#define _HAVE_FULL_GL 1 -#endif - -#define FEATURE_userclip _HAVE_FULL_GL -#define FEATURE_texgen _HAVE_FULL_GL -#define FEATURE_windowpos _HAVE_FULL_GL -#define FEATURE_ARB_occlusion_query _HAVE_FULL_GL -#define FEATURE_ARB_fragment_program _HAVE_FULL_GL -#define FEATURE_ARB_vertex_buffer_object _HAVE_FULL_GL -#define FEATURE_ARB_vertex_program _HAVE_FULL_GL - -#define FEATURE_ARB_vertex_shader _HAVE_FULL_GL -#define FEATURE_ARB_fragment_shader _HAVE_FULL_GL -#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader) -#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects -#define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects - -#define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL -#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL -#define FEATURE_EXT_pixel_buffer_object _HAVE_FULL_GL -#define FEATURE_EXT_texture_sRGB _HAVE_FULL_GL -#define FEATURE_EXT_timer_query _HAVE_FULL_GL -#define FEATURE_ATI_fragment_shader _HAVE_FULL_GL -#define FEATURE_MESA_program_debug _HAVE_FULL_GL -#define FEATURE_NV_fence _HAVE_FULL_GL -#define FEATURE_NV_fragment_program _HAVE_FULL_GL -#define FEATURE_NV_vertex_program _HAVE_FULL_GL -/*@}*/ - - -/** - * Maximum number of temporary vertices required for clipping. - * - * Used in array_cache and tnl modules. - */ -#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1) - - -#endif /* MESA_CONFIG_H_INCLUDED */ - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/other/libosmesa/src/main/context.c b/src/other/libosmesa/src/main/context.c index db390f2a375..dc00b09518b 100644 --- a/src/other/libosmesa/src/main/context.c +++ b/src/other/libosmesa/src/main/context.c @@ -134,9 +134,6 @@ #endif #include "shader_api.h" -#ifdef USE_SPARC_ASM -#include "sparc/sparc.h" -#endif #ifndef MESA_VERBOSE int MESA_VERBOSE = 0; @@ -216,7 +213,7 @@ _mesa_create_visual(GLboolean rgbFlag, GLint accumAlphaBits, GLint numSamples) { - GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual)); + GLvisual *vis = (GLvisual *) calloc(1,sizeof(GLvisual)); if (vis) { if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag, redBits, greenBits, blueBits, alphaBits, @@ -224,7 +221,7 @@ _mesa_create_visual(GLboolean rgbFlag, accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits, numSamples)) { - _mesa_free(vis); + free(vis); return NULL; } } @@ -314,7 +311,7 @@ _mesa_initialize_visual(GLvisual *vis, void _mesa_destroy_visual(GLvisual *vis) { - _mesa_free(vis); + free(vis); } /*@}*/ @@ -372,9 +369,6 @@ one_time_init(GLcontext *ctx) } #endif -#ifdef USE_SPARC_ASM - _mesa_init_sparc_glapi_relocs(); -#endif if (_mesa_getenv("MESA_DEBUG")) { _glapi_noop_enable_warnings(GL_TRUE); _glapi_set_warning_func((_glapi_warning_func) _mesa_warning); @@ -536,7 +530,7 @@ alloc_shared_state(GLcontext *ctx) if (ss->DefaultRect) (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect); if (ss) - _mesa_free(ss); + free(ss); return GL_FALSE; } @@ -751,7 +745,7 @@ free_shared_state(GLcontext *ctx, struct gl_shared_state *ss) _glthread_DESTROY_MUTEX(ss->Mutex); - _mesa_free(ss); + free(ss); } @@ -797,7 +791,7 @@ init_natives(struct gl_program_constants *prog) /** * Initialize fields of gl_constants (aka ctx->Const.*). - * Use defaults from config.h. The device drivers will often override + * Use defaults from gllimits.h. The device drivers will often override * some of these values (such as number of texture units). */ static void @@ -1018,22 +1012,15 @@ generic_nop(void) /** * Allocate and initialize a new dispatch table. */ +#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *)) static struct _glapi_table * alloc_dispatch_table(void) { - /* Find the larger of Mesa's dispatch table and libGL's dispatch table. - * In practice, this'll be the same for stand-alone Mesa. But for DRI - * Mesa we do this to accomodate different versions of libGL and various - * DRI drivers. - */ - GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), - sizeof(struct _glapi_table) / sizeof(_glapi_proc)); - struct _glapi_table *table = - (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc)); + struct _glapi_table *table = (struct _glapi_table *)malloc(sizeof(struct _glapi_table)); if (table) { _glapi_proc *entry = (_glapi_proc *) table; GLint i; - for (i = 0; i < numEntries; i++) { + for (i = 0; i < DISPATCH_TABLE_SIZE; i++) { entry[i] = (_glapi_proc) generic_nop; } } @@ -1119,7 +1106,7 @@ _mesa_initialize_context(GLcontext *ctx, if (!ctx->Exec || !ctx->Save) { free_shared_state(ctx, ctx->Shared); if (ctx->Exec) { - _mesa_free(ctx->Exec); + free(ctx->Exec); ctx->Exec = NULL; } } @@ -1176,7 +1163,7 @@ _mesa_create_context(const GLvisual *visual, ASSERT(visual); ASSERT(driverContext); - ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext)); + ctx = (GLcontext *) calloc(1,sizeof(GLcontext)); if (!ctx) return NULL; @@ -1184,7 +1171,7 @@ _mesa_create_context(const GLvisual *visual, driverFunctions, driverContext)) { return ctx; } else { - _mesa_free(ctx); + free(ctx); return NULL; } } @@ -1230,8 +1217,8 @@ _mesa_free_context_data(GLcontext *ctx) _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); /* free dispatch tables */ - _mesa_free(ctx->Exec); - _mesa_free(ctx->Save); + free(ctx->Exec); + free(ctx->Save); /* Shared context state (display lists, textures, etc) */ _glthread_LOCK_MUTEX(ctx->Shared->Mutex); @@ -1244,7 +1231,7 @@ _mesa_free_context_data(GLcontext *ctx) } if (ctx->Extensions.String) - _mesa_free((void *) ctx->Extensions.String); + free((void *) ctx->Extensions.String); /* unbind the context if it's currently bound */ if (ctx == _mesa_get_current_context()) { @@ -1265,7 +1252,7 @@ _mesa_destroy_context(GLcontext *ctx) { if (ctx) { _mesa_free_context_data(ctx); - _mesa_free((void *) ctx); + free((void *) ctx); } } diff --git a/src/other/libosmesa/src/main/debug.c b/src/other/libosmesa/src/main/debug.c index da3e7c1f390..e7b24085aae 100644 --- a/src/other/libosmesa/src/main/debug.c +++ b/src/other/libosmesa/src/main/debug.c @@ -126,16 +126,8 @@ void _mesa_print_info(void) #else _mesa_debug(NULL, "Mesa thread-safe: NO\n"); #endif -#if defined(USE_X86_ASM) - _mesa_debug(NULL, "Mesa x86-optimized: YES\n"); -#else _mesa_debug(NULL, "Mesa x86-optimized: NO\n"); -#endif -#if defined(USE_SPARC_ASM) - _mesa_debug(NULL, "Mesa sparc-optimized: YES\n"); -#else _mesa_debug(NULL, "Mesa sparc-optimized: NO\n"); -#endif } @@ -150,52 +142,41 @@ void _mesa_print_info(void) static void add_debug_flags(const char *debug) { #ifdef DEBUG - if (_mesa_strstr(debug, "varray")) + if (strstr(debug, "varray")) MESA_VERBOSE |= VERBOSE_VARRAY; - if (_mesa_strstr(debug, "tex")) + if (strstr(debug, "tex")) MESA_VERBOSE |= VERBOSE_TEXTURE; - if (_mesa_strstr(debug, "imm")) + if (strstr(debug, "imm")) MESA_VERBOSE |= VERBOSE_IMMEDIATE; - if (_mesa_strstr(debug, "pipe")) + if (strstr(debug, "pipe")) MESA_VERBOSE |= VERBOSE_PIPELINE; - if (_mesa_strstr(debug, "driver")) + if (strstr(debug, "driver")) MESA_VERBOSE |= VERBOSE_DRIVER; - if (_mesa_strstr(debug, "state")) + if (strstr(debug, "state")) MESA_VERBOSE |= VERBOSE_STATE; - if (_mesa_strstr(debug, "api")) + if (strstr(debug, "api")) MESA_VERBOSE |= VERBOSE_API; - if (_mesa_strstr(debug, "list")) + if (strstr(debug, "list")) MESA_VERBOSE |= VERBOSE_DISPLAY_LIST; - if (_mesa_strstr(debug, "lighting")) + if (strstr(debug, "lighting")) MESA_VERBOSE |= VERBOSE_LIGHTING; - if (_mesa_strstr(debug, "disassem")) + if (strstr(debug, "disassem")) MESA_VERBOSE |= VERBOSE_DISASSEM; /* Debug flag: */ - if (_mesa_strstr(debug, "flush")) + if (strstr(debug, "flush")) MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH; -#if defined(_FPU_GETCW) && defined(_FPU_SETCW) - if (_mesa_strstr(debug, "fpexceptions")) { - /* raise FP exceptions */ - fpu_control_t mask; - _FPU_GETCW(mask); - mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM - | _FPU_MASK_OM | _FPU_MASK_UM); - _FPU_SETCW(mask); - } -#endif - #else (void) debug; #endif diff --git a/src/other/libosmesa/src/main/depthstencil.c b/src/other/libosmesa/src/main/depthstencil.c index 56cb1963695..a36fa932c78 100644 --- a/src/other/libosmesa/src/main/depthstencil.c +++ b/src/other/libosmesa/src/main/depthstencil.c @@ -71,7 +71,7 @@ delete_wrapper(struct gl_renderbuffer *rb) if (dsrb->RefCount <= 0) { dsrb->Delete(dsrb); } - _mesa_free(rb); + free(rb); } @@ -647,7 +647,7 @@ _mesa_promote_stencil(GLcontext *ctx, struct gl_renderbuffer *stencilRb) } stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL); } - _mesa_free(data); + free(data); stencilRb->_BaseFormat = GL_DEPTH_STENCIL_EXT; } diff --git a/src/other/libosmesa/src/main/dlist.c b/src/other/libosmesa/src/main/dlist.c index 1920af11a62..d79183fff2d 100644 --- a/src/other/libosmesa/src/main/dlist.c +++ b/src/other/libosmesa/src/main/dlist.c @@ -32,7 +32,7 @@ #include "imports.h" #include "api_arrayelt.h" #include "api_loopback.h" -#include "config.h" +#include "gllimits.h" #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program #include "arbprogram.h" #include "program.h" @@ -148,7 +148,7 @@ do { \ if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \ ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ - _mesa_free(_tofree); \ + free(_tofree); \ return; \ } \ } while (0) @@ -448,7 +448,7 @@ make_list(GLuint list, GLuint count) { struct mesa_display_list *dlist = CALLOC_STRUCT(mesa_display_list); dlist->id = list; - dlist->node = (Node *) _mesa_malloc(sizeof(Node) * count); + dlist->node = (Node *) malloc(sizeof(Node) * count); dlist->node[0].opcode = OPCODE_END_OF_LIST; return dlist; } @@ -491,118 +491,118 @@ _mesa_delete_list(GLcontext *ctx, struct mesa_display_list *dlist) switch (n[0].opcode) { /* for some commands, we need to free malloc'd memory */ case OPCODE_MAP1: - _mesa_free(n[6].data); + free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_MAP2: - _mesa_free(n[10].data); + free(n[10].data); n += InstSize[n[0].opcode]; break; case OPCODE_DRAW_PIXELS: - _mesa_free(n[5].data); + free(n[5].data); n += InstSize[n[0].opcode]; break; case OPCODE_BITMAP: - _mesa_free(n[7].data); + free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COLOR_TABLE: - _mesa_free(n[6].data); + free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_COLOR_SUB_TABLE: - _mesa_free(n[6].data); + free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_CONVOLUTION_FILTER_1D: - _mesa_free(n[6].data); + free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_CONVOLUTION_FILTER_2D: - _mesa_free(n[7].data); + free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_POLYGON_STIPPLE: - _mesa_free(n[1].data); + free(n[1].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE1D: - _mesa_free(n[8].data); + free(n[8].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE2D: - _mesa_free(n[9].data); + free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE3D: - _mesa_free(n[10].data); + free(n[10].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE1D: - _mesa_free(n[7].data); + free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE2D: - _mesa_free(n[9].data); + free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE3D: - _mesa_free(n[11].data); + free(n[11].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_1D: - _mesa_free(n[7].data); + free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_2D: - _mesa_free(n[8].data); + free(n[8].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_3D: - _mesa_free(n[9].data); + free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: - _mesa_free(n[7].data); + free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: - _mesa_free(n[9].data); + free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: - _mesa_free(n[11].data); + free(n[11].data); n += InstSize[n[0].opcode]; break; #if FEATURE_NV_vertex_program case OPCODE_LOAD_PROGRAM_NV: - _mesa_free(n[4].data); /* program string */ + free(n[4].data); /* program string */ n += InstSize[n[0].opcode]; break; case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV: - _mesa_free(n[2].data); /* array of program ids */ + free(n[2].data); /* array of program ids */ n += InstSize[n[0].opcode]; break; #endif #if FEATURE_NV_fragment_program case OPCODE_PROGRAM_NAMED_PARAMETER_NV: - _mesa_free(n[3].data); /* parameter name */ + free(n[3].data); /* parameter name */ n += InstSize[n[0].opcode]; break; #endif #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program case OPCODE_PROGRAM_STRING_ARB: - _mesa_free(n[4].data); /* program string */ + free(n[4].data); /* program string */ n += InstSize[n[0].opcode]; break; #endif case OPCODE_CONTINUE: n = (Node *) n[1].next; - _mesa_free(block); + free(block); block = n; break; case OPCODE_END_OF_LIST: - _mesa_free(block); + free(block); done = GL_TRUE; break; default: @@ -613,7 +613,7 @@ _mesa_delete_list(GLcontext *ctx, struct mesa_display_list *dlist) } } - _mesa_free(dlist); + free(dlist); } @@ -754,7 +754,7 @@ _mesa_alloc_instruction(GLcontext *ctx, GLuint opcode, GLuint bytes) return NULL; #endif n[0].opcode = OPCODE_CONTINUE; - newblock = (Node *) _mesa_malloc(sizeof(Node) * BLOCK_SIZE); + newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE); if (!newblock) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; @@ -2564,8 +2564,8 @@ save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values) if (n) { n[1].e = map; n[2].i = mapsize; - n[3].data = (void *) _mesa_malloc(mapsize * sizeof(GLfloat)); - MEMCPY(n[3].data, (void *) values, mapsize * sizeof(GLfloat)); + n[3].data = (void *) malloc(mapsize * sizeof(GLfloat)); + memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat)); } if (ctx->ExecuteFlag) { CALL_PixelMapfv(ctx->Exec, (map, mapsize, values)); @@ -3969,12 +3969,12 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, GLvoid *image; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7); n[1].e = target; n[2].i = level; @@ -4009,12 +4009,12 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, GLvoid *image; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8); n[1].e = target; n[2].i = level; @@ -4050,12 +4050,12 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, GLvoid *image; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9); n[1].e = target; n[2].i = level; @@ -4088,12 +4088,12 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7); n[1].e = target; n[2].i = level; @@ -4123,12 +4123,12 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9); n[1].e = target; n[2].i = level; @@ -4160,12 +4160,12 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); /* make copy of image */ - image = _mesa_malloc(imageSize); + image = malloc(imageSize); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB"); return; } - MEMCPY(image, data, imageSize); + memcpy(image, data, imageSize); n = ALLOC_INSTRUCTION(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11); n[1].e = target; n[2].i = level; @@ -4328,12 +4328,12 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len, Node *n; GLubyte *programCopy; - programCopy = (GLubyte *) _mesa_malloc(len); + programCopy = (GLubyte *) malloc(len); if (!programCopy) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } - _mesa_memcpy(programCopy, program, len); + memcpy(programCopy, program, len); ASSERT_OUTSIDE_SAVE_BEGIN_END_FREE_AND_FLUSH(ctx, programCopy); n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_PROGRAM_NV, 4); @@ -4342,6 +4342,8 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len, n[2].ui = id; n[3].i = len; n[4].data = programCopy; + } else { + free(programCopy); } if (ctx->ExecuteFlag) { CALL_LoadProgramNV(ctx->Exec, (target, id, len, program)); @@ -4354,17 +4356,19 @@ save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids) { GET_CURRENT_CONTEXT(ctx); Node *n; - GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint)); + GLuint *idCopy = (GLuint *) malloc(num * sizeof(GLuint)); if (!idCopy) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV"); return; } - _mesa_memcpy(idCopy, ids, num * sizeof(GLuint)); + memcpy(idCopy, ids, num * sizeof(GLuint)); ASSERT_OUTSIDE_SAVE_BEGIN_END_FREE_AND_FLUSH(ctx, idCopy); n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 2); if (n) { n[1].i = num; n[2].data = idCopy; + } else { + free(idCopy); } if (ctx->ExecuteFlag) { CALL_RequestResidentProgramsNV(ctx->Exec, (num, ids)); @@ -4523,12 +4527,12 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name, { GET_CURRENT_CONTEXT(ctx); Node *n; - GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len); + GLubyte *nameCopy = (GLubyte *) malloc(len); if (!nameCopy) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV"); return; } - _mesa_memcpy(nameCopy, name, len); + memcpy(nameCopy, name, len); ASSERT_OUTSIDE_SAVE_BEGIN_END_FREE_AND_FLUSH(ctx, nameCopy); n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6); @@ -4540,6 +4544,8 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name, n[5].f = y; n[6].f = z; n[7].f = w; + } else { + free(nameCopy); } if (ctx->ExecuteFlag) { CALL_ProgramNamedParameter4fNV(ctx->Exec, (id, len, name, x, y, z, w)); @@ -4623,12 +4629,12 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, Node *n; GLubyte *programCopy; - programCopy = (GLubyte *) _mesa_malloc(len); + programCopy = (GLubyte *) malloc(len); if (!programCopy) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); return; } - _mesa_memcpy(programCopy, string, len); + memcpy(programCopy, string, len); ASSERT_OUTSIDE_SAVE_BEGIN_END_FREE_AND_FLUSH(ctx, programCopy); n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_STRING_ARB, 4); @@ -4637,6 +4643,8 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, n[2].e = format; n[3].i = len; n[4].data = programCopy; + } else { + free(programCopy); } if (ctx->ExecuteFlag) { CALL_ProgramStringARB(ctx->Exec, (target, format, len, string)); diff --git a/src/other/libosmesa/src/main/enums.c b/src/other/libosmesa/src/main/enums.c index ed0894cbccc..58587a640ec 100644 --- a/src/other/libosmesa/src/main/enums.c +++ b/src/other/libosmesa/src/main/enums.c @@ -4818,7 +4818,7 @@ typedef int (*cfunc)(const void *, const void *); */ static int compar_name(const char *a, const enum_elt *b) { - return _mesa_strcmp(a, & enum_string_table[ b->offset ]); + return strcmp(a, & enum_string_table[ b->offset ]); } /** diff --git a/src/other/libosmesa/src/main/eval.c b/src/other/libosmesa/src/main/eval.c index 2708562d2b4..d8d99aa1ade 100644 --- a/src/other/libosmesa/src/main/eval.c +++ b/src/other/libosmesa/src/main/eval.c @@ -232,7 +232,7 @@ GLfloat *_mesa_copy_map_points1f(GLenum target, GLint ustride, GLint uorder, if (!points || !size) return NULL; - buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat)); + buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat)); if (buffer) for (i = 0, p = buffer; i < uorder; i++, points += ustride) @@ -256,7 +256,7 @@ GLfloat *_mesa_copy_map_points1d(GLenum target, GLint ustride, GLint uorder, if (!points || !size) return NULL; - buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat)); + buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat)); if (buffer) for (i = 0, p = buffer; i < uorder; i++, points += ustride) @@ -300,9 +300,9 @@ GLfloat *_mesa_copy_map_points2f(GLenum target, hsize = (uorder > vorder ? uorder : vorder)*size; if (hsize>dsize) - buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); + buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat)); else - buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); + buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat)); /* compute the increment value for the u-loop */ uinc = ustride - vorder*vstride; @@ -343,9 +343,9 @@ GLfloat *_mesa_copy_map_points2d(GLenum target, hsize = (uorder > vorder ? uorder : vorder)*size; if (hsize>dsize) - buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); + buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat)); else - buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); + buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat)); /* compute the increment value for the u-loop */ uinc = ustride - vorder*vstride; @@ -430,7 +430,7 @@ map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, map->u2 = u2; map->du = 1.0F / (u2 - u1); if (map->Points) - FREE(map->Points); + free(map->Points); map->Points = pnts; } @@ -530,7 +530,7 @@ map2(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, map->v2 = v2; map->dv = 1.0F / (v2 - v1); if (map->Points) - FREE(map->Points); + free(map->Points); map->Points = pnts; } @@ -821,7 +821,7 @@ init_1d_map(struct gl_1d_map *map, int n, const float *initial) map->Order = 1; map->u1 = 0.0; map->u2 = 1.0; - map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); + map->Points = (GLfloat *) malloc(n * sizeof(GLfloat)); if (map->Points) { GLint i; for (i=0; iu2 = 1.0; map->v1 = 0.0; map->v2 = 1.0; - map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); + map->Points = (GLfloat *) malloc(n * sizeof(GLfloat)); if (map->Points) { GLint i; for (i=0; iEval.Map1TextureCoord4 = GL_FALSE; ctx->Eval.Map1Vertex3 = GL_FALSE; ctx->Eval.Map1Vertex4 = GL_FALSE; - MEMSET(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib)); + memset(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib)); ctx->Eval.Map2Color4 = GL_FALSE; ctx->Eval.Map2Index = GL_FALSE; ctx->Eval.Map2Normal = GL_FALSE; @@ -875,7 +875,7 @@ void _mesa_init_eval(GLcontext *ctx) ctx->Eval.Map2TextureCoord4 = GL_FALSE; ctx->Eval.Map2Vertex3 = GL_FALSE; ctx->Eval.Map2Vertex4 = GL_FALSE; - MEMSET(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib)); + memset(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib)); ctx->Eval.AutoNormal = GL_FALSE; ctx->Eval.MapGrid1un = 1; ctx->Eval.MapGrid1u1 = 0.0; @@ -929,46 +929,46 @@ void _mesa_free_eval_data(GLcontext *ctx) /* Free evaluator data */ if (ctx->EvalMap.Map1Vertex3.Points) - FREE(ctx->EvalMap.Map1Vertex3.Points); + free(ctx->EvalMap.Map1Vertex3.Points); if (ctx->EvalMap.Map1Vertex4.Points) - FREE(ctx->EvalMap.Map1Vertex4.Points); + free(ctx->EvalMap.Map1Vertex4.Points); if (ctx->EvalMap.Map1Index.Points) - FREE(ctx->EvalMap.Map1Index.Points); + free(ctx->EvalMap.Map1Index.Points); if (ctx->EvalMap.Map1Color4.Points) - FREE(ctx->EvalMap.Map1Color4.Points); + free(ctx->EvalMap.Map1Color4.Points); if (ctx->EvalMap.Map1Normal.Points) - FREE(ctx->EvalMap.Map1Normal.Points); + free(ctx->EvalMap.Map1Normal.Points); if (ctx->EvalMap.Map1Texture1.Points) - FREE(ctx->EvalMap.Map1Texture1.Points); + free(ctx->EvalMap.Map1Texture1.Points); if (ctx->EvalMap.Map1Texture2.Points) - FREE(ctx->EvalMap.Map1Texture2.Points); + free(ctx->EvalMap.Map1Texture2.Points); if (ctx->EvalMap.Map1Texture3.Points) - FREE(ctx->EvalMap.Map1Texture3.Points); + free(ctx->EvalMap.Map1Texture3.Points); if (ctx->EvalMap.Map1Texture4.Points) - FREE(ctx->EvalMap.Map1Texture4.Points); + free(ctx->EvalMap.Map1Texture4.Points); for (i = 0; i < 16; i++) - FREE((ctx->EvalMap.Map1Attrib[i].Points)); + free((ctx->EvalMap.Map1Attrib[i].Points)); if (ctx->EvalMap.Map2Vertex3.Points) - FREE(ctx->EvalMap.Map2Vertex3.Points); + free(ctx->EvalMap.Map2Vertex3.Points); if (ctx->EvalMap.Map2Vertex4.Points) - FREE(ctx->EvalMap.Map2Vertex4.Points); + free(ctx->EvalMap.Map2Vertex4.Points); if (ctx->EvalMap.Map2Index.Points) - FREE(ctx->EvalMap.Map2Index.Points); + free(ctx->EvalMap.Map2Index.Points); if (ctx->EvalMap.Map2Color4.Points) - FREE(ctx->EvalMap.Map2Color4.Points); + free(ctx->EvalMap.Map2Color4.Points); if (ctx->EvalMap.Map2Normal.Points) - FREE(ctx->EvalMap.Map2Normal.Points); + free(ctx->EvalMap.Map2Normal.Points); if (ctx->EvalMap.Map2Texture1.Points) - FREE(ctx->EvalMap.Map2Texture1.Points); + free(ctx->EvalMap.Map2Texture1.Points); if (ctx->EvalMap.Map2Texture2.Points) - FREE(ctx->EvalMap.Map2Texture2.Points); + free(ctx->EvalMap.Map2Texture2.Points); if (ctx->EvalMap.Map2Texture3.Points) - FREE(ctx->EvalMap.Map2Texture3.Points); + free(ctx->EvalMap.Map2Texture3.Points); if (ctx->EvalMap.Map2Texture4.Points) - FREE(ctx->EvalMap.Map2Texture4.Points); + free(ctx->EvalMap.Map2Texture4.Points); for (i = 0; i < 16; i++) - FREE((ctx->EvalMap.Map2Attrib[i].Points)); + free((ctx->EvalMap.Map2Attrib[i].Points)); } /* diff --git a/src/other/libosmesa/src/main/execmem.c b/src/other/libosmesa/src/main/execmem.c deleted file mode 100644 index aea98e263f4..00000000000 --- a/src/other/libosmesa/src/main/execmem.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file exemem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - - -#include "imports.h" -#include "glthread.h" - - - -#if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) - -/* - * Allocate a large block of memory which can hold code then dole it out - * in pieces by means of the generic memory manager code. -*/ - -#include -#include -#include "mm.h" - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - - -#define EXEC_HEAP_SIZE (10*1024*1024) - -_glthread_DECLARE_STATIC_MUTEX(exec_mutex); - -static struct mem_block *exec_heap = NULL; -static unsigned char *exec_mem = NULL; - - -static void -init_heap(void) -{ - if (!exec_heap) - exec_heap = mmInit(0, EXEC_HEAP_SIZE); - - if (!exec_mem) - exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -} - - -void * -_mesa_exec_malloc(GLuint size) -{ - struct mem_block *block = NULL; - void *addr = NULL; - - _glthread_LOCK_MUTEX(exec_mutex); - - init_heap(); - - if (exec_heap) { - size = (size + 31) & ~31; - block = mmAllocMem(exec_heap, size, 32, 0); - } - - if (block) - addr = exec_mem + block->ofs; - else - _mesa_printf("_mesa_exec_malloc failed\n"); - - _glthread_UNLOCK_MUTEX(exec_mutex); - - return addr; -} - - -void -_mesa_exec_free(void *addr) -{ - _glthread_LOCK_MUTEX(exec_mutex); - - if (exec_heap) { - struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); - - if (block) - mmFreeMem(block); - } - - _glthread_UNLOCK_MUTEX(exec_mutex); -} - - -#else - -/* - * Just use regular memory. - */ - -void * -_mesa_exec_malloc(GLuint size) -{ - return _mesa_malloc(size); -} - - -void -_mesa_exec_free(void *addr) -{ - _mesa_free(addr); -} - - -#endif - -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ diff --git a/src/other/libosmesa/src/main/extensions.c b/src/other/libosmesa/src/main/extensions.c index 8cb19a36b45..d5d4a07ec3d 100644 --- a/src/other/libosmesa/src/main/extensions.c +++ b/src/other/libosmesa/src/main/extensions.c @@ -437,7 +437,7 @@ set_extension(GLcontext *ctx, const char *name, GLboolean state) } for (i = 0 ; i < Elements(default_extensions) ; i++) { - if (_mesa_strcmp(default_extensions[i].name, name) == 0) { + if (strcmp(default_extensions[i].name, name) == 0) { if (default_extensions[i].flag_offset) { GLboolean *enabled = base + default_extensions[i].flag_offset; *enabled = state; @@ -481,7 +481,7 @@ _mesa_extension_is_enabled(GLcontext *ctx, const char *name) GLuint i; for (i = 0 ; i < Elements(default_extensions) ; i++) { - if (_mesa_strcmp(default_extensions[i].name, name) == 0) { + if (strcmp(default_extensions[i].name, name) == 0) { if (!default_extensions[i].flag_offset) return GL_TRUE; return *(base + default_extensions[i].flag_offset); @@ -527,18 +527,18 @@ _mesa_make_extension_string(GLcontext *ctx) for (i = 0 ; i < Elements(default_extensions) ; i++) { if (!default_extensions[i].flag_offset || *(base + default_extensions[i].flag_offset)) { - extStrLen += (GLuint)_mesa_strlen(default_extensions[i].name) + 1; + extStrLen += (GLuint)strlen(default_extensions[i].name) + 1; } } - s = (GLubyte *) _mesa_malloc(extStrLen); + s = (GLubyte *) malloc(extStrLen); /* second, build the extension string */ extStrLen = 0; for (i = 0 ; i < Elements(default_extensions) ; i++) { if (!default_extensions[i].flag_offset || *(base + default_extensions[i].flag_offset)) { - GLuint len = (GLuint)_mesa_strlen(default_extensions[i].name); - _mesa_memcpy(s + extStrLen, default_extensions[i].name, len); + GLuint len = (GLuint)strlen(default_extensions[i].name); + memcpy(s + extStrLen, default_extensions[i].name, len); extStrLen += len; s[extStrLen] = (GLubyte) ' '; extStrLen++; diff --git a/src/other/libosmesa/src/main/framebuffer.c b/src/other/libosmesa/src/main/framebuffer.c index 46127e531cc..27db2dc049a 100644 --- a/src/other/libosmesa/src/main/framebuffer.c +++ b/src/other/libosmesa/src/main/framebuffer.c @@ -163,7 +163,7 @@ _mesa_destroy_framebuffer(struct gl_framebuffer *fb) { if (fb) { _mesa_free_framebuffer_data(fb); - _mesa_free(fb); + free(fb); } } diff --git a/src/other/libosmesa/src/main/glheader.h b/src/other/libosmesa/src/main/glheader.h index 5e78aede532..5a053039d64 100644 --- a/src/other/libosmesa/src/main/glheader.h +++ b/src/other/libosmesa/src/main/glheader.h @@ -46,62 +46,34 @@ #ifndef GLHEADER_H #define GLHEADER_H -/* This allows Mesa to be integrated into XFree86 */ -#ifdef HAVE_DIX_CONFIG_H -#include "dix-config.h" -#endif - #include #include -#if defined(__alpha__) && defined(CCPML) -#include /* use Compaq's Fast Math Library on Alpha */ -#else #include -#endif #include #include #include #include -#if defined(__linux__) && defined(__i386__) -#include -#endif #include #include /* Get typedefs for uintptr_t and friends */ -#if defined(__MINGW32__) || defined(__NetBSD__) -# include -#elif defined(_WIN32) +#include +#if defined(_WIN32) # include -# if _MSC_VER == 1200 -typedef UINT_PTR uintptr_t; -# endif -#elif defined(__INTERIX) -/* Interix 3.x has a gcc that shadows this. */ -# ifndef _UINTPTR_T_DEFINED -typedef unsigned long uintptr_t; -# define _UINTPTR_T_DEFINED -# endif -#else -# include #endif +#include -#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(BUILD_FOR_SNAP) +#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) # define __WIN32__ # define finite _finite #endif -#if defined(__WATCOMC__) -# define finite _finite -# pragma disable_message(201) /* Disable unreachable code warnings */ -#endif - #ifdef WGLAPI # undef WGLAPI #endif -#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) && !defined(BUILD_FOR_SNAP) +#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) # if !defined(__GNUC__) /* mingw environment */ # pragma warning( disable : 4068 ) /* unknown pragma */ # pragma warning( disable : 4710 ) /* function 'foo' not inlined */ @@ -125,37 +97,11 @@ typedef unsigned long uintptr_t; #endif /* WIN32 / CYGWIN bracket */ -/* - * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN. - * Do not use them unless absolutely necessary! - * Try to use a runtime test instead. - * For now, only used by some DRI hardware drivers for color/texel packing. - */ -#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN -#if defined(__linux__) -#include -#define CPU_TO_LE32( x ) bswap_32( x ) -#else /*__linux__*/ -#define CPU_TO_LE32( x ) ( x ) /* fix me for non-Linux big-endian! */ -#endif /*__linux__*/ -#define MESA_BIG_ENDIAN 1 -#else -#define CPU_TO_LE32( x ) ( x ) -#define MESA_LITTLE_ENDIAN 1 -#endif -#define LE32_TO_CPU( x ) CPU_TO_LE32( x ) - - #define GL_GLEXT_PROTOTYPES #include "OSMesa/gl.h" #include "OSMesa/glext.h" -#if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP) -#define CAPI _cdecl -#endif - - /* This is a macro on IRIX */ #ifdef _P #undef _P @@ -172,7 +118,7 @@ typedef unsigned long uintptr_t; * than GNU C */ #ifndef _ASMAPI -#if defined(WIN32) && !defined(BUILD_FOR_SNAP)/* was: !defined( __GNUC__ ) && !defined( VMS ) && !defined( __INTEL_COMPILER )*/ +#if defined(WIN32) #define _ASMAPI __cdecl #else #define _ASMAPI @@ -184,13 +130,8 @@ typedef unsigned long uintptr_t; #endif #endif -#ifdef USE_X86_ASM -#define _NORMAPI _ASMAPI -#define _NORMAPIP _ASMAPIP -#else #define _NORMAPI #define _NORMAPIP * -#endif /* Function inlining */ @@ -204,8 +145,6 @@ typedef unsigned long uintptr_t; # define INLINE __inline #elif defined(__INTEL_COMPILER) # define INLINE inline -#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) -# define INLINE __inline #else # define INLINE #endif @@ -234,9 +173,7 @@ typedef unsigned long uintptr_t; #endif -#if defined(BUILD_FOR_SNAP) && defined(CHECKED) -# define ASSERT(X) _CHECK(X) -#elif defined(DEBUG) +#if defined(DEBUG) # define ASSERT(X) assert(X) #else # define ASSERT(X) @@ -247,21 +184,7 @@ typedef unsigned long uintptr_t; # define __builtin_expect(x, y) x #endif -/* The __FUNCTION__ gcc variable is generally only used for debugging. - * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. - * Don't define it if using a newer Windows compiler. - */ -#if defined(__VMS) -# define __FUNCTION__ "VMS$NL:" -#elif __STDC_VERSION__ < 199901L -# if ((!defined __GNUC__) || (__GNUC__ < 2)) && (!defined __xlC__) && \ - (!defined(_MSC_VER) || _MSC_VER < 1300) -# define __FUNCTION__ "" -# endif -#endif - - -#include "config.h" +#include "gllimits.h" #endif /* GLHEADER_H */ diff --git a/src/other/libosmesa/src/main/gllimits.h b/src/other/libosmesa/src/main/gllimits.h new file mode 100644 index 00000000000..19ef7d8ff32 --- /dev/null +++ b/src/other/libosmesa/src/main/gllimits.h @@ -0,0 +1,329 @@ +/** + * \file gllimits.h + * Tunable configuration parameters. + */ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef MESA_GLLIMITS_H_INCLUDED +#define MESA_GLLIMITS_H_INCLUDED + +/** + * \name OpenGL implementation limits + */ +/*@{*/ + +/** Maximum modelview matrix stack depth */ +#define MAX_MODELVIEW_STACK_DEPTH 32 + +/** Maximum projection matrix stack depth */ +#define MAX_PROJECTION_STACK_DEPTH 32 + +/** Maximum texture matrix stack depth */ +#define MAX_TEXTURE_STACK_DEPTH 10 + +/** Maximum color matrix stack depth */ +#define MAX_COLOR_STACK_DEPTH 4 + +/** Maximum attribute stack depth */ +#define MAX_ATTRIB_STACK_DEPTH 16 + +/** Maximum client attribute stack depth */ +#define MAX_CLIENT_ATTRIB_STACK_DEPTH 16 + +/** Maximum recursion depth of display list calls */ +#define MAX_LIST_NESTING 64 + +/** Maximum number of lights */ +#define MAX_LIGHTS 8 + +/** Maximum user-defined clipping planes */ +#define MAX_CLIP_PLANES 6 + +/** Maximum pixel map lookup table size */ +#define MAX_PIXEL_MAP_TABLE 256 + +/** Maximum number of auxillary color buffers */ +#define MAX_AUX_BUFFERS 4 + +/** Maximum order (degree) of curves */ +# define MAX_EVAL_ORDER 30 + +/** Maximum Name stack depth */ +#define MAX_NAME_STACK_DEPTH 64 + +/** Minimum point size */ +#define MIN_POINT_SIZE 1.0 +/** Maximum point size */ +#define MAX_POINT_SIZE 20.0 +/** Point size granularity */ +#define POINT_SIZE_GRANULARITY 0.1 + +/** Minimum line width */ +#define MIN_LINE_WIDTH 1.0 +/** Maximum line width */ +#define MAX_LINE_WIDTH 10.0 +/** Line width granularity */ +#define LINE_WIDTH_GRANULARITY 0.1 + +/** Max texture palette / color table size */ +#define MAX_COLOR_TABLE_SIZE 256 + +/** Number of 1D/2D texture mipmap levels */ +#define MAX_TEXTURE_LEVELS 12 + +/** Number of 3D texture mipmap levels */ +#define MAX_3D_TEXTURE_LEVELS 9 + +/** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */ +#define MAX_CUBE_TEXTURE_LEVELS 12 + +/** Maximum rectangular texture size - GL_NV_texture_rectangle */ +#define MAX_TEXTURE_RECT_SIZE 2048 + +/** Number of texture units - GL_ARB_multitexture + * This needs to be the larger of MAX_TEXTURE_COORD_UNITS and + * MAX_TEXTURE_IMAGE_UNITS seen below, since MAX_TEXTURE_UNITS is used + * to dimension some arrays that store both coord and image data. +*/ +#define MAX_TEXTURE_UNITS 8 + +/*@}*/ + + +/** + * \name Separate numbers of texture coordinates and texture image units. + * + * These values will eventually replace most instances of MAX_TEXTURE_UNITS. + * We should always have MAX_TEXTURE_COORD_UNITS <= MAX_TEXTURE_IMAGE_UNITS. + * And, GL_MAX_TEXTURE_UNITS <= MAX_TEXTURE_COORD_UNITS. + */ +/*@{*/ +#define MAX_TEXTURE_COORD_UNITS 8 +#define MAX_TEXTURE_IMAGE_UNITS 8 +/*@}*/ + +/** + * Maximum viewport/image width. Must accomodate all texture sizes too. + */ +#define MAX_WIDTH 4096 +/** Maximum viewport/image height */ +#define MAX_HEIGHT 4096 + +/** Maxmimum size for CVA. May be overridden by the drivers. */ +#define MAX_ARRAY_LOCK_SIZE 3000 + +/** Subpixel precision for antialiasing, window coordinate snapping */ +#define SUB_PIXEL_BITS 4 + +/** Size of histogram tables */ +#define HISTOGRAM_TABLE_SIZE 256 + +/** Max convolution filter width */ +#define MAX_CONVOLUTION_WIDTH 9 +/** Max convolution filter height */ +#define MAX_CONVOLUTION_HEIGHT 9 + +/** For GL_ARB_texture_compression */ +#define MAX_COMPRESSED_TEXTURE_FORMATS 25 + +/** For GL_EXT_texture_filter_anisotropic */ +#define MAX_TEXTURE_MAX_ANISOTROPY 16.0 + +/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */ +#define MAX_TEXTURE_LOD_BIAS 11.0 + +/** For GL_NV_vertex_program */ +/*@{*/ +#define MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS 128 +#define MAX_NV_VERTEX_PROGRAM_TEMPS 12 +#define MAX_NV_VERTEX_PROGRAM_PARAMS 128 /* KW: power of two */ +#define MAX_NV_VERTEX_PROGRAM_INPUTS 16 +#define MAX_NV_VERTEX_PROGRAM_OUTPUTS 15 +/*@}*/ + +/** For GL_NV_fragment_program */ +/*@{*/ +#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */ +#define MAX_NV_FRAGMENT_PROGRAM_TEMPS 96 +#define MAX_NV_FRAGMENT_PROGRAM_PARAMS 64 +#define MAX_NV_FRAGMENT_PROGRAM_INPUTS 12 +#define MAX_NV_FRAGMENT_PROGRAM_OUTPUTS 3 +#define MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS 2 +/*@}*/ + +/** For GL_ARB_vertex_program */ +/*@{*/ +#define MAX_VERTEX_PROGRAM_ADDRESS_REGS 1 +#define MAX_VERTEX_PROGRAM_ATTRIBS 16 +/*@}*/ + +/** For GL_ARB_fragment_program */ +/*@{*/ +#define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0 +#define MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS 48 +#define MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS 24 +#define MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS 4 +/*@}*/ + +/** For any program target/extension */ +/*@{*/ +#define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */ +#define MAX_PROGRAM_ENV_PARAMS 128 +#define MAX_PROGRAM_MATRICES 8 +#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 +#define MAX_PROGRAM_CALL_DEPTH 8 +#define MAX_PROGRAM_TEMPS 128 +#define MAX_PROGRAM_ADDRESS_REGS 2 +#define MAX_UNIFORMS 128 +#define MAX_VARYING 8 +/*@}*/ + +/** For GL_ARB_vertex_shader */ +/*@{*/ +#define MAX_VERTEX_ATTRIBS 16 +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS MAX_TEXTURE_UNITS +#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS) +/*@}*/ + + +/** For GL_ARB_draw_buffers */ +/*@{*/ +#define MAX_DRAW_BUFFERS 4 +/*@}*/ + + +/** For GL_EXT_framebuffer_object */ +/*@{*/ +#define MAX_COLOR_ATTACHMENTS 8 +/*@}*/ + + + +/** + * \name Mesa-specific parameters + */ +/*@{*/ + + +/** + * If non-zero use GLdouble for walking triangle edges, for better accuracy. + */ +#define TRIANGLE_WALK_DOUBLE 0 + + +/** + * Bits per depth buffer value (max is 32). + */ +#ifndef DEFAULT_SOFTWARE_DEPTH_BITS +#define DEFAULT_SOFTWARE_DEPTH_BITS 16 +#endif +/** Depth buffer data type */ +#if DEFAULT_SOFTWARE_DEPTH_BITS <= 16 +#define DEFAULT_SOFTWARE_DEPTH_TYPE GLushort +#else +#define DEFAULT_SOFTWARE_DEPTH_TYPE GLuint +#endif + + +/** + * Bits per stencil value: 8 + */ +#define STENCIL_BITS 8 + + +/** + * Bits per color channel: 8, 16 or 32 + */ +#ifndef CHAN_BITS +#define CHAN_BITS 8 +#endif + + +/* + * Color channel component order + * + * \note Changes will almost certainly cause problems at this time. + */ +#define RCOMP 0 +#define GCOMP 1 +#define BCOMP 2 +#define ACOMP 3 + + +/* + * Enable/disable features (blocks of code) by setting FEATURE_xyz to 0 or 1. + */ +#ifndef _HAVE_FULL_GL +#define _HAVE_FULL_GL 1 +#endif + +#define FEATURE_userclip _HAVE_FULL_GL +#define FEATURE_texgen _HAVE_FULL_GL +#define FEATURE_windowpos _HAVE_FULL_GL +#define FEATURE_ARB_occlusion_query _HAVE_FULL_GL +#define FEATURE_ARB_fragment_program _HAVE_FULL_GL +#define FEATURE_ARB_vertex_buffer_object _HAVE_FULL_GL +#define FEATURE_ARB_vertex_program _HAVE_FULL_GL + +#define FEATURE_ARB_vertex_shader _HAVE_FULL_GL +#define FEATURE_ARB_fragment_shader _HAVE_FULL_GL +#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader) +#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects +#define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects + +#define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL +#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL +#define FEATURE_EXT_pixel_buffer_object _HAVE_FULL_GL +#define FEATURE_EXT_texture_sRGB _HAVE_FULL_GL +#define FEATURE_EXT_timer_query _HAVE_FULL_GL +#define FEATURE_ATI_fragment_shader _HAVE_FULL_GL +#define FEATURE_MESA_program_debug _HAVE_FULL_GL +#define FEATURE_NV_fence _HAVE_FULL_GL +#define FEATURE_NV_fragment_program _HAVE_FULL_GL +#define FEATURE_NV_vertex_program _HAVE_FULL_GL +/*@}*/ + + +/** + * Maximum number of temporary vertices required for clipping. + * + * Used in array_cache and tnl modules. + */ +#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1) + + +#endif /* MESA_GLLIMITS_H_INCLUDED */ + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ diff --git a/src/other/libosmesa/src/main/hash.c b/src/other/libosmesa/src/main/hash.c index 8fc9f30eff6..3932fafdcc2 100644 --- a/src/other/libosmesa/src/main/hash.c +++ b/src/other/libosmesa/src/main/hash.c @@ -106,12 +106,12 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table) _mesa_problem(NULL, "In _mesa_DeleteHashTable, found non-freed data"); } - _mesa_free(entry); + free(entry); entry = next; } } _glthread_DESTROY_MUTEX(table->Mutex); - _mesa_free(table); + free(table); } @@ -236,7 +236,7 @@ _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key) } else { table->Table[pos] = entry->Next; } - _mesa_free(entry); + free(entry); _glthread_UNLOCK_MUTEX(table->Mutex); return; } @@ -273,7 +273,7 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table, for (entry = table->Table[pos]; entry; entry = next) { callback(entry->Key, entry->Data, userData); next = entry->Next; - _mesa_free(entry); + free(entry); } table->Table[pos] = NULL; } diff --git a/src/other/libosmesa/src/main/image.c b/src/other/libosmesa/src/main/image.c index ce1aef82ebd..7d14c063101 100644 --- a/src/other/libosmesa/src/main/image.c +++ b/src/other/libosmesa/src/main/image.c @@ -782,7 +782,7 @@ _mesa_unpack_polygon_stipple(const GLubyte *pattern, GLuint dest[32], | (p[3]); p += 4; } - _mesa_free(ptrn); + free(ptrn); } } @@ -827,7 +827,7 @@ _mesa_unpack_bitmap(GLint width, GLint height, const GLubyte *pixels, /* Alloc dest storage */ bytes = ((width + 7) / 8 * height); - buffer = (GLubyte *) _mesa_malloc(bytes); + buffer = (GLubyte *) malloc(bytes); if (!buffer) return NULL; @@ -838,12 +838,12 @@ _mesa_unpack_bitmap(GLint width, GLint height, const GLubyte *pixels, _mesa_image_address2d(packing, pixels, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); if (!src) { - _mesa_free(buffer); + free(buffer); return NULL; } if ((packing->SkipPixels & 7) == 0) { - _mesa_memcpy(dst, src, width_in_bytes); + memcpy(dst, src, width_in_bytes); if (packing->LsbFirst) { flip_bytes(dst, width_in_bytes); } @@ -929,7 +929,7 @@ _mesa_pack_bitmap(GLint width, GLint height, const GLubyte *source, return; if ((packing->SkipPixels & 7) == 0) { - _mesa_memcpy(dst, src, width_in_bytes); + memcpy(dst, src, width_in_bytes); if (packing->LsbFirst) { flip_bytes(dst, width_in_bytes); } @@ -2915,7 +2915,7 @@ _mesa_unpack_color_span_chan(GLcontext *ctx, if (srcType == CHAN_TYPE) { if (dstFormat == GL_RGBA) { if (srcFormat == GL_RGBA) { - _mesa_memcpy(dest, source, n * 4 * sizeof(GLchan)); + memcpy(dest, source, n * 4 * sizeof(GLchan)); return; } else if (srcFormat == GL_RGB) { GLuint i; @@ -2933,7 +2933,7 @@ _mesa_unpack_color_span_chan(GLcontext *ctx, } } else if (dstFormat == GL_RGB) { if (srcFormat == GL_RGB) { - _mesa_memcpy(dest, source, n * 3 * sizeof(GLchan)); + memcpy(dest, source, n * 3 * sizeof(GLchan)); return; } else if (srcFormat == GL_RGBA) { GLuint i; @@ -2951,7 +2951,7 @@ _mesa_unpack_color_span_chan(GLcontext *ctx, } else if (dstFormat == srcFormat) { GLint comps = _mesa_components_in_format(srcFormat); assert(comps > 0); - _mesa_memcpy(dest, source, n * comps * sizeof(GLchan)); + memcpy(dest, source, n * comps * sizeof(GLchan)); return; } } @@ -3437,10 +3437,10 @@ _mesa_unpack_index_span(const GLcontext *ctx, GLuint n, */ if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE && dstType == GL_UNSIGNED_BYTE) { - _mesa_memcpy(dest, source, n * sizeof(GLubyte)); + memcpy(dest, source, n * sizeof(GLubyte)); } else if (transferOps == 0 && srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) { - _mesa_memcpy(dest, source, n * sizeof(GLuint)); + memcpy(dest, source, n * sizeof(GLuint)); } else { /* * general solution @@ -3473,7 +3473,7 @@ _mesa_unpack_index_span(const GLcontext *ctx, GLuint n, } break; case GL_UNSIGNED_INT: - _mesa_memcpy(dest, indexes, n * sizeof(GLuint)); + memcpy(dest, indexes, n * sizeof(GLuint)); break; default: _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span"); @@ -3496,7 +3496,7 @@ _mesa_pack_index_span(const GLcontext *ctx, GLuint n, if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) { /* make a copy of input */ - _mesa_memcpy(indexes, source, n * sizeof(GLuint)); + memcpy(indexes, source, n * sizeof(GLuint)); _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); source = indexes; } @@ -3636,13 +3636,13 @@ _mesa_unpack_stencil_span(const GLcontext *ctx, GLuint n, !ctx->Pixel.MapStencilFlag && srcType == GL_UNSIGNED_BYTE && dstType == GL_UNSIGNED_BYTE) { - _mesa_memcpy(dest, source, n * sizeof(GLubyte)); + memcpy(dest, source, n * sizeof(GLubyte)); } else if (transferOps == 0 && !ctx->Pixel.MapStencilFlag && srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) { - _mesa_memcpy(dest, source, n * sizeof(GLuint)); + memcpy(dest, source, n * sizeof(GLuint)); } else { /* * general solution @@ -3686,7 +3686,7 @@ _mesa_unpack_stencil_span(const GLcontext *ctx, GLuint n, } break; case GL_UNSIGNED_INT: - _mesa_memcpy(dest, indexes, n * sizeof(GLuint)); + memcpy(dest, indexes, n * sizeof(GLuint)); break; default: _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span"); @@ -3707,7 +3707,7 @@ _mesa_pack_stencil_span(const GLcontext *ctx, GLuint n, if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag) { /* make a copy of input */ - _mesa_memcpy(stencil, source, n * sizeof(GLstencil)); + memcpy(stencil, source, n * sizeof(GLstencil)); _mesa_apply_stencil_transfer_ops(ctx, n, stencil); source = stencil; } @@ -3715,7 +3715,7 @@ _mesa_pack_stencil_span(const GLcontext *ctx, GLuint n, switch (dstType) { case GL_UNSIGNED_BYTE: if (sizeof(GLstencil) == 1) { - _mesa_memcpy(dest, source, n); + memcpy(dest, source, n); } else { GLubyte *dst = (GLubyte *) dest; GLuint i; @@ -4053,7 +4053,7 @@ _mesa_pack_depth_span(const GLcontext *ctx, GLuint n, GLvoid *dest, ASSERT(n <= MAX_WIDTH); if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { - _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat)); + memcpy(depthCopy, depthSpan, n * sizeof(GLfloat)); _mesa_scale_and_bias_depth(ctx, n, depthCopy); depthSpan = depthCopy; } @@ -4164,7 +4164,7 @@ _mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest, ASSERT(n <= MAX_WIDTH); if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { - _mesa_memcpy(depthCopy, depthVals, n * sizeof(GLfloat)); + memcpy(depthCopy, depthVals, n * sizeof(GLfloat)); _mesa_scale_and_bias_depth(ctx, n, depthCopy); depthVals = depthCopy; } @@ -4172,7 +4172,7 @@ _mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest, if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag) { - _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil)); + memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil)); _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy); stencilVals = stencilCopy; } @@ -4237,7 +4237,7 @@ _mesa_unpack_image(GLuint dimensions, { GLubyte *destBuffer - = (GLubyte *) _mesa_malloc(bytesPerRow * height * depth); + = (GLubyte *) malloc(bytesPerRow * height * depth); GLubyte *dst; GLint img, row; if (!destBuffer) @@ -4302,7 +4302,7 @@ _mesa_unpack_image(GLuint dimensions, } } } else { - _mesa_memcpy(dst, src, bytesPerRow); + memcpy(dst, src, bytesPerRow); } /* byte flipping/swapping */ @@ -4353,7 +4353,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); } else { const GLubyte(*src1)[4] = (const GLubyte(*)[4]) src; GLfloat(*dst4)[4] = (GLfloat(*)[4])(useTemp ? tempBuffer : dst); @@ -4368,7 +4368,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); } break; case GL_UNSIGNED_SHORT: @@ -4385,7 +4385,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); } else { const GLushort(*src2)[4] = (const GLushort(*)[4]) src; GLfloat(*dst4)[4] = (GLfloat(*)[4])(useTemp ? tempBuffer : dst); @@ -4400,7 +4400,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); } break; case GL_FLOAT: @@ -4417,7 +4417,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); } else { const GLfloat(*src4)[4] = (const GLfloat(*)[4]) src; GLushort(*dst2)[4] = (GLushort(*)[4])(useTemp ? tempBuffer : dst); @@ -4432,7 +4432,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, } } if (useTemp) - _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); + memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); } break; default: diff --git a/src/other/libosmesa/src/main/imports.c b/src/other/libosmesa/src/main/imports.c index eed1210de64..733abba6be3 100644 --- a/src/other/libosmesa/src/main/imports.c +++ b/src/other/libosmesa/src/main/imports.c @@ -55,36 +55,12 @@ #define vsnprintf _vsnprintf #elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 ) extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg); -#ifdef __VMS -#include "vsnprintf.c" -#endif #endif /**********************************************************************/ /** \name Memory */ /*@{*/ -/** Wrapper around malloc() */ -void * -_mesa_malloc(size_t bytes) -{ - return malloc(bytes); -} - -/** Wrapper around calloc() */ -void * -_mesa_calloc(size_t bytes) -{ - return calloc(1, bytes); -} - -/** Wrapper around free() */ -void -_mesa_free(void *ptr) -{ - free(ptr); -} - /** * Allocate aligned memory. * @@ -111,7 +87,7 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment) ASSERT(alignment > 0); - ptr = (uintptr_t) _mesa_malloc(bytes + alignment + sizeof(void *)); + ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *)); if (!ptr) return NULL; @@ -131,8 +107,8 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment) } /** - * Same as _mesa_align_malloc(), but using _mesa_calloc() instead of - * _mesa_malloc() + * Same as _mesa_align_malloc(), but using calloc(1,) instead of + * malloc() */ void * _mesa_align_calloc(size_t bytes, unsigned long alignment) @@ -160,7 +136,7 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment) ASSERT(alignment > 0); - ptr = (uintptr_t) _mesa_calloc(bytes + alignment + sizeof(void *)); + ptr = (uintptr_t) calloc(1,bytes + alignment + sizeof(void *)); if (!ptr) return NULL; @@ -196,7 +172,7 @@ _mesa_align_free(void *ptr) #else void **cubbyHole = (void **)((char *) ptr - sizeof(void *)); void *realAddr = *cubbyHole; - _mesa_free(realAddr); + free(realAddr); #endif /* defined(HAVE_POSIX_MEMALIGN) */ } @@ -214,7 +190,7 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, const size_t copySize = (oldSize < newSize) ? oldSize : newSize; void *newBuf = _mesa_align_malloc(newSize, alignment); if (newBuf && oldBuffer && copySize > 0) { - _mesa_memcpy(newBuf, oldBuffer, copySize); + memcpy(newBuf, oldBuffer, copySize); } if (oldBuffer) _mesa_align_free(oldBuffer); @@ -229,36 +205,14 @@ void * _mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize) { const size_t copySize = (oldSize < newSize) ? oldSize : newSize; - void *newBuffer = _mesa_malloc(newSize); + void *newBuffer = malloc(newSize); if (newBuffer && oldBuffer && copySize > 0) - _mesa_memcpy(newBuffer, oldBuffer, copySize); + memcpy(newBuffer, oldBuffer, copySize); if (oldBuffer) - _mesa_free(oldBuffer); + free(oldBuffer); return newBuffer; } -/** memcpy wrapper */ -void * -_mesa_memcpy(void *dest, const void *src, size_t n) -{ -#if defined(SUNOS4) - return memcpy((char *) dest, (char *) src, (int) n); -#else - return memcpy(dest, src, n); -#endif -} - -/** Wrapper around memset() */ -void -_mesa_memset(void *dst, int val, size_t n) -{ -#if defined(SUNOS4) - memset((char *) dst, (int) val, (int) n); -#else - memset(dst, val, n); -#endif -} - /** * Fill memory with a constant 16bit word. * \param dst destination pointer. @@ -283,17 +237,6 @@ _mesa_bzero(void *dst, size_t n) #endif } -/** Wrapper around memcmp() */ -int -_mesa_memcmp(const void *s1, const void *s2, size_t n) -{ -#if defined(SUNOS4) - return memcmp((char *) s1, (char *) s2, (int) n); -#else - return memcmp(s1, s2, n); -#endif -} - /*@}*/ @@ -301,13 +244,6 @@ _mesa_memcmp(const void *s1, const void *s2, size_t n) /** \name Math */ /*@{*/ -/** Wrapper around sin() */ -double -_mesa_sin(double a) -{ - return sin(a); -} - /** Single precision wrapper around sin() */ float _mesa_sinf(float a) @@ -315,13 +251,6 @@ _mesa_sinf(float a) return (float) sin((double) a); } -/** Wrapper around cos() */ -double -_mesa_cos(double a) -{ - return cos(a); -} - /** Single precision wrapper around asin() */ float _mesa_asinf(float x) @@ -336,13 +265,6 @@ _mesa_atanf(float x) return (float) atan((double) x); } -/** Wrapper around sqrt() */ -double -_mesa_sqrtd(double x) -{ - return sqrt(x); -} - /* * A High Speed, Low Precision Square Root @@ -375,7 +297,7 @@ _mesa_init_sqrt_table(void) */ fi.i = (i << 16) | (127 << 23); - fi.f = _mesa_sqrtd(fi.f); + fi.f = sqrt(fi.f); /* * Take the square root then strip the first 7 bits of @@ -433,7 +355,7 @@ _mesa_sqrtf(float x) return num.f; #else - return (float) _mesa_sqrtd((double) x); + return (float) sqrt((double) x); #endif } @@ -548,14 +470,6 @@ _mesa_inv_sqrtf(float n) } -/** Wrapper around pow() */ -double -_mesa_pow(double x, double y) -{ - return pow(x, y); -} - - /** * Find the first bit set in a word. */ @@ -786,23 +700,6 @@ _mesa_half_to_float(GLhalfARB val) /*@}*/ -/**********************************************************************/ -/** \name Sort & Search */ -/*@{*/ - -/** - * Wrapper for bsearch(). - */ -void * -_mesa_bsearch(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)) -{ - return bsearch(key, base, nmemb, size, compar); -} - -/*@}*/ - - /**********************************************************************/ /** \name Environment vars */ /*@{*/ @@ -827,87 +724,24 @@ _mesa_getenv(const char *var) /** \name String */ /*@{*/ -/** Wrapper around strstr() */ -char * -_mesa_strstr(const char *haystack, const char *needle) -{ - return strstr(haystack, needle); -} - -/** Wrapper around strncat() */ -char * -_mesa_strncat(char *dest, const char *src, size_t n) -{ - return strncat(dest, src, n); -} - -/** Wrapper around strcpy() */ -char * -_mesa_strcpy(char *dest, const char *src) -{ - return strcpy(dest, src); -} - -/** Wrapper around strncpy() */ -char * -_mesa_strncpy(char *dest, const char *src, size_t n) -{ - return strncpy(dest, src, n); -} - -/** Wrapper around strlen() */ -size_t -_mesa_strlen(const char *s) -{ - return strlen(s); -} - -/** Wrapper around strcmp() */ -int -_mesa_strcmp(const char *s1, const char *s2) -{ - return strcmp(s1, s2); -} - -/** Wrapper around strncmp() */ -int -_mesa_strncmp(const char *s1, const char *s2, size_t n) -{ - return strncmp(s1, s2, n); -} - /** - * Implemented using _mesa_malloc() and _mesa_strcpy. + * Implemented using malloc() and _mesa_strcpy. * Note that NULL is handled accordingly. */ char * _mesa_strdup(const char *s) { if (s) { - size_t l = _mesa_strlen(s); - char *s2 = (char *) _mesa_malloc(l + 1); + size_t l = strlen(s); + char *s2 = (char *) malloc(l + 1); if (s2) - _mesa_strcpy(s2, s); + strcpy(s2, s); return s2; } else { return NULL; } } -/** Wrapper around atoi() */ -int -_mesa_atoi(const char *s) -{ - return atoi(s); -} - -/** Wrapper around strtod() */ -double -_mesa_strtod(const char *s, char **end) -{ - return strtod(s, end); -} - /*@}*/ @@ -939,13 +773,6 @@ _mesa_printf(const char *fmtString, ...) fprintf(stderr,"%s", s); } -/** Wrapper around vsprintf() */ -int -_mesa_vsprintf(char *str, const char *fmt, va_list args) -{ - return vsprintf(str, fmt, args); -} - /*@}*/ @@ -1023,7 +850,7 @@ _mesa_error(GLcontext *ctx, GLenum error, const char *fmtString, ...) debugEnv = _mesa_getenv("MESA_DEBUG"); #ifdef DEBUG - if (debugEnv && _mesa_strstr(debugEnv, "silent")) + if (debugEnv && strstr(debugEnv, "silent")) debug = GL_FALSE; else debug = GL_TRUE; diff --git a/src/other/libosmesa/src/main/imports.h b/src/other/libosmesa/src/main/imports.h index f9aff0eb002..e15df278c08 100644 --- a/src/other/libosmesa/src/main/imports.h +++ b/src/other/libosmesa/src/main/imports.h @@ -71,16 +71,10 @@ extern "C" { /** Memory macros */ /*@{*/ -/** Allocate \p BYTES bytes */ -#define MALLOC(BYTES) _mesa_malloc(BYTES) -/** Allocate and zero \p BYTES bytes */ -#define CALLOC(BYTES) _mesa_calloc(BYTES) /** Allocate a structure of type \p T */ -#define MALLOC_STRUCT(T) (struct T *) _mesa_malloc(sizeof(struct T)) +#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T)) /** Allocate and zero a structure of type \p T */ -#define CALLOC_STRUCT(T) (struct T *) _mesa_calloc(sizeof(struct T)) -/** Free memory */ -#define FREE(PTR) _mesa_free(PTR) +#define CALLOC_STRUCT(T) (struct T *) calloc(1,sizeof(struct T)) /** Allocate \p BYTES aligned at \p N bytes */ #define ALIGN_MALLOC(BYTES, N) _mesa_align_malloc(BYTES, N) @@ -93,11 +87,6 @@ extern "C" { /** Free aligned memory */ #define ALIGN_FREE(PTR) _mesa_align_free(PTR) -/** Copy \p BYTES bytes from \p SRC into \p DST */ -#define MEMCPY( DST, SRC, BYTES) _mesa_memcpy(DST, SRC, BYTES) -/** Set \p N bytes in \p DST to \p VAL */ -#define MEMSET( DST, VAL, N ) _mesa_memset(DST, VAL, N) - /*@}*/ @@ -198,19 +187,6 @@ typedef union { *** LOG2: Log base 2 of float ***/ #ifdef USE_IEEE -#if 0 -/* This is pretty fast, but not accurate enough (only 2 fractional bits). - * Based on code from http://www.stereopsis.com/log2.html - */ -static INLINE GLfloat LOG2(GLfloat x) -{ - const GLfloat y = x * x * x * x; - const GLuint ix = *((GLuint *) &y); - const GLuint exp = (ix >> 23) & 0xFF; - const GLint log2 = ((GLint) exp) - 127; - return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */ -} -#endif /* Pretty fast, and accurate. * Based on code from http://www.flipcode.com/totd/ */ @@ -248,8 +224,6 @@ static INLINE int IS_INF_OR_NAN(float x) #define IS_INF_OR_NAN(x) (!isfinite(x)) #elif defined(finite) #define IS_INF_OR_NAN(x) (!finite(x)) -#elif defined(__VMS) -#define IS_INF_OR_NAN(x) (!finite(x)) #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define IS_INF_OR_NAN(x) (!isfinite(x)) #else @@ -318,47 +292,7 @@ static INLINE int GET_FLOAT_BITS(float x) /*** *** IROUND: return (as an integer) float rounded to nearest integer ***/ -#if defined(USE_SPARC_ASM) && defined(__GNUC__) && defined(__sparc__) -static INLINE int iround(float f) -{ - int r; - __asm__("fstoi %1, %0" : "=f"(r) : "f"(f)); - return r; -} -#define IROUND(x) iround(x) -#elif defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) && \ - (!defined(__BEOS__) || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))) -static INLINE int iround(float f) -{ - int r; - __asm__("fistpl %0" : "=m"(r) : "t"(f) : "st"); - return r; -} -#define IROUND(x) iround(x) -#elif defined(USE_X86_ASM) && defined(__MSC__) && defined(__WIN32__) -static INLINE int iround(float f) -{ - int r; - _asm { - fld f - fistp r - } - return r; -} -#define IROUND(x) iround(x) -#elif defined(__WATCOMC__) && defined(__386__) -long iround(float f); -#pragma aux iround = \ - "push eax" \ - "fistp dword ptr [esp]" \ - "pop eax" \ - parm [8087] \ - value [eax] \ - modify exact [eax]; -#define IROUND(x) iround(x) -#else #define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) -#endif /*** @@ -374,27 +308,7 @@ long iround(float f); /*** *** IFLOOR: return (as an integer) floor of float ***/ -#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) -/* - * IEEE floor for computers that round to nearest or even. - * 'f' must be between -4194304 and 4194303. - * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1", - * but uses some IEEE specific tricks for better speed. - * Contributed by Josh Vanderhoof - */ -static INLINE int ifloor(float f) -{ - int ai, bi; - double af, bf; - af = (3 << 22) + 0.5 + (double)f; - bf = (3 << 22) + 0.5 - (double)f; - /* GCC generates an extra fstp/fld without this. */ - __asm__("fstps %0" : "=m"(ai) : "t"(af) : "st"); - __asm__("fstps %0" : "=m"(bi) : "t"(bf) : "st"); - return (ai - bi) >> 1; -} -#define IFLOOR(x) ifloor(x) -#elif defined(USE_IEEE) +#if defined(USE_IEEE) static INLINE int ifloor(float f) { int ai, bi; @@ -423,27 +337,7 @@ static INLINE int ifloor(float f) /*** *** ICEIL: return (as an integer) ceiling of float ***/ -#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) -/* - * IEEE ceil for computers that round to nearest or even. - * 'f' must be between -4194304 and 4194303. - * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1", - * but uses some IEEE specific tricks for better speed. - * Contributed by Josh Vanderhoof - */ -static INLINE int iceil(float f) -{ - int ai, bi; - double af, bf; - af = (3 << 22) + 0.5 + (double)f; - bf = (3 << 22) + 0.5 - (double)f; - /* GCC generates an extra fstp/fld without this. */ - __asm__("fstps %0" : "=m"(ai) : "t"(af) : "st"); - __asm__("fstps %0" : "=m"(bi) : "t"(bf) : "st"); - return (ai - bi + 1) >> 1; -} -#define ICEIL(x) iceil(x) -#elif defined(USE_IEEE) +#if defined(USE_IEEE) static INLINE int iceil(float f) { int ai, bi; @@ -553,37 +447,6 @@ do { \ do { \ __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) ); \ } while (0) - -#elif defined(__WATCOMC__) && defined(__386__) -#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */ -#define FAST_X86_FPU 0x003f /* See GCC comments above */ -void _watcom_start_fast_math(unsigned short *x,unsigned short *mask); -#pragma aux _watcom_start_fast_math = \ - "fnstcw word ptr [eax]" \ - "fldcw word ptr [ecx]" \ - parm [eax] [ecx] \ - modify exact []; -void _watcom_end_fast_math(unsigned short *x); -#pragma aux _watcom_end_fast_math = \ - "fnclex" \ - "fldcw word ptr [eax]" \ - parm [eax] \ - modify exact []; -#if defined(NO_FAST_MATH) -#define START_FAST_MATH(x) \ -do { \ - static GLushort mask = DEFAULT_X86_FPU; \ - _watcom_start_fast_math(&x,&mask); \ -} while (0) -#else -#define START_FAST_MATH(x) \ -do { \ - static GLushort mask = FAST_X86_FPU; \ - _watcom_start_fast_math(&x,&mask); \ -} while (0) -#endif -#define END_FAST_MATH(x) _watcom_end_fast_math(&x) - #elif defined(_MSC_VER) && defined(_M_IX86) #define DEFAULT_X86_FPU 0x037f /* See GCC comments above */ #define FAST_X86_FPU 0x003f /* See GCC comments above */ @@ -627,15 +490,6 @@ _mesa_little_endian(void) * Functions */ -extern void * -_mesa_malloc(size_t bytes); - -extern void * -_mesa_calloc(size_t bytes); - -extern void -_mesa_free(void *ptr); - extern void * _mesa_align_malloc(size_t bytes, unsigned long alignment); @@ -649,48 +503,24 @@ extern void * _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, unsigned long alignment); -extern void * -_mesa_exec_malloc(GLuint size); - -extern void -_mesa_exec_free(void *addr); - extern void * _mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize); -extern void * -_mesa_memcpy(void *dest, const void *src, size_t n); - -extern void -_mesa_memset(void *dst, int val, size_t n); - extern void _mesa_memset16(unsigned short *dst, unsigned short val, size_t n); extern void _mesa_bzero(void *dst, size_t n); -extern int -_mesa_memcmp(const void *s1, const void *s2, size_t n); - -extern double -_mesa_sin(double a); - extern float _mesa_sinf(float a); -extern double -_mesa_cos(double a); - extern float _mesa_asinf(float x); extern float _mesa_atanf(float x); -extern double -_mesa_sqrtd(double x); - extern float _mesa_sqrtf(float x); @@ -700,9 +530,6 @@ _mesa_inv_sqrtf(float x); extern void _mesa_init_sqrt_table(void); -extern double -_mesa_pow(double x, double y); - extern int _mesa_ffs(int i); @@ -722,53 +549,18 @@ _mesa_float_to_half(float f); extern float _mesa_half_to_float(GLhalfARB h); - -extern void * -_mesa_bsearch(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)); - extern char * _mesa_getenv(const char *var); -extern char * -_mesa_strstr(const char *haystack, const char *needle); - -extern char * -_mesa_strncat(char *dest, const char *src, size_t n); - -extern char * -_mesa_strcpy(char *dest, const char *src); - -extern char * -_mesa_strncpy(char *dest, const char *src, size_t n); - -extern size_t -_mesa_strlen(const char *s); - -extern int -_mesa_strcmp(const char *s1, const char *s2); - -extern int -_mesa_strncmp(const char *s1, const char *s2, size_t n); - extern char * _mesa_strdup(const char *s); -extern int -_mesa_atoi(const char *s); - -extern double -_mesa_strtod(const char *s, char **end); - extern int _mesa_sprintf(char *str, const char *fmt, ...); extern void _mesa_printf(const char *fmtString, ...); -extern int -_mesa_vsprintf(char *str, const char *fmt, va_list args); - extern void _mesa_warning(__GLcontext *gc, const char *fmtString, ...); diff --git a/src/other/libosmesa/src/main/light.c b/src/other/libosmesa/src/main/light.c index 9bf70ae3fa2..ba9e4ce5661 100644 --- a/src/other/libosmesa/src/main/light.c +++ b/src/other/libosmesa/src/main/light.c @@ -130,7 +130,7 @@ _mesa_light(GLcontext *ctx, GLuint lnum, GLenum pname, const GLfloat *params) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); light->SpotCutoff = params[0]; - light->_CosCutoffNeg = (GLfloat)(_mesa_cos(light->SpotCutoff * DEG2RAD)); + light->_CosCutoffNeg = (GLfloat)(cos(light->SpotCutoff * DEG2RAD)); if (light->_CosCutoffNeg < 0) light->_CosCutoff = 0; else @@ -907,7 +907,7 @@ validate_spot_exp_table(struct gl_light *l) for (i = EXP_TABLE_SIZE - 1; i > 0 ; i--) { if (clamp == 0) { - tmp = _mesa_pow(i / (GLdouble)(EXP_TABLE_SIZE - 1), exponent); + tmp = pow(i / (GLdouble)(EXP_TABLE_SIZE - 1), exponent); if (tmp < FLT_MIN * 100.0) { tmp = 0.0; clamp = 1; @@ -968,7 +968,7 @@ validate_shine_table(GLcontext *ctx, GLuint side, GLfloat shininess) GLdouble t, x = j / (GLfloat)(SHINE_TABLE_SIZE - 1); if (x < 0.005) /* underflow check */ x = 0.005; - t = _mesa_pow(x, shininess); + t = pow(x, shininess); if (t > 1e-20) m[j] = (GLfloat) t; else @@ -1373,9 +1373,9 @@ _mesa_free_lighting_data(GLcontext *ctx) /* Free lighting shininess exponentiation table */ foreach_s(s, tmps, ctx->_ShineTabList) { - _mesa_free(s); + free(s); } - _mesa_free(ctx->_ShineTabList); + free(ctx->_ShineTabList); } /* diff --git a/src/other/libosmesa/src/main/light.h b/src/other/libosmesa/src/main/light.h index a557c610bcf..12c98d2bf3f 100644 --- a/src/other/libosmesa/src/main/light.h +++ b/src/other/libosmesa/src/main/light.h @@ -94,7 +94,7 @@ do { \ int k = (int) f; \ if (k < 0 /* gcc may cast an overflow float value to negative int value*/ \ || k > SHINE_TABLE_SIZE-2) \ - result = (GLfloat) _mesa_pow( dp, _tab->shininess ); \ + result = (GLfloat) pow( dp, _tab->shininess ); \ else \ result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]); \ } while (0) diff --git a/src/other/libosmesa/src/main/matrix.c b/src/other/libosmesa/src/main/matrix.c index 5be816e4c3a..d155c716a67 100644 --- a/src/other/libosmesa/src/main/matrix.c +++ b/src/other/libosmesa/src/main/matrix.c @@ -769,7 +769,7 @@ init_matrix_stack(struct gl_matrix_stack *stack, stack->MaxDepth = maxDepth; stack->DirtyFlag = dirtyFlag; /* The stack */ - stack->Stack = (GLmatrix *) CALLOC(maxDepth * sizeof(GLmatrix)); + stack->Stack = (GLmatrix *) calloc(1,maxDepth * sizeof(GLmatrix)); for (i = 0; i < maxDepth; i++) { _math_matrix_ctr(&stack->Stack[i]); _math_matrix_alloc_inv(&stack->Stack[i]); @@ -792,7 +792,7 @@ free_matrix_stack(struct gl_matrix_stack *stack) for (i = 0; i < stack->MaxDepth; i++) { _math_matrix_dtr(&stack->Stack[i]); } - FREE(stack->Stack); + free(stack->Stack); stack->Stack = stack->Top = NULL; } diff --git a/src/other/libosmesa/src/main/mipmap.c b/src/other/libosmesa/src/main/mipmap.c index 000141a844c..92889d96799 100644 --- a/src/other/libosmesa/src/main/mipmap.c +++ b/src/other/libosmesa/src/main/mipmap.c @@ -490,6 +490,9 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border, GLint srcWidth, const GLubyte *srcPtr, GLint dstWidth, GLubyte *dstPtr) { + if (!srcPtr || !dstPtr) + return; + const GLint bpt = format->TexelBytes; const GLubyte *src; GLubyte *dst; @@ -504,9 +507,9 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border, if (border) { /* copy left-most pixel from source */ - MEMCPY(dstPtr, srcPtr, bpt); + memcpy(dstPtr, srcPtr, bpt); /* copy right-most pixel from source */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); } @@ -521,6 +524,9 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) { + if (!srcPtr || !dstPtr) + return; + const GLint bpt = format->TexelBytes; const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint dstWidthNB = dstWidth - 2 * border; @@ -551,15 +557,15 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, if (border > 0) { /* fill in dest border */ /* lower-left border pixel */ - MEMCPY(dstPtr, srcPtr, bpt); + memcpy(dstPtr, srcPtr, bpt); /* lower-right border pixel */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); /* upper-left border pixel */ - MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, + memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt, srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); /* upper-right border pixel */ - MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, + memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt, srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); /* lower border */ do_row(format, srcWidthNB, @@ -576,9 +582,9 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, if (srcHeight == dstHeight) { /* copy border pixel from src to dst */ for (row = 1; row < srcHeight; row++) { - MEMCPY(dstPtr + dstWidth * row * bpt, + memcpy(dstPtr + dstWidth * row * bpt, srcPtr + srcWidth * row * bpt, bpt); - MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); } } else { @@ -605,6 +611,9 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstPtr) { + if (!srcPtr || !dstPtr) + return; + const GLint bpt = format->TexelBytes; const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint srcDepthNB = srcDepth - 2 * border; @@ -620,12 +629,12 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, (void) srcDepthNB; /* silence warnings */ /* Need two temporary row buffers */ - tmpRowA = _mesa_malloc(srcWidth * bpt); + tmpRowA = malloc(srcWidth * bpt); if (!tmpRowA) return; - tmpRowB = _mesa_malloc(srcWidth * bpt); + tmpRowB = malloc(srcWidth * bpt); if (!tmpRowB) { - _mesa_free(tmpRowA); + free(tmpRowA); return; } @@ -692,8 +701,8 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, } } - _mesa_free(tmpRowA); - _mesa_free(tmpRowB); + free(tmpRowA); + free(tmpRowB); /* Luckily we can leverage the make_2d_mipmap() function here! */ if (border > 0) { @@ -715,28 +724,28 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, /* do border along [img][row=0][col=0] */ src = srcPtr + (img + 1) * bytesPerSrcImage; dst = dstPtr + (img + 1) * bytesPerDstImage; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* do border along [img][row=dstHeight-1][col=0] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (srcHeight - 1) * bytesPerSrcRow; dst = dstPtr + (img + 1) * bytesPerDstImage + (dstHeight - 1) * bytesPerDstRow; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* do border along [img][row=0][col=dstWidth-1] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (srcWidth - 1) * bpt; dst = dstPtr + (img + 1) * bytesPerDstImage + (dstWidth - 1) * bpt; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (bytesPerSrcImage - bpt); dst = dstPtr + (img + 1) * bytesPerDstImage + (bytesPerDstImage - bpt); - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); } } else { /* average border pixels from adjacent src image pairs */ @@ -824,15 +833,15 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE) * srcImage->Width * srcImage->Height * srcImage->Depth + 20; /* 20 extra bytes, just be safe when calling last FetchTexel */ - srcData = (GLubyte *) _mesa_malloc(size); + srcData = (GLubyte *) malloc(size); if (!srcData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); return; } - dstData = (GLubyte *) _mesa_malloc(size / 2); /* 1/4 would probably be OK */ + dstData = (GLubyte *) malloc(size / 2); /* 1/4 would probably be OK */ if (!dstData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); - _mesa_free((void *) srcData); + free((void *) srcData); return; } @@ -889,21 +898,25 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, dstDepth == srcDepth) { /* all done */ if (srcData) - _mesa_free((void *)srcData); + free((void *)srcData); if (dstData) - _mesa_free(dstData); + free(dstData); return; } /* get dest gl_texture_image */ dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); if (!dstImage) { + if (srcData) + free((void *)srcData); + if (dstData) + free(dstData); _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); return; } if (dstImage->ImageOffsets) - _mesa_free(dstImage->ImageOffsets); + free(dstImage->ImageOffsets); /* Free old image data */ if (dstImage->Data) @@ -938,9 +951,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, if (!dstImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); if (srcData) - _mesa_free((void *)srcData); + free((void *)srcData); if (dstData) - _mesa_free(dstData); + free(dstData); return; } /* srcData and dstData are already set */ @@ -955,9 +968,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, /* If we're assigning these below, free up anything which has * been allocated first so we don't leak it */ if (srcData) - _mesa_free((void *)srcData); + free((void *)srcData); if (dstData) - _mesa_free(dstData); + free(dstData); if (!dstImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); @@ -999,9 +1012,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, default: _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); if (srcData) - _mesa_free((void *)srcData); + free((void *)srcData); if (dstData) - _mesa_free(dstData); + free(dstData); return; } @@ -1030,9 +1043,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, } /* loop over mipmap levels */ if (srcData) - _mesa_free((void *)srcData); + free((void *)srcData); if (dstData) - _mesa_free(dstData); + free(dstData); } diff --git a/src/other/libosmesa/src/main/mm.c b/src/other/libosmesa/src/main/mm.c index 85ff099db3c..a73699ffda1 100644 --- a/src/other/libosmesa/src/main/mm.c +++ b/src/other/libosmesa/src/main/mm.c @@ -60,13 +60,13 @@ mmInit(unsigned int ofs, int size) if (size <= 0) return NULL; - heap = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); + heap = (struct mem_block *) calloc(1,sizeof(struct mem_block)); if (!heap) return NULL; - block = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); + block = (struct mem_block *) calloc(1,sizeof(struct mem_block)); if (!block) { - _mesa_free(heap); + free(heap); return NULL; } @@ -98,7 +98,7 @@ SliceBlock(struct mem_block *p, /* break left [p, newblock, p->next], then p = newblock */ if (startofs > p->ofs) { - newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); + newblock = (struct mem_block*) calloc(1,sizeof(struct mem_block)); if (!newblock) return NULL; newblock->ofs = startofs; @@ -122,7 +122,7 @@ SliceBlock(struct mem_block *p, /* break right, also [p, newblock, p->next] */ if (size < p->size) { - newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); + newblock = (struct mem_block*) calloc(1,sizeof(struct mem_block)); if (!newblock) return NULL; newblock->ofs = startofs + size; @@ -225,7 +225,7 @@ Join2Blocks(struct mem_block *p) q->next_free->prev_free = q->prev_free; q->prev_free->next_free = q->next_free; - _mesa_free(q); + free(q); return 1; } return 0; @@ -270,11 +270,11 @@ mmDestroy(struct mem_block *heap) for (p = heap->next; p != heap;) { struct mem_block *next = p->next; - _mesa_free(p); + free(p); p = next; } - _mesa_free(heap); + free(heap); } /* diff --git a/src/other/libosmesa/src/main/mtypes.h b/src/other/libosmesa/src/main/mtypes.h index 383a4c5e991..0a353447105 100644 --- a/src/other/libosmesa/src/main/mtypes.h +++ b/src/other/libosmesa/src/main/mtypes.h @@ -37,7 +37,7 @@ #include "glheader.h" #include "OSMesa/internal/glcore.h" /* __GLcontextModes (GLvisual) */ -#include "config.h" /* Hardwired parameters */ +#include "gllimits.h" /* Hardwired parameters */ #include "glapitable.h" #include "glthread.h" #include "math/m_matrix.h" /* GLmatrix */ @@ -2992,7 +2992,7 @@ extern const char *_mesa_prim_name[GL_POLYGON+4]; #ifdef DEBUG extern int MESA_VERBOSE; extern int MESA_DEBUG_FLAGS; -# define MESA_FUNCTION __FUNCTION__ +# define MESA_FUNCTION __func__ #else # define MESA_VERBOSE 0 # define MESA_DEBUG_FLAGS 0 diff --git a/src/other/libosmesa/src/main/pixel.c b/src/other/libosmesa/src/main/pixel.c index a47988db88e..5e4579576cd 100644 --- a/src/other/libosmesa/src/main/pixel.c +++ b/src/other/libosmesa/src/main/pixel.c @@ -577,7 +577,7 @@ _mesa_GetPixelMapfv(GLenum map, GLfloat *values) values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; } } else { - MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat)); + memcpy(values, pm->Map, mapsize * sizeof(GLfloat)); } if (ctx->Pack.BufferObj->Name) { @@ -632,7 +632,7 @@ _mesa_GetPixelMapuiv(GLenum map, GLuint *values) if (map == GL_PIXEL_MAP_S_TO_S) { /* special case */ - MEMCPY(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); + memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); } else { for (i = 0; i < mapsize; i++) { values[i] = FLOAT_TO_UINT(pm->Map[i]); diff --git a/src/other/libosmesa/src/main/polygon.c b/src/other/libosmesa/src/main/polygon.c index 734c2f226dd..753a0eb123b 100644 --- a/src/other/libosmesa/src/main/polygon.c +++ b/src/other/libosmesa/src/main/polygon.c @@ -349,7 +349,7 @@ void _mesa_init_polygon(GLcontext * ctx) /* Polygon Stipple group */ - MEMSET(ctx->PolygonStipple, 0xff, 32*sizeof(GLuint)); + memset(ctx->PolygonStipple, 0xff, 32*sizeof(GLuint)); } /*@}*/ diff --git a/src/other/libosmesa/src/main/queryobj.c b/src/other/libosmesa/src/main/queryobj.c index 1eec4cf3932..ebd5e5de59b 100644 --- a/src/other/libosmesa/src/main/queryobj.c +++ b/src/other/libosmesa/src/main/queryobj.c @@ -61,7 +61,7 @@ _mesa_new_query_object(GLcontext *ctx, GLuint id) static void delete_query_object(struct gl_query_object *q) { - FREE(q); + free(q); } diff --git a/src/other/libosmesa/src/main/renderbuffer.c b/src/other/libosmesa/src/main/renderbuffer.c index 649be0aebfa..cf339ecb549 100644 --- a/src/other/libosmesa/src/main/renderbuffer.c +++ b/src/other/libosmesa/src/main/renderbuffer.c @@ -85,7 +85,7 @@ get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, { const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - _mesa_memcpy(values, src, count * sizeof(GLubyte)); + memcpy(values, src, count * sizeof(GLubyte)); } @@ -118,7 +118,7 @@ put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, values, count * sizeof(GLubyte)); + memcpy(dst, values, count * sizeof(GLubyte)); } } @@ -203,7 +203,7 @@ get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, { const void *src = rb->GetPointer(ctx, rb, x, y); ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - _mesa_memcpy(values, src, count * sizeof(GLushort)); + memcpy(values, src, count * sizeof(GLushort)); } @@ -236,7 +236,7 @@ put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, src, count * sizeof(GLushort)); + memcpy(dst, src, count * sizeof(GLushort)); } } @@ -330,7 +330,7 @@ get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, const void *src = rb->GetPointer(ctx, rb, x, y); ASSERT(rb->DataType == GL_UNSIGNED_INT || rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - _mesa_memcpy(values, src, count * sizeof(GLuint)); + memcpy(values, src, count * sizeof(GLuint)); } @@ -365,7 +365,7 @@ put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, src, count * sizeof(GLuint)); + memcpy(dst, src, count * sizeof(GLuint)); } } @@ -539,7 +539,7 @@ put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, ASSERT(rb->DataType == GL_UNSIGNED_BYTE); if (!mask && val0 == val1 && val1 == val2) { /* optimized case */ - _mesa_memset(dst, val0, 3 * count); + memset(dst, val0, 3 * count); } else { GLuint i; for (i = 0; i < count; i++) { @@ -621,7 +621,7 @@ get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x); ASSERT(rb->DataType == GL_UNSIGNED_BYTE); ASSERT(rb->_ActualFormat == GL_RGBA8); - _mesa_memcpy(values, src, 4 * count * sizeof(GLubyte)); + memcpy(values, src, 4 * count * sizeof(GLubyte)); } @@ -658,7 +658,7 @@ put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte)); + memcpy(dst, src, 4 * count * sizeof(GLubyte)); } } @@ -775,7 +775,7 @@ get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, { const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x); ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - _mesa_memcpy(values, src, 4 * count * sizeof(GLshort)); + memcpy(values, src, 4 * count * sizeof(GLshort)); } @@ -812,7 +812,7 @@ put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); + memcpy(dst, src, 4 * count * sizeof(GLushort)); } } @@ -836,7 +836,7 @@ put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, } } } else { - _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); + memcpy(dst, src, 4 * count * sizeof(GLushort)); } } @@ -1178,13 +1178,13 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, /* free old buffer storage */ if (rb->Data) { - _mesa_free(rb->Data); + free(rb->Data); rb->Data = NULL; } if (width > 0 && height > 0) { /* allocate new buffer storage */ - rb->Data = _mesa_malloc(width * height * pixelSize); + rb->Data = malloc(width * height * pixelSize); if (rb->Data == NULL) { rb->Width = 0; rb->Height = 0; @@ -1233,10 +1233,10 @@ alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, /* next, resize my alpha buffer */ if (arb->Data) { - _mesa_free(arb->Data); + free(arb->Data); } - arb->Data = _mesa_malloc(width * height * sizeof(GLubyte)); + arb->Data = malloc(width * height * sizeof(GLubyte)); if (arb->Data == NULL) { arb->Width = 0; arb->Height = 0; @@ -1258,13 +1258,13 @@ static void delete_renderbuffer_alpha8(struct gl_renderbuffer *arb) { if (arb->Data) { - _mesa_free(arb->Data); + free(arb->Data); } ASSERT(arb->Wrapped); ASSERT(arb != arb->Wrapped); arb->Wrapped->Delete(arb->Wrapped); arb->Wrapped = NULL; - _mesa_free(arb); + free(arb); } @@ -1372,7 +1372,7 @@ put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count, } } } else { - _mesa_memset(dst, val, count); + memset(dst, val, count); } } @@ -1427,7 +1427,7 @@ copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) ASSERT(dst->Width == src->Width); ASSERT(dst->Height == src->Height); - _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte)); + memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte)); } @@ -1517,9 +1517,9 @@ void _mesa_delete_renderbuffer(struct gl_renderbuffer *rb) { if (rb->Data) { - _mesa_free(rb->Data); + free(rb->Data); } - _mesa_free(rb); + free(rb); } diff --git a/src/other/libosmesa/src/main/shaders.c b/src/other/libosmesa/src/main/shaders.c index be0c57906dc..f21e78582d5 100644 --- a/src/other/libosmesa/src/main/shaders.c +++ b/src/other/libosmesa/src/main/shaders.c @@ -381,7 +381,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, * This array holds offsets of where the appropriate string ends, thus the * last element will be set to the total length of the source code. */ - offsets = (GLint *) _mesa_malloc(count * sizeof(GLint)); + offsets = (GLint *) malloc(count * sizeof(GLint)); if (offsets == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); return; @@ -389,12 +389,12 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, for (i = 0; i < count; i++) { if (string[i] == NULL) { - _mesa_free((GLvoid *) offsets); + free((GLvoid *) offsets); _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)"); return; } if (length == NULL || length[i] < 0) - offsets[i] = _mesa_strlen(string[i]); + offsets[i] = strlen(string[i]); else offsets[i] = length[i]; /* accumulate string lengths */ @@ -407,16 +407,16 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, * valgrind warnings in the parser/grammer code. */ totalLength = offsets[count - 1] + 2; - source = (GLcharARB *) _mesa_malloc(totalLength * sizeof(GLcharARB)); + source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB)); if (source == NULL) { - _mesa_free((GLvoid *) offsets); + free((GLvoid *) offsets); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); return; } for (i = 0; i < count; i++) { GLint start = (i > 0) ? offsets[i - 1] : 0; - _mesa_memcpy(source + start, string[i], + memcpy(source + start, string[i], (offsets[i] - start) * sizeof(GLcharARB)); } source[totalLength - 1] = '\0'; @@ -424,7 +424,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, ctx->Driver.ShaderSource(ctx, shaderObj, source); - _mesa_free(offsets); + free(offsets); } diff --git a/src/other/libosmesa/src/main/texcompress_fxt1.c b/src/other/libosmesa/src/main/texcompress_fxt1.c index 0e073deeeb3..7d587414d42 100644 --- a/src/other/libosmesa/src/main/texcompress_fxt1.c +++ b/src/other/libosmesa/src/main/texcompress_fxt1.c @@ -110,7 +110,7 @@ texstore_rgb_fxt1(TEXSTORE_PARAMS) dst, dstRowStride); if (tempImage) - _mesa_free((void*) tempImage); + free((void*) tempImage); return GL_TRUE; } @@ -165,7 +165,7 @@ texstore_rgba_fxt1(TEXSTORE_PARAMS) dst, dstRowStride); if (tempImage) - _mesa_free((void*) tempImage); + free((void*) tempImage); return GL_TRUE; } @@ -482,7 +482,7 @@ fxt1_choose(GLfloat vec[][MAX_COMP], GLint nv, } hist[N_TEXELS]; GLint lenh = 0; - _mesa_memset(hist, 0, sizeof(hist)); + memset(hist, 0, sizeof(hist)); for (k = 0; k < n; k++) { GLint l; @@ -1296,7 +1296,7 @@ fxt1_quantize(GLuint *cc, const GLubyte *lines[], GLint comps) if (comps == 3) { /* make the whole block opaque */ - _mesa_memset(input, -1, sizeof(input)); + memset(input, -1, sizeof(input)); } /* 8 texels each line */ @@ -1390,7 +1390,7 @@ fxt1_encode(GLuint width, GLuint height, GLint comps, if ((width & 7) | (height & 3)) { GLint newWidth = (width + 7) & ~7; GLint newHeight = (height + 3) & ~3; - newSource = _mesa_malloc(comps * newWidth * newHeight * sizeof(GLchan)); + newSource = malloc(comps * newWidth * newHeight * sizeof(GLchan)); if (!newSource) { GET_CURRENT_CONTEXT(ctx); _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression"); @@ -1409,7 +1409,7 @@ fxt1_encode(GLuint width, GLuint height, GLint comps, if (CHAN_TYPE != GL_UNSIGNED_BYTE) { const GLuint n = width * height * comps; const GLchan *src = (const GLchan *) source; - GLubyte *dest = (GLubyte *) _mesa_malloc(n * sizeof(GLubyte)); + GLubyte *dest = (GLubyte *) malloc(n * sizeof(GLubyte)); GLuint i; if (!dest) { GET_CURRENT_CONTEXT(ctx); @@ -1420,7 +1420,7 @@ fxt1_encode(GLuint width, GLuint height, GLint comps, dest[i] = CHAN_TO_UBYTE(src[i]); } if (newSource != NULL) { - _mesa_free(newSource); + free(newSource); } newSource = dest; /* we'll free this buffer before returning */ source = dest; /* the new, GLubyte incoming image */ @@ -1446,7 +1446,7 @@ fxt1_encode(GLuint width, GLuint height, GLint comps, cleanUp: if (newSource != NULL) { - _mesa_free(newSource); + free(newSource); } } diff --git a/src/other/libosmesa/src/main/texcompress_s3tc.c b/src/other/libosmesa/src/main/texcompress_s3tc.c index ebe588f32ee..80885b89f41 100644 --- a/src/other/libosmesa/src/main/texcompress_s3tc.c +++ b/src/other/libosmesa/src/main/texcompress_s3tc.c @@ -28,10 +28,6 @@ * GL_EXT_texture_compression_s3tc support. */ -#ifndef USE_EXTERNAL_DXTN_LIB -#define USE_EXTERNAL_DXTN_LIB 0 -#endif - #include "glheader.h" #include "imports.h" #include "colormac.h" @@ -42,21 +38,6 @@ #include "texformat.h" #include "texstore.h" -#if USE_EXTERNAL_DXTN_LIB && !defined(__MINGW32__) -#include -#endif - -#ifdef __MINGW32__ -#define DXTN_LIBNAME "dxtn.dll" -#define RTLD_LAZY 0 -#define RTLD_GLOBAL 0 -#elif defined(__DJGPP__) -#define DXTN_LIBNAME "dxtn.dxe" -#else -#define DXTN_LIBNAME "libtxc_dxtn.so" -#endif - - typedef void (*dxtFetchTexelFuncExt)(GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut); dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL; @@ -78,50 +59,7 @@ _mesa_init_texture_s3tc(GLcontext *ctx) { /* called during context initialization */ ctx->Mesa_DXTn = GL_FALSE; -#if USE_EXTERNAL_DXTN_LIB - if (!dxtlibhandle) { - dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, RTLD_LAZY | RTLD_GLOBAL); - if (!dxtlibhandle) { - _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn " - "compression/decompression unavailable"); - } else { - /* the fetch functions are not per context! Might be problematic... */ - fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt) - _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1"); - fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt) - _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1"); - fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt) - _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3"); - fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt) - _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5"); - ext_tx_compress_dxtn = (dxtCompressTexFuncExt) - _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn"); - - if (!fetch_ext_rgb_dxt1 || - !fetch_ext_rgba_dxt1 || - !fetch_ext_rgba_dxt3 || - !fetch_ext_rgba_dxt5 || - !ext_tx_compress_dxtn) { - _mesa_warning(ctx, "couldn't reference all symbols in " - DXTN_LIBNAME ", software DXTn compression/decompression " - "unavailable"); - fetch_ext_rgb_dxt1 = NULL; - fetch_ext_rgba_dxt1 = NULL; - fetch_ext_rgba_dxt3 = NULL; - fetch_ext_rgba_dxt5 = NULL; - ext_tx_compress_dxtn = NULL; - _mesa_dlclose(dxtlibhandle); - dxtlibhandle = NULL; - } - } - } - if (dxtlibhandle) { - ctx->Mesa_DXTn = GL_TRUE; - _mesa_warning(ctx, "software DXTn compression/decompression available"); - } -#else (void) ctx; -#endif } /** @@ -176,7 +114,7 @@ texstore_rgb_dxt1(TEXSTORE_PARAMS) } if (tempImage) - _mesa_free((void *) tempImage); + free((void *) tempImage); return GL_TRUE; } @@ -233,7 +171,7 @@ texstore_rgba_dxt1(TEXSTORE_PARAMS) } if (tempImage) - _mesa_free((void*) tempImage); + free((void*) tempImage); return GL_TRUE; } @@ -290,7 +228,7 @@ texstore_rgba_dxt3(TEXSTORE_PARAMS) } if (tempImage) - _mesa_free((void *) tempImage); + free((void *) tempImage); return GL_TRUE; } @@ -347,7 +285,7 @@ texstore_rgba_dxt5(TEXSTORE_PARAMS) } if (tempImage) - _mesa_free((void *) tempImage); + free((void *) tempImage); return GL_TRUE; } diff --git a/src/other/libosmesa/src/main/texenvprogram.c b/src/other/libosmesa/src/main/texenvprogram.c index cd19536967d..ca919544419 100644 --- a/src/other/libosmesa/src/main/texenvprogram.c +++ b/src/other/libosmesa/src/main/texenvprogram.c @@ -844,7 +844,7 @@ static struct ureg emit_combine(struct texenv_fragment_program *p, emit_arith(p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, two, src[0], neg1); - if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) + if (memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) tmp1 = tmp0; else emit_arith(p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, @@ -1052,7 +1052,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, GLuint unit; struct ureg cf, out; - _mesa_memset(&p, 0, sizeof(p)); + memset(&p, 0, sizeof(p)); p.ctx = ctx; p.state = key; p.program = program; @@ -1115,7 +1115,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); emit_arith(&p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef); emit_arith(&p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef); - } else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { + } else if (memcmp(&cf, &out, sizeof(cf)) != 0) { /* Will wind up in here if no texture enabled or a couple of * other scenarios (GL_REPLACE for instance). */ @@ -1193,8 +1193,8 @@ static void rehash(struct texenvprog_cache *cache) GLuint size, i; size = cache->size * 3; - items = (struct texenvprog_cache_item**) _mesa_malloc(size * sizeof(*items)); - _mesa_memset(items, 0, size * sizeof(*items)); + items = (struct texenvprog_cache_item**) malloc(size * sizeof(*items)); + memset(items, 0, size * sizeof(*items)); for (i = 0; i < cache->size; i++) for (c = cache->items[i]; c; c = next) { @@ -1203,7 +1203,7 @@ static void rehash(struct texenvprog_cache *cache) items[c->hash % size] = c; } - _mesa_free(cache->items); + free(cache->items); cache->items = items; cache->size = size; } @@ -1216,10 +1216,10 @@ static void clear_cache(struct texenvprog_cache *cache) for (i = 0; i < cache->size; i++) { for (c = cache->items[i]; c; c = next) { next = c->next; - _mesa_free(c->key); + free(c->key); cache->ctx->Driver.DeleteProgram(cache->ctx, (struct gl_program *) c->data); - _mesa_free(c); + free(c); } cache->items[i] = NULL; } @@ -1234,10 +1234,10 @@ static void cache_item(struct texenvprog_cache *cache, const struct state_key *key, void *data) { - struct texenvprog_cache_item *c = (struct texenvprog_cache_item *) MALLOC(sizeof(*c)); + struct texenvprog_cache_item *c = (struct texenvprog_cache_item *) malloc(sizeof(*c)); c->hash = hash; - c->key = _mesa_malloc(sizeof(*key)); + c->key = malloc(sizeof(*key)); memcpy(c->key, key, sizeof(*key)); c->data = (struct gl_fragment_program *) data; @@ -1252,11 +1252,14 @@ static void cache_item(struct texenvprog_cache *cache, cache->n_items++; // I think this is a false positive from clang? % triggers a // core.UndefinedBinaryOperatorResult with clang 12 - #ifndef __clang_analyzer__ +#ifndef __clang_analyzer__ size_t hmod = hash % cache->size; c->next = cache->items[hmod]; cache->items[hmod] = c; - #endif +#else + // Be quiet clang_analyzer... + free(c); +#endif } static GLuint hash_key(const struct state_key *key) @@ -1339,7 +1342,7 @@ void _mesa_TexEnvProgramCacheInit(GLcontext *ctx) ctx->Texture.env_fp_cache.size = 17; ctx->Texture.env_fp_cache.n_items = 0; ctx->Texture.env_fp_cache.items = (struct texenvprog_cache_item **) - _mesa_calloc(ctx->Texture.env_fp_cache.size * + calloc(1,ctx->Texture.env_fp_cache.size * sizeof(struct texenvprog_cache_item *)); } @@ -1347,7 +1350,7 @@ void _mesa_TexEnvProgramCacheInit(GLcontext *ctx) void _mesa_TexEnvProgramCacheDestroy(GLcontext *ctx) { clear_cache(&ctx->Texture.env_fp_cache); - _mesa_free(ctx->Texture.env_fp_cache.items); + free(ctx->Texture.env_fp_cache.items); } /* diff --git a/src/other/libosmesa/src/main/texformat.c b/src/other/libosmesa/src/main/texformat.c index 99c6cc129d6..526d300b230 100644 --- a/src/other/libosmesa/src/main/texformat.c +++ b/src/other/libosmesa/src/main/texformat.c @@ -57,7 +57,7 @@ nonlinear_to_linear(GLubyte cs8) if (cs <= 0.04045) { table[i] = cs / 12.92; } else { - table[i] = _mesa_pow((cs + 0.055) / 1.055, 2.4); + table[i] = pow((cs + 0.055) / 1.055, 2.4); } } tableReady = GL_TRUE; diff --git a/src/other/libosmesa/src/main/teximage.c b/src/other/libosmesa/src/main/teximage.c index 4b75055b0ac..ee21ee27757 100644 --- a/src/other/libosmesa/src/main/teximage.c +++ b/src/other/libosmesa/src/main/teximage.c @@ -712,8 +712,8 @@ _mesa_delete_texture_image(GLcontext *ctx, struct gl_texture_image *texImage) ASSERT(texImage->Data == NULL); if (texImage->ImageOffsets) - _mesa_free(texImage->ImageOffsets); - _mesa_free(texImage); + free(texImage->ImageOffsets); + free(texImage); } @@ -1029,7 +1029,7 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format) { const GLint components = _mesa_components_in_format(format); const GLint numPixels = width * height * depth; - GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); + GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte)); #ifdef DEBUG /* @@ -1095,7 +1095,7 @@ clear_teximage_fields(struct gl_texture_image *img) img->Depth = 0; img->RowStride = 0; if (img->ImageOffsets) { - _mesa_free(img->ImageOffsets); + free(img->ImageOffsets); img->ImageOffsets = NULL; } img->Width2 = 0; @@ -1177,7 +1177,7 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, * We allocate the array for 1D/2D textures too in order to avoid special- * case code in the texstore routines. */ - img->ImageOffsets = (GLuint *) _mesa_malloc(depth * sizeof(GLuint)); + img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); for (i = 0; i < depth; i++) { img->ImageOffsets[i] = i * width * height; } diff --git a/src/other/libosmesa/src/main/teximage.h b/src/other/libosmesa/src/main/teximage.h index 9af849f5b27..002c96ad06c 100644 --- a/src/other/libosmesa/src/main/teximage.h +++ b/src/other/libosmesa/src/main/teximage.h @@ -229,11 +229,6 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -#ifdef VMS -#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR -#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR -#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR -#endif extern void GLAPIENTRY _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, diff --git a/src/other/libosmesa/src/main/texobj.c b/src/other/libosmesa/src/main/texobj.c index 747298db4e2..480f4bc44e4 100644 --- a/src/other/libosmesa/src/main/texobj.c +++ b/src/other/libosmesa/src/main/texobj.c @@ -42,9 +42,6 @@ #include "mtypes.h" -#ifdef __VMS -#define _mesa_sprintf sprintf -#endif /**********************************************************************/ /** \name Internal functions */ @@ -175,7 +172,7 @@ _mesa_delete_texture_object(GLcontext *ctx, struct gl_texture_object *texObj) _glthread_DESTROY_MUTEX(texObj->Mutex); /* free this object */ - _mesa_free(texObj); + free(texObj); } diff --git a/src/other/libosmesa/src/main/texrender.c b/src/other/libosmesa/src/main/texrender.c index 296bf642415..af6bc7db3cf 100644 --- a/src/other/libosmesa/src/main/texrender.c +++ b/src/other/libosmesa/src/main/texrender.c @@ -269,7 +269,7 @@ static void delete_texture_wrapper(struct gl_renderbuffer *rb) { ASSERT(rb->RefCount == 0); - _mesa_free(rb); + free(rb); } diff --git a/src/other/libosmesa/src/main/texstore.c b/src/other/libosmesa/src/main/texstore.c index 5411759a673..42afaddde76 100644 --- a/src/other/libosmesa/src/main/texstore.c +++ b/src/other/libosmesa/src/main/texstore.c @@ -352,16 +352,16 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, GLfloat *convImage; /* pre-convolution image buffer (3D) */ - tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth + tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth * 4 * sizeof(GLfloat)); if (!tempImage) return NULL; /* post-convolution image buffer (2D) */ - convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight + convImage = (GLfloat *) malloc(srcWidth * srcHeight * 4 * sizeof(GLfloat)); if (!convImage) { - _mesa_free(tempImage); + free(tempImage); return NULL; } @@ -419,7 +419,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, } } /* loop over 3D image slices */ - _mesa_free(convImage); + free(convImage); /* might need these below */ srcWidth = convWidth; @@ -432,7 +432,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, GLfloat *dst; GLint img, row; - tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth + tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth * components * sizeof(GLfloat)); if (!tempImage) return NULL; @@ -471,10 +471,10 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, */ ASSERT(texComponents >= logComponents); - newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth + newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth * texComponents * sizeof(GLfloat)); if (!newImage) { - _mesa_free(tempImage); + free(tempImage); return NULL; } @@ -494,7 +494,7 @@ make_temp_float_image(GLcontext *ctx, GLuint dims, } } - _mesa_free(tempImage); + free(tempImage); tempImage = newImage; } @@ -580,11 +580,11 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, } /* unpack and transfer the source image */ - tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLchan)); + tempImage = (GLchan *) calloc(srcWidth * srcHeight * srcDepth + * components, sizeof(GLchan)); if (!tempImage) { if (convImage) - _mesa_free(convImage); + free(convImage); return NULL; } @@ -609,7 +609,7 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, /* If we made a temporary image for convolution, free it here */ if (freeSrcImage) { - _mesa_free((void *) srcAddr); + free((void *) srcAddr); } if (logicalBaseFormat != textureBaseFormat) { @@ -629,10 +629,10 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, */ ASSERT(texComponents >= logComponents); - newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLchan)); + newImage = (GLchan *) calloc(srcWidth * srcHeight * srcDepth + * texComponents, sizeof(GLchan)); if (!newImage) { - _mesa_free(tempImage); + free(tempImage); return NULL; } @@ -652,7 +652,7 @@ _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, } } - _mesa_free(tempImage); + free(tempImage); tempImage = newImage; } @@ -1122,13 +1122,13 @@ _mesa_texstore_rgba(TEXSTORE_PARAMS) + dstYoffset * dstRowStride + dstXoffset * dstFormat->TexelBytes; for (row = 0; row < srcHeight; row++) { - _mesa_memcpy(dstRow, src, bytesPerRow); + memcpy(dstRow, src, bytesPerRow); dstRow += dstRowStride; src += srcWidth * components; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1322,7 +1322,7 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1443,7 +1443,7 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1654,7 +1654,7 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1775,7 +1775,7 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1878,7 +1878,7 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -1944,7 +1944,7 @@ _mesa_texstore_argb4444(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2011,7 +2011,7 @@ _mesa_texstore_argb1555(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2108,7 +2108,7 @@ _mesa_texstore_al88(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2159,7 +2159,7 @@ _mesa_texstore_rgb332(TEXSTORE_PARAMS) dstRow += dstRowStride; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2240,7 +2240,7 @@ _mesa_texstore_a8(TEXSTORE_PARAMS) src += srcWidth; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2467,13 +2467,13 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) + dstYoffset * dstRowStride + dstXoffset * dstFormat->TexelBytes; for (row = 0; row < srcHeight; row++) { - _mesa_memcpy(dstRow, srcRow, bytesPerRow); + memcpy(dstRow, srcRow, bytesPerRow); dstRow += dstRowStride; srcRow += srcWidth * components; } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -2541,7 +2541,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) } } - _mesa_free((void *) tempImage); + free((void *) tempImage); } return GL_TRUE; } @@ -3324,7 +3324,7 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, /* copy the data */ ASSERT(texImage->CompressedSize == (GLuint) imageSize); - MEMCPY(texImage->Data, data, imageSize); + memcpy(texImage->Data, data, imageSize); /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { @@ -3440,7 +3440,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, rows = height / 4; for (i = 0; i < rows; i++) { - MEMCPY(dest, src, bytesPerRow); + memcpy(dest, src, bytesPerRow); dest += destRowStride; src += srcRowStride; } @@ -3596,14 +3596,14 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, /* XXX Note: we're bypassing texImage->FetchTexel()! */ const GLuint *src = (const GLuint *) texImage->Data; src += width * row + width * height * img; - _mesa_memcpy(dest, src, width * sizeof(GLuint)); + memcpy(dest, src, width * sizeof(GLuint)); if (ctx->Pack.SwapBytes) { _mesa_swap4((GLuint *) dest, width); } } else if (format == GL_YCBCR_MESA) { /* No pixel transfer */ const GLint rowstride = texImage->RowStride; - MEMCPY(dest, + memcpy(dest, (const GLushort *) texImage->Data + row * rowstride, width * sizeof(GLushort)); /* check for byte swapping */ @@ -3622,7 +3622,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, /* no pixel transfer and no non-linear to linear conversion */ const GLint comps = texImage->TexFormat->TexelBytes; const GLint rowstride = comps * texImage->RowStride; - MEMCPY(dest, + memcpy(dest, (const GLubyte *) texImage->Data + row * rowstride, comps * width * sizeof(GLubyte)); } @@ -3708,7 +3708,7 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, texImage->TexFormat->MesaFormat); /* just memcpy, no pixelstore or pixel transfer */ - _mesa_memcpy(img, texImage->Data, size); + memcpy(img, texImage->Data, size); if (ctx->Pack.BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, diff --git a/src/other/libosmesa/src/math/m_debug_util.h b/src/other/libosmesa/src/math/m_debug_util.h index 8117691eb21..f6ef72bef9a 100644 --- a/src/other/libosmesa/src/math/m_debug_util.h +++ b/src/other/libosmesa/src/math/m_debug_util.h @@ -305,8 +305,6 @@ enum { NIL = 0, ONE = 1, NEG = -1, VAR = 2 }; # define ALIGN16(type, array) type array __attribute__ ((aligned (16))) #elif defined(__MSC__) # define ALIGN16(type, array) type array __declspec(align(16)) /* GH: Does this work? */ -#elif defined(__WATCOMC__) -# define ALIGN16(type, array) /* Watcom does not support this */ #elif defined(__xlC__) # define ALIGN16(type, array) type __align (16) array #else diff --git a/src/other/libosmesa/src/math/m_eval.c b/src/other/libosmesa/src/math/m_eval.c index 1d423467803..ec62e418f4e 100644 --- a/src/other/libosmesa/src/math/m_eval.c +++ b/src/other/libosmesa/src/math/m_eval.c @@ -38,7 +38,7 @@ #include "glheader.h" -#include "config.h" +#include "gllimits.h" #include "m_eval.h" static GLfloat inv_tab[MAX_EVAL_ORDER]; diff --git a/src/other/libosmesa/src/math/m_matrix.c b/src/other/libosmesa/src/math/m_matrix.c index 854507ab688..0881b6c3cf5 100644 --- a/src/other/libosmesa/src/math/m_matrix.c +++ b/src/other/libosmesa/src/math/m_matrix.c @@ -659,7 +659,7 @@ static GLboolean invert_matrix_3d(GLmatrix *mat) MAT(out,2,2) = MAT(in,2,2); } else { /* pure translation */ - MEMCPY(out, Identity, sizeof(Identity)); + memcpy(out, Identity, sizeof(Identity)); MAT(out,0,3) = - MAT(in,0,3); MAT(out,1,3) = - MAT(in,1,3); MAT(out,2,3) = - MAT(in,2,3); @@ -696,7 +696,7 @@ static GLboolean invert_matrix_3d(GLmatrix *mat) */ static GLboolean invert_matrix_identity(GLmatrix *mat) { - MEMCPY(mat->inv, Identity, sizeof(Identity)); + memcpy(mat->inv, Identity, sizeof(Identity)); return GL_TRUE; } @@ -718,7 +718,7 @@ static GLboolean invert_matrix_3d_no_rot(GLmatrix *mat) if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0) return GL_FALSE; - MEMCPY(out, Identity, 16 * sizeof(GLfloat)); + memcpy(out, Identity, 16 * sizeof(GLfloat)); MAT(out,0,0) = 1.0F / MAT(in,0,0); MAT(out,1,1) = 1.0F / MAT(in,1,1); MAT(out,2,2) = 1.0F / MAT(in,2,2); @@ -751,7 +751,7 @@ static GLboolean invert_matrix_2d_no_rot(GLmatrix *mat) if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) return GL_FALSE; - MEMCPY(out, Identity, 16 * sizeof(GLfloat)); + memcpy(out, Identity, 16 * sizeof(GLfloat)); MAT(out,0,0) = 1.0F / MAT(in,0,0); MAT(out,1,1) = 1.0F / MAT(in,1,1); @@ -773,7 +773,7 @@ static GLboolean invert_matrix_perspective(GLmatrix *mat) if (MAT(in,2,3) == 0) return GL_FALSE; - MEMCPY(out, Identity, 16 * sizeof(GLfloat)); + memcpy(out, Identity, 16 * sizeof(GLfloat)); MAT(out,0,0) = 1.0F / MAT(in,0,0); MAT(out,1,1) = 1.0F / MAT(in,1,1); @@ -835,7 +835,7 @@ static GLboolean matrix_invert(GLmatrix *mat) return GL_TRUE; } else { mat->flags |= MAT_FLAG_SINGULAR; - MEMCPY(mat->inv, Identity, sizeof(Identity)); + memcpy(mat->inv, Identity, sizeof(Identity)); return GL_FALSE; } } @@ -863,10 +863,10 @@ _math_matrix_rotate(GLmatrix *mat, GLfloat m[16]; GLboolean optimized; - s = (GLfloat) _mesa_sin(angle * DEG2RAD); - c = (GLfloat) _mesa_cos(angle * DEG2RAD); + s = (GLfloat) sin(angle * DEG2RAD); + c = (GLfloat) cos(angle * DEG2RAD); - MEMCPY(m, Identity, sizeof(GLfloat)*16); + memcpy(m, Identity, sizeof(GLfloat)*16); optimized = GL_FALSE; #define M(row,col) m[col*4+row] @@ -1215,10 +1215,10 @@ _math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, void _math_matrix_set_identity(GLmatrix *mat) { - MEMCPY(mat->m, Identity, 16*sizeof(GLfloat)); + memcpy(mat->m, Identity, 16*sizeof(GLfloat)); if (mat->inv) - MEMCPY(mat->inv, Identity, 16*sizeof(GLfloat)); + memcpy(mat->inv, Identity, 16*sizeof(GLfloat)); mat->type = MATRIX_IDENTITY; mat->flags &= ~(MAT_DIRTY_FLAGS| @@ -1504,7 +1504,7 @@ _math_matrix_is_dirty(const GLmatrix *m) void _math_matrix_copy(GLmatrix *to, const GLmatrix *from) { - MEMCPY(to->m, from->m, sizeof(Identity)); + memcpy(to->m, from->m, sizeof(Identity)); to->flags = from->flags; to->type = from->type; @@ -1512,7 +1512,7 @@ _math_matrix_copy(GLmatrix *to, const GLmatrix *from) if (from->inv == 0) { matrix_invert(to); } else { - MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16); + memcpy(to->inv, from->inv, sizeof(GLfloat)*16); } } } @@ -1529,7 +1529,7 @@ _math_matrix_copy(GLmatrix *to, const GLmatrix *from) void _math_matrix_loadf(GLmatrix *mat, const GLfloat *m) { - MEMCPY(mat->m, m, 16*sizeof(GLfloat)); + memcpy(mat->m, m, 16*sizeof(GLfloat)); mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY); } @@ -1545,7 +1545,7 @@ _math_matrix_ctr(GLmatrix *m) { m->m = (GLfloat *) ALIGN_MALLOC(16 * sizeof(GLfloat), 16); if (m->m) - MEMCPY(m->m, Identity, sizeof(Identity)); + memcpy(m->m, Identity, sizeof(Identity)); m->inv = NULL; m->type = MATRIX_IDENTITY; m->flags = 0; @@ -1584,7 +1584,7 @@ _math_matrix_alloc_inv(GLmatrix *m) if (!m->inv) { m->inv = (GLfloat *) ALIGN_MALLOC(16 * sizeof(GLfloat), 16); if (m->inv) - MEMCPY(m->inv, Identity, 16 * sizeof(GLfloat)); + memcpy(m->inv, Identity, 16 * sizeof(GLfloat)); } } diff --git a/src/other/libosmesa/src/math/m_translate.c b/src/other/libosmesa/src/math/m_translate.c index acca4009e0c..0ed9daf078f 100644 --- a/src/other/libosmesa/src/math/m_translate.c +++ b/src/other/libosmesa/src/math/m_translate.c @@ -556,13 +556,13 @@ static void trans_4_GLubyte_4ub_raw(GLubyte(*t)[4], static void init_translate_raw(void) { - MEMSET(TAB(_1ui), 0, sizeof(TAB(_1ui))); - MEMSET(TAB(_1ub), 0, sizeof(TAB(_1ub))); - MEMSET(TAB(_3fn), 0, sizeof(TAB(_3fn))); - MEMSET(TAB(_4ub), 0, sizeof(TAB(_4ub))); - MEMSET(TAB(_4us), 0, sizeof(TAB(_4us))); - MEMSET(TAB(_4f), 0, sizeof(TAB(_4f))); - MEMSET(TAB(_4fn), 0, sizeof(TAB(_4fn))); + memset(TAB(_1ui), 0, sizeof(TAB(_1ui))); + memset(TAB(_1ub), 0, sizeof(TAB(_1ub))); + memset(TAB(_3fn), 0, sizeof(TAB(_3fn))); + memset(TAB(_4ub), 0, sizeof(TAB(_4ub))); + memset(TAB(_4us), 0, sizeof(TAB(_4us))); + memset(TAB(_4f), 0, sizeof(TAB(_4f))); + memset(TAB(_4fn), 0, sizeof(TAB(_4fn))); init_trans_4_GLbyte_raw(); init_trans_3_GLbyte_raw(); diff --git a/src/other/libosmesa/src/math/m_translate.h b/src/other/libosmesa/src/math/m_translate.h index bffa2d0f3b7..42f28c27281 100644 --- a/src/other/libosmesa/src/math/m_translate.h +++ b/src/other/libosmesa/src/math/m_translate.h @@ -26,7 +26,7 @@ #ifndef _M_TRANSLATE_H_ #define _M_TRANSLATE_H_ -#include "config.h" +#include "gllimits.h" #include "mtypes.h" /* hack for GLchan */ diff --git a/src/other/libosmesa/src/math/m_xform.c b/src/other/libosmesa/src/math/m_xform.c index c6ff845f405..ed02e77c0e3 100644 --- a/src/other/libosmesa/src/math/m_xform.c +++ b/src/other/libosmesa/src/math/m_xform.c @@ -186,13 +186,7 @@ _math_init_transformation(void) _math_test_all_cliptest_functions("default"); #endif -#ifdef USE_X86_ASM - _mesa_init_all_x86_transform_asm(); -#elif defined( USE_SPARC_ASM ) - _mesa_init_all_sparc_transform_asm(); -#elif defined( USE_PPC_ASM ) - _mesa_init_all_ppc_transform_asm(); -#elif defined( USE_X86_64_ASM ) +#if defined( USE_X86_64_ASM ) _mesa_init_all_x86_64_transform_asm(); #endif } diff --git a/src/other/libosmesa/src/math/m_xform.h b/src/other/libosmesa/src/math/m_xform.h index 29bc2f33a64..31397b8ece9 100644 --- a/src/other/libosmesa/src/math/m_xform.h +++ b/src/other/libosmesa/src/math/m_xform.h @@ -28,17 +28,12 @@ #include "glheader.h" -#include "config.h" +#include "gllimits.h" #include "math/m_vector.h" #include "math/m_matrix.h" -#ifdef USE_X86_ASM -#define _XFORMAPI _ASMAPI -#define _XFORMAPIP _ASMAPIP -#else #define _XFORMAPI #define _XFORMAPIP * -#endif extern void diff --git a/src/other/libosmesa/src/shader/arbprogparse.c b/src/other/libosmesa/src/shader/arbprogparse.c index c86bab38044..d9473da5e1c 100644 --- a/src/other/libosmesa/src/shader/arbprogparse.c +++ b/src/other/libosmesa/src/shader/arbprogparse.c @@ -542,7 +542,7 @@ struct var_cache { static GLvoid var_cache_create(struct var_cache **va) { - *va = (struct var_cache *) _mesa_malloc(sizeof(struct var_cache)); + *va = (struct var_cache *) malloc(sizeof(struct var_cache)); if (*va) { (**va).name = NULL; (**va).type = vt_none; @@ -563,7 +563,7 @@ var_cache_destroy(struct var_cache **va) { if (*va) { var_cache_destroy(&(**va).next); - _mesa_free(*va); + free(*va); *va = NULL; } } @@ -583,7 +583,7 @@ var_cache_find(struct var_cache *va, const GLubyte * name) /*struct var_cache *first = va;*/ while (va) { - if (!_mesa_strcmp((const char*) name, (const char*) va->name)) { + if (!strcmp((const char*) name, (const char*) va->name)) { if (va->type == vt_alias) return va->alias_binding; return va; @@ -609,13 +609,13 @@ program_error(GLcontext *ctx, GLint position, const char *descrip) { if (descrip) { const char *prefix = "glProgramString(", *suffix = ")"; - char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + - _mesa_strlen(prefix) + - _mesa_strlen(suffix) + 1); + char *str = (char *) malloc(strlen(descrip) + + strlen(prefix) + + strlen(suffix) + 1); if (str) { _mesa_sprintf(str, "%s%s%s", prefix, descrip, suffix); _mesa_error(ctx, GL_INVALID_OPERATION, str); - _mesa_free(str); + free(str); } } _mesa_set_program_error(ctx, position, descrip); @@ -629,27 +629,26 @@ static void program_error2(GLcontext *ctx, GLint position, const char *descrip, const char *var) { - char *str = NULL; if (descrip) { const char *prefix = "glProgramString(", *suffix = ")"; - char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + - _mesa_strlen(": ") + - _mesa_strlen(var) + - _mesa_strlen(prefix) + - _mesa_strlen(suffix) + 1); + char *str = (char *) malloc(strlen(descrip) + + strlen(": ") + + strlen(var) + + strlen(prefix) + + strlen(suffix) + 1); if (str) { _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix); _mesa_error(ctx, GL_INVALID_OPERATION, str); - _mesa_free(str); + free(str); } - str = (char *) _mesa_malloc(_mesa_strlen(descrip) + - _mesa_strlen(": ") + - _mesa_strlen(var) + 1); + str = (char *) malloc(strlen(descrip) + + strlen(": ") + + strlen(var) + 1); if (str) { _mesa_sprintf(str, "%s: %s", descrip, var); _mesa_set_program_error(ctx, position, str); - _mesa_free(str); + free(str); } } } @@ -689,7 +688,7 @@ parse_string(const GLubyte ** inst, struct var_cache **vc_head, struct var_cache *va = NULL; (void) Program; - *inst += _mesa_strlen((char *) i) + 1; + *inst += strlen((char *) i) + 1; va = var_cache_find(*vc_head, i); @@ -713,7 +712,7 @@ parse_string_without_adding(const GLubyte ** inst, struct arb_program *Program) const GLubyte *i = *inst; (void) Program; - *inst += _mesa_strlen((char *) i) + 1; + *inst += strlen((char *) i) + 1; return (char *) i; } @@ -760,7 +759,7 @@ parse_integer(const GLubyte ** inst, struct arb_program *Program) } /* parse the integer as you normally would do it */ - value = _mesa_atoi(parse_string_without_adding(inst, Program)); + value = atoi(parse_string_without_adding(inst, Program)); /* now, after terminating 0 there is a position * to parse it - parse_position() @@ -823,7 +822,7 @@ parse_float(const GLubyte ** inst, struct arb_program *Program) /* Assemble parts of floating-point number: */ return (GLfloat)((whole + fraction / fracScale) * - _mesa_pow(10.0, (GLfloat) exponent)); + pow(10.0, (GLfloat) exponent)); } @@ -3378,7 +3377,7 @@ debug_variables(GLcontext * ctx, struct var_cache *vc_head, s = _mesa_program_state_string(Program->Base.Parameters->Parameters [a + b].StateIndexes); fprintf(stderr, "%s\n", s); - _mesa_free((char *) s); + free((char *) s); } else fprintf(stderr, "%f %f %f %f\n", Program->Base.Parameters->ParameterValues[a + b][0], @@ -3669,7 +3668,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, &parsed, &parsed_len); /* 'parsed' is unused here */ - _mesa_free(parsed); + free(parsed); parsed = NULL; /* NOTE: we can't destroy grammar_syn_id right here because @@ -3726,13 +3725,13 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, } /* copy the program string to a null-terminated string */ - strz = (GLubyte *) _mesa_malloc(len + 1); + strz = (GLubyte *) malloc(len + 1); if (!strz) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); grammar_destroy(arbprogram_syn_id); return GL_FALSE; } - _mesa_memcpy(strz, str, len); + memcpy(strz, str, len); strz[len] = '\0'; /* do a fast check on program string - initial production buffer is 4K */ @@ -3757,8 +3756,8 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, } while (0) #endif - _mesa_free(strz); - _mesa_free(parsed); + free(strz); + free(parsed); grammar_destroy(arbprogram_syn_id); return GL_FALSE; @@ -3814,7 +3813,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, /* We're done with the parsed binary array */ var_cache_destroy(&vc_head); - _mesa_free(parsed); + free(parsed); /* Reallocate the instruction array from size [MAX_INSTRUCTIONS] * to size [ap.Base.NumInstructions]. @@ -3871,7 +3870,7 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->UsesKill = ap.UsesKill; if (program->Base.Instructions) - _mesa_free(program->Base.Instructions); + free(program->Base.Instructions); program->Base.Instructions = ap.Base.Instructions; if (program->Base.Parameters) @@ -3924,7 +3923,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, program->IsPositionInvariant = ap.HintPositionInvariant; if (program->Base.Instructions) - _mesa_free(program->Base.Instructions); + free(program->Base.Instructions); program->Base.Instructions = ap.Base.Instructions; if (program->Base.Parameters) diff --git a/src/other/libosmesa/src/shader/arbprogram.c b/src/other/libosmesa/src/shader/arbprogram.c index 932de54675e..ef056c8d102 100644 --- a/src/other/libosmesa/src/shader/arbprogram.c +++ b/src/other/libosmesa/src/shader/arbprogram.c @@ -602,7 +602,7 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) switch (pname) { case GL_PROGRAM_LENGTH_ARB: *params - = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0; + = prog->String ? (GLint) strlen((char *) prog->String) : 0; return; case GL_PROGRAM_FORMAT_ARB: *params = prog->Format; @@ -777,7 +777,7 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) } if (prog->String) - _mesa_memcpy(dst, prog->String, _mesa_strlen((char *) prog->String)); + memcpy(dst, prog->String, strlen((char *) prog->String)); else *dst = '\0'; } diff --git a/src/other/libosmesa/src/shader/atifragshader.c b/src/other/libosmesa/src/shader/atifragshader.c index 57fdcdab67c..ebcbd14fd68 100644 --- a/src/other/libosmesa/src/shader/atifragshader.c +++ b/src/other/libosmesa/src/shader/atifragshader.c @@ -60,11 +60,11 @@ _mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s) GLuint i; for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { if (s->Instructions[i]) - _mesa_free(s->Instructions[i]); + free(s->Instructions[i]); if (s->SetupInst[i]) - _mesa_free(s->SetupInst[i]); + free(s->SetupInst[i]); } - _mesa_free(s); + free(s); } @@ -96,27 +96,27 @@ create_dst_mod_str(GLuint mod) { static char ret_str[1024]; - _mesa_memset(ret_str, 0, 1024); + memset(ret_str, 0, 1024); if (mod & GL_2X_BIT_ATI) - _mesa_strncat(ret_str, "|2X", 1024); + strncat(ret_str, "|2X", 1024); if (mod & GL_4X_BIT_ATI) - _mesa_strncat(ret_str, "|4X", 1024); + strncat(ret_str, "|4X", 1024); if (mod & GL_8X_BIT_ATI) - _mesa_strncat(ret_str, "|8X", 1024); + strncat(ret_str, "|8X", 1024); if (mod & GL_HALF_BIT_ATI) - _mesa_strncat(ret_str, "|HA", 1024); + strncat(ret_str, "|HA", 1024); if (mod & GL_QUARTER_BIT_ATI) - _mesa_strncat(ret_str, "|QU", 1024); + strncat(ret_str, "|QU", 1024); if (mod & GL_EIGHTH_BIT_ATI) - _mesa_strncat(ret_str, "|EI", 1024); + strncat(ret_str, "|EI", 1024); if (mod & GL_SATURATE_BIT_ATI) - _mesa_strncat(ret_str, "|SAT", 1024); + strncat(ret_str, "|SAT", 1024); - if (_mesa_strlen(ret_str) == 0) - _mesa_strncat(ret_str, "NONE", 1024); + if (strlen(ret_str) == 0) + strncat(ret_str, "NONE", 1024); return ret_str; } @@ -287,7 +287,7 @@ _mesa_DeleteFragmentShaderATI(GLuint id) if (prog && (prog != &DummyShader)) { prog->RefCount--; if (prog->RefCount <= 0) { - _mesa_free(prog); + free(prog); } } } @@ -312,9 +312,9 @@ _mesa_BeginFragmentShaderATI(void) /* no idea if it's allowed to redefine a shader */ for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { if (ctx->ATIFragmentShader.Current->Instructions[i]) - _mesa_free(ctx->ATIFragmentShader.Current->Instructions[i]); + free(ctx->ATIFragmentShader.Current->Instructions[i]); if (ctx->ATIFragmentShader.Current->SetupInst[i]) - _mesa_free(ctx->ATIFragmentShader.Current->SetupInst[i]); + free(ctx->ATIFragmentShader.Current->SetupInst[i]); } /* malloc the instructions here - not sure if the best place but its @@ -322,11 +322,11 @@ _mesa_BeginFragmentShaderATI(void) for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { ctx->ATIFragmentShader.Current->Instructions[i] = (struct atifs_instruction *) - _mesa_calloc(sizeof(struct atifs_instruction) * + calloc(1,sizeof(struct atifs_instruction) * (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI)); ctx->ATIFragmentShader.Current->SetupInst[i] = (struct atifs_setupinst *) - _mesa_calloc(sizeof(struct atifs_setupinst) * + calloc(1,sizeof(struct atifs_setupinst) * (MAX_NUM_FRAGMENT_REGISTERS_ATI)); } @@ -466,7 +466,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) curI->swizzle = swizzle; #if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, + _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__, _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord), _mesa_lookup_enum_by_nr(swizzle)); #endif @@ -539,7 +539,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) curI->swizzle = swizzle; #if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, + _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__, _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp), _mesa_lookup_enum_by_nr(swizzle)); #endif diff --git a/src/other/libosmesa/src/shader/grammar/grammar_mesa.c b/src/other/libosmesa/src/shader/grammar/grammar_mesa.c index ea8ed64aa0d..774d1faee2a 100644 --- a/src/other/libosmesa/src/shader/grammar/grammar_mesa.c +++ b/src/other/libosmesa/src/shader/grammar/grammar_mesa.c @@ -37,12 +37,12 @@ void grammar_alloc_free(void *ptr) { - _mesa_free(ptr); + free(ptr); } void *grammar_alloc_malloc(size_t size) { - return _mesa_malloc(size); + return malloc(size); } void *grammar_alloc_realloc(void *ptr, size_t old_size, size_t size) @@ -52,27 +52,27 @@ void *grammar_alloc_realloc(void *ptr, size_t old_size, size_t size) void *grammar_memory_copy(void *dst, const void * src, size_t size) { - return _mesa_memcpy(dst, src, size); + return memcpy(dst, src, size); } int grammar_string_compare(const byte *str1, const byte *str2) { - return _mesa_strcmp((const char *) str1, (const char *) str2); + return strcmp((const char *) str1, (const char *) str2); } int grammar_string_compare_n(const byte *str1, const byte *str2, size_t n) { - return _mesa_strncmp((const char *) str1, (const char *) str2, n); + return strncmp((const char *) str1, (const char *) str2, n); } byte *grammar_string_copy(byte *dst, const byte *src) { - return (byte *) _mesa_strcpy((char *) dst, (const char *) src); + return (byte *) strcpy((char *) dst, (const char *) src); } byte *grammar_string_copy_n(byte *dst, const byte *src, size_t n) { - return (byte *) _mesa_strncpy((char *) dst, (const char *) src, n); + return (byte *) strncpy((char *) dst, (const char *) src, n); } byte *grammar_string_duplicate(const byte *src) @@ -82,7 +82,7 @@ byte *grammar_string_duplicate(const byte *src) unsigned int grammar_string_length(const byte *str) { - return (unsigned int)_mesa_strlen((const char *) str); + return (unsigned int)strlen((const char *) str); } diff --git a/src/other/libosmesa/src/shader/nvfragparse.c b/src/other/libosmesa/src/shader/nvfragparse.c index ac4aac79d02..110df55e7ec 100644 --- a/src/other/libosmesa/src/shader/nvfragparse.c +++ b/src/other/libosmesa/src/shader/nvfragparse.c @@ -170,7 +170,7 @@ record_error(struct parse_state *parseState, const char *msg, int lineNo) _mesa_debug(parseState->ctx, "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", lineNo, line, column, (char *) lineStr, msg); - _mesa_free((void *) lineStr); + free((void *) lineStr); #else (void) lineNo; #endif @@ -217,7 +217,7 @@ static struct instruction_pattern struct instruction_pattern result = {NULL, (enum prog_opcode) -1, 0, 0, 0}; for (inst = Instructions; inst->name; inst++) { - if (_mesa_strncmp((const char *) token, inst->name, 3) == 0) { + if (strncmp((const char *) token, inst->name, 3) == 0) { /* matched! */ int i = 3; result = *inst; @@ -368,7 +368,7 @@ Peek_Token(struct parse_state *parseState, GLubyte *token) parseState->pos += (-i); return GL_FALSE; } - len = (GLint)_mesa_strlen((const char *) token); + len = (GLint)strlen((const char *) token); parseState->pos += (i - len); return GL_TRUE; } @@ -455,7 +455,7 @@ Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number) { char *end = NULL; - *number = (GLfloat) _mesa_strtod((const char *) parseState->pos, &end); + *number = (GLfloat) strtod((const char *) parseState->pos, &end); if (end && end > (char *) parseState->pos) { /* got a number */ @@ -585,7 +585,7 @@ Parse_TextureImageId(struct parse_state *parseState, imageSrc[2] != 'X') { RETURN_ERROR1("Expected TEX# source"); } - unit = _mesa_atoi((const char *) imageSrc + 3); + unit = atoi((const char *) imageSrc + 3); if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { RETURN_ERROR1("Invalied TEX# source index"); @@ -716,7 +716,7 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) RETURN_ERROR1("Expected R## or H##"); if (IsDigit(token[1])) { - GLint reg = _mesa_atoi((const char *)(token + 1)); + GLint reg = atoi((const char *)(token + 1)); if (token[0] == 'H') reg += 32; if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) @@ -764,7 +764,7 @@ Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) if (IsDigit(token[0])) { /* a numbered program parameter register */ - GLint reg = _mesa_atoi((const char *) token); + GLint reg = atoi((const char *) token); if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) RETURN_ERROR1("Invalid constant program number"); *regNum = reg; @@ -797,7 +797,7 @@ Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum) RETURN_ERROR; } for (j = 0; InputRegisters[j]; j++) { - if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { + if (strcmp((const char *) token, InputRegisters[j]) == 0) { *tempRegNum = j; parseState->inputsRead |= (1 << j); break; @@ -832,7 +832,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) /* try to match an output register name */ for (j = 0; OutputRegisters[j]; j++) { - if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { + if (strcmp((const char *) token, OutputRegisters[j]) == 0) { static GLuint bothColors = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_COLH); *outputRegNum = j; parseState->outputsWritten |= (1 << j); @@ -864,8 +864,8 @@ Parse_MaskedDstReg(struct parse_state *parseState, if (!Peek_Token(parseState, token)) RETURN_ERROR; - if (_mesa_strcmp((const char *) token, "RC") == 0 || - _mesa_strcmp((const char *) token, "HC") == 0) { + if (strcmp((const char *) token, "RC") == 0 || + strcmp((const char *) token, "HC") == 0) { /* a write-only register */ dstReg->File = PROGRAM_WRITE_ONLY; if (!Parse_DummyReg(parseState, &idx)) @@ -1199,9 +1199,9 @@ Parse_PrintInstruction(struct parse_state *parseState, for (len = 0; str[len] != '\''; len++) /* find closing quote */ ; parseState->pos += len + 1; - msg = (GLubyte*) _mesa_malloc(len + 1); + msg = (GLubyte*) malloc(len + 1); - _mesa_memcpy(msg, str, len); + memcpy(msg, str, len); msg[len] = 0; inst->Data = msg; @@ -1432,12 +1432,12 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, GLubyte *programString; /* Make a null-terminated copy of the program string */ - programString = (GLubyte *) MALLOC(len + 1); + programString = (GLubyte *) malloc(len + 1); if (!programString) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } - MEMCPY(programString, str, len); + memcpy(programString, str, len); programString[len] = 0; /* Get ready to parse */ @@ -1453,16 +1453,18 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, _mesa_set_program_error(ctx, -1, NULL); /* check the program header */ - if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) { + if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) { target = GL_FRAGMENT_PROGRAM_NV; parseState.pos = programString + 7; - } else if (_mesa_strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { + } else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { /* fragment / register combiner program - not supported */ + free(programString); _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); return; } else { /* invalid header */ + free(programString); _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); return; @@ -1470,6 +1472,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, /* make sure target and header match */ if (target != dstTarget) { + free(programString); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target mismatch 0x%x != 0x%x)", target, dstTarget); @@ -1499,12 +1502,12 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, /* install the program */ program->Base.Target = target; if (program->Base.String) { - FREE(program->Base.String); + free(program->Base.String); } program->Base.String = programString; program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; if (program->Base.Instructions) { - _mesa_free(program->Base.Instructions); + free(program->Base.Instructions); } program->Base.Instructions = newInst; program->Base.NumInstructions = parseState.numInst; diff --git a/src/other/libosmesa/src/shader/nvprogram.c b/src/other/libosmesa/src/shader/nvprogram.c index 93b77402da7..a20381f669a 100644 --- a/src/other/libosmesa/src/shader/nvprogram.c +++ b/src/other/libosmesa/src/shader/nvprogram.c @@ -253,7 +253,7 @@ _mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params) *params = prog->Target; return; case GL_PROGRAM_LENGTH_NV: - *params = prog->String ?(GLint)_mesa_strlen((char *) prog->String) : 0; + *params = prog->String ?(GLint)strlen((char *) prog->String) : 0; return; case GL_PROGRAM_RESIDENT_NV: *params = prog->Resident; @@ -291,7 +291,7 @@ _mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program) } if (prog->String) { - MEMCPY(program, prog->String, _mesa_strlen((char *) prog->String)); + memcpy(program, prog->String, strlen((char *) prog->String)); } else { program[0] = 0; } diff --git a/src/other/libosmesa/src/shader/nvvertparse.c b/src/other/libosmesa/src/shader/nvvertparse.c index e6481a32dc3..7d73f3ff7e3 100644 --- a/src/other/libosmesa/src/shader/nvvertparse.c +++ b/src/other/libosmesa/src/shader/nvvertparse.c @@ -81,7 +81,7 @@ record_error(struct parse_state *parseState, const char *msg, int lineNo) _mesa_debug(parseState->ctx, "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", lineNo, line, column, (char *) lineStr, msg); - _mesa_free((void *) lineStr); + free((void *) lineStr); #else (void) lineNo; #endif @@ -230,7 +230,7 @@ Peek_Token(struct parse_state *parseState, GLubyte *token) parseState->pos += (-i); return GL_FALSE; } - len = (GLint)_mesa_strlen((const char *) token); + len = (GLint)strlen((const char *) token); parseState->pos += (i - len); return GL_TRUE; } @@ -306,7 +306,7 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) RETURN_ERROR1("Expected R##"); if (IsDigit(token[1])) { - GLint reg = _mesa_atoi((char *)(token + 1)); + GLint reg = atoi((char *)(token + 1)); if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS) RETURN_ERROR1("Bad temporary register name"); *tempRegNum = reg; @@ -359,7 +359,7 @@ Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) if (IsDigit(token[0])) { /* a numbered program parameter register */ - GLint reg = _mesa_atoi((char *) token); + GLint reg = atoi((char *) token); if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) RETURN_ERROR1("Bad program parameter number"); *regNum = reg; @@ -392,12 +392,12 @@ Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg) /* a numbered program parameter register */ GLint reg; (void) Parse_Token(parseState, token); - reg = _mesa_atoi((char *) token); + reg = atoi((char *) token); if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) RETURN_ERROR1("Bad program parameter number"); srcReg->File = PROGRAM_ENV_PARAM; srcReg->Index = reg; - } else if (_mesa_strcmp((const char *) token, "A0") == 0) { + } else if (strcmp((const char *) token, "A0") == 0) { /* address register "A0.x" */ if (!Parse_AddrReg(parseState)) RETURN_ERROR; @@ -417,7 +417,7 @@ Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg) RETURN_ERROR; if (IsDigit(token[0])) { - const GLint k = _mesa_atoi((char *) token); + const GLint k = atoi((char *) token); if (sign == '-') { if (k > 64) RETURN_ERROR1("Bad address offset"); @@ -470,13 +470,13 @@ Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) RETURN_ERROR1("Only v[0] accessible in vertex state programs"); if (IsDigit(token[0])) { - GLint reg = _mesa_atoi((char *) token); + GLint reg = atoi((char *) token); if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS) RETURN_ERROR1("Bad vertex attribute register name"); *tempRegNum = reg; } else { for (j = 0; InputRegisters[j]; j++) { - if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { + if (strcmp((const char *) token, InputRegisters[j]) == 0) { *tempRegNum = j; break; } @@ -520,7 +520,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) /* try to match an output register name */ for (j = start; OutputRegisters[j]; j++) { - if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { + if (strcmp((const char *) token, OutputRegisters[j]) == 0) { *outputRegNum = j; break; } @@ -1027,9 +1027,9 @@ Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction * for (len = 0; str[len] != '\''; len++) /* find closing quote */ ; parseState->pos += len + 1; - msg = (GLubyte*) _mesa_malloc(len + 1); + msg = (GLubyte*) malloc(len + 1); - _mesa_memcpy(msg, str, len); + memcpy(msg, str, len); msg[len] = 0; inst->Data = msg; @@ -1241,12 +1241,12 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, GLubyte *programString; /* Make a null-terminated copy of the program string */ - programString = (GLubyte *) MALLOC(len + 1); + programString = (GLubyte *) malloc(len + 1); if (!programString) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } - MEMCPY(programString, str, len); + memcpy(programString, str, len); programString[len] = 0; /* Get ready to parse */ @@ -1263,28 +1263,30 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, _mesa_set_program_error(ctx, -1, NULL); /* check the program header */ - if (_mesa_strncmp((const char *) programString, "!!VP1.0", 7) == 0) { + if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) { target = GL_VERTEX_PROGRAM_NV; parseState.pos = programString + 7; parseState.isStateProgram = GL_FALSE; - } else if (_mesa_strncmp((const char *) programString, "!!VP1.1", 7) == 0) { + } else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) { target = GL_VERTEX_PROGRAM_NV; parseState.pos = programString + 7; parseState.isStateProgram = GL_FALSE; parseState.isVersion1_1 = GL_TRUE; - } else if (_mesa_strncmp((const char *) programString, "!!VSP1.0", 8) == 0) { + } else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) { target = GL_VERTEX_STATE_PROGRAM_NV; parseState.pos = programString + 8; parseState.isStateProgram = GL_TRUE; } else { /* invalid header */ ctx->Program.ErrorPos = 0; + free(programString); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); return; } /* make sure target and header match */ if (target != dstTarget) { + free(programString); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target mismatch)"); return; @@ -1315,7 +1317,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, newInst = _mesa_alloc_instructions(parseState.numInst); if (!newInst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - _mesa_free(programString); + free(programString); return; /* out of memory */ } _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); @@ -1323,12 +1325,12 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, /* install the program */ program->Base.Target = target; if (program->Base.String) { - _mesa_free(program->Base.String); + free(program->Base.String); } program->Base.String = programString; program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; if (program->Base.Instructions) { - _mesa_free(program->Base.Instructions); + free(program->Base.Instructions); } program->Base.Instructions = newInst; program->Base.InputsRead = parseState.inputsRead; diff --git a/src/other/libosmesa/src/shader/prog_debug.c b/src/other/libosmesa/src/shader/prog_debug.c index 15b78e50fe0..ad60f5c01dd 100644 --- a/src/other/libosmesa/src/shader/prog_debug.c +++ b/src/other/libosmesa/src/shader/prog_debug.c @@ -116,7 +116,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, /* make null-terminated copy of registerName */ len = MIN2((unsigned int) len, sizeof(reg) - 1); - _mesa_memcpy(reg, registerName, len); + memcpy(reg, registerName, len); reg[len] = 0; switch (target) { @@ -135,7 +135,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, /* GL_NV_vertex_program */ if (reg[0] == 'R') { /* Temp register */ - GLint i = _mesa_atoi(reg + 1); + GLint i = atoi(reg + 1); if (i >= (GLint)ctx->Const.VertexProgram.MaxTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); @@ -149,8 +149,8 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, const char *name = _mesa_nv_vertex_input_register_name(i); char number[10]; _mesa_sprintf(number, "%d", i); - if (_mesa_strncmp(reg + 2, name, 4) == 0 || - _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { + if (strncmp(reg + 2, name, 4) == 0 || + strncmp(reg + 2, number, strlen(number)) == 0) { ctx->Driver.GetProgramRegister(ctx, PROGRAM_INPUT, i, v); return; } @@ -162,7 +162,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, /* Vertex output attribute */ } /* GL_ARB_vertex_program */ - else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { + else if (strncmp(reg, "vertex.", 7) == 0) { } else { _mesa_error(ctx, GL_INVALID_VALUE, @@ -196,7 +196,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, } if (reg[0] == 'R') { /* Temp register */ - GLint i = _mesa_atoi(reg + 1); + GLint i = atoi(reg + 1); if (i >= (GLint)ctx->Const.FragmentProgram.MaxTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); @@ -209,7 +209,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, GLuint i; for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) { const char *name = _mesa_nv_fragment_input_register_name(i); - if (_mesa_strncmp(reg + 2, name, 4) == 0) { + if (strncmp(reg + 2, name, 4) == 0) { ctx->Driver.GetProgramRegister(ctx, PROGRAM_INPUT, i, v); return; } @@ -217,15 +217,15 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; - } else if (_mesa_strcmp(reg, "o[COLR]") == 0) { + } else if (strcmp(reg, "o[COLR]") == 0) { /* Fragment output color */ ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT, FRAG_RESULT_COLR, v); - } else if (_mesa_strcmp(reg, "o[COLH]") == 0) { + } else if (strcmp(reg, "o[COLH]") == 0) { /* Fragment output color */ ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT, FRAG_RESULT_COLH, v); - } else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { + } else if (strcmp(reg, "o[DEPR]") == 0) { /* Fragment output depth */ ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT, FRAG_RESULT_DEPR, v); diff --git a/src/other/libosmesa/src/shader/prog_execute.c b/src/other/libosmesa/src/shader/prog_execute.c index 3e3d85d03e4..892f9fc5ec8 100644 --- a/src/other/libosmesa/src/shader/prog_execute.c +++ b/src/other/libosmesa/src/shader/prog_execute.c @@ -64,9 +64,6 @@ #define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL #endif -#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits - - static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; @@ -584,7 +581,7 @@ _mesa_execute_program(GLcontext * ctx, GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_cos(a[0]); + = (GLfloat) cos(a[0]); store_vector4(inst, machine, result); } break; @@ -674,7 +671,7 @@ _mesa_execute_program(GLcontext * ctx, GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = - (GLfloat) _mesa_pow(2.0, a[0]); + (GLfloat) pow(2.0, a[0]); store_vector4(inst, machine, result); } break; @@ -1018,7 +1015,7 @@ _mesa_execute_program(GLcontext * ctx, fetch_vector1(&inst->SrcReg[0], machine, a); fetch_vector1(&inst->SrcReg[1], machine, b); result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_pow(a[0], b[0]); + = (GLfloat) pow(a[0], b[0]); store_vector4(inst, machine, result); } break; @@ -1071,8 +1068,8 @@ _mesa_execute_program(GLcontext * ctx, case OPCODE_SCS: { /* sine and cos */ GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = (GLfloat) _mesa_cos(a[0]); - result[1] = (GLfloat) _mesa_sin(a[0]); + result[0] = (GLfloat) cos(a[0]); + result[1] = (GLfloat) sin(a[0]); result[2] = 0.0; /* undefined! */ result[3] = 0.0; /* undefined! */ store_vector4(inst, machine, result); @@ -1138,7 +1135,7 @@ _mesa_execute_program(GLcontext * ctx, GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_sin(a[0]); + = (GLfloat) sin(a[0]); store_vector4(inst, machine, result); } break; diff --git a/src/other/libosmesa/src/shader/prog_instruction.c b/src/other/libosmesa/src/shader/prog_instruction.c index c3e46d4c994..bf4d806d4cd 100644 --- a/src/other/libosmesa/src/shader/prog_instruction.c +++ b/src/other/libosmesa/src/shader/prog_instruction.c @@ -69,7 +69,7 @@ struct prog_instruction * _mesa_alloc_instructions(GLuint numInst) { return (struct prog_instruction *) - _mesa_calloc(numInst * sizeof(struct prog_instruction)); + calloc(1,numInst * sizeof(struct prog_instruction)); } @@ -109,7 +109,7 @@ struct prog_instruction * const struct prog_instruction *src, GLuint n) { GLuint i; - _mesa_memcpy(dest, src, n * sizeof(struct prog_instruction)); + memcpy(dest, src, n * sizeof(struct prog_instruction)); for (i = 0; i < n; i++) { if (src[i].Comment) dest[i].Comment = _mesa_strdup(src[i].Comment); diff --git a/src/other/libosmesa/src/shader/prog_parameter.c b/src/other/libosmesa/src/shader/prog_parameter.c index 17547878d58..83b1cfd9820 100644 --- a/src/other/libosmesa/src/shader/prog_parameter.c +++ b/src/other/libosmesa/src/shader/prog_parameter.c @@ -53,12 +53,12 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList) GLuint i; for (i = 0; i < paramList->NumParameters; i++) { if (paramList->Parameters[i].Name) - _mesa_free((void *) paramList->Parameters[i].Name); + free((void *) paramList->Parameters[i].Name); } - _mesa_free(paramList->Parameters); + free(paramList->Parameters); if (paramList->ParameterValues) _mesa_align_free(paramList->ParameterValues); - _mesa_free(paramList); + free(paramList); } @@ -116,7 +116,7 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, paramList->NumParameters = oldNum + sz4; - _mesa_memset(¶mList->Parameters[oldNum], 0, + memset(¶mList->Parameters[oldNum], 0, sz4 * sizeof(struct gl_program_parameter)); for (i = 0; i < sz4; i++) { @@ -410,7 +410,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, paramList->StateFlags |= _mesa_program_state_flags(stateTokens); /* free name string here since we duplicated it in add_parameter() */ - _mesa_free((void *) name); + free((void *) name); return index; } @@ -450,15 +450,15 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, /* name is null-terminated */ for (i = 0; i < (GLint) paramList->NumParameters; i++) { if (paramList->Parameters[i].Name && - _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) + strcmp(paramList->Parameters[i].Name, name) == 0) return i; } } else { /* name is not null-terminated, use nameLen */ for (i = 0; i < (GLint) paramList->NumParameters; i++) { if (paramList->Parameters[i].Name && - _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 - && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) + strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 + && strlen(paramList->Parameters[i].Name) == (size_t)nameLen) return i; } } @@ -573,13 +573,15 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) ASSERT(j >= 0); /* copy state indexes */ if (p->Type == PROGRAM_STATE_VAR) { - GLint k; struct gl_program_parameter *q = clone->Parameters + j; - for (k = 0; k < STATE_LENGTH; k++) { - q->StateIndexes[k] = p->StateIndexes[k]; + if (q) { + for (GLint k = 0; k < STATE_LENGTH; k++) { + q->StateIndexes[k] = p->StateIndexes[k]; + } } } else { - clone->Parameters[j].Size = p->Size; + if (clone->Parameters) + clone->Parameters[j].Size = p->Size; } } @@ -599,7 +601,7 @@ _mesa_longest_parameter_name(const struct gl_program_parameter_list *list, return 0; for (i = 0; i < list->NumParameters; i++) { if (list->Parameters[i].Type == type) { - GLuint len = _mesa_strlen(list->Parameters[i].Name); + GLuint len = strlen(list->Parameters[i].Name); if (len > maxLen) maxLen = len; } diff --git a/src/other/libosmesa/src/shader/prog_print.c b/src/other/libosmesa/src/shader/prog_print.c index 1cf037dcbb8..9a7c46ab726 100644 --- a/src/other/libosmesa/src/shader/prog_print.c +++ b/src/other/libosmesa/src/shader/prog_print.c @@ -229,7 +229,7 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, struct gl_program_parameter *param = prog->Parameters->Parameters + index; const char *sstr = _mesa_program_state_string(param->StateIndexes); sprintf(str, "%s", sstr); - _mesa_free((void *)sstr); + free((void *)sstr); } break; case PROGRAM_ADDRESS: diff --git a/src/other/libosmesa/src/shader/prog_statevars.c b/src/other/libosmesa/src/shader/prog_statevars.c index 80fcc2f85d8..7e4cbc62029 100644 --- a/src/other/libosmesa/src/shader/prog_statevars.c +++ b/src/other/libosmesa/src/shader/prog_statevars.c @@ -676,7 +676,7 @@ append_index(char *dst, GLint index) /** * Make a string from the given state vector. * For example, return "state.matrix.texture[2].inverse". - * Use _mesa_free() to deallocate the string. + * Use free() to deallocate the string. */ const char * _mesa_program_state_string(const gl_state_index state[STATE_LENGTH]) @@ -828,7 +828,7 @@ static void load_transpose_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) { - MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat)); + memcpy(registers[pos], mat, 16 * sizeof(GLfloat)); } diff --git a/src/other/libosmesa/src/shader/program.c b/src/other/libosmesa/src/shader/program.c index bc32b942bdc..6378378cd1e 100644 --- a/src/other/libosmesa/src/shader/program.c +++ b/src/other/libosmesa/src/shader/program.c @@ -110,11 +110,11 @@ _mesa_free_program_data(GLcontext *ctx) if (ctx->ATIFragmentShader.Current) { ctx->ATIFragmentShader.Current->RefCount--; if (ctx->ATIFragmentShader.Current->RefCount <= 0) { - _mesa_free(ctx->ATIFragmentShader.Current); + free(ctx->ATIFragmentShader.Current); } } #endif - _mesa_free((void *) ctx->Program.ErrorString); + free((void *) ctx->Program.ErrorString); } @@ -128,7 +128,7 @@ void _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string) { ctx->Program.ErrorPos = pos; - _mesa_free((void *) ctx->Program.ErrorString); + free((void *) ctx->Program.ErrorString); if (!string) string = ""; ctx->Program.ErrorString = _mesa_strdup(string); @@ -138,7 +138,7 @@ _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string) /** * Find the line number and column for 'pos' within 'string'. * Return a copy of the line which contains 'pos'. Free the line with - * _mesa_free(). + * free(). * \param string the program string * \param pos the position within the string * \param line returns the line number corresponding to 'pos'. @@ -170,8 +170,8 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos, while (*p != 0 && *p != '\n') p++; len = p - lineStart; - s = (GLubyte *) _mesa_malloc(len + 1); - _mesa_memcpy(s, lineStart, len); + s = (GLubyte *) malloc(len + 1); + memcpy(s, lineStart, len); s[len] = 0; return s; @@ -273,17 +273,17 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) return; if (prog->String) - _mesa_free(prog->String); + free(prog->String); if (prog->Instructions) { GLuint i; for (i = 0; i < prog->NumInstructions; i++) { if (prog->Instructions[i].Data) - _mesa_free(prog->Instructions[i].Data); + free(prog->Instructions[i].Data); if (prog->Instructions[i].Comment) - _mesa_free((char *) prog->Instructions[i].Comment); + free((char *) prog->Instructions[i].Comment); } - _mesa_free(prog->Instructions); + free(prog->Instructions); } if (prog->Parameters) { @@ -300,10 +300,10 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) if (prog->Target == GL_VERTEX_PROGRAM_ARB) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; if (vprog->TnlData) - _mesa_free(vprog->TnlData); + free(vprog->TnlData); } - _mesa_free(prog); + free(prog); } diff --git a/src/other/libosmesa/src/shader/programopt.c b/src/other/libosmesa/src/shader/programopt.c index fd061ad7451..11bbb76e86b 100644 --- a/src/other/libosmesa/src/shader/programopt.c +++ b/src/other/libosmesa/src/shader/programopt.c @@ -102,7 +102,7 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) _mesa_copy_instructions(newInst + 4, vprog->Base.Instructions, origLen); /* free old instructions */ - _mesa_free(vprog->Base.Instructions); + free(vprog->Base.Instructions); /* install new instructions */ vprog->Base.Instructions = newInst; @@ -274,7 +274,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst++; /* free old instructions */ - _mesa_free(fprog->Base.Instructions); + free(fprog->Base.Instructions); /* install new instructions */ fprog->Base.Instructions = newInst; diff --git a/src/other/libosmesa/src/shader/shader_api.c b/src/other/libosmesa/src/shader/shader_api.c index bf7ce3eb02f..7468cb46528 100644 --- a/src/other/libosmesa/src/shader/shader_api.c +++ b/src/other/libosmesa/src/shader/shader_api.c @@ -131,12 +131,12 @@ _mesa_free_shader_program_data(GLcontext *ctx, shProg->NumShaders = 0; if (shProg->Shaders) { - _mesa_free(shProg->Shaders); + free(shProg->Shaders); shProg->Shaders = NULL; } if (shProg->InfoLog) { - _mesa_free(shProg->InfoLog); + free(shProg->InfoLog); shProg->InfoLog = NULL; } } @@ -150,7 +150,7 @@ _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) { _mesa_free_shader_program_data(ctx, shProg); - _mesa_free(shProg); + free(shProg); } @@ -246,16 +246,16 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) { GLuint i; if (sh->Source) - _mesa_free((void *) sh->Source); + free((void *) sh->Source); if (sh->InfoLog) - _mesa_free(sh->InfoLog); + free(sh->InfoLog); for (i = 0; i < sh->NumPrograms; i++) { assert(sh->Programs[i]); ctx->Driver.DeleteProgram(ctx, sh->Programs[i]); } if (sh->Programs) - _mesa_free(sh->Programs); - _mesa_free(sh); + free(sh->Programs); + free(sh); } @@ -633,7 +633,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) /* alloc new, smaller array */ newList = (struct gl_shader **) - _mesa_malloc((n - 1) * sizeof(struct gl_shader *)); + malloc((n - 1) * sizeof(struct gl_shader *)); if (!newList) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); return; @@ -643,7 +643,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) } while (++i < n) newList[j++] = shProg->Shaders[i]; - _mesa_free(shProg->Shaders); + free(shProg->Shaders); shProg->Shaders = newList; shProg->NumShaders = n - 1; @@ -1114,7 +1114,7 @@ _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source) /* free old shader source string and install new one */ if (sh->Source) { - _mesa_free((void *) sh->Source); + free((void *) sh->Source); } sh->Source = source; sh->CompileStatus = GL_FALSE; diff --git a/src/other/libosmesa/src/shader/slang/slang_codegen.c b/src/other/libosmesa/src/shader/slang/slang_codegen.c index 300497729b0..48adf2f6a7b 100644 --- a/src/other/libosmesa/src/shader/slang/slang_codegen.c +++ b/src/other/libosmesa/src/shader/slang/slang_codegen.c @@ -1246,7 +1246,7 @@ slang_find_asm_info(const char *name) { GLuint i; for (i = 0; AsmInfo[i].Name; i++) { - if (_mesa_strcmp(AsmInfo[i].Name, name) == 0) { + if (strcmp(AsmInfo[i].Name, name) == 0) { return AsmInfo + i; } } @@ -2995,7 +2995,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) slang_ir_node *n; GLboolean success = GL_TRUE; - if (_mesa_strcmp((char *) fun->header.a_name, "main") != 0) { + if (strcmp((char *) fun->header.a_name, "main") != 0) { /* we only really generate code for main, all other functions get * inlined. */ @@ -3082,7 +3082,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) /* free codegen context */ /* - _mesa_free(A->codegen); + free(A->codegen); */ return success; diff --git a/src/other/libosmesa/src/shader/slang/slang_compile.c b/src/other/libosmesa/src/shader/slang/slang_compile.c index 4a39a96809f..d4b872b638e 100644 --- a/src/other/libosmesa/src/shader/slang/slang_compile.c +++ b/src/other/libosmesa/src/shader/slang/slang_compile.c @@ -145,7 +145,7 @@ static void parse_identifier_str(slang_parse_ctx * C, char **id) { *id = (char *) C->I; - C->I += _mesa_strlen(*id) + 1; + C->I += strlen(*id) + 1; } static slang_atom @@ -154,7 +154,7 @@ parse_identifier(slang_parse_ctx * C) const char *id; id = (const char *) C->I; - C->I += _mesa_strlen(id) + 1; + C->I += strlen(id) + 1; return slang_atom_pool_atom(C->atoms, id); } @@ -192,9 +192,9 @@ parse_float(slang_parse_ctx * C, float *number) parse_identifier_str(C, &fractional); parse_identifier_str(C, &exponent); - whole = (char *) _slang_alloc((_mesa_strlen(integral) + - _mesa_strlen(fractional) + - _mesa_strlen(exponent) + 3) * sizeof(char)); + whole = (char *) _slang_alloc((strlen(integral) + + strlen(fractional) + + strlen(exponent) + 3) * sizeof(char)); if (whole == NULL) { slang_info_log_memory(C->L); return 0; @@ -206,7 +206,7 @@ parse_float(slang_parse_ctx * C, float *number) slang_string_concat(whole, "E"); slang_string_concat(whole, exponent); - *number = (float)(_mesa_strtod(whole, (char **) NULL)); + *number = (float)(strtod(whole, (char **) NULL)); _slang_free(whole); @@ -2139,7 +2139,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) /* free shader's prev info log */ if (shader->InfoLog) { - _mesa_free(shader->InfoLog); + free(shader->InfoLog); shader->InfoLog = NULL; } diff --git a/src/other/libosmesa/src/shader/slang/slang_compile_operation.c b/src/other/libosmesa/src/shader/slang/slang_compile_operation.c index 6adfe9aac28..3950f635209 100644 --- a/src/other/libosmesa/src/shader/slang/slang_compile_operation.c +++ b/src/other/libosmesa/src/shader/slang/slang_compile_operation.c @@ -208,9 +208,9 @@ slang_operation_insert(GLuint *numElements, slang_operation **array, slang_operation *newOp; newOp = ops + pos; if (pos > 0) - _mesa_memcpy(ops, *array, pos * sizeof(slang_operation)); + memcpy(ops, *array, pos * sizeof(slang_operation)); if (pos < *numElements) - _mesa_memcpy(newOp + 1, (*array) + pos, + memcpy(newOp + 1, (*array) + pos, (*numElements - pos) * sizeof(slang_operation)); if (!slang_operation_construct(newOp)) { diff --git a/src/other/libosmesa/src/shader/slang/slang_compile_variable.c b/src/other/libosmesa/src/shader/slang/slang_compile_variable.c index aeccc5acd7f..8366ba84953 100644 --- a/src/other/libosmesa/src/shader/slang/slang_compile_variable.c +++ b/src/other/libosmesa/src/shader/slang/slang_compile_variable.c @@ -280,7 +280,7 @@ slang_variable_destruct(slang_variable * var) } #if 0 if (var->aux) { - _mesa_free(var->aux); + free(var->aux); } #endif } diff --git a/src/other/libosmesa/src/shader/slang/slang_emit.c b/src/other/libosmesa/src/shader/slang/slang_emit.c index 33044ca87a5..86519e03276 100644 --- a/src/other/libosmesa/src/shader/slang/slang_emit.c +++ b/src/other/libosmesa/src/shader/slang/slang_emit.c @@ -173,7 +173,7 @@ free_temp_storage(slang_var_table *vt, slang_ir_node *n) _slang_free_temp(vt, n->Store); n->Store->Index = -1; n->Store->Size = -1; - /*_mesa_free(n->Store);*/ /* XXX leak */ + /*free(n->Store);*/ /* XXX leak */ n->Store = NULL; } } @@ -423,7 +423,7 @@ instruction_annotation(gl_inst_opcode opcode, char *dstAnnot, s = (char *) malloc(len); sprintf(s, "%s = %s %s %s %s", dstAnnot, srcAnnot0, operator, srcAnnot1, srcAnnot2); - assert(_mesa_strlen(s) < len); + assert(strlen(s) < len); free(dstAnnot); free(srcAnnot0); @@ -1748,7 +1748,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo) GLuint *subroutineLoc, i, total; subroutineLoc - = (GLuint *) _mesa_malloc(emitInfo->NumSubroutines * sizeof(GLuint)); + = (GLuint *) malloc(emitInfo->NumSubroutines * sizeof(GLuint)); /* total number of instructions */ total = mainP->NumInstructions; @@ -1786,7 +1786,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo) /* free subroutine list */ if (emitInfo->Subroutines) { - _mesa_free(emitInfo->Subroutines); + free(emitInfo->Subroutines); emitInfo->Subroutines = NULL; } emitInfo->NumSubroutines = 0; @@ -1805,7 +1805,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo) } } - _mesa_free(subroutineLoc); + free(subroutineLoc); } diff --git a/src/other/libosmesa/src/shader/slang/slang_label.c b/src/other/libosmesa/src/shader/slang/slang_label.c index cf2646a63ca..2674fe0c51b 100644 --- a/src/other/libosmesa/src/shader/slang/slang_label.c +++ b/src/other/libosmesa/src/shader/slang/slang_label.c @@ -32,9 +32,9 @@ _slang_label_new_unique(const char *name) static int id = 1; slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label)); if (l) { - l->Name = (char *) _slang_alloc(_mesa_strlen(name) + 10); + l->Name = (char *) _slang_alloc(strlen(name) + 10); if (!l->Name) { - _mesa_free(l); + free(l); return NULL; } _mesa_sprintf(l->Name, "%s_%d", name, id); diff --git a/src/other/libosmesa/src/shader/slang/slang_link.c b/src/other/libosmesa/src/shader/slang/slang_link.c index 1b83e500144..f736cbe3818 100644 --- a/src/other/libosmesa/src/shader/slang/slang_link.c +++ b/src/other/libosmesa/src/shader/slang/slang_link.c @@ -503,7 +503,7 @@ static void link_error(struct gl_shader_program *shProg, const char *msg) { if (shProg->InfoLog) { - _mesa_free(shProg->InfoLog); + free(shProg->InfoLog); } shProg->InfoLog = _mesa_strdup(msg); shProg->LinkStatus = GL_FALSE; diff --git a/src/other/libosmesa/src/shader/slang/slang_log.c b/src/other/libosmesa/src/shader/slang/slang_log.c index 0f8f51077a1..2d9bd68226f 100644 --- a/src/other/libosmesa/src/shader/slang/slang_log.c +++ b/src/other/libosmesa/src/shader/slang/slang_log.c @@ -45,7 +45,7 @@ slang_info_log_destruct(slang_info_log * log) #if 0 slang_alloc_free(log->text); #else - _mesa_free(log->text); + free(log->text); #endif } @@ -72,7 +72,7 @@ slang_info_log_message(slang_info_log * log, const char *prefix, #if 0 log->text = (char *)(slang_alloc_malloc(size)); #else - log->text = (char *)(_mesa_malloc(size)); + log->text = (char *)(malloc(size)); #endif if (log->text != NULL) log->text[0] = '\0'; @@ -95,7 +95,7 @@ slang_info_log_print(slang_info_log * log, const char *msg, ...) char buf[1024]; va_start(va, msg); - _mesa_vsprintf(buf, msg, va); + vsprintf(buf, msg, va); va_end(va); return slang_info_log_message(log, NULL, buf); } @@ -107,7 +107,7 @@ slang_info_log_error(slang_info_log * log, const char *msg, ...) char buf[1024]; va_start(va, msg); - _mesa_vsprintf(buf, msg, va); + vsprintf(buf, msg, va); va_end(va); log->error_flag = GL_TRUE; if (slang_info_log_message(log, "Error", buf)) @@ -123,7 +123,7 @@ slang_info_log_warning(slang_info_log * log, const char *msg, ...) char buf[1024]; va_start(va, msg); - _mesa_vsprintf(buf, msg, va); + vsprintf(buf, msg, va); va_end(va); if (slang_info_log_message(log, "Warning", buf)) return 1; diff --git a/src/other/libosmesa/src/shader/slang/slang_mem.c b/src/other/libosmesa/src/shader/slang/slang_mem.c index 7e98098335d..04df49b8950 100644 --- a/src/other/libosmesa/src/shader/slang/slang_mem.c +++ b/src/other/libosmesa/src/shader/slang/slang_mem.c @@ -55,12 +55,12 @@ struct slang_mempool_ { slang_mempool * _slang_new_mempool(GLuint initialSize) { - slang_mempool *pool = (slang_mempool *) _mesa_calloc(sizeof(slang_mempool)); + slang_mempool *pool = (slang_mempool *) calloc(1,sizeof(slang_mempool)); if (pool) { - pool->Data = (char *) _mesa_calloc(initialSize); + pool->Data = (char *) calloc(1,initialSize); /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/ if (!pool->Data) { - _mesa_free(pool); + free(pool); return NULL; } pool->Size = initialSize; @@ -81,8 +81,8 @@ _slang_delete_mempool(slang_mempool *pool) pool->Used, pool->Size, pool->Count, pool->Largest); */ total += pool->Used; - _mesa_free(pool->Data); - _mesa_free(pool); + free(pool->Data); + free(pool); pool = next; } /*printf("TOTAL ALLOCATED: %u\n", total);*/ @@ -124,7 +124,7 @@ void * _slang_alloc(GLuint bytes) { #if USE_MALLOC_FREE - return _mesa_calloc(bytes); + return calloc(1,bytes); #else slang_mempool *pool; GET_CURRENT_CONTEXT(ctx); @@ -194,7 +194,7 @@ _slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize) #endif if (newBuffer && oldBuffer && copySize > 0) - _mesa_memcpy(newBuffer, oldBuffer, copySize); + memcpy(newBuffer, oldBuffer, copySize); return newBuffer; } @@ -209,10 +209,10 @@ char * _slang_strdup(const char *s) { if (s) { - size_t l = _mesa_strlen(s); + size_t l = strlen(s); char *s2 = (char *) _slang_alloc(l + 1); if (s2) - _mesa_strcpy(s2, s); + strcpy(s2, s); return s2; } else { return NULL; @@ -227,7 +227,7 @@ void _slang_free(void *addr) { #if USE_MALLOC_FREE - _mesa_free(addr); + free(addr); #else if (addr) { //GET_CURRENT_CONTEXT(ctx); diff --git a/src/other/libosmesa/src/shader/slang/slang_preprocess.c b/src/other/libosmesa/src/shader/slang/slang_preprocess.c index 43759739377..0519beaa0e1 100644 --- a/src/other/libosmesa/src/shader/slang/slang_preprocess.c +++ b/src/other/libosmesa/src/shader/slang/slang_preprocess.c @@ -106,9 +106,9 @@ pp_annotate(slang_string *output, const char *fmt, ...) char buffer[1024]; va_start(va, fmt); - _mesa_vsprintf(buffer, fmt, va); + vsprintf(buffer, fmt, va); va_end(va); - slang_string_pushs(output, buffer, _mesa_strlen(buffer)); + slang_string_pushs(output, buffer, strlen(buffer)); #else (GLvoid)(output); (GLvoid)(fmt); @@ -204,8 +204,8 @@ execute_expression(slang_string *output, const byte *code, GLuint *pi, GLint *re switch (code[i++]) { case OP_PUSHINT: i++; - PUSH(_mesa_atoi((const char *)(&code[i]))); - i += _mesa_strlen((const char *)(&code[i])) + 1; + PUSH(atoi((const char *)(&code[i]))); + i += strlen((const char *)(&code[i])) + 1; break; case OP_LOGICALOR: BINARY(||); @@ -388,7 +388,7 @@ pp_symbols_free(pp_symbols *self) for (i = 0; i < self->count; i++) pp_symbol_free(&self->symbols[i]); - _mesa_free(self->symbols); + free(self->symbols); } static pp_symbol * @@ -410,7 +410,7 @@ pp_symbols_erase(pp_symbols *self, pp_symbol *symbol) self->count--; pp_symbol_free(symbol); if (symbol < self->symbols + self->count) - _mesa_memcpy(symbol, symbol + 1, sizeof(pp_symbol) * (self->symbols + self->count - symbol)); + memcpy(symbol, symbol + 1, sizeof(pp_symbol) * (self->symbols + self->count - symbol)); self->symbols = (pp_symbol *)(_mesa_realloc(self->symbols, (self->count + 1) * sizeof(pp_symbol), self->count * sizeof(pp_symbol))); return self->symbols != NULL; @@ -422,7 +422,7 @@ pp_symbols_find(pp_symbols *self, const char *name) GLuint i; for (i = 0; i < self->count; i++) - if (_mesa_strcmp(name, slang_string_cstr(&self->symbols[i].name)) == 0) + if (strcmp(name, slang_string_cstr(&self->symbols[i].name)) == 0) return &self->symbols[i]; return NULL; } @@ -501,9 +501,9 @@ pp_ext_init(pp_ext *self) static GLboolean pp_ext_set(pp_ext *self, const char *name, GLboolean enable) { - if (_mesa_strcmp(name, "MESA_shader_debug") == 0) + if (strcmp(name, "MESA_shader_debug") == 0) self->MESA_shader_debug = enable; - else if (_mesa_strcmp(name, "GL_ARB_texture_rectangle") == 0) + else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) self->ARB_texture_rectangle = enable; /* Next extension name tests go here. */ else @@ -702,18 +702,18 @@ expand(expand_state *e, pp_symbols *symbols) * actually an operator that we must handle here and expand it either to " 0 " or " 1 ". * The other identifiers start with "__" and we expand it to appropriate values * taken from the preprocessor state. */ - if (_mesa_strcmp(id, "defined") == 0) { + if (strcmp(id, "defined") == 0) { if (!expand_defined(e, &buffer)) return GL_FALSE; - } else if (_mesa_strcmp(id, "__LINE__") == 0) { + } else if (strcmp(id, "__LINE__") == 0) { slang_string_pushc(e->output, ' '); slang_string_pushi(e->output, e->state->line); slang_string_pushc(e->output, ' '); - } else if (_mesa_strcmp(id, "__FILE__") == 0) { + } else if (strcmp(id, "__FILE__") == 0) { slang_string_pushc(e->output, ' '); slang_string_pushi(e->output, e->state->file); slang_string_pushc(e->output, ' '); - } else if (_mesa_strcmp(id, "__VERSION__") == 0) { + } else if (strcmp(id, "__VERSION__") == 0) { slang_string_pushc(e->output, ' '); slang_string_pushi(e->output, e->state->version); slang_string_pushc(e->output, ' '); @@ -755,7 +755,7 @@ parse_if(slang_string *output, const byte *prod, GLuint *pi, GLint *result, pp_s GLuint len; text = (const char *)(&prod[*pi]); - len = _mesa_strlen(text); + len = strlen(text); if (state->cond.top->effective) { slang_string expr; @@ -882,7 +882,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar /* Parse macro name. */ id = (const char *)(&prod[i]); - idlen = _mesa_strlen(id); + idlen = strlen(id); if (state.cond.top->effective) { pp_annotate(output, "// #define %s(", id); @@ -905,7 +905,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar pp_symbol *param; id = (const char *)(&prod[i]); - idlen = _mesa_strlen(id); + idlen = strlen(id); pp_annotate(output, "%s, ", id); param = pp_symbols_push(&symbol->parameters); if (param == NULL) @@ -917,7 +917,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar /* Parse macro replacement. */ id = (const char *)(&prod[i]); - idlen = _mesa_strlen(id); + idlen = strlen(id); if (state.cond.top->effective) { pp_annotate(output, ") %s", id); slang_string_pushs(&symbol->replacement, id, idlen); @@ -928,7 +928,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case TOKEN_UNDEF: id = (const char *)(&prod[i]); - i += _mesa_strlen(id) + 1; + i += strlen(id) + 1; if (state.cond.top->effective) { pp_symbol *symbol; @@ -1017,7 +1017,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case TOKEN_EXTENSION: /* Parse the extension name. */ id = (const char *)(&prod[i]); - i += _mesa_strlen(id) + 1; + i += strlen(id) + 1; if (state.cond.top->effective) pp_annotate(output, "// #extension %s: ", id); @@ -1028,7 +1028,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case BEHAVIOR_REQUIRE: pp_annotate(output, "require"); if (!pp_ext_set(&state.ext, id, GL_TRUE)) { - if (_mesa_strcmp(id, "all") == 0) { + if (strcmp(id, "all") == 0) { slang_info_log_error(elog, "require: bad behavior for #extension all."); goto error; } else { @@ -1041,7 +1041,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case BEHAVIOR_ENABLE: pp_annotate(output, "enable"); if (!pp_ext_set(&state.ext, id, GL_TRUE)) { - if (_mesa_strcmp(id, "all") == 0) { + if (strcmp(id, "all") == 0) { slang_info_log_error(elog, "enable: bad behavior for #extension all."); goto error; } else { @@ -1053,7 +1053,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case BEHAVIOR_WARN: pp_annotate(output, "warn"); if (!pp_ext_set(&state.ext, id, GL_TRUE)) { - if (_mesa_strcmp(id, "all") != 0) { + if (strcmp(id, "all") != 0) { slang_info_log_warning(elog, "%s: enabled extension is not supported.", id); } } @@ -1062,7 +1062,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case BEHAVIOR_DISABLE: pp_annotate(output, "disable"); if (!pp_ext_set(&state.ext, id, GL_FALSE)) { - if (_mesa_strcmp(id, "all") == 0) { + if (strcmp(id, "all") == 0) { pp_ext_disable_all(&state.ext); } else { slang_info_log_warning(elog, "%s: disabled extension is not supported.", id); @@ -1078,7 +1078,7 @@ preprocess_source(slang_string *output, const char *source, grammar pid, grammar case TOKEN_LINE: id = (const char *)(&prod[i]); - i += _mesa_strlen(id) + 1; + i += strlen(id) + 1; if (state.cond.top->effective) { slang_string buffer; diff --git a/src/other/libosmesa/src/shader/slang/slang_print.c b/src/other/libosmesa/src/shader/slang/slang_print.c index ce0b3ff84cb..902542f7847 100644 --- a/src/other/libosmesa/src/shader/slang/slang_print.c +++ b/src/other/libosmesa/src/shader/slang/slang_print.c @@ -625,7 +625,7 @@ slang_print_function(const slang_function *f, GLboolean body) int i; #if 0 - if (_mesa_strcmp((char *) f->header.a_name, "main") != 0) + if (strcmp((char *) f->header.a_name, "main") != 0) return; #endif diff --git a/src/other/libosmesa/src/shader/slang/slang_utility.c b/src/other/libosmesa/src/shader/slang/slang_utility.c index 6d407c6958a..e22e35c565b 100644 --- a/src/other/libosmesa/src/shader/slang/slang_utility.c +++ b/src/other/libosmesa/src/shader/slang/slang_utility.c @@ -35,7 +35,7 @@ char * slang_string_concat(char *dst, const char *src) { - return _mesa_strcpy(dst + _mesa_strlen(dst), src); + return strcpy(dst + strlen(dst), src); } @@ -54,7 +54,7 @@ GLvoid slang_string_free(slang_string *self) { if (self->data != NULL) - _mesa_free(self->data); + free(self->data); } GLvoid @@ -92,7 +92,7 @@ slang_string_push(slang_string *self, const slang_string *str) return; } if (grow(self, self->length + str->length)) { - _mesa_memcpy(&self->data[self->length], str->data, str->length); + memcpy(&self->data[self->length], str->data, str->length); self->length += str->length; } } @@ -110,7 +110,7 @@ GLvoid slang_string_pushs(slang_string *self, const char *cstr, GLuint len) { if (grow(self, self->length + len)) { - _mesa_memcpy(&self->data[self->length], cstr, len); + memcpy(&self->data[self->length], cstr, len); self->length += len; } } diff --git a/src/other/libosmesa/src/shader/slang/slang_utility.h b/src/other/libosmesa/src/shader/slang/slang_utility.h index f8741aa3598..f9904261e12 100644 --- a/src/other/libosmesa/src/shader/slang/slang_utility.h +++ b/src/other/libosmesa/src/shader/slang/slang_utility.h @@ -33,9 +33,9 @@ # define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0) #endif -#define slang_string_compare(str1, str2) _mesa_strcmp (str1, str2) -#define slang_string_copy(dst, src) _mesa_strcpy (dst, src) -#define slang_string_length(str) _mesa_strlen (str) +#define slang_string_compare(str1, str2) strcmp (str1, str2) +#define slang_string_copy(dst, src) strcpy (dst, src) +#define slang_string_length(str) strlen (str) char *slang_string_concat(char *, const char *); diff --git a/src/other/libosmesa/src/swrast/s_blend.c b/src/other/libosmesa/src/swrast/s_blend.c index bf8a8beb27b..07b2222f66c 100644 --- a/src/other/libosmesa/src/swrast/s_blend.c +++ b/src/other/libosmesa/src/swrast/s_blend.c @@ -81,7 +81,7 @@ blend_noop(GLcontext *ctx, GLuint n, const GLubyte mask[], else bytes = 4 * n * sizeof(GLfloat); - _mesa_memcpy(src, dst, bytes); + memcpy(src, dst, bytes); } @@ -791,7 +791,7 @@ static void blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[], void *src, const void *dst, GLenum chanType) { - GLfloat rgbaF[MAX_WIDTH][4] = {0.0}, destF[MAX_WIDTH][4] = {0.0}; + GLfloat rgbaF[MAX_WIDTH][4] = {{0.0}}, destF[MAX_WIDTH][4] = {{0.0}}; if (chanType == GL_UNSIGNED_BYTE) { GLubyte(*rgba)[4] = (GLubyte(*)[4]) src; diff --git a/src/other/libosmesa/src/swrast/s_blit.c b/src/other/libosmesa/src/swrast/s_blit.c index 36ab602d063..6bc9361fd24 100644 --- a/src/other/libosmesa/src/swrast/s_blit.c +++ b/src/other/libosmesa/src/swrast/s_blit.c @@ -196,14 +196,14 @@ blit_nearest(GLcontext *ctx, } /* allocate the src/dst row buffers */ - srcBuffer = _mesa_malloc(pixelSize * srcWidth); + srcBuffer = malloc(pixelSize * srcWidth); if (!srcBuffer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; } - dstBuffer = _mesa_malloc(pixelSize * dstWidth); + dstBuffer = malloc(pixelSize * dstWidth); if (!dstBuffer) { - _mesa_free(srcBuffer); + free(srcBuffer); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; } @@ -233,8 +233,8 @@ blit_nearest(GLcontext *ctx, drawRb->PutRow(ctx, drawRb, dstWidth, dstXpos, dstY, dstBuffer, NULL); } - _mesa_free(srcBuffer); - _mesa_free(dstBuffer); + free(srcBuffer); + free(dstBuffer); } @@ -364,21 +364,21 @@ blit_linear(GLcontext *ctx, /* Allocate the src/dst row buffers. * Keep two adjacent src rows around for bilinear sampling. */ - srcBuffer0 = _mesa_malloc(pixelSize * srcWidth); + srcBuffer0 = malloc(pixelSize * srcWidth); if (!srcBuffer0) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; } - srcBuffer1 = _mesa_malloc(pixelSize * srcWidth); + srcBuffer1 = malloc(pixelSize * srcWidth); if (!srcBuffer1) { - _mesa_free(srcBuffer0); + free(srcBuffer0); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; } - dstBuffer = _mesa_malloc(pixelSize * dstWidth); + dstBuffer = malloc(pixelSize * dstWidth); if (!dstBuffer) { - _mesa_free(srcBuffer0); - _mesa_free(srcBuffer1); + free(srcBuffer0); + free(srcBuffer1); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; } @@ -439,9 +439,9 @@ blit_linear(GLcontext *ctx, drawRb->PutRow(ctx, drawRb, dstWidth, dstXpos, dstY, dstBuffer, NULL); } - _mesa_free(srcBuffer0); - _mesa_free(srcBuffer1); - _mesa_free(dstBuffer); + free(srcBuffer0); + free(srcBuffer1); + free(dstBuffer); } @@ -529,7 +529,7 @@ simple_blit(GLcontext *ctx, } /* allocate the row buffer */ - rowBuffer = _mesa_malloc(bytesPerRow); + rowBuffer = malloc(bytesPerRow); if (!rowBuffer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); return; @@ -542,7 +542,7 @@ simple_blit(GLcontext *ctx, dstY += yStep; } - _mesa_free(rowBuffer); + free(rowBuffer); } diff --git a/src/other/libosmesa/src/swrast/s_context.c b/src/other/libosmesa/src/swrast/s_context.c index 8645254f7a4..aad81c95f7a 100644 --- a/src/other/libosmesa/src/swrast/s_context.c +++ b/src/other/libosmesa/src/swrast/s_context.c @@ -747,7 +747,7 @@ GLboolean _swrast_CreateContext(GLcontext *ctx) { GLuint i; - SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); + SWcontext *swrast = (SWcontext *)calloc(1,sizeof(SWcontext)); if (SWRAST_DEBUG) { _mesa_debug(ctx, "_swrast_CreateContext\n"); @@ -784,7 +784,7 @@ _swrast_CreateContext(GLcontext *ctx) swrast->SpanArrays = MALLOC_STRUCT(sw_span_arrays); if (!swrast->SpanArrays) { - FREE(swrast); + free(swrast); return GL_FALSE; } swrast->SpanArrays->ChanType = CHAN_TYPE; @@ -805,11 +805,11 @@ _swrast_CreateContext(GLcontext *ctx) swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; - swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureImageUnits * + swrast->TexelBuffer = (GLchan *) malloc(ctx->Const.MaxTextureImageUnits * MAX_WIDTH * 4 * sizeof(GLchan)); if (!swrast->TexelBuffer) { - FREE(swrast->SpanArrays); - FREE(swrast); + free(swrast->SpanArrays); + free(swrast); return GL_FALSE; } @@ -827,11 +827,11 @@ _swrast_DestroyContext(GLcontext *ctx) _mesa_debug(ctx, "_swrast_DestroyContext\n"); } - FREE(swrast->SpanArrays); + free(swrast->SpanArrays); if (swrast->ZoomedArrays) - FREE(swrast->ZoomedArrays); - FREE(swrast->TexelBuffer); - FREE(swrast); + free(swrast->ZoomedArrays); + free(swrast->TexelBuffer); + free(swrast); ctx->swrast_context = 0; } diff --git a/src/other/libosmesa/src/swrast/s_copypix.c b/src/other/libosmesa/src/swrast/s_copypix.c index fa84d903426..f0470c54680 100644 --- a/src/other/libosmesa/src/swrast/s_copypix.c +++ b/src/other/libosmesa/src/swrast/s_copypix.c @@ -110,14 +110,14 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, _swrast_span_default_secondary_color(ctx, &span); /* allocate space for GLfloat image */ - tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + tmpImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; } - convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + convImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!convImage) { - _mesa_free(tmpImage); + free(tmpImage); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; } @@ -145,7 +145,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); } - _mesa_free(tmpImage); + free(tmpImage); /* do remaining post-convolution image transfer ops */ for (row = 0; row < height; row++) { @@ -162,7 +162,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLvoid *rgba = (GLvoid *) span.array->attribs[FRAG_ATTRIB_COL0]; /* copy convolved colors into span array */ - _mesa_memcpy(rgba, src, width * 4 * sizeof(GLfloat)); + memcpy(rgba, src, width * 4 * sizeof(GLfloat)); /* write span */ span.x = destx; @@ -179,7 +179,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, span.array->ChanType = CHAN_TYPE; } - _mesa_free(convImage); + free(convImage); } @@ -251,7 +251,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, _swrast_span_default_secondary_color(ctx, &span); if (overlapping) { - tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4); + tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; @@ -277,7 +277,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* Get row/span of source pixels */ if (overlapping) { /* get from buffered image */ - _mesa_memcpy(rgba, p, width * sizeof(GLfloat) * 4); + memcpy(rgba, p, width * sizeof(GLfloat) * 4); p += width * 4; } else { /* get from framebuffer */ @@ -305,7 +305,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, span.array->ChanType = CHAN_TYPE; /* restore */ if (overlapping) - _mesa_free(tmpImage); + free(tmpImage); } @@ -355,7 +355,7 @@ copy_ci_pixels(GLcontext *ctx, GLint srcx, GLint srcy, if (overlapping) { GLint ssy = sy; - tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); + tmpImage = (GLuint *) malloc(width * height * sizeof(GLuint)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; @@ -376,7 +376,7 @@ copy_ci_pixels(GLcontext *ctx, GLint srcx, GLint srcy, for (j = 0; j < height; j++, sy += stepy, dy += stepy) { /* Get color indexes */ if (overlapping) { - _mesa_memcpy(span.array->index, p, width * sizeof(GLuint)); + memcpy(span.array->index, p, width * sizeof(GLuint)); p += width; } else { _swrast_read_index_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, @@ -398,7 +398,7 @@ copy_ci_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (overlapping) - _mesa_free(tmpImage); + free(tmpImage); } @@ -495,7 +495,7 @@ copy_depth_pixels(GLcontext *ctx, GLint srcx, GLint srcy, if (overlapping) { GLint ssy = sy; - tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat)); + tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; @@ -515,7 +515,7 @@ copy_depth_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLfloat depth[MAX_WIDTH]; /* get depth values */ if (overlapping) { - _mesa_memcpy(depth, p, width * sizeof(GLfloat)); + memcpy(depth, p, width * sizeof(GLfloat)); p += width; } else { _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth); @@ -542,7 +542,7 @@ copy_depth_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (overlapping) - _mesa_free(tmpImage); + free(tmpImage); } @@ -587,7 +587,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, if (overlapping) { GLint ssy = sy; - tmpImage = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil)); + tmpImage = (GLstencil *) malloc(width * height * sizeof(GLstencil)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; @@ -608,7 +608,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* Get stencil values */ if (overlapping) { - _mesa_memcpy(stencil, p, width * sizeof(GLstencil)); + memcpy(stencil, p, width * sizeof(GLstencil)); p += width; } else { _swrast_read_stencil_span(ctx, rb, width, srcx, sy, stencil); @@ -626,7 +626,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (overlapping) - _mesa_free(tmpImage); + free(tmpImage); } @@ -686,7 +686,7 @@ copy_depth_stencil_pixels(GLcontext *ctx, if (stencilMask != 0x0) { tempStencilImage - = (GLstencil *) _mesa_malloc(width * height * sizeof(GLstencil)); + = (GLstencil *) malloc(width * height * sizeof(GLstencil)); if (!tempStencilImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); return; @@ -704,10 +704,10 @@ copy_depth_stencil_pixels(GLcontext *ctx, if (ctx->Depth.Mask) { tempDepthImage - = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat)); + = (GLfloat *) malloc(width * height * sizeof(GLfloat)); if (!tempDepthImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); - _mesa_free(tempStencilImage); + free(tempStencilImage); return; } @@ -728,7 +728,7 @@ copy_depth_stencil_pixels(GLcontext *ctx, /* Get stencil values */ if (overlapping) { - _mesa_memcpy(stencil, stencilPtr, width * sizeof(GLstencil)); + memcpy(stencil, stencilPtr, width * sizeof(GLstencil)); stencilPtr += width; } else { _swrast_read_stencil_span(ctx, stencilReadRb, @@ -754,8 +754,8 @@ copy_depth_stencil_pixels(GLcontext *ctx, GLuint zBytes; /* get depth values */ - if (overlapping) { - _mesa_memcpy(depth, depthPtr, width * sizeof(GLfloat)); + if (overlapping && depthPtr) { + memcpy(depth, depthPtr, width * sizeof(GLfloat)); depthPtr += width; } else { _swrast_read_depth_span_float(ctx, depthReadRb, @@ -792,10 +792,10 @@ copy_depth_stencil_pixels(GLcontext *ctx, } if (tempStencilImage) - _mesa_free(tempStencilImage); + free(tempStencilImage); if (tempDepthImage) - _mesa_free(tempDepthImage); + free(tempDepthImage); } diff --git a/src/other/libosmesa/src/swrast/s_depth.c b/src/other/libosmesa/src/swrast/s_depth.c index 88d5d217b76..4073e842aae 100644 --- a/src/other/libosmesa/src/swrast/s_depth.c +++ b/src/other/libosmesa/src/swrast/s_depth.c @@ -1293,7 +1293,7 @@ _swrast_clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) /* optimized case */ GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y); GLuint len = width * height * sizeof(GLushort); - _mesa_memset(dst, (clearValue & 0xff), len); + memset(dst, (clearValue & 0xff), len); } else { /* general case */ GLint i, j; diff --git a/src/other/libosmesa/src/swrast/s_drawpix.c b/src/other/libosmesa/src/swrast/s_drawpix.c index 0cd650f259c..069b8b73dba 100644 --- a/src/other/libosmesa/src/swrast/s_drawpix.c +++ b/src/other/libosmesa/src/swrast/s_drawpix.c @@ -473,7 +473,7 @@ draw_depth_pixels(GLcontext *ctx, GLint x, GLint y, _mesa_image_address2d(unpack, pixels, width, height, GL_DEPTH_COMPONENT, type, row, 0); if (shift == 0) { - _mesa_memcpy(span.array->z, zSrc, width * sizeof(GLuint)); + memcpy(span.array->z, zSrc, width * sizeof(GLuint)); } else { GLint col; for (col = 0; col < width; col++) @@ -565,14 +565,14 @@ draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, GLint row; GLfloat *dest, *tmpImage; - tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + tmpImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); return; } - convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + convImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!convImage) { - _mesa_free(tmpImage); + free(tmpImage); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); return; } @@ -595,7 +595,7 @@ draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); } - _mesa_free(tmpImage); + free(tmpImage); /* continue transfer ops and draw the convolved image */ unpack = &ctx->DefaultPacking; @@ -673,7 +673,7 @@ draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, } if (convImage) { - _mesa_free(convImage); + free(convImage); } } diff --git a/src/other/libosmesa/src/swrast/s_linetemp.h b/src/other/libosmesa/src/swrast/s_linetemp.h index c8290bad907..48763a257f6 100644 --- a/src/other/libosmesa/src/swrast/s_linetemp.h +++ b/src/other/libosmesa/src/swrast/s_linetemp.h @@ -114,7 +114,7 @@ NAME(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1) } /* - printf("%s():\n", __FUNCTION__); + printf("%s():\n", __func__); printf(" (%f, %f, %f) -> (%f, %f, %f)\n", vert0->win[0], vert0->win[1], vert0->win[2], vert1->win[0], vert1->win[1], vert1->win[2]); diff --git a/src/other/libosmesa/src/swrast/s_readpix.c b/src/other/libosmesa/src/swrast/s_readpix.c index 84fd0f79371..1ac33c474d6 100644 --- a/src/other/libosmesa/src/swrast/s_readpix.c +++ b/src/other/libosmesa/src/swrast/s_readpix.c @@ -342,14 +342,14 @@ read_rgba_pixels(GLcontext *ctx, GLfloat *dest, *src, *tmpImage, *convImage; GLint row; - tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + tmpImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } - convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); + convImage = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); if (!convImage) { - _mesa_free(tmpImage); + free(tmpImage); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } @@ -381,7 +381,7 @@ read_rgba_pixels(GLcontext *ctx, ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); } - _mesa_free(tmpImage); + free(tmpImage); /* finish transfer ops and pack the resulting image */ src = convImage; @@ -394,7 +394,7 @@ read_rgba_pixels(GLcontext *ctx, transferOps & IMAGE_POST_CONVOLUTION_BITS); src += width * 4; } - _mesa_free(convImage); + free(convImage); } else { /* no convolution */ const GLint dstStride diff --git a/src/other/libosmesa/src/swrast/s_span.c b/src/other/libosmesa/src/swrast/s_span.c index 68aa48bbbfb..fa7fdfffe30 100644 --- a/src/other/libosmesa/src/swrast/s_span.c +++ b/src/other/libosmesa/src/swrast/s_span.c @@ -916,7 +916,7 @@ _swrast_write_index_span(GLcontext *ctx, SWspan *span) /* mask was initialized by caller, probably glBitmap */ span->writeAll = GL_FALSE; } else { - _mesa_memset(span->array->mask, 1, span->end); + memset(span->array->mask, 1, span->end); span->writeAll = GL_TRUE; } @@ -1029,7 +1029,7 @@ _swrast_write_index_span(GLcontext *ctx, SWspan *span) if (numDrawBuffers > 1) { /* save indexes for second, third renderbuffer writes */ - _mesa_memcpy(indexSave, span->array->index, + memcpy(indexSave, span->array->index, span->end * sizeof(indexSave[0])); } @@ -1106,7 +1106,7 @@ _swrast_write_index_span(GLcontext *ctx, SWspan *span) if (buf + 1 < numDrawBuffers) { /* restore original span values */ - _mesa_memcpy(span->array->index, indexSave, + memcpy(span->array->index, indexSave, span->end * sizeof(indexSave[0])); } } /* for buf */ @@ -1359,7 +1359,7 @@ _swrast_write_rgba_span(GLcontext *ctx, SWspan *span) GLboolean deferredTexture; /* - printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, + printf("%s() interp 0x%x array 0x%x\n", __func__, span->interpMask, span->arrayMask); */ @@ -1404,7 +1404,7 @@ _swrast_write_rgba_span(GLcontext *ctx, SWspan *span) /* mask was initialized by caller, probably glBitmap */ span->writeAll = GL_FALSE; } else { - _mesa_memset(span->array->mask, 1, span->end); + memset(span->array->mask, 1, span->end); span->writeAll = GL_TRUE; } @@ -1558,7 +1558,7 @@ _swrast_write_rgba_span(GLcontext *ctx, SWspan *span) if (numDrawBuffers > 1) { /* save colors for second, third renderbuffer writes */ - _mesa_memcpy(rgbaSave, span->array->rgba, + memcpy(rgbaSave, span->array->rgba, 4 * span->end * sizeof(GLchan)); } @@ -1593,7 +1593,7 @@ _swrast_write_rgba_span(GLcontext *ctx, SWspan *span) if (buf + 1 < numDrawBuffers) { /* restore original span values */ - _mesa_memcpy(span->array->rgba, rgbaSave, + memcpy(span->array->rgba, rgbaSave, 4 * span->end * sizeof(GLchan)); } } /* for buf */ diff --git a/src/other/libosmesa/src/swrast/s_stencil.c b/src/other/libosmesa/src/swrast/s_stencil.c index 41939c472dd..fb643359500 100644 --- a/src/other/libosmesa/src/swrast/s_stencil.c +++ b/src/other/libosmesa/src/swrast/s_stencil.c @@ -443,7 +443,7 @@ stencil_and_ztest_span(GLcontext *ctx, SWspan *span, GLuint face) GLuint i; /* save the current mask bits */ - _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte)); + memcpy(oldmask, mask, n * sizeof(GLubyte)); /* apply the depth test */ _swrast_depth_test_span(ctx, span); @@ -880,7 +880,7 @@ stencil_and_ztest_pixels(GLcontext *ctx, SWspan *span, GLuint face) ASSERT(rb->DataType == GL_UNSIGNED_BYTE); _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte)); - _mesa_memcpy(origMask, mask, n * sizeof(GLubyte)); + memcpy(origMask, mask, n * sizeof(GLubyte)); (void) do_stencil_test(ctx, face, n, stencil, mask); @@ -931,7 +931,7 @@ stencil_and_ztest_pixels(GLcontext *ctx, SWspan *span, GLuint face) GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH]; GLuint i; - _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte)); + memcpy(oldmask, mask, n * sizeof(GLubyte)); _swrast_depth_test_span(ctx, span); @@ -1148,14 +1148,14 @@ _swrast_clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) /* Note: bottom-to-top raster assumed! */ GLubyte *stencil = (GLubyte *) rb->GetPointer(ctx, rb, x, y); GLuint len = width * height * sizeof(GLubyte); - _mesa_memset(stencil, clearVal, len); + memset(stencil, clearVal, len); } else { /* general case */ GLint i; for (i = 0; i < height; i++) { GLvoid *stencil = rb->GetPointer(ctx, rb, x, y + i); if (rb->DataType == GL_UNSIGNED_BYTE) { - _mesa_memset(stencil, clearVal, width); + memset(stencil, clearVal, width); } else { _mesa_memset16((short unsigned int*) stencil, clearVal, width); } diff --git a/src/other/libosmesa/src/swrast/s_texcombine.c b/src/other/libosmesa/src/swrast/s_texcombine.c index 8d36b32cc26..f55944e47bb 100644 --- a/src/other/libosmesa/src/swrast/s_texcombine.c +++ b/src/other/libosmesa/src/swrast/s_texcombine.c @@ -1161,7 +1161,7 @@ _swrast_texture_span(GLcontext *ctx, SWspan *span) * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) */ if (swrast->_AnyTextureCombine) - MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); + memcpy(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); /* * Must do all texture sampling before combining in order to diff --git a/src/other/libosmesa/src/swrast/s_texstore.c b/src/other/libosmesa/src/swrast/s_texstore.c index 0193dc9e203..1e8e503898b 100644 --- a/src/other/libosmesa/src/swrast/s_texstore.c +++ b/src/other/libosmesa/src/swrast/s_texstore.c @@ -74,7 +74,7 @@ read_color_image(GLcontext *ctx, GLint x, GLint y, GLenum type, GLint row; GLubyte *image, *dst; - image = (GLubyte *) _mesa_malloc(width * height * pixelSize); + image = (GLubyte *) malloc(width * height * pixelSize); if (!image) return NULL; @@ -105,7 +105,7 @@ read_depth_image(GLcontext *ctx, GLint x, GLint y, GLuint *image, *dst; GLint i; - image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); + image = (GLuint *) malloc(width * height * sizeof(GLuint)); if (!image) return NULL; @@ -139,7 +139,7 @@ read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y, ASSERT(depthRb); ASSERT(stencilRb); - image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); + image = (GLuint *) calloc(width * height, sizeof(GLuint)); if (!image) return NULL; @@ -268,7 +268,7 @@ _swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level, width, border, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else if (is_depth_stencil_format(internalFormat)) { /* read depth/stencil image from framebuffer */ GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1); @@ -281,7 +281,7 @@ _swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level, width, border, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else { /* read RGBA image from framebuffer */ const GLenum format = GL_RGBA; @@ -295,7 +295,7 @@ _swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level, ctx->Driver.TexImage1D(ctx, target, level, internalFormat, width, border, format, type, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } /* GL_SGIS_generate_mipmap */ @@ -343,7 +343,7 @@ _swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level, width, height, border, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else if (is_depth_stencil_format(internalFormat)) { GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); if (!image) { @@ -355,7 +355,7 @@ _swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level, width, height, border, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else { /* read RGBA image from framebuffer */ const GLenum format = GL_RGBA; @@ -369,7 +369,7 @@ _swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level, ctx->Driver.TexImage2D(ctx, target, level, internalFormat, width, height, border, format, type, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } /* GL_SGIS_generate_mipmap */ @@ -410,7 +410,7 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { /* read depth/stencil image from framebuffer */ GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1); @@ -422,7 +422,7 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else { /* read RGBA image from framebuffer */ const GLenum format = GL_RGBA; @@ -436,7 +436,7 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, format, type, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } /* GL_SGIS_generate_mipmap */ @@ -482,7 +482,7 @@ _swrast_copy_texsubimage2d(GLcontext *ctx, xoffset, yoffset, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { /* read depth/stencil image from framebuffer */ GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); @@ -495,7 +495,7 @@ _swrast_copy_texsubimage2d(GLcontext *ctx, xoffset, yoffset, width, height, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else { /* read RGBA image from framebuffer */ const GLenum format = GL_RGBA; @@ -510,7 +510,7 @@ _swrast_copy_texsubimage2d(GLcontext *ctx, xoffset, yoffset, width, height, format, type, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } /* GL_SGIS_generate_mipmap */ @@ -553,7 +553,7 @@ _swrast_copy_texsubimage3d(GLcontext *ctx, xoffset, yoffset, zoffset, width, height, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { /* read depth/stencil image from framebuffer */ GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); @@ -566,7 +566,7 @@ _swrast_copy_texsubimage3d(GLcontext *ctx, xoffset, yoffset, zoffset, width, height, 1, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } else { /* read RGBA image from framebuffer */ const GLenum format = GL_RGBA; @@ -581,7 +581,7 @@ _swrast_copy_texsubimage3d(GLcontext *ctx, xoffset, yoffset, zoffset, width, height, 1, format, type, image, &ctx->DefaultPacking, texObj, texImage); - _mesa_free(image); + free(image); } /* GL_SGIS_generate_mipmap */ diff --git a/src/other/libosmesa/src/swrast/s_tritemp.h b/src/other/libosmesa/src/swrast/s_tritemp.h index 0b9a3d128f7..87b2e4dba3e 100644 --- a/src/other/libosmesa/src/swrast/s_tritemp.h +++ b/src/other/libosmesa/src/swrast/s_tritemp.h @@ -191,7 +191,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif /* - printf("%s()\n", __FUNCTION__); + printf("%s()\n", __func__); printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]); printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]); printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]); diff --git a/src/other/libosmesa/src/swrast/s_zoom.c b/src/other/libosmesa/src/swrast/s_zoom.c index 0ce95594f05..fb807acb4c9 100644 --- a/src/other/libosmesa/src/swrast/s_zoom.c +++ b/src/other/libosmesa/src/swrast/s_zoom.c @@ -142,7 +142,7 @@ zoom_span(GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, if (!swrast->ZoomedArrays) { /* allocate on demand */ - swrast->ZoomedArrays = (SWspanarrays *) CALLOC(sizeof(SWspanarrays)); + swrast->ZoomedArrays = (SWspanarrays *) calloc(1,sizeof(SWspanarrays)); if (!swrast->ZoomedArrays) return; } @@ -320,14 +320,14 @@ zoom_span(GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) : 4 * sizeof(GLfloat)); if (y1 - y0 > 1) { - MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); + memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); } for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { _swrast_write_rgba_span(ctx, &zoomed); zoomed.end = end; /* restore */ if (y1 - y0 > 1) { /* restore the colors */ - MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); + memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); } } } else if (format == GL_COLOR_INDEX) { @@ -335,14 +335,14 @@ zoom_span(GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLuint *indexSave = (GLuint *) zoomed.array->spec; const GLint end = zoomed.end; /* save */ if (y1 - y0 > 1) { - MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint)); + memcpy(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint)); } for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { _swrast_write_index_span(ctx, &zoomed); zoomed.end = end; /* restore */ if (y1 - y0 > 1) { /* restore the colors */ - MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint)); + memcpy(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint)); } } } diff --git a/src/other/libosmesa/src/swrast_setup/ss_context.c b/src/other/libosmesa/src/swrast_setup/ss_context.c index 32e8074fbad..68eb7845df1 100644 --- a/src/other/libosmesa/src/swrast_setup/ss_context.c +++ b/src/other/libosmesa/src/swrast_setup/ss_context.c @@ -48,7 +48,7 @@ GLboolean _swsetup_CreateContext(GLcontext *ctx) { - SScontext *swsetup = (SScontext *)CALLOC(sizeof(SScontext)); + SScontext *swsetup = (SScontext *)calloc(1,sizeof(SScontext)); if (!swsetup) return GL_FALSE; @@ -71,7 +71,7 @@ _swsetup_DestroyContext(GLcontext *ctx) SScontext *swsetup = SWSETUP_CONTEXT(ctx); if (swsetup) { - FREE(swsetup); + free(swsetup); ctx->swsetup_context = 0; } diff --git a/src/other/libosmesa/src/tnl/t_context.c b/src/other/libosmesa/src/tnl/t_context.c index 473d52f6c52..8afb7a2704d 100644 --- a/src/other/libosmesa/src/tnl/t_context.c +++ b/src/other/libosmesa/src/tnl/t_context.c @@ -47,7 +47,7 @@ _tnl_CreateContext(GLcontext *ctx) /* Create the TNLcontext structure */ - ctx->swtnl_context = tnl = (TNLcontext *) CALLOC(sizeof(TNLcontext)); + ctx->swtnl_context = tnl = (TNLcontext *) calloc(1,sizeof(TNLcontext)); if (!tnl) { return GL_FALSE; @@ -93,7 +93,7 @@ _tnl_DestroyContext(GLcontext *ctx) if (ctx->VertexProgram._MaintainTnlProgram) _tnl_ProgramCacheDestroy(ctx); - FREE(tnl); + free(tnl); ctx->swtnl_context = NULL; } diff --git a/src/other/libosmesa/src/tnl/t_draw.c b/src/other/libosmesa/src/tnl/t_draw.c index 13db2ae59bb..85eba4862aa 100644 --- a/src/other/libosmesa/src/tnl/t_draw.c +++ b/src/other/libosmesa/src/tnl/t_draw.c @@ -44,7 +44,7 @@ static GLubyte *get_space(GLcontext *ctx, GLuint bytes) { TNLcontext *tnl = TNL_CONTEXT(ctx); - GLubyte *space = _mesa_malloc(bytes); + GLubyte *space = malloc(bytes); tnl->block[tnl->nr_blocks++] = space; return space; @@ -56,7 +56,7 @@ static void free_space(GLcontext *ctx) TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; for (i = 0; i < tnl->nr_blocks; i++) - _mesa_free(tnl->block[i]); + free(tnl->block[i]); tnl->nr_blocks = 0; } @@ -345,7 +345,7 @@ void _tnl_draw_prims(GLcontext *ctx, if (0) { GLuint i; - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + _mesa_printf("%s %d..%d\n", __func__, min_index, max_index); for (i = 0; i < nr_prims; i++) _mesa_printf("prim %d: %s start %d count %d\n", i, _mesa_lookup_enum_by_nr(prim[i].mode), diff --git a/src/other/libosmesa/src/tnl/t_pipeline.c b/src/other/libosmesa/src/tnl/t_pipeline.c index ade872999df..dc5420d18a3 100644 --- a/src/other/libosmesa/src/tnl/t_pipeline.c +++ b/src/other/libosmesa/src/tnl/t_pipeline.c @@ -48,7 +48,7 @@ void _tnl_install_pipeline(GLcontext *ctx, */ for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) { struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; - MEMCPY(s, stages[i], sizeof(*s)); + memcpy(s, stages[i], sizeof(*s)); if (s->create) s->create(ctx, s); } diff --git a/src/other/libosmesa/src/tnl/t_vb_fog.c b/src/other/libosmesa/src/tnl/t_vb_fog.c index 3726f90a707..d547fa1f20a 100644 --- a/src/other/libosmesa/src/tnl/t_vb_fog.c +++ b/src/other/libosmesa/src/tnl/t_vb_fog.c @@ -237,7 +237,7 @@ alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct fog_stage_data *store; - stage->privatePtr = MALLOC(sizeof(*store)); + stage->privatePtr = malloc(sizeof(*store)); store = FOG_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -257,7 +257,7 @@ free_fog_data(struct tnl_pipeline_stage *stage) struct fog_stage_data *store = FOG_STAGE_DATA(stage); if (store) { _mesa_vector4f_free(&store->fogcoord); - FREE(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_light.c b/src/other/libosmesa/src/tnl/t_vb_light.c index 40d2990200e..2838e278fb3 100644 --- a/src/other/libosmesa/src/tnl/t_vb_light.c +++ b/src/other/libosmesa/src/tnl/t_vb_light.c @@ -299,7 +299,7 @@ static GLboolean init_lighting(GLcontext *ctx, struct light_stage_data *store; GLuint size = tnl->vb.Size; - stage->privatePtr = MALLOC(sizeof(*store)); + stage->privatePtr = malloc(sizeof(*store)); store = LIGHT_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -344,7 +344,7 @@ static void dtr(struct tnl_pipeline_stage *stage) _mesa_vector4f_free(&store->LitSecondary[1]); _mesa_vector4f_free(&store->LitIndex[0]); _mesa_vector4f_free(&store->LitIndex[1]); - FREE(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_lighttmp.h b/src/other/libosmesa/src/tnl/t_vb_lighttmp.h index f24e336e6af..63a03a7efa9 100644 --- a/src/other/libosmesa/src/tnl/t_vb_lighttmp.h +++ b/src/other/libosmesa/src/tnl/t_vb_lighttmp.h @@ -69,7 +69,7 @@ static void TAG(light_rgba_spec)(GLcontext *ctx, const GLuint nr = VB->Count; #ifdef TRACE - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s\n", __func__); #endif VB->ColorPtr[0] = &store->LitColor[0]; @@ -251,7 +251,7 @@ static void TAG(light_rgba)(GLcontext *ctx, const GLuint nr = VB->Count; #ifdef TRACE - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s\n", __func__); #endif VB->ColorPtr[0] = &store->LitColor[0]; @@ -425,7 +425,7 @@ static void TAG(light_fast_rgba_single)(GLcontext *ctx, #endif const struct gl_light *light = ctx->Light.EnabledList.next; GLuint j = 0; - GLfloat base[2][4]; + GLfloat base[2][4] = {{0}}; #if IDX & LIGHT_MATERIAL const GLuint nr = VB->Count; #else @@ -433,7 +433,7 @@ static void TAG(light_fast_rgba_single)(GLcontext *ctx, #endif #ifdef TRACE - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s\n", __func__); #endif (void) input; /* doesn't refer to Eye or Obj */ @@ -538,7 +538,7 @@ static void TAG(light_fast_rgba)(GLcontext *ctx, const struct gl_light *light; #ifdef TRACE - fprintf(stderr, "%s %d\n", __FUNCTION__, nr); + fprintf(stderr, "%s %d\n", __func__, nr); #endif (void) input; @@ -648,7 +648,7 @@ static void TAG(light_ci)(GLcontext *ctx, const GLuint nr = VB->Count; #ifdef TRACE - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s\n", __func__); #endif VB->IndexPtr[0] = &store->LitIndex[0]; diff --git a/src/other/libosmesa/src/tnl/t_vb_normals.c b/src/other/libosmesa/src/tnl/t_vb_normals.c index 1c8521696b5..c04b69a23c7 100644 --- a/src/other/libosmesa/src/tnl/t_vb_normals.c +++ b/src/other/libosmesa/src/tnl/t_vb_normals.c @@ -147,7 +147,7 @@ alloc_normal_data(GLcontext *ctx, struct tnl_pipeline_stage *stage) TNLcontext *tnl = TNL_CONTEXT(ctx); struct normal_stage_data *store; - stage->privatePtr = _mesa_malloc(sizeof(*store)); + stage->privatePtr = malloc(sizeof(*store)); store = NORMAL_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -166,7 +166,7 @@ free_normal_data(struct tnl_pipeline_stage *stage) struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); if (store) { _mesa_vector4f_free(&store->normal); - _mesa_free(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_points.c b/src/other/libosmesa/src/tnl/t_vb_points.c index affec603c45..1dfedddc683 100644 --- a/src/other/libosmesa/src/tnl/t_vb_points.c +++ b/src/other/libosmesa/src/tnl/t_vb_points.c @@ -79,7 +79,7 @@ alloc_point_data(GLcontext *ctx, struct tnl_pipeline_stage *stage) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct point_stage_data *store; - stage->privatePtr = _mesa_malloc(sizeof(*store)); + stage->privatePtr = malloc(sizeof(*store)); store = POINT_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -95,7 +95,7 @@ free_point_data(struct tnl_pipeline_stage *stage) struct point_stage_data *store = POINT_STAGE_DATA(stage); if (store) { _mesa_vector4f_free(&store->PointSize); - _mesa_free(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_program.c b/src/other/libosmesa/src/tnl/t_vb_program.c index d0e972fcc64..ea5959e9520 100644 --- a/src/other/libosmesa/src/tnl/t_vb_program.c +++ b/src/other/libosmesa/src/tnl/t_vb_program.c @@ -212,7 +212,7 @@ static void init_machine(GLcontext *ctx, struct gl_program_machine *machine) { /* Input registers get initialized from the current vertex attribs */ - MEMCPY(machine->VertAttribs, ctx->Current.Attrib, + memcpy(machine->VertAttribs, ctx->Current.Attrib, MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); if (ctx->VertexProgram._Current->IsNVProgram) { @@ -471,7 +471,7 @@ init_vp(GLcontext *ctx, struct tnl_pipeline_stage *stage) const GLuint size = VB->Size; GLuint i; - stage->privatePtr = MALLOC(sizeof(*store)); + stage->privatePtr = malloc(sizeof(*store)); store = VP_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -509,7 +509,7 @@ dtr(struct tnl_pipeline_stage *stage) _mesa_vector4f_free(&store->ndcCoords); ALIGN_FREE(store->clipmask); - FREE(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_texgen.c b/src/other/libosmesa/src/tnl/t_vb_texgen.c index a455608cdb0..6391de702ae 100644 --- a/src/other/libosmesa/src/tnl/t_vb_texgen.c +++ b/src/other/libosmesa/src/tnl/t_vb_texgen.c @@ -562,7 +562,7 @@ static GLboolean alloc_texgen_data(GLcontext *ctx, struct texgen_stage_data *store; GLuint i; - stage->privatePtr = CALLOC(sizeof(*store)); + stage->privatePtr = calloc(1,sizeof(*store)); store = TEXGEN_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -570,8 +570,8 @@ static GLboolean alloc_texgen_data(GLcontext *ctx, for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) _mesa_vector4f_alloc(&store->texcoord[i], 0, VB->Size, 32); - store->tmp_f = (GLfloat(*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3); - store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat)); + store->tmp_f = (GLfloat(*)[3]) malloc(VB->Size * sizeof(GLfloat[3])); + store->tmp_m = (GLfloat *) malloc(VB->Size * sizeof(GLfloat)); return GL_TRUE; } @@ -589,9 +589,9 @@ static void free_texgen_data(struct tnl_pipeline_stage *stage) _mesa_vector4f_free(&store->texcoord[i]); - if (store->tmp_f) FREE(store->tmp_f); - if (store->tmp_m) FREE(store->tmp_m); - FREE(store); + if (store->tmp_f) free(store->tmp_f); + if (store->tmp_m) free(store->tmp_m); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_texmat.c b/src/other/libosmesa/src/tnl/t_vb_texmat.c index cf9653d808f..ebd87773011 100644 --- a/src/other/libosmesa/src/tnl/t_vb_texmat.c +++ b/src/other/libosmesa/src/tnl/t_vb_texmat.c @@ -91,7 +91,7 @@ static GLboolean alloc_texmat_data(GLcontext *ctx, struct texmat_stage_data *store; GLuint i; - stage->privatePtr = CALLOC(sizeof(*store)); + stage->privatePtr = calloc(1,sizeof(*store)); store = TEXMAT_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -112,7 +112,7 @@ static void free_texmat_data(struct tnl_pipeline_stage *stage) for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) if (store->texcoord[i].data) _mesa_vector4f_free(&store->texcoord[i]); - FREE(store); + free(store); stage->privatePtr = NULL; } } diff --git a/src/other/libosmesa/src/tnl/t_vb_vertex.c b/src/other/libosmesa/src/tnl/t_vb_vertex.c index d6f9d3a5120..5fbf6ecfb03 100644 --- a/src/other/libosmesa/src/tnl/t_vb_vertex.c +++ b/src/other/libosmesa/src/tnl/t_vb_vertex.c @@ -215,7 +215,7 @@ static GLboolean init_vertex_stage(GLcontext *ctx, struct vertex_stage_data *store; GLuint size = VB->Size; - stage->privatePtr = CALLOC(sizeof(*store)); + stage->privatePtr = calloc(1,sizeof(*store)); store = VERTEX_STAGE_DATA(stage); if (!store) return GL_FALSE; @@ -244,7 +244,7 @@ static void dtr(struct tnl_pipeline_stage *stage) _mesa_vector4f_free(&store->clip); _mesa_vector4f_free(&store->proj); ALIGN_FREE(store->clipmask); - FREE(store); + free(store); stage->privatePtr = NULL; stage->run = init_vertex_stage; } diff --git a/src/other/libosmesa/src/tnl/t_vertex.c b/src/other/libosmesa/src/tnl/t_vertex.c index 0c0851aea23..eeca56e1a1a 100644 --- a/src/other/libosmesa/src/tnl/t_vertex.c +++ b/src/other/libosmesa/src/tnl/t_vertex.c @@ -88,7 +88,7 @@ void _tnl_register_fastpath(struct tnl_clipspace *vtx, fastpath->match_strides = match_strides; fastpath->func = vtx->emit; fastpath->attr = (struct tnl_attr_type *) - _mesa_malloc(vtx->attr_count * sizeof(fastpath->attr[0])); + malloc(vtx->attr_count * sizeof(fastpath->attr[0])); for (i = 0; i < vtx->attr_count; i++) { fastpath->attr[i].format = vtx->attr[i].format; @@ -234,7 +234,7 @@ void _tnl_get_attr(GLcontext *ctx, const void *vin, */ dest[0] = ctx->Point._Size; } else { - _mesa_memcpy(dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); + memcpy(dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); } } @@ -501,16 +501,8 @@ void _tnl_free_vertices(GLcontext *ctx) for (fp = vtx->fastpath ; fp ; fp = tmp) { tmp = fp->next; - FREE(fp->attr); - - /* KW: At the moment, fp->func is constrained to be allocated by - * _mesa_exec_alloc(), as the hardwired fastpaths in - * t_vertex_generic.c are handled specially. It would be nice - * to unify them, but this probably won't change until this - * module gets another overhaul. - */ - _mesa_exec_free((void *) fp->func); - FREE(fp); + free(fp->attr); + free(fp); } vtx->fastpath = NULL; diff --git a/src/other/libosmesa/src/tnl/t_vertex_generic.c b/src/other/libosmesa/src/tnl/t_vertex_generic.c index 6b52316d499..3ce469ed4c3 100644 --- a/src/other/libosmesa/src/tnl/t_vertex_generic.c +++ b/src/other/libosmesa/src/tnl/t_vertex_generic.c @@ -1093,7 +1093,7 @@ void _tnl_generic_copy_pv(GLcontext *ctx, GLuint edst, GLuint esrc) if (a[j].attrib == VERT_ATTRIB_COLOR0 || a[j].attrib == VERT_ATTRIB_COLOR1) { - _mesa_memcpy(vdst + a[j].vertoffset, + memcpy(vdst + a[j].vertoffset, vsrc + a[j].vertoffset, a[j].vertattrsize); } diff --git a/src/other/libosmesa/src/tnl/t_vp_build.c b/src/other/libosmesa/src/tnl/t_vp_build.c index df797dbe2a8..3ee6cd89874 100644 --- a/src/other/libosmesa/src/tnl/t_vp_build.c +++ b/src/other/libosmesa/src/tnl/t_vp_build.c @@ -559,13 +559,13 @@ static void emit_op3fn(struct tnl_program *p, #define emit_op3(p, op, dst, mask, src0, src1, src2) \ - emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, src1, src2, __func__, __LINE__) #define emit_op2(p, op, dst, mask, src0, src1) \ - emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, src1, undef, __func__, __LINE__) #define emit_op1(p, op, dst, mask, src0) \ - emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, undef, undef, __func__, __LINE__) static struct ureg make_temp(struct tnl_program *p, struct ureg reg) @@ -1436,7 +1436,7 @@ create_new_program(const struct state_key *key, { struct tnl_program p; - _mesa_memset(&p, 0, sizeof(p)); + memset(&p, 0, sizeof(p)); p.state = key; p.program = program; p.eye_position = undef; @@ -1471,7 +1471,7 @@ static void *search_cache(struct tnl_cache *cache, struct tnl_cache_item *c; for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0) + if (c->hash == hash && memcmp(c->key, key, keysize) == 0) return c->data; } @@ -1485,8 +1485,8 @@ static void rehash(struct tnl_cache *cache) GLuint size, i; size = cache->size * 3; - items = (struct tnl_cache_item**) _mesa_malloc(size * sizeof(*items)); - _mesa_memset(items, 0, size * sizeof(*items)); + items = (struct tnl_cache_item**) malloc(size * sizeof(*items)); + memset(items, 0, size * sizeof(*items)); for (i = 0; i < cache->size; i++) for (c = cache->items[i]; c; c = next) { @@ -1495,7 +1495,7 @@ static void rehash(struct tnl_cache *cache) items[c->hash % size] = c; } - FREE(cache->items); + free(cache->items); cache->items = items; cache->size = size; } @@ -1505,7 +1505,7 @@ static void cache_item(struct tnl_cache *cache, void *key, void *data) { - struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c)); + struct tnl_cache_item *c = (struct tnl_cache_item*) malloc(sizeof(*c)); c->hash = hash; c->key = key; c->data = data; @@ -1567,7 +1567,7 @@ void _tnl_UpdateFixedFunctionProgram(GLcontext *ctx) cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram); } else { - FREE(key); + free(key); if (0) _mesa_printf("Found existing TNL program for key %x\n", hash); } @@ -1587,11 +1587,11 @@ void _tnl_ProgramCacheInit(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); + tnl->vp_cache = (struct tnl_cache *) malloc(sizeof(*tnl->vp_cache)); tnl->vp_cache->size = 17; tnl->vp_cache->n_items = 0; tnl->vp_cache->items = (struct tnl_cache_item**) - _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); + calloc(1,tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); } void _tnl_ProgramCacheDestroy(GLcontext *ctx) @@ -1603,13 +1603,13 @@ void _tnl_ProgramCacheDestroy(GLcontext *ctx) for (i = 0; i < tnl->vp_cache->size; i++) for (c = tnl->vp_cache->items[i]; c; c = next) { next = c->next; - FREE(c->key); - FREE(c->data); - FREE(c); + free(c->key); + free(c->data); + free(c); } - FREE(tnl->vp_cache->items); - FREE(tnl->vp_cache); + free(tnl->vp_cache->items); + free(tnl->vp_cache); } /* diff --git a/src/other/libosmesa/src/vbo/vbo_context.c b/src/other/libosmesa/src/vbo/vbo_context.c index 1cca2381483..ce21ef2ee1a 100644 --- a/src/other/libosmesa/src/vbo/vbo_context.c +++ b/src/other/libosmesa/src/vbo/vbo_context.c @@ -239,7 +239,7 @@ void _vbo_DestroyContext(GLcontext *ctx) vbo_exec_destroy(ctx); vbo_save_destroy(ctx); - FREE(vbo_context(ctx)); + free(vbo_context(ctx)); ctx->swtnl_im = NULL; } diff --git a/src/other/libosmesa/src/vbo/vbo_exec_api.c b/src/other/libosmesa/src/vbo/vbo_exec_api.c index e866c6ddfb9..4e7564c1434 100644 --- a/src/other/libosmesa/src/vbo/vbo_exec_api.c +++ b/src/other/libosmesa/src/vbo/vbo_exec_api.c @@ -117,7 +117,7 @@ void vbo_exec_vtx_wrap(struct vbo_exec_context *exec) assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - _mesa_memcpy(exec->vtx.vbptr, data, + memcpy(exec->vtx.vbptr, data, exec->vtx.vertex_size * sizeof(GLfloat)); exec->vtx.vbptr += exec->vtx.vertex_size; data += exec->vtx.vertex_size; @@ -373,7 +373,7 @@ do { \ } while (0) -#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) +#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __func__ ) #define TAG(x) vbo_##x #include "vbo_attrib_tmp.h" @@ -402,12 +402,12 @@ static void GLAPIENTRY vbo_exec_EvalCoord1f(GLfloat u) } - _mesa_memcpy(exec->vtx.copied.buffer, exec->vtx.vertex, + memcpy(exec->vtx.copied.buffer, exec->vtx.vertex, exec->vtx.vertex_size * sizeof(GLfloat)); vbo_exec_do_EvalCoord1f(exec, u); - _mesa_memcpy(exec->vtx.vertex, exec->vtx.copied.buffer, + memcpy(exec->vtx.vertex, exec->vtx.copied.buffer, exec->vtx.vertex_size * sizeof(GLfloat)); } @@ -432,12 +432,12 @@ static void GLAPIENTRY vbo_exec_EvalCoord2f(GLfloat u, GLfloat v) vbo_exec_fixup_vertex(ctx, VBO_ATTRIB_NORMAL, 3); } - _mesa_memcpy(exec->vtx.copied.buffer, exec->vtx.vertex, + memcpy(exec->vtx.copied.buffer, exec->vtx.vertex, exec->vtx.vertex_size * sizeof(GLfloat)); vbo_exec_do_EvalCoord2f(exec, u, v); - _mesa_memcpy(exec->vtx.vertex, exec->vtx.copied.buffer, + memcpy(exec->vtx.vertex, exec->vtx.copied.buffer, exec->vtx.vertex_size * sizeof(GLfloat)); } diff --git a/src/other/libosmesa/src/vbo/vbo_exec_draw.c b/src/other/libosmesa/src/vbo/vbo_exec_draw.c index 8e73b78f222..c0f1b124ba8 100644 --- a/src/other/libosmesa/src/vbo/vbo_exec_draw.c +++ b/src/other/libosmesa/src/vbo/vbo_exec_draw.c @@ -40,7 +40,7 @@ static void vbo_exec_debug_verts(struct vbo_exec_context *exec) GLuint i; _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n", - __FUNCTION__, + __func__, count, exec->vtx.prim_count, exec->vtx.vertex_size); @@ -80,23 +80,23 @@ static GLuint vbo_copy_vertices(struct vbo_exec_context *exec) case GL_LINES: ovf = nr&1; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); return i; case GL_TRIANGLES: ovf = nr%3; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); return i; case GL_QUADS: ovf = nr&3; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); return i; case GL_LINE_STRIP: if (nr == 0) return 0; else { - _mesa_memcpy(dst, src+(nr-1)*sz, sz * sizeof(GLfloat)); + memcpy(dst, src+(nr-1)*sz, sz * sizeof(GLfloat)); return 1; } case GL_LINE_LOOP: @@ -105,11 +105,11 @@ static GLuint vbo_copy_vertices(struct vbo_exec_context *exec) if (nr == 0) return 0; else if (nr == 1) { - _mesa_memcpy(dst, src+0, sz * sizeof(GLfloat)); + memcpy(dst, src+0, sz * sizeof(GLfloat)); return 1; } else { - _mesa_memcpy(dst, src+0, sz * sizeof(GLfloat)); - _mesa_memcpy(dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat)); + memcpy(dst, src+0, sz * sizeof(GLfloat)); + memcpy(dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat)); return 2; } case GL_TRIANGLE_STRIP: @@ -131,7 +131,7 @@ static GLuint vbo_copy_vertices(struct vbo_exec_context *exec) break; } for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); return i; case GL_POLYGON+1: return 0; diff --git a/src/other/libosmesa/src/vbo/vbo_rebase.c b/src/other/libosmesa/src/vbo/vbo_rebase.c index fabaeff013f..edb4ac3e81d 100644 --- a/src/other/libosmesa/src/vbo/vbo_rebase.c +++ b/src/other/libosmesa/src/vbo/vbo_rebase.c @@ -124,7 +124,7 @@ void vbo_rebase_prims(GLcontext *ctx, assert(min_index != 0); if (0) - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + _mesa_printf("%s %d..%d\n", __func__, min_index, max_index); if (ib) { /* Unfortunately need to adjust each index individually. @@ -170,7 +170,7 @@ void vbo_rebase_prims(GLcontext *ctx, } else { /* Otherwise the primitives need adjustment. */ - tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims); + tmp_prims = (struct _mesa_prim *)malloc(sizeof(*prim) * nr_prims); for (i = 0; i < nr_prims; i++) { /* If this fails, it could indicate an application error: @@ -211,10 +211,10 @@ void vbo_rebase_prims(GLcontext *ctx, max_index - min_index); if (tmp_indices) - _mesa_free(tmp_indices); + free(tmp_indices); if (tmp_prims) - _mesa_free(tmp_prims); + free(tmp_prims); } diff --git a/src/other/libosmesa/src/vbo/vbo_save.c b/src/other/libosmesa/src/vbo/vbo_save.c index 603b0e97755..85b4217fc17 100644 --- a/src/other/libosmesa/src/vbo/vbo_save.c +++ b/src/other/libosmesa/src/vbo/vbo_save.c @@ -73,14 +73,14 @@ void vbo_save_destroy(GLcontext *ctx) struct vbo_save_context *save = &vbo->save; if (save->prim_store) { if (--save->prim_store->refcount == 0) { - FREE(save->prim_store); + free(save->prim_store); save->prim_store = NULL; } if (--save->vertex_store->refcount == 0) { if (save->vertex_store->bufferobj) ctx->Driver.DeleteBuffer(ctx, save->vertex_store->bufferobj); - FREE(save->vertex_store); + free(save->vertex_store); save->vertex_store = NULL; } } diff --git a/src/other/libosmesa/src/vbo/vbo_save_api.c b/src/other/libosmesa/src/vbo/vbo_save_api.c index b37f7ce1d09..7cdb13f8774 100644 --- a/src/other/libosmesa/src/vbo/vbo_save_api.c +++ b/src/other/libosmesa/src/vbo/vbo_save_api.c @@ -110,23 +110,23 @@ static GLuint _save_copy_vertices(GLcontext *ctx, case GL_LINES: ovf = nr&1; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); return i; case GL_TRIANGLES: ovf = nr%3; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); return i; case GL_QUADS: ovf = nr&3; for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); return i; case GL_LINE_STRIP: if (nr == 0) return 0; else { - _mesa_memcpy(dst, src+(nr-1)*sz, sz*sizeof(GLfloat)); + memcpy(dst, src+(nr-1)*sz, sz*sizeof(GLfloat)); return 1; } case GL_LINE_LOOP: @@ -135,11 +135,11 @@ static GLuint _save_copy_vertices(GLcontext *ctx, if (nr == 0) return 0; else if (nr == 1) { - _mesa_memcpy(dst, src+0, sz*sizeof(GLfloat)); + memcpy(dst, src+0, sz*sizeof(GLfloat)); return 1; } else { - _mesa_memcpy(dst, src+0, sz*sizeof(GLfloat)); - _mesa_memcpy(dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat)); + memcpy(dst, src+0, sz*sizeof(GLfloat)); + memcpy(dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat)); return 2; } case GL_TRIANGLE_STRIP: @@ -156,7 +156,7 @@ static GLuint _save_copy_vertices(GLcontext *ctx, break; } for (i = 0 ; i < ovf ; i++) - _mesa_memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); + memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat)); return i; default: assert(0); @@ -198,7 +198,7 @@ static void free_vertex_store(GLcontext *ctx, struct vbo_save_vertex_store *vert if (vertex_store->bufferobj) ctx->Driver.DeleteBuffer(ctx, vertex_store->bufferobj); - FREE(vertex_store); + free(vertex_store); } static GLfloat *map_vertex_store(GLcontext *ctx, struct vbo_save_vertex_store *vertex_store) @@ -272,7 +272,7 @@ static void _save_compile_vertex_list(GLcontext *ctx) /* Duplicate our template, increment refcounts to the storage structs: */ - _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); + memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); node->vertex_size = save->vertex_size; node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); node->count = save->vert_count; @@ -411,7 +411,7 @@ static void _save_wrap_filled_vertex(GLcontext *ctx) assert(save->max_vert - save->vert_count > save->copied.nr); for (i = 0 ; i < save->copied.nr ; i++) { - _mesa_memcpy(save->vbptr, data, save->vertex_size * sizeof(GLfloat)); + memcpy(save->vbptr, data, save->vertex_size * sizeof(GLfloat)); data += save->vertex_size; save->vbptr += save->vertex_size; save->vert_count++; @@ -591,7 +591,7 @@ static void _save_reset_vertex(GLcontext *ctx) -#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ); +#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __func__ ); /* Only one size for each attribute may be active at once. Eg. if @@ -1095,7 +1095,7 @@ static void vbo_destroy_vertex_list(GLcontext *ctx, void *data) free_vertex_store(ctx, node->vertex_store); if (--node->prim_store->refcount == 0) - FREE(node->prim_store); + free(node->prim_store); } diff --git a/src/other/libosmesa/src/vbo/vbo_split_copy.c b/src/other/libosmesa/src/vbo/vbo_split_copy.c index d35b79df60f..c81f9036a2f 100644 --- a/src/other/libosmesa/src/vbo/vbo_split_copy.c +++ b/src/other/libosmesa/src/vbo/vbo_split_copy.c @@ -420,7 +420,7 @@ static void replay_init(struct copy_context *copy) switch (copy->ib->type) { case GL_UNSIGNED_BYTE: - copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count); + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); copy->srcelt = copy->translated_elt_buf; for (i = 0; i < copy->ib->count; i++) @@ -428,7 +428,7 @@ static void replay_init(struct copy_context *copy) break; case GL_UNSIGNED_SHORT: - copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count); + copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); copy->srcelt = copy->translated_elt_buf; for (i = 0; i < copy->ib->count; i++) @@ -454,7 +454,7 @@ static void replay_init(struct copy_context *copy) * * XXX: This should be a VBO! */ - copy->dstbuf = _mesa_malloc(copy->dstbuf_size * + copy->dstbuf = malloc(copy->dstbuf_size * copy->vertex_size); copy->dstptr = copy->dstbuf; @@ -483,7 +483,7 @@ static void replay_init(struct copy_context *copy) copy->ib->count * 2 + 3); copy->dstelt_size = MIN2(copy->dstelt_size, copy->limits->max_indices); - copy->dstelt = _mesa_malloc(sizeof(GLuint) * copy->dstelt_size); + copy->dstelt = malloc(sizeof(GLuint) * copy->dstelt_size); copy->dstelt_nr = 0; /* Setup the new index buffer to point to the allocated element @@ -503,9 +503,9 @@ static void replay_finish(struct copy_context *copy) /* Free our vertex and index buffers: */ - _mesa_free(copy->translated_elt_buf); - _mesa_free(copy->dstbuf); - _mesa_free(copy->dstelt); + free(copy->translated_elt_buf); + free(copy->dstbuf); + free(copy->dstelt); /* Unmap VBO's */ diff --git a/src/other/ext/linenoise.dist b/src/other/linenoise.dist similarity index 89% rename from src/other/ext/linenoise.dist rename to src/other/linenoise.dist index 15d5ba3872b..4b0e46880d0 100644 --- a/src/other/ext/linenoise.dist +++ b/src/other/linenoise.dist @@ -1,4 +1,5 @@ set(linenoise_ignore_files +CMakeLists.txt README.markdown linenoise-win32.c linenoise.c diff --git a/src/other/linenoise/CMakeLists.txt b/src/other/linenoise/CMakeLists.txt new file mode 100644 index 00000000000..7365a245648 --- /dev/null +++ b/src/other/linenoise/CMakeLists.txt @@ -0,0 +1,88 @@ +# C M A K E L I S T S . T X T +# BRL-CAD +# +# Copyright (c) 2022 United States Government as represented by +# the U.S. Army Research Laboratory. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Build file for linenoise (above license applies to only this file - linenoise +# is covered by its own license.) +# +# linenoise fork from https://github.com/msteveb/linenoise +### + +# Minimum required version of CMake +cmake_minimum_required(VERSION 3.18) + +# Set CMake project name +project(LN) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +if (NOT DEFINED BIN_DIR) + set (BIN_DIR bin) +endif (NOT DEFINED BIN_DIR) + +if (NOT DEFINED LIB_DIR) + set (LIB_DIR lib) +endif (NOT DEFINED LIB_DIR) + +if (NOT DEFINED INCLUDE_DIR) + set (INCLUDE_DIR include) +endif (NOT DEFINED INCLUDE_DIR) + +set(LN_SRCS + utf8.c + linenoise.c + stringbuf.c + ) + +add_library(linenoise SHARED ${LN_SRCS}) +set_property(TARGET linenoise APPEND PROPERTY COMPILE_DEFINITIONS "LINENOISE_DLL_EXPORTS") +set_property(TARGET linenoise APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "LINENOISE_DLL_IMPORTS") +install(TARGETS linenoise + RUNTIME DESTINATION ${BIN_DIR} + LIBRARY DESTINATION ${LIB_DIR} + ARCHIVE DESTINATION ${LIB_DIR} + ) + +set(LN_HDRS + linenoise.h + stringbuf.h + utf8.h + ) +install(FILES ${LN_HDRS} DESTINATION ${INCLUDE_DIR}/linenoise) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/src/other/ext/linenoise/README.markdown b/src/other/linenoise/README.markdown similarity index 100% rename from src/other/ext/linenoise/README.markdown rename to src/other/linenoise/README.markdown diff --git a/src/other/ext/linenoise/linenoise-win32.c b/src/other/linenoise/linenoise-win32.c similarity index 100% rename from src/other/ext/linenoise/linenoise-win32.c rename to src/other/linenoise/linenoise-win32.c diff --git a/src/other/ext/linenoise/linenoise.c b/src/other/linenoise/linenoise.c similarity index 100% rename from src/other/ext/linenoise/linenoise.c rename to src/other/linenoise/linenoise.c diff --git a/src/other/linenoise/linenoise.h b/src/other/linenoise/linenoise.h new file mode 100644 index 00000000000..69b1e9878a4 --- /dev/null +++ b/src/other/linenoise/linenoise.h @@ -0,0 +1,171 @@ +/* linenoise.h -- guerrilla line editing library against the idea that a + * line editing lib needs to be 20,000 lines of C code. + * + * See linenoise.c for more information. + * + * ------------------------------------------------------------------------ + * + * Copyright (c) 2010, Salvatore Sanfilippo + * Copyright (c) 2010, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINENOISE_H +#define __LINENOISE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef COMPILER_DLLEXPORT +# if defined(_WIN32) +# define COMPILER_DLLEXPORT __declspec(dllexport) +# define COMPILER_DLLIMPORT __declspec(dllimport) +# else +# define COMPILER_DLLEXPORT __attribute__ ((visibility ("default"))) +# define COMPILER_DLLIMPORT __attribute__ ((visibility ("default"))) +# endif +#endif + +#ifndef LINENOISE_EXPORT +# if defined(LINENOISE_DLL_EXPORTS) && defined(LINENOISE_DLL_IMPORTS) +# error "Only LINENOISE_DLL_EXPORTS or LINENOISE_DLL_IMPORTS can be defined, not both." +# elif defined(LINENOISE_DLL_EXPORTS) +# define LINENOISE_EXPORT COMPILER_DLLEXPORT +# elif defined(LINENOISE_DLL_IMPORTS) +# define LINENOISE_EXPORT COMPILER_DLLIMPORT +# else +# define LINENOISE_EXPORT +# endif +#endif + +#ifndef NO_COMPLETION +typedef struct linenoiseCompletions { + size_t len; + char **cvec; +} linenoiseCompletions; + +/* + * The callback type for tab completion handlers. + */ +typedef void(linenoiseCompletionCallback)(const char *prefix, linenoiseCompletions *comp, void *userdata); + +/* + * Sets the current tab completion handler and returns the previous one, or NULL + * if no prior one has been set. + */ +LINENOISE_EXPORT linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *comp, void *userdata); + +/* + * Adds a copy of the given string to the given completion list. The copy is owned + * by the linenoiseCompletions object. + */ +LINENOISE_EXPORT void linenoiseAddCompletion(linenoiseCompletions *comp, const char *str); + +typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold, void *userdata); +typedef void(linenoiseFreeHintsCallback)(void *hint, void *userdata); +LINENOISE_EXPORT void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata); +LINENOISE_EXPORT void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback); + +#endif + +/* + * Prompts for input using the given string as the input + * prompt. Returns when the user has tapped ENTER or (on an empty + * line) EOF (Ctrl-D on Unix, Ctrl-Z on Windows). Returns either + * a copy of the entered string (for ENTER) or NULL (on EOF). The + * caller owns the returned string and must eventually free() it. + */ +LINENOISE_EXPORT char *linenoise(const char *prompt); + +/** + * Like linenoise() but starts with an initial buffer. + */ +LINENOISE_EXPORT char *linenoiseWithInitial(const char *prompt, const char *initial); + +/** + * Clear the screen. + */ +LINENOISE_EXPORT void linenoiseClearScreen(void); + +/* + * Adds a copy of the given line of the command history. + */ +LINENOISE_EXPORT int linenoiseHistoryAdd(const char *line); + +/* + * Sets the maximum length of the command history, in lines. + * If the history is currently longer, it will be trimmed, + * retaining only the most recent entries. If len is 0 or less + * then this function does nothing. + */ +LINENOISE_EXPORT int linenoiseHistorySetMaxLen(int len); + +/* + * Returns the current maximum length of the history, in lines. + */ +LINENOISE_EXPORT int linenoiseHistoryGetMaxLen(void); + +/* + * Saves the current contents of the history to the given file. + * Returns 0 on success. + */ +LINENOISE_EXPORT int linenoiseHistorySave(const char *filename); + +/* + * Replaces the current history with the contents + * of the given file. Returns 0 on success. + */ +LINENOISE_EXPORT int linenoiseHistoryLoad(const char *filename); + +/* + * Frees all history entries, clearing the history. + */ +LINENOISE_EXPORT void linenoiseHistoryFree(void); + +/* + * Returns a pointer to the list of history entries, writing its + * length to *len if len is not NULL. The memory is owned by linenoise + * and must not be freed. + */ +LINENOISE_EXPORT char **linenoiseHistory(int *len); + +/* + * Returns the number of display columns in the current terminal. + */ +LINENOISE_EXPORT int linenoiseColumns(void); + +/** + * Enable or disable multiline mode (disabled by default) + */ +LINENOISE_EXPORT void linenoiseSetMultiLine(int enableml); + +#ifdef __cplusplus +} +#endif + +#endif /* __LINENOISE_H */ diff --git a/src/other/ext/linenoise/stringbuf.c b/src/other/linenoise/stringbuf.c similarity index 100% rename from src/other/ext/linenoise/stringbuf.c rename to src/other/linenoise/stringbuf.c diff --git a/src/other/ext/linenoise/stringbuf.h b/src/other/linenoise/stringbuf.h similarity index 100% rename from src/other/ext/linenoise/stringbuf.h rename to src/other/linenoise/stringbuf.h diff --git a/src/other/ext/linenoise/utf8.c b/src/other/linenoise/utf8.c similarity index 100% rename from src/other/ext/linenoise/utf8.c rename to src/other/linenoise/utf8.c diff --git a/src/other/ext/linenoise/utf8.h b/src/other/linenoise/utf8.h similarity index 100% rename from src/other/ext/linenoise/utf8.h rename to src/other/linenoise/utf8.h diff --git a/src/other/manifold.dist b/src/other/manifold.dist new file mode 100644 index 00000000000..e5ea3f63975 --- /dev/null +++ b/src/other/manifold.dist @@ -0,0 +1,2501 @@ +set(manifold_ignore_files +AUTHORS +CMakeLists.txt +CONTRIBUTING.md +LICENSE +LICENSE.clipper2 +README.md +glm/copying.txt +glm/glm/CMakeLists.txt +glm/glm/common.hpp +glm/glm/detail/_features.hpp +glm/glm/detail/_fixes.hpp +glm/glm/detail/_noise.hpp +glm/glm/detail/_swizzle.hpp +glm/glm/detail/_swizzle_func.hpp +glm/glm/detail/_vectorize.hpp +glm/glm/detail/compute_common.hpp +glm/glm/detail/compute_vector_relational.hpp +glm/glm/detail/func_common.inl +glm/glm/detail/func_common_simd.inl +glm/glm/detail/func_exponential.inl +glm/glm/detail/func_exponential_simd.inl +glm/glm/detail/func_geometric.inl +glm/glm/detail/func_geometric_simd.inl +glm/glm/detail/func_integer.inl +glm/glm/detail/func_integer_simd.inl +glm/glm/detail/func_matrix.inl +glm/glm/detail/func_matrix_simd.inl +glm/glm/detail/func_packing.inl +glm/glm/detail/func_packing_simd.inl +glm/glm/detail/func_trigonometric.inl +glm/glm/detail/func_trigonometric_simd.inl +glm/glm/detail/func_vector_relational.inl +glm/glm/detail/func_vector_relational_simd.inl +glm/glm/detail/glm.cpp +glm/glm/detail/qualifier.hpp +glm/glm/detail/setup.hpp +glm/glm/detail/type_float.hpp +glm/glm/detail/type_half.hpp +glm/glm/detail/type_half.inl +glm/glm/detail/type_mat2x2.hpp +glm/glm/detail/type_mat2x2.inl +glm/glm/detail/type_mat2x3.hpp +glm/glm/detail/type_mat2x3.inl +glm/glm/detail/type_mat2x4.hpp +glm/glm/detail/type_mat2x4.inl +glm/glm/detail/type_mat3x2.hpp +glm/glm/detail/type_mat3x2.inl +glm/glm/detail/type_mat3x3.hpp +glm/glm/detail/type_mat3x3.inl +glm/glm/detail/type_mat3x4.hpp +glm/glm/detail/type_mat3x4.inl +glm/glm/detail/type_mat4x2.hpp +glm/glm/detail/type_mat4x2.inl +glm/glm/detail/type_mat4x3.hpp +glm/glm/detail/type_mat4x3.inl +glm/glm/detail/type_mat4x4.hpp +glm/glm/detail/type_mat4x4.inl +glm/glm/detail/type_mat4x4_simd.inl +glm/glm/detail/type_quat.hpp +glm/glm/detail/type_quat.inl +glm/glm/detail/type_quat_simd.inl +glm/glm/detail/type_vec1.hpp +glm/glm/detail/type_vec1.inl +glm/glm/detail/type_vec2.hpp +glm/glm/detail/type_vec2.inl +glm/glm/detail/type_vec3.hpp +glm/glm/detail/type_vec3.inl +glm/glm/detail/type_vec4.hpp +glm/glm/detail/type_vec4.inl +glm/glm/detail/type_vec4_simd.inl +glm/glm/exponential.hpp +glm/glm/ext.hpp +glm/glm/ext/matrix_clip_space.hpp +glm/glm/ext/matrix_clip_space.inl +glm/glm/ext/matrix_common.hpp +glm/glm/ext/matrix_common.inl +glm/glm/ext/matrix_double2x2.hpp +glm/glm/ext/matrix_double2x2_precision.hpp +glm/glm/ext/matrix_double2x3.hpp +glm/glm/ext/matrix_double2x3_precision.hpp +glm/glm/ext/matrix_double2x4.hpp +glm/glm/ext/matrix_double2x4_precision.hpp +glm/glm/ext/matrix_double3x2.hpp +glm/glm/ext/matrix_double3x2_precision.hpp +glm/glm/ext/matrix_double3x3.hpp +glm/glm/ext/matrix_double3x3_precision.hpp +glm/glm/ext/matrix_double3x4.hpp +glm/glm/ext/matrix_double3x4_precision.hpp +glm/glm/ext/matrix_double4x2.hpp +glm/glm/ext/matrix_double4x2_precision.hpp +glm/glm/ext/matrix_double4x3.hpp +glm/glm/ext/matrix_double4x3_precision.hpp +glm/glm/ext/matrix_double4x4.hpp +glm/glm/ext/matrix_double4x4_precision.hpp +glm/glm/ext/matrix_float2x2.hpp +glm/glm/ext/matrix_float2x2_precision.hpp +glm/glm/ext/matrix_float2x3.hpp +glm/glm/ext/matrix_float2x3_precision.hpp +glm/glm/ext/matrix_float2x4.hpp +glm/glm/ext/matrix_float2x4_precision.hpp +glm/glm/ext/matrix_float3x2.hpp +glm/glm/ext/matrix_float3x2_precision.hpp +glm/glm/ext/matrix_float3x3.hpp +glm/glm/ext/matrix_float3x3_precision.hpp +glm/glm/ext/matrix_float3x4.hpp +glm/glm/ext/matrix_float3x4_precision.hpp +glm/glm/ext/matrix_float4x2.hpp +glm/glm/ext/matrix_float4x2_precision.hpp +glm/glm/ext/matrix_float4x3.hpp +glm/glm/ext/matrix_float4x3_precision.hpp +glm/glm/ext/matrix_float4x4.hpp +glm/glm/ext/matrix_float4x4_precision.hpp +glm/glm/ext/matrix_int2x2.hpp +glm/glm/ext/matrix_int2x2_sized.hpp +glm/glm/ext/matrix_int2x3.hpp +glm/glm/ext/matrix_int2x3_sized.hpp +glm/glm/ext/matrix_int2x4.hpp +glm/glm/ext/matrix_int2x4_sized.hpp +glm/glm/ext/matrix_int3x2.hpp +glm/glm/ext/matrix_int3x2_sized.hpp +glm/glm/ext/matrix_int3x3.hpp +glm/glm/ext/matrix_int3x3_sized.hpp +glm/glm/ext/matrix_int3x4.hpp +glm/glm/ext/matrix_int3x4_sized.hpp +glm/glm/ext/matrix_int4x2.hpp +glm/glm/ext/matrix_int4x2_sized.hpp +glm/glm/ext/matrix_int4x3.hpp +glm/glm/ext/matrix_int4x3_sized.hpp +glm/glm/ext/matrix_int4x4.hpp +glm/glm/ext/matrix_int4x4_sized.hpp +glm/glm/ext/matrix_projection.hpp +glm/glm/ext/matrix_projection.inl +glm/glm/ext/matrix_relational.hpp +glm/glm/ext/matrix_relational.inl +glm/glm/ext/matrix_transform.hpp +glm/glm/ext/matrix_transform.inl +glm/glm/ext/matrix_uint2x2.hpp +glm/glm/ext/matrix_uint2x2_sized.hpp +glm/glm/ext/matrix_uint2x3.hpp +glm/glm/ext/matrix_uint2x3_sized.hpp +glm/glm/ext/matrix_uint2x4.hpp +glm/glm/ext/matrix_uint2x4_sized.hpp +glm/glm/ext/matrix_uint3x2.hpp +glm/glm/ext/matrix_uint3x2_sized.hpp +glm/glm/ext/matrix_uint3x3.hpp +glm/glm/ext/matrix_uint3x3_sized.hpp +glm/glm/ext/matrix_uint3x4.hpp +glm/glm/ext/matrix_uint3x4_sized.hpp +glm/glm/ext/matrix_uint4x2.hpp +glm/glm/ext/matrix_uint4x2_sized.hpp +glm/glm/ext/matrix_uint4x3.hpp +glm/glm/ext/matrix_uint4x3_sized.hpp +glm/glm/ext/matrix_uint4x4.hpp +glm/glm/ext/matrix_uint4x4_sized.hpp +glm/glm/ext/quaternion_common.hpp +glm/glm/ext/quaternion_common.inl +glm/glm/ext/quaternion_common_simd.inl +glm/glm/ext/quaternion_double.hpp +glm/glm/ext/quaternion_double_precision.hpp +glm/glm/ext/quaternion_exponential.hpp +glm/glm/ext/quaternion_exponential.inl +glm/glm/ext/quaternion_float.hpp +glm/glm/ext/quaternion_float_precision.hpp +glm/glm/ext/quaternion_geometric.hpp +glm/glm/ext/quaternion_geometric.inl +glm/glm/ext/quaternion_relational.hpp +glm/glm/ext/quaternion_relational.inl +glm/glm/ext/quaternion_transform.hpp +glm/glm/ext/quaternion_transform.inl +glm/glm/ext/quaternion_trigonometric.hpp +glm/glm/ext/quaternion_trigonometric.inl +glm/glm/ext/scalar_common.hpp +glm/glm/ext/scalar_common.inl +glm/glm/ext/scalar_constants.hpp +glm/glm/ext/scalar_constants.inl +glm/glm/ext/scalar_int_sized.hpp +glm/glm/ext/scalar_integer.hpp +glm/glm/ext/scalar_integer.inl +glm/glm/ext/scalar_packing.hpp +glm/glm/ext/scalar_packing.inl +glm/glm/ext/scalar_relational.hpp +glm/glm/ext/scalar_relational.inl +glm/glm/ext/scalar_uint_sized.hpp +glm/glm/ext/scalar_ulp.hpp +glm/glm/ext/scalar_ulp.inl +glm/glm/ext/vector_bool1.hpp +glm/glm/ext/vector_bool1_precision.hpp +glm/glm/ext/vector_bool2.hpp +glm/glm/ext/vector_bool2_precision.hpp +glm/glm/ext/vector_bool3.hpp +glm/glm/ext/vector_bool3_precision.hpp +glm/glm/ext/vector_bool4.hpp +glm/glm/ext/vector_bool4_precision.hpp +glm/glm/ext/vector_common.hpp +glm/glm/ext/vector_common.inl +glm/glm/ext/vector_double1.hpp +glm/glm/ext/vector_double1_precision.hpp +glm/glm/ext/vector_double2.hpp +glm/glm/ext/vector_double2_precision.hpp +glm/glm/ext/vector_double3.hpp +glm/glm/ext/vector_double3_precision.hpp +glm/glm/ext/vector_double4.hpp +glm/glm/ext/vector_double4_precision.hpp +glm/glm/ext/vector_float1.hpp +glm/glm/ext/vector_float1_precision.hpp +glm/glm/ext/vector_float2.hpp +glm/glm/ext/vector_float2_precision.hpp +glm/glm/ext/vector_float3.hpp +glm/glm/ext/vector_float3_precision.hpp +glm/glm/ext/vector_float4.hpp +glm/glm/ext/vector_float4_precision.hpp +glm/glm/ext/vector_int1.hpp +glm/glm/ext/vector_int1_sized.hpp +glm/glm/ext/vector_int2.hpp +glm/glm/ext/vector_int2_sized.hpp +glm/glm/ext/vector_int3.hpp +glm/glm/ext/vector_int3_sized.hpp +glm/glm/ext/vector_int4.hpp +glm/glm/ext/vector_int4_sized.hpp +glm/glm/ext/vector_integer.hpp +glm/glm/ext/vector_integer.inl +glm/glm/ext/vector_packing.hpp +glm/glm/ext/vector_packing.inl +glm/glm/ext/vector_relational.hpp +glm/glm/ext/vector_relational.inl +glm/glm/ext/vector_uint1.hpp +glm/glm/ext/vector_uint1_sized.hpp +glm/glm/ext/vector_uint2.hpp +glm/glm/ext/vector_uint2_sized.hpp +glm/glm/ext/vector_uint3.hpp +glm/glm/ext/vector_uint3_sized.hpp +glm/glm/ext/vector_uint4.hpp +glm/glm/ext/vector_uint4_sized.hpp +glm/glm/ext/vector_ulp.hpp +glm/glm/ext/vector_ulp.inl +glm/glm/fwd.hpp +glm/glm/geometric.hpp +glm/glm/glm.hpp +glm/glm/gtc/bitfield.hpp +glm/glm/gtc/bitfield.inl +glm/glm/gtc/color_space.hpp +glm/glm/gtc/color_space.inl +glm/glm/gtc/constants.hpp +glm/glm/gtc/constants.inl +glm/glm/gtc/epsilon.hpp +glm/glm/gtc/epsilon.inl +glm/glm/gtc/integer.hpp +glm/glm/gtc/integer.inl +glm/glm/gtc/matrix_access.hpp +glm/glm/gtc/matrix_access.inl +glm/glm/gtc/matrix_integer.hpp +glm/glm/gtc/matrix_inverse.hpp +glm/glm/gtc/matrix_inverse.inl +glm/glm/gtc/matrix_transform.hpp +glm/glm/gtc/matrix_transform.inl +glm/glm/gtc/noise.hpp +glm/glm/gtc/noise.inl +glm/glm/gtc/packing.hpp +glm/glm/gtc/packing.inl +glm/glm/gtc/quaternion.hpp +glm/glm/gtc/quaternion.inl +glm/glm/gtc/quaternion_simd.inl +glm/glm/gtc/random.hpp +glm/glm/gtc/random.inl +glm/glm/gtc/reciprocal.hpp +glm/glm/gtc/reciprocal.inl +glm/glm/gtc/round.hpp +glm/glm/gtc/round.inl +glm/glm/gtc/type_aligned.hpp +glm/glm/gtc/type_precision.hpp +glm/glm/gtc/type_precision.inl +glm/glm/gtc/type_ptr.hpp +glm/glm/gtc/type_ptr.inl +glm/glm/gtc/ulp.hpp +glm/glm/gtc/ulp.inl +glm/glm/gtc/vec1.hpp +glm/glm/gtx/associated_min_max.hpp +glm/glm/gtx/associated_min_max.inl +glm/glm/gtx/bit.hpp +glm/glm/gtx/bit.inl +glm/glm/gtx/closest_point.hpp +glm/glm/gtx/closest_point.inl +glm/glm/gtx/color_encoding.hpp +glm/glm/gtx/color_encoding.inl +glm/glm/gtx/color_space.hpp +glm/glm/gtx/color_space.inl +glm/glm/gtx/color_space_YCoCg.hpp +glm/glm/gtx/color_space_YCoCg.inl +glm/glm/gtx/common.hpp +glm/glm/gtx/common.inl +glm/glm/gtx/compatibility.hpp +glm/glm/gtx/compatibility.inl +glm/glm/gtx/component_wise.hpp +glm/glm/gtx/component_wise.inl +glm/glm/gtx/dual_quaternion.hpp +glm/glm/gtx/dual_quaternion.inl +glm/glm/gtx/easing.hpp +glm/glm/gtx/easing.inl +glm/glm/gtx/euler_angles.hpp +glm/glm/gtx/euler_angles.inl +glm/glm/gtx/extend.hpp +glm/glm/gtx/extend.inl +glm/glm/gtx/extended_min_max.hpp +glm/glm/gtx/extended_min_max.inl +glm/glm/gtx/exterior_product.hpp +glm/glm/gtx/exterior_product.inl +glm/glm/gtx/fast_exponential.hpp +glm/glm/gtx/fast_exponential.inl +glm/glm/gtx/fast_square_root.hpp +glm/glm/gtx/fast_square_root.inl +glm/glm/gtx/fast_trigonometry.hpp +glm/glm/gtx/fast_trigonometry.inl +glm/glm/gtx/float_notmalize.inl +glm/glm/gtx/functions.hpp +glm/glm/gtx/functions.inl +glm/glm/gtx/gradient_paint.hpp +glm/glm/gtx/gradient_paint.inl +glm/glm/gtx/handed_coordinate_space.hpp +glm/glm/gtx/handed_coordinate_space.inl +glm/glm/gtx/hash.hpp +glm/glm/gtx/hash.inl +glm/glm/gtx/integer.hpp +glm/glm/gtx/integer.inl +glm/glm/gtx/intersect.hpp +glm/glm/gtx/intersect.inl +glm/glm/gtx/io.hpp +glm/glm/gtx/io.inl +glm/glm/gtx/log_base.hpp +glm/glm/gtx/log_base.inl +glm/glm/gtx/matrix_cross_product.hpp +glm/glm/gtx/matrix_cross_product.inl +glm/glm/gtx/matrix_decompose.hpp +glm/glm/gtx/matrix_decompose.inl +glm/glm/gtx/matrix_factorisation.hpp +glm/glm/gtx/matrix_factorisation.inl +glm/glm/gtx/matrix_interpolation.hpp +glm/glm/gtx/matrix_interpolation.inl +glm/glm/gtx/matrix_major_storage.hpp +glm/glm/gtx/matrix_major_storage.inl +glm/glm/gtx/matrix_operation.hpp +glm/glm/gtx/matrix_operation.inl +glm/glm/gtx/matrix_query.hpp +glm/glm/gtx/matrix_query.inl +glm/glm/gtx/matrix_transform_2d.hpp +glm/glm/gtx/matrix_transform_2d.inl +glm/glm/gtx/mixed_product.hpp +glm/glm/gtx/mixed_product.inl +glm/glm/gtx/norm.hpp +glm/glm/gtx/norm.inl +glm/glm/gtx/normal.hpp +glm/glm/gtx/normal.inl +glm/glm/gtx/normalize_dot.hpp +glm/glm/gtx/normalize_dot.inl +glm/glm/gtx/number_precision.hpp +glm/glm/gtx/number_precision.inl +glm/glm/gtx/optimum_pow.hpp +glm/glm/gtx/optimum_pow.inl +glm/glm/gtx/orthonormalize.hpp +glm/glm/gtx/orthonormalize.inl +glm/glm/gtx/perpendicular.hpp +glm/glm/gtx/perpendicular.inl +glm/glm/gtx/polar_coordinates.hpp +glm/glm/gtx/polar_coordinates.inl +glm/glm/gtx/projection.hpp +glm/glm/gtx/projection.inl +glm/glm/gtx/quaternion.hpp +glm/glm/gtx/quaternion.inl +glm/glm/gtx/range.hpp +glm/glm/gtx/raw_data.hpp +glm/glm/gtx/raw_data.inl +glm/glm/gtx/rotate_normalized_axis.hpp +glm/glm/gtx/rotate_normalized_axis.inl +glm/glm/gtx/rotate_vector.hpp +glm/glm/gtx/rotate_vector.inl +glm/glm/gtx/scalar_multiplication.hpp +glm/glm/gtx/scalar_relational.hpp +glm/glm/gtx/scalar_relational.inl +glm/glm/gtx/spline.hpp +glm/glm/gtx/spline.inl +glm/glm/gtx/std_based_type.hpp +glm/glm/gtx/std_based_type.inl +glm/glm/gtx/string_cast.hpp +glm/glm/gtx/string_cast.inl +glm/glm/gtx/texture.hpp +glm/glm/gtx/texture.inl +glm/glm/gtx/transform.hpp +glm/glm/gtx/transform.inl +glm/glm/gtx/transform2.hpp +glm/glm/gtx/transform2.inl +glm/glm/gtx/type_aligned.hpp +glm/glm/gtx/type_aligned.inl +glm/glm/gtx/type_trait.hpp +glm/glm/gtx/type_trait.inl +glm/glm/gtx/vec_swizzle.hpp +glm/glm/gtx/vector_angle.hpp +glm/glm/gtx/vector_angle.inl +glm/glm/gtx/vector_query.hpp +glm/glm/gtx/vector_query.inl +glm/glm/gtx/wrap.hpp +glm/glm/gtx/wrap.inl +glm/glm/integer.hpp +glm/glm/mat2x2.hpp +glm/glm/mat2x3.hpp +glm/glm/mat2x4.hpp +glm/glm/mat3x2.hpp +glm/glm/mat3x3.hpp +glm/glm/mat3x4.hpp +glm/glm/mat4x2.hpp +glm/glm/mat4x3.hpp +glm/glm/mat4x4.hpp +glm/glm/matrix.hpp +glm/glm/packing.hpp +glm/glm/simd/common.h +glm/glm/simd/exponential.h +glm/glm/simd/geometric.h +glm/glm/simd/integer.h +glm/glm/simd/matrix.h +glm/glm/simd/neon.h +glm/glm/simd/packing.h +glm/glm/simd/platform.h +glm/glm/simd/trigonometric.h +glm/glm/simd/vector_relational.h +glm/glm/trigonometric.hpp +glm/glm/vec2.hpp +glm/glm/vec3.hpp +glm/glm/vec4.hpp +glm/glm/vector_relational.hpp +glm/readme.md +include/CMakeLists.txt +include/ConvexHull.hpp +include/HalfEdgeMesh.hpp +include/MathUtils.hpp +include/QuickHull.hpp +include/Structs/Mesh.hpp +include/Structs/Plane.hpp +include/Structs/Pool.hpp +include/Structs/Ray.hpp +include/Structs/Vector3.hpp +include/Structs/VertexDataSource.hpp +include/clipper2/clipper.core.h +include/clipper2/clipper.engine.h +include/clipper2/clipper.export.h +include/clipper2/clipper.h +include/clipper2/clipper.minkowski.h +include/clipper2/clipper.offset.h +include/clipper2/clipper.rectclip.h +include/collider.h +include/hashtable.h +include/manifold/cross_section.h +include/manifold/manifold.h +include/manifold/public.h +include/manifold/sdf.h +include/optional_assert.h +include/par.h +include/polygon.h +include/sparse.h +include/thrust/addressof.h +include/thrust/adjacent_difference.h +include/thrust/advance.h +include/thrust/allocate_unique.h +include/thrust/async/copy.h +include/thrust/async/for_each.h +include/thrust/async/reduce.h +include/thrust/async/scan.h +include/thrust/async/sort.h +include/thrust/async/transform.h +include/thrust/binary_search.h +include/thrust/cmake/FindTBB.cmake +include/thrust/cmake/README.md +include/thrust/cmake/thrust-config-version.cmake +include/thrust/cmake/thrust-config.cmake +include/thrust/cmake/thrust-header-search.cmake +include/thrust/cmake/thrust-header-search.cmake.in +include/thrust/complex.h +include/thrust/copy.h +include/thrust/count.h +include/thrust/detail/adjacent_difference.inl +include/thrust/detail/advance.inl +include/thrust/detail/algorithm_wrapper.h +include/thrust/detail/alignment.h +include/thrust/detail/allocator/allocator_traits.h +include/thrust/detail/allocator/allocator_traits.inl +include/thrust/detail/allocator/copy_construct_range.h +include/thrust/detail/allocator/copy_construct_range.inl +include/thrust/detail/allocator/default_construct_range.h +include/thrust/detail/allocator/default_construct_range.inl +include/thrust/detail/allocator/destroy_range.h +include/thrust/detail/allocator/destroy_range.inl +include/thrust/detail/allocator/fill_construct_range.h +include/thrust/detail/allocator/fill_construct_range.inl +include/thrust/detail/allocator/malloc_allocator.h +include/thrust/detail/allocator/malloc_allocator.inl +include/thrust/detail/allocator/no_throw_allocator.h +include/thrust/detail/allocator/tagged_allocator.h +include/thrust/detail/allocator/tagged_allocator.inl +include/thrust/detail/allocator/temporary_allocator.h +include/thrust/detail/allocator/temporary_allocator.inl +include/thrust/detail/allocator_aware_execution_policy.h +include/thrust/detail/binary_search.inl +include/thrust/detail/caching_allocator.h +include/thrust/detail/complex/arithmetic.h +include/thrust/detail/complex/c99math.h +include/thrust/detail/complex/catrig.h +include/thrust/detail/complex/catrigf.h +include/thrust/detail/complex/ccosh.h +include/thrust/detail/complex/ccoshf.h +include/thrust/detail/complex/cexp.h +include/thrust/detail/complex/cexpf.h +include/thrust/detail/complex/clog.h +include/thrust/detail/complex/clogf.h +include/thrust/detail/complex/complex.inl +include/thrust/detail/complex/cpow.h +include/thrust/detail/complex/cproj.h +include/thrust/detail/complex/csinh.h +include/thrust/detail/complex/csinhf.h +include/thrust/detail/complex/csqrt.h +include/thrust/detail/complex/csqrtf.h +include/thrust/detail/complex/ctanh.h +include/thrust/detail/complex/ctanhf.h +include/thrust/detail/complex/math_private.h +include/thrust/detail/complex/stream.h +include/thrust/detail/config.h +include/thrust/detail/config/compiler.h +include/thrust/detail/config/compiler_fence.h +include/thrust/detail/config/config.h +include/thrust/detail/config/cpp_compatibility.h +include/thrust/detail/config/cpp_dialect.h +include/thrust/detail/config/debug.h +include/thrust/detail/config/deprecated.h +include/thrust/detail/config/device_system.h +include/thrust/detail/config/exec_check_disable.h +include/thrust/detail/config/forceinline.h +include/thrust/detail/config/global_workarounds.h +include/thrust/detail/config/host_device.h +include/thrust/detail/config/host_system.h +include/thrust/detail/config/memory_resource.h +include/thrust/detail/config/namespace.h +include/thrust/detail/config/simple_defines.h +include/thrust/detail/contiguous_storage.h +include/thrust/detail/contiguous_storage.inl +include/thrust/detail/copy.h +include/thrust/detail/copy.inl +include/thrust/detail/copy_if.h +include/thrust/detail/copy_if.inl +include/thrust/detail/count.h +include/thrust/detail/count.inl +include/thrust/detail/cpp11_required.h +include/thrust/detail/cpp14_required.h +include/thrust/detail/cstdint.h +include/thrust/detail/dependencies_aware_execution_policy.h +include/thrust/detail/device_delete.inl +include/thrust/detail/device_free.inl +include/thrust/detail/device_malloc.inl +include/thrust/detail/device_new.inl +include/thrust/detail/device_ptr.inl +include/thrust/detail/distance.inl +include/thrust/detail/equal.inl +include/thrust/detail/event_error.h +include/thrust/detail/execute_with_allocator.h +include/thrust/detail/execute_with_allocator_fwd.h +include/thrust/detail/execute_with_dependencies.h +include/thrust/detail/execution_policy.h +include/thrust/detail/extrema.inl +include/thrust/detail/fill.inl +include/thrust/detail/find.inl +include/thrust/detail/for_each.inl +include/thrust/detail/function.h +include/thrust/detail/functional.inl +include/thrust/detail/functional/actor.h +include/thrust/detail/functional/actor.inl +include/thrust/detail/functional/argument.h +include/thrust/detail/functional/composite.h +include/thrust/detail/functional/operators.h +include/thrust/detail/functional/operators/arithmetic_operators.h +include/thrust/detail/functional/operators/assignment_operator.h +include/thrust/detail/functional/operators/bitwise_operators.h +include/thrust/detail/functional/operators/compound_assignment_operators.h +include/thrust/detail/functional/operators/logical_operators.h +include/thrust/detail/functional/operators/operator_adaptors.h +include/thrust/detail/functional/operators/relational_operators.h +include/thrust/detail/functional/placeholder.h +include/thrust/detail/functional/value.h +include/thrust/detail/gather.inl +include/thrust/detail/generate.inl +include/thrust/detail/get_iterator_value.h +include/thrust/detail/inner_product.inl +include/thrust/detail/integer_math.h +include/thrust/detail/integer_traits.h +include/thrust/detail/internal_functional.h +include/thrust/detail/logical.inl +include/thrust/detail/malloc_and_free.h +include/thrust/detail/memory_algorithms.h +include/thrust/detail/memory_wrapper.h +include/thrust/detail/merge.inl +include/thrust/detail/minmax.h +include/thrust/detail/mismatch.inl +include/thrust/detail/modern_gcc_required.h +include/thrust/detail/mpl/math.h +include/thrust/detail/numeric_traits.h +include/thrust/detail/numeric_wrapper.h +include/thrust/detail/overlapped_copy.h +include/thrust/detail/pair.inl +include/thrust/detail/partition.inl +include/thrust/detail/pointer.h +include/thrust/detail/pointer.inl +include/thrust/detail/preprocessor.h +include/thrust/detail/range/head_flags.h +include/thrust/detail/range/tail_flags.h +include/thrust/detail/raw_pointer_cast.h +include/thrust/detail/raw_reference_cast.h +include/thrust/detail/reduce.inl +include/thrust/detail/reference.h +include/thrust/detail/reference_forward_declaration.h +include/thrust/detail/remove.inl +include/thrust/detail/replace.inl +include/thrust/detail/reverse.inl +include/thrust/detail/scan.inl +include/thrust/detail/scatter.inl +include/thrust/detail/select_system.h +include/thrust/detail/seq.h +include/thrust/detail/sequence.inl +include/thrust/detail/set_operations.inl +include/thrust/detail/shuffle.inl +include/thrust/detail/sort.inl +include/thrust/detail/static_assert.h +include/thrust/detail/static_map.h +include/thrust/detail/swap.h +include/thrust/detail/swap.inl +include/thrust/detail/swap_ranges.inl +include/thrust/detail/tabulate.inl +include/thrust/detail/temporary_array.h +include/thrust/detail/temporary_array.inl +include/thrust/detail/temporary_buffer.h +include/thrust/detail/transform.inl +include/thrust/detail/transform_reduce.inl +include/thrust/detail/transform_scan.inl +include/thrust/detail/trivial_sequence.h +include/thrust/detail/tuple.inl +include/thrust/detail/tuple_algorithms.h +include/thrust/detail/tuple_meta_transform.h +include/thrust/detail/tuple_transform.h +include/thrust/detail/type_deduction.h +include/thrust/detail/type_traits.h +include/thrust/detail/type_traits/function_traits.h +include/thrust/detail/type_traits/has_member_function.h +include/thrust/detail/type_traits/has_nested_type.h +include/thrust/detail/type_traits/has_trivial_assign.h +include/thrust/detail/type_traits/is_call_possible.h +include/thrust/detail/type_traits/is_metafunction_defined.h +include/thrust/detail/type_traits/iterator/is_discard_iterator.h +include/thrust/detail/type_traits/iterator/is_output_iterator.h +include/thrust/detail/type_traits/minimum_type.h +include/thrust/detail/type_traits/pointer_traits.h +include/thrust/detail/type_traits/result_of_adaptable_function.h +include/thrust/detail/uninitialized_copy.inl +include/thrust/detail/uninitialized_fill.inl +include/thrust/detail/unique.inl +include/thrust/detail/use_default.h +include/thrust/detail/util/align.h +include/thrust/detail/vector_base.h +include/thrust/detail/vector_base.inl +include/thrust/device_allocator.h +include/thrust/device_delete.h +include/thrust/device_free.h +include/thrust/device_make_unique.h +include/thrust/device_malloc.h +include/thrust/device_malloc_allocator.h +include/thrust/device_new.h +include/thrust/device_new_allocator.h +include/thrust/device_ptr.h +include/thrust/device_reference.h +include/thrust/device_vector.h +include/thrust/distance.h +include/thrust/equal.h +include/thrust/event.h +include/thrust/execution_policy.h +include/thrust/extrema.h +include/thrust/fill.h +include/thrust/find.h +include/thrust/for_each.h +include/thrust/functional.h +include/thrust/future.h +include/thrust/gather.h +include/thrust/generate.h +include/thrust/host_vector.h +include/thrust/inner_product.h +include/thrust/iterator/constant_iterator.h +include/thrust/iterator/counting_iterator.h +include/thrust/iterator/detail/any_assign.h +include/thrust/iterator/detail/any_system_tag.h +include/thrust/iterator/detail/constant_iterator_base.h +include/thrust/iterator/detail/counting_iterator.inl +include/thrust/iterator/detail/device_system_tag.h +include/thrust/iterator/detail/discard_iterator_base.h +include/thrust/iterator/detail/distance_from_result.h +include/thrust/iterator/detail/host_system_tag.h +include/thrust/iterator/detail/is_iterator_category.h +include/thrust/iterator/detail/iterator_adaptor_base.h +include/thrust/iterator/detail/iterator_category_to_system.h +include/thrust/iterator/detail/iterator_category_to_traversal.h +include/thrust/iterator/detail/iterator_category_with_system_and_traversal.h +include/thrust/iterator/detail/iterator_facade_category.h +include/thrust/iterator/detail/iterator_traits.inl +include/thrust/iterator/detail/iterator_traversal_tags.h +include/thrust/iterator/detail/join_iterator.h +include/thrust/iterator/detail/minimum_category.h +include/thrust/iterator/detail/minimum_system.h +include/thrust/iterator/detail/normal_iterator.h +include/thrust/iterator/detail/permutation_iterator_base.h +include/thrust/iterator/detail/retag.h +include/thrust/iterator/detail/reverse_iterator.inl +include/thrust/iterator/detail/reverse_iterator_base.h +include/thrust/iterator/detail/tagged_iterator.h +include/thrust/iterator/detail/transform_input_output_iterator.inl +include/thrust/iterator/detail/transform_iterator.inl +include/thrust/iterator/detail/transform_output_iterator.inl +include/thrust/iterator/detail/tuple_of_iterator_references.h +include/thrust/iterator/detail/universal_categories.h +include/thrust/iterator/detail/zip_iterator.inl +include/thrust/iterator/detail/zip_iterator_base.h +include/thrust/iterator/discard_iterator.h +include/thrust/iterator/iterator_adaptor.h +include/thrust/iterator/iterator_categories.h +include/thrust/iterator/iterator_facade.h +include/thrust/iterator/iterator_traits.h +include/thrust/iterator/permutation_iterator.h +include/thrust/iterator/retag.h +include/thrust/iterator/reverse_iterator.h +include/thrust/iterator/transform_input_output_iterator.h +include/thrust/iterator/transform_iterator.h +include/thrust/iterator/transform_output_iterator.h +include/thrust/iterator/zip_iterator.h +include/thrust/limits.h +include/thrust/logical.h +include/thrust/memory.h +include/thrust/merge.h +include/thrust/mismatch.h +include/thrust/mr/allocator.h +include/thrust/mr/device_memory_resource.h +include/thrust/mr/disjoint_pool.h +include/thrust/mr/disjoint_sync_pool.h +include/thrust/mr/disjoint_tls_pool.h +include/thrust/mr/fancy_pointer_resource.h +include/thrust/mr/host_memory_resource.h +include/thrust/mr/memory_resource.h +include/thrust/mr/new.h +include/thrust/mr/polymorphic_adaptor.h +include/thrust/mr/pool.h +include/thrust/mr/pool_options.h +include/thrust/mr/sync_pool.h +include/thrust/mr/tls_pool.h +include/thrust/mr/universal_memory_resource.h +include/thrust/mr/validator.h +include/thrust/optional.h +include/thrust/pair.h +include/thrust/partition.h +include/thrust/per_device_resource.h +include/thrust/random.h +include/thrust/random/detail/discard_block_engine.inl +include/thrust/random/detail/linear_congruential_engine.inl +include/thrust/random/detail/linear_congruential_engine_discard.h +include/thrust/random/detail/linear_feedback_shift_engine.inl +include/thrust/random/detail/linear_feedback_shift_engine_wordmask.h +include/thrust/random/detail/mod.h +include/thrust/random/detail/normal_distribution.inl +include/thrust/random/detail/normal_distribution_base.h +include/thrust/random/detail/random_core_access.h +include/thrust/random/detail/subtract_with_carry_engine.inl +include/thrust/random/detail/uniform_int_distribution.inl +include/thrust/random/detail/uniform_real_distribution.inl +include/thrust/random/detail/xor_combine_engine.inl +include/thrust/random/detail/xor_combine_engine_max.h +include/thrust/random/discard_block_engine.h +include/thrust/random/linear_congruential_engine.h +include/thrust/random/linear_feedback_shift_engine.h +include/thrust/random/normal_distribution.h +include/thrust/random/subtract_with_carry_engine.h +include/thrust/random/uniform_int_distribution.h +include/thrust/random/uniform_real_distribution.h +include/thrust/random/xor_combine_engine.h +include/thrust/reduce.h +include/thrust/remove.h +include/thrust/replace.h +include/thrust/reverse.h +include/thrust/scan.h +include/thrust/scatter.h +include/thrust/sequence.h +include/thrust/set_operations.h +include/thrust/shuffle.h +include/thrust/sort.h +include/thrust/swap.h +include/thrust/system/cpp/detail/adjacent_difference.h +include/thrust/system/cpp/detail/assign_value.h +include/thrust/system/cpp/detail/binary_search.h +include/thrust/system/cpp/detail/copy.h +include/thrust/system/cpp/detail/copy_if.h +include/thrust/system/cpp/detail/count.h +include/thrust/system/cpp/detail/equal.h +include/thrust/system/cpp/detail/execution_policy.h +include/thrust/system/cpp/detail/extrema.h +include/thrust/system/cpp/detail/fill.h +include/thrust/system/cpp/detail/find.h +include/thrust/system/cpp/detail/for_each.h +include/thrust/system/cpp/detail/gather.h +include/thrust/system/cpp/detail/generate.h +include/thrust/system/cpp/detail/get_value.h +include/thrust/system/cpp/detail/inner_product.h +include/thrust/system/cpp/detail/iter_swap.h +include/thrust/system/cpp/detail/logical.h +include/thrust/system/cpp/detail/malloc_and_free.h +include/thrust/system/cpp/detail/memory.inl +include/thrust/system/cpp/detail/merge.h +include/thrust/system/cpp/detail/mismatch.h +include/thrust/system/cpp/detail/par.h +include/thrust/system/cpp/detail/partition.h +include/thrust/system/cpp/detail/per_device_resource.h +include/thrust/system/cpp/detail/reduce.h +include/thrust/system/cpp/detail/reduce_by_key.h +include/thrust/system/cpp/detail/remove.h +include/thrust/system/cpp/detail/replace.h +include/thrust/system/cpp/detail/reverse.h +include/thrust/system/cpp/detail/scan.h +include/thrust/system/cpp/detail/scan_by_key.h +include/thrust/system/cpp/detail/scatter.h +include/thrust/system/cpp/detail/sequence.h +include/thrust/system/cpp/detail/set_operations.h +include/thrust/system/cpp/detail/sort.h +include/thrust/system/cpp/detail/swap_ranges.h +include/thrust/system/cpp/detail/tabulate.h +include/thrust/system/cpp/detail/temporary_buffer.h +include/thrust/system/cpp/detail/transform.h +include/thrust/system/cpp/detail/transform_reduce.h +include/thrust/system/cpp/detail/transform_scan.h +include/thrust/system/cpp/detail/uninitialized_copy.h +include/thrust/system/cpp/detail/uninitialized_fill.h +include/thrust/system/cpp/detail/unique.h +include/thrust/system/cpp/detail/unique_by_key.h +include/thrust/system/cpp/detail/vector.inl +include/thrust/system/cpp/execution_policy.h +include/thrust/system/cpp/memory.h +include/thrust/system/cpp/memory_resource.h +include/thrust/system/cpp/pointer.h +include/thrust/system/cpp/vector.h +include/thrust/system/cuda/config.h +include/thrust/system/cuda/detail/adjacent_difference.h +include/thrust/system/cuda/detail/assign_value.h +include/thrust/system/cuda/detail/async/copy.h +include/thrust/system/cuda/detail/async/customization.h +include/thrust/system/cuda/detail/async/exclusive_scan.h +include/thrust/system/cuda/detail/async/for_each.h +include/thrust/system/cuda/detail/async/inclusive_scan.h +include/thrust/system/cuda/detail/async/reduce.h +include/thrust/system/cuda/detail/async/scan.h +include/thrust/system/cuda/detail/async/sort.h +include/thrust/system/cuda/detail/async/transform.h +include/thrust/system/cuda/detail/binary_search.h +include/thrust/system/cuda/detail/cdp_dispatch.h +include/thrust/system/cuda/detail/copy.h +include/thrust/system/cuda/detail/copy_if.h +include/thrust/system/cuda/detail/core/agent_launcher.h +include/thrust/system/cuda/detail/core/alignment.h +include/thrust/system/cuda/detail/core/triple_chevron_launch.h +include/thrust/system/cuda/detail/core/util.h +include/thrust/system/cuda/detail/count.h +include/thrust/system/cuda/detail/cross_system.h +include/thrust/system/cuda/detail/dispatch.h +include/thrust/system/cuda/detail/equal.h +include/thrust/system/cuda/detail/error.inl +include/thrust/system/cuda/detail/execution_policy.h +include/thrust/system/cuda/detail/extrema.h +include/thrust/system/cuda/detail/fill.h +include/thrust/system/cuda/detail/find.h +include/thrust/system/cuda/detail/for_each.h +include/thrust/system/cuda/detail/future.inl +include/thrust/system/cuda/detail/gather.h +include/thrust/system/cuda/detail/generate.h +include/thrust/system/cuda/detail/get_value.h +include/thrust/system/cuda/detail/guarded_cuda_runtime_api.h +include/thrust/system/cuda/detail/guarded_driver_types.h +include/thrust/system/cuda/detail/inner_product.h +include/thrust/system/cuda/detail/internal/copy_cross_system.h +include/thrust/system/cuda/detail/internal/copy_device_to_device.h +include/thrust/system/cuda/detail/iter_swap.h +include/thrust/system/cuda/detail/logical.h +include/thrust/system/cuda/detail/make_unsigned_special.h +include/thrust/system/cuda/detail/malloc_and_free.h +include/thrust/system/cuda/detail/memory.inl +include/thrust/system/cuda/detail/merge.h +include/thrust/system/cuda/detail/mismatch.h +include/thrust/system/cuda/detail/par.h +include/thrust/system/cuda/detail/par_to_seq.h +include/thrust/system/cuda/detail/parallel_for.h +include/thrust/system/cuda/detail/partition.h +include/thrust/system/cuda/detail/per_device_resource.h +include/thrust/system/cuda/detail/reduce.h +include/thrust/system/cuda/detail/reduce_by_key.h +include/thrust/system/cuda/detail/remove.h +include/thrust/system/cuda/detail/replace.h +include/thrust/system/cuda/detail/reverse.h +include/thrust/system/cuda/detail/scan.h +include/thrust/system/cuda/detail/scan_by_key.h +include/thrust/system/cuda/detail/scatter.h +include/thrust/system/cuda/detail/sequence.h +include/thrust/system/cuda/detail/set_operations.h +include/thrust/system/cuda/detail/sort.h +include/thrust/system/cuda/detail/swap_ranges.h +include/thrust/system/cuda/detail/tabulate.h +include/thrust/system/cuda/detail/temporary_buffer.h +include/thrust/system/cuda/detail/terminate.h +include/thrust/system/cuda/detail/transform.h +include/thrust/system/cuda/detail/transform_reduce.h +include/thrust/system/cuda/detail/transform_scan.h +include/thrust/system/cuda/detail/uninitialized_copy.h +include/thrust/system/cuda/detail/uninitialized_fill.h +include/thrust/system/cuda/detail/unique.h +include/thrust/system/cuda/detail/unique_by_key.h +include/thrust/system/cuda/detail/util.h +include/thrust/system/cuda/error.h +include/thrust/system/cuda/execution_policy.h +include/thrust/system/cuda/future.h +include/thrust/system/cuda/memory.h +include/thrust/system/cuda/memory_resource.h +include/thrust/system/cuda/pointer.h +include/thrust/system/cuda/vector.h +include/thrust/system/detail/adl/adjacent_difference.h +include/thrust/system/detail/adl/assign_value.h +include/thrust/system/detail/adl/async/copy.h +include/thrust/system/detail/adl/async/for_each.h +include/thrust/system/detail/adl/async/reduce.h +include/thrust/system/detail/adl/async/scan.h +include/thrust/system/detail/adl/async/sort.h +include/thrust/system/detail/adl/async/transform.h +include/thrust/system/detail/adl/binary_search.h +include/thrust/system/detail/adl/copy.h +include/thrust/system/detail/adl/copy_if.h +include/thrust/system/detail/adl/count.h +include/thrust/system/detail/adl/equal.h +include/thrust/system/detail/adl/extrema.h +include/thrust/system/detail/adl/fill.h +include/thrust/system/detail/adl/find.h +include/thrust/system/detail/adl/for_each.h +include/thrust/system/detail/adl/gather.h +include/thrust/system/detail/adl/generate.h +include/thrust/system/detail/adl/get_value.h +include/thrust/system/detail/adl/inner_product.h +include/thrust/system/detail/adl/iter_swap.h +include/thrust/system/detail/adl/logical.h +include/thrust/system/detail/adl/malloc_and_free.h +include/thrust/system/detail/adl/merge.h +include/thrust/system/detail/adl/mismatch.h +include/thrust/system/detail/adl/partition.h +include/thrust/system/detail/adl/per_device_resource.h +include/thrust/system/detail/adl/reduce.h +include/thrust/system/detail/adl/reduce_by_key.h +include/thrust/system/detail/adl/remove.h +include/thrust/system/detail/adl/replace.h +include/thrust/system/detail/adl/reverse.h +include/thrust/system/detail/adl/scan.h +include/thrust/system/detail/adl/scan_by_key.h +include/thrust/system/detail/adl/scatter.h +include/thrust/system/detail/adl/sequence.h +include/thrust/system/detail/adl/set_operations.h +include/thrust/system/detail/adl/sort.h +include/thrust/system/detail/adl/swap_ranges.h +include/thrust/system/detail/adl/tabulate.h +include/thrust/system/detail/adl/temporary_buffer.h +include/thrust/system/detail/adl/transform.h +include/thrust/system/detail/adl/transform_reduce.h +include/thrust/system/detail/adl/transform_scan.h +include/thrust/system/detail/adl/uninitialized_copy.h +include/thrust/system/detail/adl/uninitialized_fill.h +include/thrust/system/detail/adl/unique.h +include/thrust/system/detail/adl/unique_by_key.h +include/thrust/system/detail/bad_alloc.h +include/thrust/system/detail/errno.h +include/thrust/system/detail/error_category.inl +include/thrust/system/detail/error_code.inl +include/thrust/system/detail/error_condition.inl +include/thrust/system/detail/generic/adjacent_difference.h +include/thrust/system/detail/generic/adjacent_difference.inl +include/thrust/system/detail/generic/advance.h +include/thrust/system/detail/generic/advance.inl +include/thrust/system/detail/generic/binary_search.h +include/thrust/system/detail/generic/binary_search.inl +include/thrust/system/detail/generic/copy.h +include/thrust/system/detail/generic/copy.inl +include/thrust/system/detail/generic/copy_if.h +include/thrust/system/detail/generic/copy_if.inl +include/thrust/system/detail/generic/count.h +include/thrust/system/detail/generic/count.inl +include/thrust/system/detail/generic/distance.h +include/thrust/system/detail/generic/distance.inl +include/thrust/system/detail/generic/equal.h +include/thrust/system/detail/generic/equal.inl +include/thrust/system/detail/generic/extrema.h +include/thrust/system/detail/generic/extrema.inl +include/thrust/system/detail/generic/fill.h +include/thrust/system/detail/generic/find.h +include/thrust/system/detail/generic/find.inl +include/thrust/system/detail/generic/for_each.h +include/thrust/system/detail/generic/gather.h +include/thrust/system/detail/generic/gather.inl +include/thrust/system/detail/generic/generate.h +include/thrust/system/detail/generic/generate.inl +include/thrust/system/detail/generic/inner_product.h +include/thrust/system/detail/generic/inner_product.inl +include/thrust/system/detail/generic/logical.h +include/thrust/system/detail/generic/memory.h +include/thrust/system/detail/generic/memory.inl +include/thrust/system/detail/generic/merge.h +include/thrust/system/detail/generic/merge.inl +include/thrust/system/detail/generic/mismatch.h +include/thrust/system/detail/generic/mismatch.inl +include/thrust/system/detail/generic/partition.h +include/thrust/system/detail/generic/partition.inl +include/thrust/system/detail/generic/per_device_resource.h +include/thrust/system/detail/generic/reduce.h +include/thrust/system/detail/generic/reduce.inl +include/thrust/system/detail/generic/reduce_by_key.h +include/thrust/system/detail/generic/reduce_by_key.inl +include/thrust/system/detail/generic/remove.h +include/thrust/system/detail/generic/remove.inl +include/thrust/system/detail/generic/replace.h +include/thrust/system/detail/generic/replace.inl +include/thrust/system/detail/generic/reverse.h +include/thrust/system/detail/generic/reverse.inl +include/thrust/system/detail/generic/scalar/binary_search.h +include/thrust/system/detail/generic/scalar/binary_search.inl +include/thrust/system/detail/generic/scan.h +include/thrust/system/detail/generic/scan.inl +include/thrust/system/detail/generic/scan_by_key.h +include/thrust/system/detail/generic/scan_by_key.inl +include/thrust/system/detail/generic/scatter.h +include/thrust/system/detail/generic/scatter.inl +include/thrust/system/detail/generic/select_system.h +include/thrust/system/detail/generic/select_system.inl +include/thrust/system/detail/generic/select_system_exists.h +include/thrust/system/detail/generic/sequence.h +include/thrust/system/detail/generic/sequence.inl +include/thrust/system/detail/generic/set_operations.h +include/thrust/system/detail/generic/set_operations.inl +include/thrust/system/detail/generic/shuffle.h +include/thrust/system/detail/generic/shuffle.inl +include/thrust/system/detail/generic/sort.h +include/thrust/system/detail/generic/sort.inl +include/thrust/system/detail/generic/swap_ranges.h +include/thrust/system/detail/generic/swap_ranges.inl +include/thrust/system/detail/generic/tabulate.h +include/thrust/system/detail/generic/tabulate.inl +include/thrust/system/detail/generic/tag.h +include/thrust/system/detail/generic/temporary_buffer.h +include/thrust/system/detail/generic/temporary_buffer.inl +include/thrust/system/detail/generic/transform.h +include/thrust/system/detail/generic/transform.inl +include/thrust/system/detail/generic/transform_reduce.h +include/thrust/system/detail/generic/transform_reduce.inl +include/thrust/system/detail/generic/transform_scan.h +include/thrust/system/detail/generic/transform_scan.inl +include/thrust/system/detail/generic/uninitialized_copy.h +include/thrust/system/detail/generic/uninitialized_copy.inl +include/thrust/system/detail/generic/uninitialized_fill.h +include/thrust/system/detail/generic/uninitialized_fill.inl +include/thrust/system/detail/generic/unique.h +include/thrust/system/detail/generic/unique.inl +include/thrust/system/detail/generic/unique_by_key.h +include/thrust/system/detail/generic/unique_by_key.inl +include/thrust/system/detail/internal/decompose.h +include/thrust/system/detail/sequential/adjacent_difference.h +include/thrust/system/detail/sequential/assign_value.h +include/thrust/system/detail/sequential/binary_search.h +include/thrust/system/detail/sequential/copy.h +include/thrust/system/detail/sequential/copy.inl +include/thrust/system/detail/sequential/copy_backward.h +include/thrust/system/detail/sequential/copy_if.h +include/thrust/system/detail/sequential/count.h +include/thrust/system/detail/sequential/equal.h +include/thrust/system/detail/sequential/execution_policy.h +include/thrust/system/detail/sequential/extrema.h +include/thrust/system/detail/sequential/fill.h +include/thrust/system/detail/sequential/find.h +include/thrust/system/detail/sequential/for_each.h +include/thrust/system/detail/sequential/gather.h +include/thrust/system/detail/sequential/general_copy.h +include/thrust/system/detail/sequential/generate.h +include/thrust/system/detail/sequential/get_value.h +include/thrust/system/detail/sequential/inner_product.h +include/thrust/system/detail/sequential/insertion_sort.h +include/thrust/system/detail/sequential/iter_swap.h +include/thrust/system/detail/sequential/logical.h +include/thrust/system/detail/sequential/malloc_and_free.h +include/thrust/system/detail/sequential/merge.h +include/thrust/system/detail/sequential/merge.inl +include/thrust/system/detail/sequential/mismatch.h +include/thrust/system/detail/sequential/partition.h +include/thrust/system/detail/sequential/per_device_resource.h +include/thrust/system/detail/sequential/reduce.h +include/thrust/system/detail/sequential/reduce_by_key.h +include/thrust/system/detail/sequential/remove.h +include/thrust/system/detail/sequential/replace.h +include/thrust/system/detail/sequential/reverse.h +include/thrust/system/detail/sequential/scan.h +include/thrust/system/detail/sequential/scan_by_key.h +include/thrust/system/detail/sequential/scatter.h +include/thrust/system/detail/sequential/sequence.h +include/thrust/system/detail/sequential/set_operations.h +include/thrust/system/detail/sequential/sort.h +include/thrust/system/detail/sequential/sort.inl +include/thrust/system/detail/sequential/stable_merge_sort.h +include/thrust/system/detail/sequential/stable_merge_sort.inl +include/thrust/system/detail/sequential/stable_primitive_sort.h +include/thrust/system/detail/sequential/stable_primitive_sort.inl +include/thrust/system/detail/sequential/stable_radix_sort.h +include/thrust/system/detail/sequential/stable_radix_sort.inl +include/thrust/system/detail/sequential/swap_ranges.h +include/thrust/system/detail/sequential/tabulate.h +include/thrust/system/detail/sequential/temporary_buffer.h +include/thrust/system/detail/sequential/transform.h +include/thrust/system/detail/sequential/transform_reduce.h +include/thrust/system/detail/sequential/transform_scan.h +include/thrust/system/detail/sequential/trivial_copy.h +include/thrust/system/detail/sequential/uninitialized_copy.h +include/thrust/system/detail/sequential/uninitialized_fill.h +include/thrust/system/detail/sequential/unique.h +include/thrust/system/detail/sequential/unique_by_key.h +include/thrust/system/detail/system_error.inl +include/thrust/system/error_code.h +include/thrust/system/omp/detail/adjacent_difference.h +include/thrust/system/omp/detail/assign_value.h +include/thrust/system/omp/detail/binary_search.h +include/thrust/system/omp/detail/copy.h +include/thrust/system/omp/detail/copy.inl +include/thrust/system/omp/detail/copy_if.h +include/thrust/system/omp/detail/copy_if.inl +include/thrust/system/omp/detail/count.h +include/thrust/system/omp/detail/default_decomposition.h +include/thrust/system/omp/detail/default_decomposition.inl +include/thrust/system/omp/detail/equal.h +include/thrust/system/omp/detail/execution_policy.h +include/thrust/system/omp/detail/extrema.h +include/thrust/system/omp/detail/fill.h +include/thrust/system/omp/detail/find.h +include/thrust/system/omp/detail/for_each.h +include/thrust/system/omp/detail/for_each.inl +include/thrust/system/omp/detail/gather.h +include/thrust/system/omp/detail/generate.h +include/thrust/system/omp/detail/get_value.h +include/thrust/system/omp/detail/inner_product.h +include/thrust/system/omp/detail/iter_swap.h +include/thrust/system/omp/detail/logical.h +include/thrust/system/omp/detail/malloc_and_free.h +include/thrust/system/omp/detail/memory.inl +include/thrust/system/omp/detail/merge.h +include/thrust/system/omp/detail/mismatch.h +include/thrust/system/omp/detail/par.h +include/thrust/system/omp/detail/partition.h +include/thrust/system/omp/detail/partition.inl +include/thrust/system/omp/detail/per_device_resource.h +include/thrust/system/omp/detail/pragma_omp.h +include/thrust/system/omp/detail/reduce.h +include/thrust/system/omp/detail/reduce.inl +include/thrust/system/omp/detail/reduce_by_key.h +include/thrust/system/omp/detail/reduce_by_key.inl +include/thrust/system/omp/detail/reduce_intervals.h +include/thrust/system/omp/detail/reduce_intervals.inl +include/thrust/system/omp/detail/remove.h +include/thrust/system/omp/detail/remove.inl +include/thrust/system/omp/detail/replace.h +include/thrust/system/omp/detail/reverse.h +include/thrust/system/omp/detail/scan.h +include/thrust/system/omp/detail/scan_by_key.h +include/thrust/system/omp/detail/scatter.h +include/thrust/system/omp/detail/sequence.h +include/thrust/system/omp/detail/set_operations.h +include/thrust/system/omp/detail/sort.h +include/thrust/system/omp/detail/sort.inl +include/thrust/system/omp/detail/swap_ranges.h +include/thrust/system/omp/detail/tabulate.h +include/thrust/system/omp/detail/temporary_buffer.h +include/thrust/system/omp/detail/transform.h +include/thrust/system/omp/detail/transform_reduce.h +include/thrust/system/omp/detail/transform_scan.h +include/thrust/system/omp/detail/uninitialized_copy.h +include/thrust/system/omp/detail/uninitialized_fill.h +include/thrust/system/omp/detail/unique.h +include/thrust/system/omp/detail/unique.inl +include/thrust/system/omp/detail/unique_by_key.h +include/thrust/system/omp/detail/unique_by_key.inl +include/thrust/system/omp/execution_policy.h +include/thrust/system/omp/memory.h +include/thrust/system/omp/memory_resource.h +include/thrust/system/omp/pointer.h +include/thrust/system/omp/vector.h +include/thrust/system/system_error.h +include/thrust/system/tbb/detail/adjacent_difference.h +include/thrust/system/tbb/detail/assign_value.h +include/thrust/system/tbb/detail/binary_search.h +include/thrust/system/tbb/detail/copy.h +include/thrust/system/tbb/detail/copy.inl +include/thrust/system/tbb/detail/copy_if.h +include/thrust/system/tbb/detail/copy_if.inl +include/thrust/system/tbb/detail/count.h +include/thrust/system/tbb/detail/equal.h +include/thrust/system/tbb/detail/execution_policy.h +include/thrust/system/tbb/detail/extrema.h +include/thrust/system/tbb/detail/fill.h +include/thrust/system/tbb/detail/find.h +include/thrust/system/tbb/detail/for_each.h +include/thrust/system/tbb/detail/for_each.inl +include/thrust/system/tbb/detail/gather.h +include/thrust/system/tbb/detail/generate.h +include/thrust/system/tbb/detail/get_value.h +include/thrust/system/tbb/detail/inner_product.h +include/thrust/system/tbb/detail/iter_swap.h +include/thrust/system/tbb/detail/logical.h +include/thrust/system/tbb/detail/malloc_and_free.h +include/thrust/system/tbb/detail/memory.inl +include/thrust/system/tbb/detail/merge.h +include/thrust/system/tbb/detail/merge.inl +include/thrust/system/tbb/detail/mismatch.h +include/thrust/system/tbb/detail/par.h +include/thrust/system/tbb/detail/partition.h +include/thrust/system/tbb/detail/partition.inl +include/thrust/system/tbb/detail/per_device_resource.h +include/thrust/system/tbb/detail/reduce.h +include/thrust/system/tbb/detail/reduce.inl +include/thrust/system/tbb/detail/reduce_by_key.h +include/thrust/system/tbb/detail/reduce_by_key.inl +include/thrust/system/tbb/detail/reduce_intervals.h +include/thrust/system/tbb/detail/remove.h +include/thrust/system/tbb/detail/remove.inl +include/thrust/system/tbb/detail/replace.h +include/thrust/system/tbb/detail/reverse.h +include/thrust/system/tbb/detail/scan.h +include/thrust/system/tbb/detail/scan.inl +include/thrust/system/tbb/detail/scan_by_key.h +include/thrust/system/tbb/detail/scatter.h +include/thrust/system/tbb/detail/sequence.h +include/thrust/system/tbb/detail/set_operations.h +include/thrust/system/tbb/detail/sort.h +include/thrust/system/tbb/detail/sort.inl +include/thrust/system/tbb/detail/swap_ranges.h +include/thrust/system/tbb/detail/tabulate.h +include/thrust/system/tbb/detail/temporary_buffer.h +include/thrust/system/tbb/detail/transform.h +include/thrust/system/tbb/detail/transform_reduce.h +include/thrust/system/tbb/detail/transform_scan.h +include/thrust/system/tbb/detail/uninitialized_copy.h +include/thrust/system/tbb/detail/uninitialized_fill.h +include/thrust/system/tbb/detail/unique.h +include/thrust/system/tbb/detail/unique.inl +include/thrust/system/tbb/detail/unique_by_key.h +include/thrust/system/tbb/detail/unique_by_key.inl +include/thrust/system/tbb/execution_policy.h +include/thrust/system/tbb/memory.h +include/thrust/system/tbb/memory_resource.h +include/thrust/system/tbb/pointer.h +include/thrust/system/tbb/vector.h +include/thrust/system_error.h +include/thrust/tabulate.h +include/thrust/transform.h +include/thrust/transform_reduce.h +include/thrust/transform_scan.h +include/thrust/tuple.h +include/thrust/type_traits/integer_sequence.h +include/thrust/type_traits/is_contiguous_iterator.h +include/thrust/type_traits/is_execution_policy.h +include/thrust/type_traits/is_operator_less_or_greater_function_object.h +include/thrust/type_traits/is_operator_plus_function_object.h +include/thrust/type_traits/is_trivially_relocatable.h +include/thrust/type_traits/logical_metafunctions.h +include/thrust/type_traits/remove_cvref.h +include/thrust/type_traits/void_t.h +include/thrust/uninitialized_copy.h +include/thrust/uninitialized_fill.h +include/thrust/unique.h +include/thrust/universal_allocator.h +include/thrust/universal_ptr.h +include/thrust/universal_vector.h +include/thrust/version.h +include/thrust/zip_function.h +include/utils.h +include/vec.h +src/CMakeLists.txt +src/QuickHull.cpp +src/boolean3.cpp +src/boolean3.h +src/boolean_result.cpp +src/clipper.engine.cpp +src/clipper.offset.cpp +src/clipper.rectclip.cpp +src/collider.cpp +src/constructors.cpp +src/cross_section.cpp +src/csg_tree.cpp +src/csg_tree.h +src/edge_op.cpp +src/face_op.cpp +src/impl.cpp +src/impl.h +src/manifold.cpp +src/mesh_fixes.h +src/polygon.cpp +src/properties.cpp +src/sdf.cpp +src/shared.h +src/smoothing.cpp +src/sort.cpp +thrust/LICENSE +thrust/README.md +thrust/dependencies/cub/LICENSE.TXT +thrust/dependencies/cub/cub/agent/agent_adjacent_difference.cuh +thrust/dependencies/cub/cub/agent/agent_batch_memcpy.cuh +thrust/dependencies/cub/cub/agent/agent_histogram.cuh +thrust/dependencies/cub/cub/agent/agent_merge_sort.cuh +thrust/dependencies/cub/cub/agent/agent_radix_sort_downsweep.cuh +thrust/dependencies/cub/cub/agent/agent_radix_sort_histogram.cuh +thrust/dependencies/cub/cub/agent/agent_radix_sort_onesweep.cuh +thrust/dependencies/cub/cub/agent/agent_radix_sort_upsweep.cuh +thrust/dependencies/cub/cub/agent/agent_reduce.cuh +thrust/dependencies/cub/cub/agent/agent_reduce_by_key.cuh +thrust/dependencies/cub/cub/agent/agent_rle.cuh +thrust/dependencies/cub/cub/agent/agent_scan.cuh +thrust/dependencies/cub/cub/agent/agent_scan_by_key.cuh +thrust/dependencies/cub/cub/agent/agent_segment_fixup.cuh +thrust/dependencies/cub/cub/agent/agent_segmented_radix_sort.cuh +thrust/dependencies/cub/cub/agent/agent_select_if.cuh +thrust/dependencies/cub/cub/agent/agent_spmv_orig.cuh +thrust/dependencies/cub/cub/agent/agent_sub_warp_merge_sort.cuh +thrust/dependencies/cub/cub/agent/agent_three_way_partition.cuh +thrust/dependencies/cub/cub/agent/agent_unique_by_key.cuh +thrust/dependencies/cub/cub/agent/single_pass_scan_operators.cuh +thrust/dependencies/cub/cub/block/block_adjacent_difference.cuh +thrust/dependencies/cub/cub/block/block_discontinuity.cuh +thrust/dependencies/cub/cub/block/block_exchange.cuh +thrust/dependencies/cub/cub/block/block_histogram.cuh +thrust/dependencies/cub/cub/block/block_load.cuh +thrust/dependencies/cub/cub/block/block_merge_sort.cuh +thrust/dependencies/cub/cub/block/block_radix_rank.cuh +thrust/dependencies/cub/cub/block/block_radix_sort.cuh +thrust/dependencies/cub/cub/block/block_raking_layout.cuh +thrust/dependencies/cub/cub/block/block_reduce.cuh +thrust/dependencies/cub/cub/block/block_run_length_decode.cuh +thrust/dependencies/cub/cub/block/block_scan.cuh +thrust/dependencies/cub/cub/block/block_shuffle.cuh +thrust/dependencies/cub/cub/block/block_store.cuh +thrust/dependencies/cub/cub/block/radix_rank_sort_operations.cuh +thrust/dependencies/cub/cub/block/specializations/block_histogram_atomic.cuh +thrust/dependencies/cub/cub/block/specializations/block_histogram_sort.cuh +thrust/dependencies/cub/cub/block/specializations/block_reduce_raking.cuh +thrust/dependencies/cub/cub/block/specializations/block_reduce_raking_commutative_only.cuh +thrust/dependencies/cub/cub/block/specializations/block_reduce_warp_reductions.cuh +thrust/dependencies/cub/cub/block/specializations/block_scan_raking.cuh +thrust/dependencies/cub/cub/block/specializations/block_scan_warp_scans.cuh +thrust/dependencies/cub/cub/cmake/cub-config-version.cmake +thrust/dependencies/cub/cub/cmake/cub-config.cmake +thrust/dependencies/cub/cub/cmake/cub-header-search.cmake +thrust/dependencies/cub/cub/cmake/cub-header-search.cmake.in +thrust/dependencies/cub/cub/config.cuh +thrust/dependencies/cub/cub/cub.cuh +thrust/dependencies/cub/cub/detail/choose_offset.cuh +thrust/dependencies/cub/cub/detail/cpp_compatibility.cuh +thrust/dependencies/cub/cub/detail/detect_cuda_runtime.cuh +thrust/dependencies/cub/cub/detail/device_double_buffer.cuh +thrust/dependencies/cub/cub/detail/device_synchronize.cuh +thrust/dependencies/cub/cub/detail/exec_check_disable.cuh +thrust/dependencies/cub/cub/detail/strong_load.cuh +thrust/dependencies/cub/cub/detail/strong_store.cuh +thrust/dependencies/cub/cub/detail/temporary_storage.cuh +thrust/dependencies/cub/cub/detail/type_traits.cuh +thrust/dependencies/cub/cub/detail/uninitialized_copy.cuh +thrust/dependencies/cub/cub/device/device_adjacent_difference.cuh +thrust/dependencies/cub/cub/device/device_histogram.cuh +thrust/dependencies/cub/cub/device/device_memcpy.cuh +thrust/dependencies/cub/cub/device/device_merge_sort.cuh +thrust/dependencies/cub/cub/device/device_partition.cuh +thrust/dependencies/cub/cub/device/device_radix_sort.cuh +thrust/dependencies/cub/cub/device/device_reduce.cuh +thrust/dependencies/cub/cub/device/device_run_length_encode.cuh +thrust/dependencies/cub/cub/device/device_scan.cuh +thrust/dependencies/cub/cub/device/device_segmented_radix_sort.cuh +thrust/dependencies/cub/cub/device/device_segmented_reduce.cuh +thrust/dependencies/cub/cub/device/device_segmented_sort.cuh +thrust/dependencies/cub/cub/device/device_select.cuh +thrust/dependencies/cub/cub/device/device_spmv.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_adjacent_difference.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_batch_memcpy.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_histogram.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_merge_sort.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_radix_sort.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_reduce.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_reduce_by_key.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_rle.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_scan.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_scan_by_key.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_segmented_sort.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_select_if.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_spmv_orig.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_three_way_partition.cuh +thrust/dependencies/cub/cub/device/dispatch/dispatch_unique_by_key.cuh +thrust/dependencies/cub/cub/grid/grid_barrier.cuh +thrust/dependencies/cub/cub/grid/grid_even_share.cuh +thrust/dependencies/cub/cub/grid/grid_mapping.cuh +thrust/dependencies/cub/cub/grid/grid_queue.cuh +thrust/dependencies/cub/cub/host/mutex.cuh +thrust/dependencies/cub/cub/iterator/arg_index_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/cache_modified_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/cache_modified_output_iterator.cuh +thrust/dependencies/cub/cub/iterator/constant_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/counting_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/discard_output_iterator.cuh +thrust/dependencies/cub/cub/iterator/tex_obj_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/tex_ref_input_iterator.cuh +thrust/dependencies/cub/cub/iterator/transform_input_iterator.cuh +thrust/dependencies/cub/cub/thread/thread_load.cuh +thrust/dependencies/cub/cub/thread/thread_operators.cuh +thrust/dependencies/cub/cub/thread/thread_reduce.cuh +thrust/dependencies/cub/cub/thread/thread_scan.cuh +thrust/dependencies/cub/cub/thread/thread_search.cuh +thrust/dependencies/cub/cub/thread/thread_sort.cuh +thrust/dependencies/cub/cub/thread/thread_store.cuh +thrust/dependencies/cub/cub/util_allocator.cuh +thrust/dependencies/cub/cub/util_arch.cuh +thrust/dependencies/cub/cub/util_compiler.cuh +thrust/dependencies/cub/cub/util_cpp_dialect.cuh +thrust/dependencies/cub/cub/util_debug.cuh +thrust/dependencies/cub/cub/util_deprecated.cuh +thrust/dependencies/cub/cub/util_device.cuh +thrust/dependencies/cub/cub/util_macro.cuh +thrust/dependencies/cub/cub/util_math.cuh +thrust/dependencies/cub/cub/util_namespace.cuh +thrust/dependencies/cub/cub/util_ptx.cuh +thrust/dependencies/cub/cub/util_type.cuh +thrust/dependencies/cub/cub/version.cuh +thrust/dependencies/cub/cub/warp/specializations/warp_reduce_shfl.cuh +thrust/dependencies/cub/cub/warp/specializations/warp_reduce_smem.cuh +thrust/dependencies/cub/cub/warp/specializations/warp_scan_shfl.cuh +thrust/dependencies/cub/cub/warp/specializations/warp_scan_smem.cuh +thrust/dependencies/cub/cub/warp/warp_exchange.cuh +thrust/dependencies/cub/cub/warp/warp_load.cuh +thrust/dependencies/cub/cub/warp/warp_merge_sort.cuh +thrust/dependencies/cub/cub/warp/warp_reduce.cuh +thrust/dependencies/cub/cub/warp/warp_scan.cuh +thrust/dependencies/cub/cub/warp/warp_store.cuh +thrust/dependencies/libcudacxx/LICENSE.TXT +thrust/dependencies/libcudacxx/include/cuda/annotated_ptr +thrust/dependencies/libcudacxx/include/cuda/atomic +thrust/dependencies/libcudacxx/include/cuda/barrier +thrust/dependencies/libcudacxx/include/cuda/latch +thrust/dependencies/libcudacxx/include/cuda/pipeline +thrust/dependencies/libcudacxx/include/cuda/semaphore +thrust/dependencies/libcudacxx/include/cuda/std/array +thrust/dependencies/libcudacxx/include/cuda/std/atomic +thrust/dependencies/libcudacxx/include/cuda/std/barrier +thrust/dependencies/libcudacxx/include/cuda/std/bit +thrust/dependencies/libcudacxx/include/cuda/std/cassert +thrust/dependencies/libcudacxx/include/cuda/std/ccomplex +thrust/dependencies/libcudacxx/include/cuda/std/cfloat +thrust/dependencies/libcudacxx/include/cuda/std/chrono +thrust/dependencies/libcudacxx/include/cuda/std/climits +thrust/dependencies/libcudacxx/include/cuda/std/cmath +thrust/dependencies/libcudacxx/include/cuda/std/complex +thrust/dependencies/libcudacxx/include/cuda/std/cstddef +thrust/dependencies/libcudacxx/include/cuda/std/cstdint +thrust/dependencies/libcudacxx/include/cuda/std/ctime +thrust/dependencies/libcudacxx/include/cuda/std/detail/__access_property +thrust/dependencies/libcudacxx/include/cuda/std/detail/__annotated_ptr +thrust/dependencies/libcudacxx/include/cuda/std/detail/__config +thrust/dependencies/libcudacxx/include/cuda/std/detail/__functional_base +thrust/dependencies/libcudacxx/include/cuda/std/detail/__pragma_pop +thrust/dependencies/libcudacxx/include/cuda/std/detail/__pragma_push +thrust/dependencies/libcudacxx/include/cuda/std/detail/__threading_support +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/CMakeLists.txt +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__bit_reference +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__bsd_locale_defaults.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__bsd_locale_fallbacks.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__config +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__config_site.in +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__debug +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__errc +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__functional_03 +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__functional_base +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__functional_base_03 +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__hash_table +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__libcpp_version +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__locale +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__mutex_base +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__node_handle +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__nullptr +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__pragma_pop +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__pragma_push +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__split_buffer +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__sso_allocator +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__std_stream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__string +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__threading_support +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__tree +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__tuple +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/__undef_macros +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/algorithm +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/any +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/array +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/atomic +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/barrier +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/bit +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/bitset +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cassert +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ccomplex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cctype +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cerrno +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cfenv +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cfloat +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/charconv +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/chrono +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cinttypes +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ciso646 +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/climits +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/clocale +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cmath +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/codecvt +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/compare +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/complex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/complex.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/condition_variable +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/csetjmp +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/csignal +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstdarg +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstdbool +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstddef +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstdint +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstdio +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstdlib +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cstring +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ctgmath +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ctime +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ctype.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cwchar +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/cwctype +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/deque +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/errno.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/exception +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/execution +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/__config +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/__memory +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/algorithm +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/coroutine +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/deque +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/filesystem +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/forward_list +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/functional +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/iterator +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/list +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/map +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/memory_resource +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/propagate_const +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/regex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/set +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/simd +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/string +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/type_traits +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/unordered_map +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/unordered_set +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/utility +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/experimental/vector +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ext/__hash +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ext/hash_map +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ext/hash_set +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/fenv.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/filesystem +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/float.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/forward_list +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/fstream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/functional +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/future +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/initializer_list +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/inttypes.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/iomanip +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ios +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/iosfwd +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/iostream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/istream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/iterator +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/latch +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/limits +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/limits.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/list +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/locale +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/locale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/map +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/math.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/memory +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/module.modulemap +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/mutex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/new +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/numeric +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/optional +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ostream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/queue +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/random +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/ratio +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/regex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/scoped_allocator +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/semaphore +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/set +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/setjmp.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/shared_mutex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/span +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/sstream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stack +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stdbool.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stddef.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stdexcept +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stdint.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stdio.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/stdlib.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/streambuf +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/string +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/string.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/string_view +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/strstream +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/android/locale_bionic.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_base.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_c11.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_cuda.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_cuda_derived.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_cuda_generated.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_gcc.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_msvc.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_nvrtc.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/atomic_scopes.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/atomic/cxx_atomic.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/fuchsia/xlocale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/ibm/limits.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/ibm/locale_mgmt_aix.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/ibm/support.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/ibm/xlocale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/musl/xlocale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/newlib/xlocale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/solaris/floatingpoint.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/solaris/wchar.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/solaris/xlocale.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/win32/limits_msvc_win32.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/win32/locale_win32.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/xlocale/__nop_locale_mgmt.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/xlocale/__posix_l_fallback.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/support/xlocale/__strtonum_fallback.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/system_error +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/tgmath.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/thread +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/tuple +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/type_traits +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/typeindex +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/typeinfo +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/unordered_map +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/unordered_set +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/utility +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/valarray +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/variant +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/vector +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/version +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/wchar.h +thrust/dependencies/libcudacxx/include/cuda/std/detail/libcxx/include/wctype.h +thrust/dependencies/libcudacxx/include/cuda/std/functional +thrust/dependencies/libcudacxx/include/cuda/std/initializer_list +thrust/dependencies/libcudacxx/include/cuda/std/iterator +thrust/dependencies/libcudacxx/include/cuda/std/latch +thrust/dependencies/libcudacxx/include/cuda/std/limits +thrust/dependencies/libcudacxx/include/cuda/std/ratio +thrust/dependencies/libcudacxx/include/cuda/std/semaphore +thrust/dependencies/libcudacxx/include/cuda/std/tuple +thrust/dependencies/libcudacxx/include/cuda/std/type_traits +thrust/dependencies/libcudacxx/include/cuda/std/utility +thrust/dependencies/libcudacxx/include/cuda/std/version +thrust/dependencies/libcudacxx/include/nv/detail/__preprocessor +thrust/dependencies/libcudacxx/include/nv/detail/__target_macros +thrust/dependencies/libcudacxx/include/nv/target +thrust/thrust/addressof.h +thrust/thrust/adjacent_difference.h +thrust/thrust/advance.h +thrust/thrust/allocate_unique.h +thrust/thrust/async/copy.h +thrust/thrust/async/for_each.h +thrust/thrust/async/reduce.h +thrust/thrust/async/scan.h +thrust/thrust/async/sort.h +thrust/thrust/async/transform.h +thrust/thrust/binary_search.h +thrust/thrust/cmake/FindTBB.cmake +thrust/thrust/cmake/README.md +thrust/thrust/cmake/thrust-config-version.cmake +thrust/thrust/cmake/thrust-config.cmake +thrust/thrust/cmake/thrust-header-search.cmake +thrust/thrust/cmake/thrust-header-search.cmake.in +thrust/thrust/complex.h +thrust/thrust/copy.h +thrust/thrust/count.h +thrust/thrust/detail/adjacent_difference.inl +thrust/thrust/detail/advance.inl +thrust/thrust/detail/algorithm_wrapper.h +thrust/thrust/detail/alignment.h +thrust/thrust/detail/allocator/allocator_traits.h +thrust/thrust/detail/allocator/allocator_traits.inl +thrust/thrust/detail/allocator/copy_construct_range.h +thrust/thrust/detail/allocator/copy_construct_range.inl +thrust/thrust/detail/allocator/default_construct_range.h +thrust/thrust/detail/allocator/default_construct_range.inl +thrust/thrust/detail/allocator/destroy_range.h +thrust/thrust/detail/allocator/destroy_range.inl +thrust/thrust/detail/allocator/fill_construct_range.h +thrust/thrust/detail/allocator/fill_construct_range.inl +thrust/thrust/detail/allocator/malloc_allocator.h +thrust/thrust/detail/allocator/malloc_allocator.inl +thrust/thrust/detail/allocator/no_throw_allocator.h +thrust/thrust/detail/allocator/tagged_allocator.h +thrust/thrust/detail/allocator/tagged_allocator.inl +thrust/thrust/detail/allocator/temporary_allocator.h +thrust/thrust/detail/allocator/temporary_allocator.inl +thrust/thrust/detail/allocator_aware_execution_policy.h +thrust/thrust/detail/binary_search.inl +thrust/thrust/detail/caching_allocator.h +thrust/thrust/detail/complex/arithmetic.h +thrust/thrust/detail/complex/c99math.h +thrust/thrust/detail/complex/catrig.h +thrust/thrust/detail/complex/catrigf.h +thrust/thrust/detail/complex/ccosh.h +thrust/thrust/detail/complex/ccoshf.h +thrust/thrust/detail/complex/cexp.h +thrust/thrust/detail/complex/cexpf.h +thrust/thrust/detail/complex/clog.h +thrust/thrust/detail/complex/clogf.h +thrust/thrust/detail/complex/complex.inl +thrust/thrust/detail/complex/cpow.h +thrust/thrust/detail/complex/cproj.h +thrust/thrust/detail/complex/csinh.h +thrust/thrust/detail/complex/csinhf.h +thrust/thrust/detail/complex/csqrt.h +thrust/thrust/detail/complex/csqrtf.h +thrust/thrust/detail/complex/ctanh.h +thrust/thrust/detail/complex/ctanhf.h +thrust/thrust/detail/complex/math_private.h +thrust/thrust/detail/complex/stream.h +thrust/thrust/detail/config.h +thrust/thrust/detail/config/compiler.h +thrust/thrust/detail/config/compiler_fence.h +thrust/thrust/detail/config/config.h +thrust/thrust/detail/config/cpp_compatibility.h +thrust/thrust/detail/config/cpp_dialect.h +thrust/thrust/detail/config/debug.h +thrust/thrust/detail/config/deprecated.h +thrust/thrust/detail/config/device_system.h +thrust/thrust/detail/config/exec_check_disable.h +thrust/thrust/detail/config/forceinline.h +thrust/thrust/detail/config/global_workarounds.h +thrust/thrust/detail/config/host_device.h +thrust/thrust/detail/config/host_system.h +thrust/thrust/detail/config/memory_resource.h +thrust/thrust/detail/config/namespace.h +thrust/thrust/detail/config/simple_defines.h +thrust/thrust/detail/contiguous_storage.h +thrust/thrust/detail/contiguous_storage.inl +thrust/thrust/detail/copy.h +thrust/thrust/detail/copy.inl +thrust/thrust/detail/copy_if.h +thrust/thrust/detail/copy_if.inl +thrust/thrust/detail/count.h +thrust/thrust/detail/count.inl +thrust/thrust/detail/cpp11_required.h +thrust/thrust/detail/cpp14_required.h +thrust/thrust/detail/cstdint.h +thrust/thrust/detail/dependencies_aware_execution_policy.h +thrust/thrust/detail/device_delete.inl +thrust/thrust/detail/device_free.inl +thrust/thrust/detail/device_malloc.inl +thrust/thrust/detail/device_new.inl +thrust/thrust/detail/device_ptr.inl +thrust/thrust/detail/distance.inl +thrust/thrust/detail/equal.inl +thrust/thrust/detail/event_error.h +thrust/thrust/detail/execute_with_allocator.h +thrust/thrust/detail/execute_with_allocator_fwd.h +thrust/thrust/detail/execute_with_dependencies.h +thrust/thrust/detail/execution_policy.h +thrust/thrust/detail/extrema.inl +thrust/thrust/detail/fill.inl +thrust/thrust/detail/find.inl +thrust/thrust/detail/for_each.inl +thrust/thrust/detail/function.h +thrust/thrust/detail/functional.inl +thrust/thrust/detail/functional/actor.h +thrust/thrust/detail/functional/actor.inl +thrust/thrust/detail/functional/argument.h +thrust/thrust/detail/functional/composite.h +thrust/thrust/detail/functional/operators.h +thrust/thrust/detail/functional/operators/arithmetic_operators.h +thrust/thrust/detail/functional/operators/assignment_operator.h +thrust/thrust/detail/functional/operators/bitwise_operators.h +thrust/thrust/detail/functional/operators/compound_assignment_operators.h +thrust/thrust/detail/functional/operators/logical_operators.h +thrust/thrust/detail/functional/operators/operator_adaptors.h +thrust/thrust/detail/functional/operators/relational_operators.h +thrust/thrust/detail/functional/placeholder.h +thrust/thrust/detail/functional/value.h +thrust/thrust/detail/gather.inl +thrust/thrust/detail/generate.inl +thrust/thrust/detail/get_iterator_value.h +thrust/thrust/detail/inner_product.inl +thrust/thrust/detail/integer_math.h +thrust/thrust/detail/integer_traits.h +thrust/thrust/detail/internal_functional.h +thrust/thrust/detail/logical.inl +thrust/thrust/detail/malloc_and_free.h +thrust/thrust/detail/memory_algorithms.h +thrust/thrust/detail/memory_wrapper.h +thrust/thrust/detail/merge.inl +thrust/thrust/detail/minmax.h +thrust/thrust/detail/mismatch.inl +thrust/thrust/detail/modern_gcc_required.h +thrust/thrust/detail/mpl/math.h +thrust/thrust/detail/numeric_traits.h +thrust/thrust/detail/numeric_wrapper.h +thrust/thrust/detail/overlapped_copy.h +thrust/thrust/detail/pair.inl +thrust/thrust/detail/partition.inl +thrust/thrust/detail/pointer.h +thrust/thrust/detail/pointer.inl +thrust/thrust/detail/preprocessor.h +thrust/thrust/detail/range/head_flags.h +thrust/thrust/detail/range/tail_flags.h +thrust/thrust/detail/raw_pointer_cast.h +thrust/thrust/detail/raw_reference_cast.h +thrust/thrust/detail/reduce.inl +thrust/thrust/detail/reference.h +thrust/thrust/detail/reference_forward_declaration.h +thrust/thrust/detail/remove.inl +thrust/thrust/detail/replace.inl +thrust/thrust/detail/reverse.inl +thrust/thrust/detail/scan.inl +thrust/thrust/detail/scatter.inl +thrust/thrust/detail/select_system.h +thrust/thrust/detail/seq.h +thrust/thrust/detail/sequence.inl +thrust/thrust/detail/set_operations.inl +thrust/thrust/detail/shuffle.inl +thrust/thrust/detail/sort.inl +thrust/thrust/detail/static_assert.h +thrust/thrust/detail/static_map.h +thrust/thrust/detail/swap.h +thrust/thrust/detail/swap.inl +thrust/thrust/detail/swap_ranges.inl +thrust/thrust/detail/tabulate.inl +thrust/thrust/detail/temporary_array.h +thrust/thrust/detail/temporary_array.inl +thrust/thrust/detail/temporary_buffer.h +thrust/thrust/detail/transform.inl +thrust/thrust/detail/transform_reduce.inl +thrust/thrust/detail/transform_scan.inl +thrust/thrust/detail/trivial_sequence.h +thrust/thrust/detail/tuple.inl +thrust/thrust/detail/tuple_algorithms.h +thrust/thrust/detail/tuple_meta_transform.h +thrust/thrust/detail/tuple_transform.h +thrust/thrust/detail/type_deduction.h +thrust/thrust/detail/type_traits.h +thrust/thrust/detail/type_traits/function_traits.h +thrust/thrust/detail/type_traits/has_member_function.h +thrust/thrust/detail/type_traits/has_nested_type.h +thrust/thrust/detail/type_traits/has_trivial_assign.h +thrust/thrust/detail/type_traits/is_call_possible.h +thrust/thrust/detail/type_traits/is_metafunction_defined.h +thrust/thrust/detail/type_traits/iterator/is_discard_iterator.h +thrust/thrust/detail/type_traits/iterator/is_output_iterator.h +thrust/thrust/detail/type_traits/minimum_type.h +thrust/thrust/detail/type_traits/pointer_traits.h +thrust/thrust/detail/type_traits/result_of_adaptable_function.h +thrust/thrust/detail/uninitialized_copy.inl +thrust/thrust/detail/uninitialized_fill.inl +thrust/thrust/detail/unique.inl +thrust/thrust/detail/use_default.h +thrust/thrust/detail/util/align.h +thrust/thrust/detail/vector_base.h +thrust/thrust/detail/vector_base.inl +thrust/thrust/device_allocator.h +thrust/thrust/device_delete.h +thrust/thrust/device_free.h +thrust/thrust/device_make_unique.h +thrust/thrust/device_malloc.h +thrust/thrust/device_malloc_allocator.h +thrust/thrust/device_new.h +thrust/thrust/device_new_allocator.h +thrust/thrust/device_ptr.h +thrust/thrust/device_reference.h +thrust/thrust/device_vector.h +thrust/thrust/distance.h +thrust/thrust/equal.h +thrust/thrust/event.h +thrust/thrust/execution_policy.h +thrust/thrust/extrema.h +thrust/thrust/fill.h +thrust/thrust/find.h +thrust/thrust/for_each.h +thrust/thrust/functional.h +thrust/thrust/future.h +thrust/thrust/gather.h +thrust/thrust/generate.h +thrust/thrust/host_vector.h +thrust/thrust/inner_product.h +thrust/thrust/iterator/constant_iterator.h +thrust/thrust/iterator/counting_iterator.h +thrust/thrust/iterator/detail/any_assign.h +thrust/thrust/iterator/detail/any_system_tag.h +thrust/thrust/iterator/detail/constant_iterator_base.h +thrust/thrust/iterator/detail/counting_iterator.inl +thrust/thrust/iterator/detail/device_system_tag.h +thrust/thrust/iterator/detail/discard_iterator_base.h +thrust/thrust/iterator/detail/distance_from_result.h +thrust/thrust/iterator/detail/host_system_tag.h +thrust/thrust/iterator/detail/is_iterator_category.h +thrust/thrust/iterator/detail/iterator_adaptor_base.h +thrust/thrust/iterator/detail/iterator_category_to_system.h +thrust/thrust/iterator/detail/iterator_category_to_traversal.h +thrust/thrust/iterator/detail/iterator_category_with_system_and_traversal.h +thrust/thrust/iterator/detail/iterator_facade_category.h +thrust/thrust/iterator/detail/iterator_traits.inl +thrust/thrust/iterator/detail/iterator_traversal_tags.h +thrust/thrust/iterator/detail/join_iterator.h +thrust/thrust/iterator/detail/minimum_category.h +thrust/thrust/iterator/detail/minimum_system.h +thrust/thrust/iterator/detail/normal_iterator.h +thrust/thrust/iterator/detail/permutation_iterator_base.h +thrust/thrust/iterator/detail/retag.h +thrust/thrust/iterator/detail/reverse_iterator.inl +thrust/thrust/iterator/detail/reverse_iterator_base.h +thrust/thrust/iterator/detail/tagged_iterator.h +thrust/thrust/iterator/detail/transform_input_output_iterator.inl +thrust/thrust/iterator/detail/transform_iterator.inl +thrust/thrust/iterator/detail/transform_output_iterator.inl +thrust/thrust/iterator/detail/tuple_of_iterator_references.h +thrust/thrust/iterator/detail/universal_categories.h +thrust/thrust/iterator/detail/zip_iterator.inl +thrust/thrust/iterator/detail/zip_iterator_base.h +thrust/thrust/iterator/discard_iterator.h +thrust/thrust/iterator/iterator_adaptor.h +thrust/thrust/iterator/iterator_categories.h +thrust/thrust/iterator/iterator_facade.h +thrust/thrust/iterator/iterator_traits.h +thrust/thrust/iterator/permutation_iterator.h +thrust/thrust/iterator/retag.h +thrust/thrust/iterator/reverse_iterator.h +thrust/thrust/iterator/transform_input_output_iterator.h +thrust/thrust/iterator/transform_iterator.h +thrust/thrust/iterator/transform_output_iterator.h +thrust/thrust/iterator/zip_iterator.h +thrust/thrust/limits.h +thrust/thrust/logical.h +thrust/thrust/memory.h +thrust/thrust/merge.h +thrust/thrust/mismatch.h +thrust/thrust/mr/allocator.h +thrust/thrust/mr/device_memory_resource.h +thrust/thrust/mr/disjoint_pool.h +thrust/thrust/mr/disjoint_sync_pool.h +thrust/thrust/mr/disjoint_tls_pool.h +thrust/thrust/mr/fancy_pointer_resource.h +thrust/thrust/mr/host_memory_resource.h +thrust/thrust/mr/memory_resource.h +thrust/thrust/mr/new.h +thrust/thrust/mr/polymorphic_adaptor.h +thrust/thrust/mr/pool.h +thrust/thrust/mr/pool_options.h +thrust/thrust/mr/sync_pool.h +thrust/thrust/mr/tls_pool.h +thrust/thrust/mr/universal_memory_resource.h +thrust/thrust/mr/validator.h +thrust/thrust/optional.h +thrust/thrust/pair.h +thrust/thrust/partition.h +thrust/thrust/per_device_resource.h +thrust/thrust/random.h +thrust/thrust/random/detail/discard_block_engine.inl +thrust/thrust/random/detail/linear_congruential_engine.inl +thrust/thrust/random/detail/linear_congruential_engine_discard.h +thrust/thrust/random/detail/linear_feedback_shift_engine.inl +thrust/thrust/random/detail/linear_feedback_shift_engine_wordmask.h +thrust/thrust/random/detail/mod.h +thrust/thrust/random/detail/normal_distribution.inl +thrust/thrust/random/detail/normal_distribution_base.h +thrust/thrust/random/detail/random_core_access.h +thrust/thrust/random/detail/subtract_with_carry_engine.inl +thrust/thrust/random/detail/uniform_int_distribution.inl +thrust/thrust/random/detail/uniform_real_distribution.inl +thrust/thrust/random/detail/xor_combine_engine.inl +thrust/thrust/random/detail/xor_combine_engine_max.h +thrust/thrust/random/discard_block_engine.h +thrust/thrust/random/linear_congruential_engine.h +thrust/thrust/random/linear_feedback_shift_engine.h +thrust/thrust/random/normal_distribution.h +thrust/thrust/random/subtract_with_carry_engine.h +thrust/thrust/random/uniform_int_distribution.h +thrust/thrust/random/uniform_real_distribution.h +thrust/thrust/random/xor_combine_engine.h +thrust/thrust/reduce.h +thrust/thrust/remove.h +thrust/thrust/replace.h +thrust/thrust/reverse.h +thrust/thrust/scan.h +thrust/thrust/scatter.h +thrust/thrust/sequence.h +thrust/thrust/set_operations.h +thrust/thrust/shuffle.h +thrust/thrust/sort.h +thrust/thrust/swap.h +thrust/thrust/system/cpp/detail/adjacent_difference.h +thrust/thrust/system/cpp/detail/assign_value.h +thrust/thrust/system/cpp/detail/binary_search.h +thrust/thrust/system/cpp/detail/copy.h +thrust/thrust/system/cpp/detail/copy_if.h +thrust/thrust/system/cpp/detail/count.h +thrust/thrust/system/cpp/detail/equal.h +thrust/thrust/system/cpp/detail/execution_policy.h +thrust/thrust/system/cpp/detail/extrema.h +thrust/thrust/system/cpp/detail/fill.h +thrust/thrust/system/cpp/detail/find.h +thrust/thrust/system/cpp/detail/for_each.h +thrust/thrust/system/cpp/detail/gather.h +thrust/thrust/system/cpp/detail/generate.h +thrust/thrust/system/cpp/detail/get_value.h +thrust/thrust/system/cpp/detail/inner_product.h +thrust/thrust/system/cpp/detail/iter_swap.h +thrust/thrust/system/cpp/detail/logical.h +thrust/thrust/system/cpp/detail/malloc_and_free.h +thrust/thrust/system/cpp/detail/memory.inl +thrust/thrust/system/cpp/detail/merge.h +thrust/thrust/system/cpp/detail/mismatch.h +thrust/thrust/system/cpp/detail/par.h +thrust/thrust/system/cpp/detail/partition.h +thrust/thrust/system/cpp/detail/per_device_resource.h +thrust/thrust/system/cpp/detail/reduce.h +thrust/thrust/system/cpp/detail/reduce_by_key.h +thrust/thrust/system/cpp/detail/remove.h +thrust/thrust/system/cpp/detail/replace.h +thrust/thrust/system/cpp/detail/reverse.h +thrust/thrust/system/cpp/detail/scan.h +thrust/thrust/system/cpp/detail/scan_by_key.h +thrust/thrust/system/cpp/detail/scatter.h +thrust/thrust/system/cpp/detail/sequence.h +thrust/thrust/system/cpp/detail/set_operations.h +thrust/thrust/system/cpp/detail/sort.h +thrust/thrust/system/cpp/detail/swap_ranges.h +thrust/thrust/system/cpp/detail/tabulate.h +thrust/thrust/system/cpp/detail/temporary_buffer.h +thrust/thrust/system/cpp/detail/transform.h +thrust/thrust/system/cpp/detail/transform_reduce.h +thrust/thrust/system/cpp/detail/transform_scan.h +thrust/thrust/system/cpp/detail/uninitialized_copy.h +thrust/thrust/system/cpp/detail/uninitialized_fill.h +thrust/thrust/system/cpp/detail/unique.h +thrust/thrust/system/cpp/detail/unique_by_key.h +thrust/thrust/system/cpp/detail/vector.inl +thrust/thrust/system/cpp/execution_policy.h +thrust/thrust/system/cpp/memory.h +thrust/thrust/system/cpp/memory_resource.h +thrust/thrust/system/cpp/pointer.h +thrust/thrust/system/cpp/vector.h +thrust/thrust/system/cuda/config.h +thrust/thrust/system/cuda/detail/adjacent_difference.h +thrust/thrust/system/cuda/detail/assign_value.h +thrust/thrust/system/cuda/detail/async/copy.h +thrust/thrust/system/cuda/detail/async/customization.h +thrust/thrust/system/cuda/detail/async/exclusive_scan.h +thrust/thrust/system/cuda/detail/async/for_each.h +thrust/thrust/system/cuda/detail/async/inclusive_scan.h +thrust/thrust/system/cuda/detail/async/reduce.h +thrust/thrust/system/cuda/detail/async/scan.h +thrust/thrust/system/cuda/detail/async/sort.h +thrust/thrust/system/cuda/detail/async/transform.h +thrust/thrust/system/cuda/detail/binary_search.h +thrust/thrust/system/cuda/detail/cdp_dispatch.h +thrust/thrust/system/cuda/detail/copy.h +thrust/thrust/system/cuda/detail/copy_if.h +thrust/thrust/system/cuda/detail/core/agent_launcher.h +thrust/thrust/system/cuda/detail/core/alignment.h +thrust/thrust/system/cuda/detail/core/triple_chevron_launch.h +thrust/thrust/system/cuda/detail/core/util.h +thrust/thrust/system/cuda/detail/count.h +thrust/thrust/system/cuda/detail/cross_system.h +thrust/thrust/system/cuda/detail/dispatch.h +thrust/thrust/system/cuda/detail/equal.h +thrust/thrust/system/cuda/detail/error.inl +thrust/thrust/system/cuda/detail/execution_policy.h +thrust/thrust/system/cuda/detail/extrema.h +thrust/thrust/system/cuda/detail/fill.h +thrust/thrust/system/cuda/detail/find.h +thrust/thrust/system/cuda/detail/for_each.h +thrust/thrust/system/cuda/detail/future.inl +thrust/thrust/system/cuda/detail/gather.h +thrust/thrust/system/cuda/detail/generate.h +thrust/thrust/system/cuda/detail/get_value.h +thrust/thrust/system/cuda/detail/guarded_cuda_runtime_api.h +thrust/thrust/system/cuda/detail/guarded_driver_types.h +thrust/thrust/system/cuda/detail/inner_product.h +thrust/thrust/system/cuda/detail/internal/copy_cross_system.h +thrust/thrust/system/cuda/detail/internal/copy_device_to_device.h +thrust/thrust/system/cuda/detail/iter_swap.h +thrust/thrust/system/cuda/detail/logical.h +thrust/thrust/system/cuda/detail/make_unsigned_special.h +thrust/thrust/system/cuda/detail/malloc_and_free.h +thrust/thrust/system/cuda/detail/memory.inl +thrust/thrust/system/cuda/detail/merge.h +thrust/thrust/system/cuda/detail/mismatch.h +thrust/thrust/system/cuda/detail/par.h +thrust/thrust/system/cuda/detail/par_to_seq.h +thrust/thrust/system/cuda/detail/parallel_for.h +thrust/thrust/system/cuda/detail/partition.h +thrust/thrust/system/cuda/detail/per_device_resource.h +thrust/thrust/system/cuda/detail/reduce.h +thrust/thrust/system/cuda/detail/reduce_by_key.h +thrust/thrust/system/cuda/detail/remove.h +thrust/thrust/system/cuda/detail/replace.h +thrust/thrust/system/cuda/detail/reverse.h +thrust/thrust/system/cuda/detail/scan.h +thrust/thrust/system/cuda/detail/scan_by_key.h +thrust/thrust/system/cuda/detail/scatter.h +thrust/thrust/system/cuda/detail/sequence.h +thrust/thrust/system/cuda/detail/set_operations.h +thrust/thrust/system/cuda/detail/sort.h +thrust/thrust/system/cuda/detail/swap_ranges.h +thrust/thrust/system/cuda/detail/tabulate.h +thrust/thrust/system/cuda/detail/temporary_buffer.h +thrust/thrust/system/cuda/detail/terminate.h +thrust/thrust/system/cuda/detail/transform.h +thrust/thrust/system/cuda/detail/transform_reduce.h +thrust/thrust/system/cuda/detail/transform_scan.h +thrust/thrust/system/cuda/detail/uninitialized_copy.h +thrust/thrust/system/cuda/detail/uninitialized_fill.h +thrust/thrust/system/cuda/detail/unique.h +thrust/thrust/system/cuda/detail/unique_by_key.h +thrust/thrust/system/cuda/detail/util.h +thrust/thrust/system/cuda/error.h +thrust/thrust/system/cuda/execution_policy.h +thrust/thrust/system/cuda/future.h +thrust/thrust/system/cuda/memory.h +thrust/thrust/system/cuda/memory_resource.h +thrust/thrust/system/cuda/pointer.h +thrust/thrust/system/cuda/vector.h +thrust/thrust/system/detail/adl/adjacent_difference.h +thrust/thrust/system/detail/adl/assign_value.h +thrust/thrust/system/detail/adl/async/copy.h +thrust/thrust/system/detail/adl/async/for_each.h +thrust/thrust/system/detail/adl/async/reduce.h +thrust/thrust/system/detail/adl/async/scan.h +thrust/thrust/system/detail/adl/async/sort.h +thrust/thrust/system/detail/adl/async/transform.h +thrust/thrust/system/detail/adl/binary_search.h +thrust/thrust/system/detail/adl/copy.h +thrust/thrust/system/detail/adl/copy_if.h +thrust/thrust/system/detail/adl/count.h +thrust/thrust/system/detail/adl/equal.h +thrust/thrust/system/detail/adl/extrema.h +thrust/thrust/system/detail/adl/fill.h +thrust/thrust/system/detail/adl/find.h +thrust/thrust/system/detail/adl/for_each.h +thrust/thrust/system/detail/adl/gather.h +thrust/thrust/system/detail/adl/generate.h +thrust/thrust/system/detail/adl/get_value.h +thrust/thrust/system/detail/adl/inner_product.h +thrust/thrust/system/detail/adl/iter_swap.h +thrust/thrust/system/detail/adl/logical.h +thrust/thrust/system/detail/adl/malloc_and_free.h +thrust/thrust/system/detail/adl/merge.h +thrust/thrust/system/detail/adl/mismatch.h +thrust/thrust/system/detail/adl/partition.h +thrust/thrust/system/detail/adl/per_device_resource.h +thrust/thrust/system/detail/adl/reduce.h +thrust/thrust/system/detail/adl/reduce_by_key.h +thrust/thrust/system/detail/adl/remove.h +thrust/thrust/system/detail/adl/replace.h +thrust/thrust/system/detail/adl/reverse.h +thrust/thrust/system/detail/adl/scan.h +thrust/thrust/system/detail/adl/scan_by_key.h +thrust/thrust/system/detail/adl/scatter.h +thrust/thrust/system/detail/adl/sequence.h +thrust/thrust/system/detail/adl/set_operations.h +thrust/thrust/system/detail/adl/sort.h +thrust/thrust/system/detail/adl/swap_ranges.h +thrust/thrust/system/detail/adl/tabulate.h +thrust/thrust/system/detail/adl/temporary_buffer.h +thrust/thrust/system/detail/adl/transform.h +thrust/thrust/system/detail/adl/transform_reduce.h +thrust/thrust/system/detail/adl/transform_scan.h +thrust/thrust/system/detail/adl/uninitialized_copy.h +thrust/thrust/system/detail/adl/uninitialized_fill.h +thrust/thrust/system/detail/adl/unique.h +thrust/thrust/system/detail/adl/unique_by_key.h +thrust/thrust/system/detail/bad_alloc.h +thrust/thrust/system/detail/errno.h +thrust/thrust/system/detail/error_category.inl +thrust/thrust/system/detail/error_code.inl +thrust/thrust/system/detail/error_condition.inl +thrust/thrust/system/detail/generic/adjacent_difference.h +thrust/thrust/system/detail/generic/adjacent_difference.inl +thrust/thrust/system/detail/generic/advance.h +thrust/thrust/system/detail/generic/advance.inl +thrust/thrust/system/detail/generic/binary_search.h +thrust/thrust/system/detail/generic/binary_search.inl +thrust/thrust/system/detail/generic/copy.h +thrust/thrust/system/detail/generic/copy.inl +thrust/thrust/system/detail/generic/copy_if.h +thrust/thrust/system/detail/generic/copy_if.inl +thrust/thrust/system/detail/generic/count.h +thrust/thrust/system/detail/generic/count.inl +thrust/thrust/system/detail/generic/distance.h +thrust/thrust/system/detail/generic/distance.inl +thrust/thrust/system/detail/generic/equal.h +thrust/thrust/system/detail/generic/equal.inl +thrust/thrust/system/detail/generic/extrema.h +thrust/thrust/system/detail/generic/extrema.inl +thrust/thrust/system/detail/generic/fill.h +thrust/thrust/system/detail/generic/find.h +thrust/thrust/system/detail/generic/find.inl +thrust/thrust/system/detail/generic/for_each.h +thrust/thrust/system/detail/generic/gather.h +thrust/thrust/system/detail/generic/gather.inl +thrust/thrust/system/detail/generic/generate.h +thrust/thrust/system/detail/generic/generate.inl +thrust/thrust/system/detail/generic/inner_product.h +thrust/thrust/system/detail/generic/inner_product.inl +thrust/thrust/system/detail/generic/logical.h +thrust/thrust/system/detail/generic/memory.h +thrust/thrust/system/detail/generic/memory.inl +thrust/thrust/system/detail/generic/merge.h +thrust/thrust/system/detail/generic/merge.inl +thrust/thrust/system/detail/generic/mismatch.h +thrust/thrust/system/detail/generic/mismatch.inl +thrust/thrust/system/detail/generic/partition.h +thrust/thrust/system/detail/generic/partition.inl +thrust/thrust/system/detail/generic/per_device_resource.h +thrust/thrust/system/detail/generic/reduce.h +thrust/thrust/system/detail/generic/reduce.inl +thrust/thrust/system/detail/generic/reduce_by_key.h +thrust/thrust/system/detail/generic/reduce_by_key.inl +thrust/thrust/system/detail/generic/remove.h +thrust/thrust/system/detail/generic/remove.inl +thrust/thrust/system/detail/generic/replace.h +thrust/thrust/system/detail/generic/replace.inl +thrust/thrust/system/detail/generic/reverse.h +thrust/thrust/system/detail/generic/reverse.inl +thrust/thrust/system/detail/generic/scalar/binary_search.h +thrust/thrust/system/detail/generic/scalar/binary_search.inl +thrust/thrust/system/detail/generic/scan.h +thrust/thrust/system/detail/generic/scan.inl +thrust/thrust/system/detail/generic/scan_by_key.h +thrust/thrust/system/detail/generic/scan_by_key.inl +thrust/thrust/system/detail/generic/scatter.h +thrust/thrust/system/detail/generic/scatter.inl +thrust/thrust/system/detail/generic/select_system.h +thrust/thrust/system/detail/generic/select_system.inl +thrust/thrust/system/detail/generic/select_system_exists.h +thrust/thrust/system/detail/generic/sequence.h +thrust/thrust/system/detail/generic/sequence.inl +thrust/thrust/system/detail/generic/set_operations.h +thrust/thrust/system/detail/generic/set_operations.inl +thrust/thrust/system/detail/generic/shuffle.h +thrust/thrust/system/detail/generic/shuffle.inl +thrust/thrust/system/detail/generic/sort.h +thrust/thrust/system/detail/generic/sort.inl +thrust/thrust/system/detail/generic/swap_ranges.h +thrust/thrust/system/detail/generic/swap_ranges.inl +thrust/thrust/system/detail/generic/tabulate.h +thrust/thrust/system/detail/generic/tabulate.inl +thrust/thrust/system/detail/generic/tag.h +thrust/thrust/system/detail/generic/temporary_buffer.h +thrust/thrust/system/detail/generic/temporary_buffer.inl +thrust/thrust/system/detail/generic/transform.h +thrust/thrust/system/detail/generic/transform.inl +thrust/thrust/system/detail/generic/transform_reduce.h +thrust/thrust/system/detail/generic/transform_reduce.inl +thrust/thrust/system/detail/generic/transform_scan.h +thrust/thrust/system/detail/generic/transform_scan.inl +thrust/thrust/system/detail/generic/uninitialized_copy.h +thrust/thrust/system/detail/generic/uninitialized_copy.inl +thrust/thrust/system/detail/generic/uninitialized_fill.h +thrust/thrust/system/detail/generic/uninitialized_fill.inl +thrust/thrust/system/detail/generic/unique.h +thrust/thrust/system/detail/generic/unique.inl +thrust/thrust/system/detail/generic/unique_by_key.h +thrust/thrust/system/detail/generic/unique_by_key.inl +thrust/thrust/system/detail/internal/decompose.h +thrust/thrust/system/detail/sequential/adjacent_difference.h +thrust/thrust/system/detail/sequential/assign_value.h +thrust/thrust/system/detail/sequential/binary_search.h +thrust/thrust/system/detail/sequential/copy.h +thrust/thrust/system/detail/sequential/copy.inl +thrust/thrust/system/detail/sequential/copy_backward.h +thrust/thrust/system/detail/sequential/copy_if.h +thrust/thrust/system/detail/sequential/count.h +thrust/thrust/system/detail/sequential/equal.h +thrust/thrust/system/detail/sequential/execution_policy.h +thrust/thrust/system/detail/sequential/extrema.h +thrust/thrust/system/detail/sequential/fill.h +thrust/thrust/system/detail/sequential/find.h +thrust/thrust/system/detail/sequential/for_each.h +thrust/thrust/system/detail/sequential/gather.h +thrust/thrust/system/detail/sequential/general_copy.h +thrust/thrust/system/detail/sequential/generate.h +thrust/thrust/system/detail/sequential/get_value.h +thrust/thrust/system/detail/sequential/inner_product.h +thrust/thrust/system/detail/sequential/insertion_sort.h +thrust/thrust/system/detail/sequential/iter_swap.h +thrust/thrust/system/detail/sequential/logical.h +thrust/thrust/system/detail/sequential/malloc_and_free.h +thrust/thrust/system/detail/sequential/merge.h +thrust/thrust/system/detail/sequential/merge.inl +thrust/thrust/system/detail/sequential/mismatch.h +thrust/thrust/system/detail/sequential/partition.h +thrust/thrust/system/detail/sequential/per_device_resource.h +thrust/thrust/system/detail/sequential/reduce.h +thrust/thrust/system/detail/sequential/reduce_by_key.h +thrust/thrust/system/detail/sequential/remove.h +thrust/thrust/system/detail/sequential/replace.h +thrust/thrust/system/detail/sequential/reverse.h +thrust/thrust/system/detail/sequential/scan.h +thrust/thrust/system/detail/sequential/scan_by_key.h +thrust/thrust/system/detail/sequential/scatter.h +thrust/thrust/system/detail/sequential/sequence.h +thrust/thrust/system/detail/sequential/set_operations.h +thrust/thrust/system/detail/sequential/sort.h +thrust/thrust/system/detail/sequential/sort.inl +thrust/thrust/system/detail/sequential/stable_merge_sort.h +thrust/thrust/system/detail/sequential/stable_merge_sort.inl +thrust/thrust/system/detail/sequential/stable_primitive_sort.h +thrust/thrust/system/detail/sequential/stable_primitive_sort.inl +thrust/thrust/system/detail/sequential/stable_radix_sort.h +thrust/thrust/system/detail/sequential/stable_radix_sort.inl +thrust/thrust/system/detail/sequential/swap_ranges.h +thrust/thrust/system/detail/sequential/tabulate.h +thrust/thrust/system/detail/sequential/temporary_buffer.h +thrust/thrust/system/detail/sequential/transform.h +thrust/thrust/system/detail/sequential/transform_reduce.h +thrust/thrust/system/detail/sequential/transform_scan.h +thrust/thrust/system/detail/sequential/trivial_copy.h +thrust/thrust/system/detail/sequential/uninitialized_copy.h +thrust/thrust/system/detail/sequential/uninitialized_fill.h +thrust/thrust/system/detail/sequential/unique.h +thrust/thrust/system/detail/sequential/unique_by_key.h +thrust/thrust/system/detail/system_error.inl +thrust/thrust/system/error_code.h +thrust/thrust/system/omp/detail/adjacent_difference.h +thrust/thrust/system/omp/detail/assign_value.h +thrust/thrust/system/omp/detail/binary_search.h +thrust/thrust/system/omp/detail/copy.h +thrust/thrust/system/omp/detail/copy.inl +thrust/thrust/system/omp/detail/copy_if.h +thrust/thrust/system/omp/detail/copy_if.inl +thrust/thrust/system/omp/detail/count.h +thrust/thrust/system/omp/detail/default_decomposition.h +thrust/thrust/system/omp/detail/default_decomposition.inl +thrust/thrust/system/omp/detail/equal.h +thrust/thrust/system/omp/detail/execution_policy.h +thrust/thrust/system/omp/detail/extrema.h +thrust/thrust/system/omp/detail/fill.h +thrust/thrust/system/omp/detail/find.h +thrust/thrust/system/omp/detail/for_each.h +thrust/thrust/system/omp/detail/for_each.inl +thrust/thrust/system/omp/detail/gather.h +thrust/thrust/system/omp/detail/generate.h +thrust/thrust/system/omp/detail/get_value.h +thrust/thrust/system/omp/detail/inner_product.h +thrust/thrust/system/omp/detail/iter_swap.h +thrust/thrust/system/omp/detail/logical.h +thrust/thrust/system/omp/detail/malloc_and_free.h +thrust/thrust/system/omp/detail/memory.inl +thrust/thrust/system/omp/detail/merge.h +thrust/thrust/system/omp/detail/mismatch.h +thrust/thrust/system/omp/detail/par.h +thrust/thrust/system/omp/detail/partition.h +thrust/thrust/system/omp/detail/partition.inl +thrust/thrust/system/omp/detail/per_device_resource.h +thrust/thrust/system/omp/detail/pragma_omp.h +thrust/thrust/system/omp/detail/reduce.h +thrust/thrust/system/omp/detail/reduce.inl +thrust/thrust/system/omp/detail/reduce_by_key.h +thrust/thrust/system/omp/detail/reduce_by_key.inl +thrust/thrust/system/omp/detail/reduce_intervals.h +thrust/thrust/system/omp/detail/reduce_intervals.inl +thrust/thrust/system/omp/detail/remove.h +thrust/thrust/system/omp/detail/remove.inl +thrust/thrust/system/omp/detail/replace.h +thrust/thrust/system/omp/detail/reverse.h +thrust/thrust/system/omp/detail/scan.h +thrust/thrust/system/omp/detail/scan_by_key.h +thrust/thrust/system/omp/detail/scatter.h +thrust/thrust/system/omp/detail/sequence.h +thrust/thrust/system/omp/detail/set_operations.h +thrust/thrust/system/omp/detail/sort.h +thrust/thrust/system/omp/detail/sort.inl +thrust/thrust/system/omp/detail/swap_ranges.h +thrust/thrust/system/omp/detail/tabulate.h +thrust/thrust/system/omp/detail/temporary_buffer.h +thrust/thrust/system/omp/detail/transform.h +thrust/thrust/system/omp/detail/transform_reduce.h +thrust/thrust/system/omp/detail/transform_scan.h +thrust/thrust/system/omp/detail/uninitialized_copy.h +thrust/thrust/system/omp/detail/uninitialized_fill.h +thrust/thrust/system/omp/detail/unique.h +thrust/thrust/system/omp/detail/unique.inl +thrust/thrust/system/omp/detail/unique_by_key.h +thrust/thrust/system/omp/detail/unique_by_key.inl +thrust/thrust/system/omp/execution_policy.h +thrust/thrust/system/omp/memory.h +thrust/thrust/system/omp/memory_resource.h +thrust/thrust/system/omp/pointer.h +thrust/thrust/system/omp/vector.h +thrust/thrust/system/system_error.h +thrust/thrust/system/tbb/detail/adjacent_difference.h +thrust/thrust/system/tbb/detail/assign_value.h +thrust/thrust/system/tbb/detail/binary_search.h +thrust/thrust/system/tbb/detail/copy.h +thrust/thrust/system/tbb/detail/copy.inl +thrust/thrust/system/tbb/detail/copy_if.h +thrust/thrust/system/tbb/detail/copy_if.inl +thrust/thrust/system/tbb/detail/count.h +thrust/thrust/system/tbb/detail/equal.h +thrust/thrust/system/tbb/detail/execution_policy.h +thrust/thrust/system/tbb/detail/extrema.h +thrust/thrust/system/tbb/detail/fill.h +thrust/thrust/system/tbb/detail/find.h +thrust/thrust/system/tbb/detail/for_each.h +thrust/thrust/system/tbb/detail/for_each.inl +thrust/thrust/system/tbb/detail/gather.h +thrust/thrust/system/tbb/detail/generate.h +thrust/thrust/system/tbb/detail/get_value.h +thrust/thrust/system/tbb/detail/inner_product.h +thrust/thrust/system/tbb/detail/iter_swap.h +thrust/thrust/system/tbb/detail/logical.h +thrust/thrust/system/tbb/detail/malloc_and_free.h +thrust/thrust/system/tbb/detail/memory.inl +thrust/thrust/system/tbb/detail/merge.h +thrust/thrust/system/tbb/detail/merge.inl +thrust/thrust/system/tbb/detail/mismatch.h +thrust/thrust/system/tbb/detail/par.h +thrust/thrust/system/tbb/detail/partition.h +thrust/thrust/system/tbb/detail/partition.inl +thrust/thrust/system/tbb/detail/per_device_resource.h +thrust/thrust/system/tbb/detail/reduce.h +thrust/thrust/system/tbb/detail/reduce.inl +thrust/thrust/system/tbb/detail/reduce_by_key.h +thrust/thrust/system/tbb/detail/reduce_by_key.inl +thrust/thrust/system/tbb/detail/reduce_intervals.h +thrust/thrust/system/tbb/detail/remove.h +thrust/thrust/system/tbb/detail/remove.inl +thrust/thrust/system/tbb/detail/replace.h +thrust/thrust/system/tbb/detail/reverse.h +thrust/thrust/system/tbb/detail/scan.h +thrust/thrust/system/tbb/detail/scan.inl +thrust/thrust/system/tbb/detail/scan_by_key.h +thrust/thrust/system/tbb/detail/scatter.h +thrust/thrust/system/tbb/detail/sequence.h +thrust/thrust/system/tbb/detail/set_operations.h +thrust/thrust/system/tbb/detail/sort.h +thrust/thrust/system/tbb/detail/sort.inl +thrust/thrust/system/tbb/detail/swap_ranges.h +thrust/thrust/system/tbb/detail/tabulate.h +thrust/thrust/system/tbb/detail/temporary_buffer.h +thrust/thrust/system/tbb/detail/transform.h +thrust/thrust/system/tbb/detail/transform_reduce.h +thrust/thrust/system/tbb/detail/transform_scan.h +thrust/thrust/system/tbb/detail/uninitialized_copy.h +thrust/thrust/system/tbb/detail/uninitialized_fill.h +thrust/thrust/system/tbb/detail/unique.h +thrust/thrust/system/tbb/detail/unique.inl +thrust/thrust/system/tbb/detail/unique_by_key.h +thrust/thrust/system/tbb/detail/unique_by_key.inl +thrust/thrust/system/tbb/execution_policy.h +thrust/thrust/system/tbb/memory.h +thrust/thrust/system/tbb/memory_resource.h +thrust/thrust/system/tbb/pointer.h +thrust/thrust/system/tbb/vector.h +thrust/thrust/system_error.h +thrust/thrust/tabulate.h +thrust/thrust/transform.h +thrust/thrust/transform_reduce.h +thrust/thrust/transform_scan.h +thrust/thrust/tuple.h +thrust/thrust/type_traits/integer_sequence.h +thrust/thrust/type_traits/is_contiguous_iterator.h +thrust/thrust/type_traits/is_execution_policy.h +thrust/thrust/type_traits/is_operator_less_or_greater_function_object.h +thrust/thrust/type_traits/is_operator_plus_function_object.h +thrust/thrust/type_traits/is_trivially_relocatable.h +thrust/thrust/type_traits/logical_metafunctions.h +thrust/thrust/type_traits/remove_cvref.h +thrust/thrust/type_traits/void_t.h +thrust/thrust/uninitialized_copy.h +thrust/thrust/uninitialized_fill.h +thrust/thrust/unique.h +thrust/thrust/universal_allocator.h +thrust/thrust/universal_ptr.h +thrust/thrust/universal_vector.h +thrust/thrust/version.h +thrust/thrust/zip_function.h +) diff --git a/src/other/manifold/AUTHORS b/src/other/manifold/AUTHORS new file mode 100644 index 00000000000..a3e3c587f41 --- /dev/null +++ b/src/other/manifold/AUTHORS @@ -0,0 +1,10 @@ +# This is the list of Manifold's significant contributors. +# +# This does not necessarily list everyone who has contributed code, +# especially since many employees of one corporation may be contributing. +# To see the full list of contributors, see the revision history in +# source control. +Emmett Lalish +Chun Kit LAM +Geoff deRosenroll +Google LLC diff --git a/src/other/manifold/CMakeLists.txt b/src/other/manifold/CMakeLists.txt new file mode 100644 index 00000000000..ac4b92b60c5 --- /dev/null +++ b/src/other/manifold/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright 2020 The Manifold Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.18) +project(manifold LANGUAGES CXX) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +set(MANIFOLD_PAR "NONE" CACHE STRING "Parallel backend, either \"TBB\" or \"NONE\"") +set(MANIFOLD_FLAGS "" CACHE STRING "Manifold compiler flags") + +if (MSVC) + set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} /DNOMINMAX) +else() + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(WARNING_FLAGS -Werror -Wall -Wno-sign-compare -Wno-unused -Wno-array-bounds -Wno-stringop-overflow) + else() + set(WARNING_FLAGS -Werror -Wall -Wno-sign-compare -Wno-unused) + endif() + set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} ${WARNING_FLAGS} -O3) +endif() + +if (NOT DEFINED BIN_DIR) + set(BIN_DIR bin) +endif (NOT DEFINED BIN_DIR) + +if (NOT DEFINED LIB_DIR) + set(LIB_DIR lib) +endif (NOT DEFINED LIB_DIR) + +if (NOT DEFINED INCLUDE_DIR) + set(INCLUDE_DIR include) +endif (NOT DEFINED INCLUDE_DIR) + + +add_subdirectory(src) +add_subdirectory(include) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/src/other/manifold/CONTRIBUTING.md b/src/other/manifold/CONTRIBUTING.md new file mode 100644 index 00000000000..9d7656bec31 --- /dev/null +++ b/src/other/manifold/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement (CLA). You (or your employer) retain the copyright to your +contribution; this simply gives us permission to use and redistribute your +contributions as part of the project. Head over to + to see your current agreements on file or +to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code Reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google/conduct/). \ No newline at end of file diff --git a/src/other/manifold/LICENSE b/src/other/manifold/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/src/other/manifold/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/other/manifold/LICENSE.clipper2 b/src/other/manifold/LICENSE.clipper2 new file mode 100644 index 00000000000..36b7cd93cdf --- /dev/null +++ b/src/other/manifold/LICENSE.clipper2 @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/other/manifold/README.md b/src/other/manifold/README.md new file mode 100644 index 00000000000..5da5b57e108 --- /dev/null +++ b/src/other/manifold/README.md @@ -0,0 +1,12 @@ +# Manifold + +NOTE: This repo is just making a single-library build of the upstream manifold. For main development work please see https://github.com/elalish/manifold + +[Manifold](https://github.com/elalish/manifold) is a geometry library dedicated to creating and operating on manifold triangle meshes. A [manifold mesh](https://github.com/elalish/manifold/wiki/Manifold-Library#manifoldness) is a mesh that represents a solid object, and so is very important in manufacturing, CAD, structural analysis, etc. Further information can be found on the [wiki](https://github.com/elalish/manifold/wiki/Manifold-Library). + +Dependencies: +- [`GLM`](https://github.com/g-truc/glm/): A compact header-only vector library. +- [`Thrust`](https://github.com/NVIDIA/thrust): NVIDIA's parallel algorithms library (basically a superset of C++17 std::parallel_algorithms) +- [`Clipper2`](https://github.com/AngusJohnson/Clipper2): provides our 2D subsystem +- [`quickhull`](https://github.com/akuukka/quickhull): 3D convex hull algorithm. + diff --git a/src/other/manifold/glm/copying.txt b/src/other/manifold/glm/copying.txt new file mode 100644 index 00000000000..73aa679d1ed --- /dev/null +++ b/src/other/manifold/glm/copying.txt @@ -0,0 +1,27 @@ +================================================================================ +OpenGL Mathematics (GLM) +-------------------------------------------------------------------------------- +GLM is licensed under The Happy Bunny License or MIT License + +================================================================================ +The MIT License +-------------------------------------------------------------------------------- +Copyright (c) 2005 - G-Truc Creation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/other/manifold/glm/glm/CMakeLists.txt b/src/other/manifold/glm/glm/CMakeLists.txt new file mode 100644 index 00000000000..4ff51c8180b --- /dev/null +++ b/src/other/manifold/glm/glm/CMakeLists.txt @@ -0,0 +1,70 @@ +file(GLOB ROOT_SOURCE *.cpp) +file(GLOB ROOT_INLINE *.inl) +file(GLOB ROOT_HEADER *.hpp) +file(GLOB ROOT_TEXT ../*.txt) +file(GLOB ROOT_MD ../*.md) +file(GLOB ROOT_NAT ../util/glm.natvis) + +file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp) +file(GLOB_RECURSE CORE_INLINE ./detail/*.inl) +file(GLOB_RECURSE CORE_HEADER ./detail/*.hpp) + +file(GLOB_RECURSE EXT_SOURCE ./ext/*.cpp) +file(GLOB_RECURSE EXT_INLINE ./ext/*.inl) +file(GLOB_RECURSE EXT_HEADER ./ext/*.hpp) + +file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp) +file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl) +file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp) + +file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp) +file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl) +file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp) + +file(GLOB_RECURSE SIMD_SOURCE ./simd/*.cpp) +file(GLOB_RECURSE SIMD_INLINE ./simd/*.inl) +file(GLOB_RECURSE SIMD_HEADER ./simd/*.h) + +source_group("Text Files" FILES ${ROOT_TEXT} ${ROOT_MD}) +source_group("Core Files" FILES ${CORE_SOURCE}) +source_group("Core Files" FILES ${CORE_INLINE}) +source_group("Core Files" FILES ${CORE_HEADER}) +source_group("EXT Files" FILES ${EXT_SOURCE}) +source_group("EXT Files" FILES ${EXT_INLINE}) +source_group("EXT Files" FILES ${EXT_HEADER}) +source_group("GTC Files" FILES ${GTC_SOURCE}) +source_group("GTC Files" FILES ${GTC_INLINE}) +source_group("GTC Files" FILES ${GTC_HEADER}) +source_group("GTX Files" FILES ${GTX_SOURCE}) +source_group("GTX Files" FILES ${GTX_INLINE}) +source_group("GTX Files" FILES ${GTX_HEADER}) +source_group("SIMD Files" FILES ${SIMD_SOURCE}) +source_group("SIMD Files" FILES ${SIMD_INLINE}) +source_group("SIMD Files" FILES ${SIMD_HEADER}) + +add_library(glm INTERFACE) +target_include_directories(glm INTERFACE ../) + +if(BUILD_STATIC_LIBS) +add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} + ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} + ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} + ${EXT_SOURCE} ${EXT_INLINE} ${EXT_HEADER} + ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} + ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) + target_link_libraries(glm_static PUBLIC glm) + add_library(glm::glm_static ALIAS glm_static) +endif() + +if(BUILD_SHARED_LIBS) +add_library(glm_shared SHARED ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} + ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} + ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} + ${EXT_SOURCE} ${EXT_INLINE} ${EXT_HEADER} + ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} + ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) + target_link_libraries(glm_shared PUBLIC glm) + add_library(glm::glm_shared ALIAS glm_shared) +endif() diff --git a/src/other/manifold/glm/glm/common.hpp b/src/other/manifold/glm/glm/common.hpp new file mode 100644 index 00000000000..0328dc91ee2 --- /dev/null +++ b/src/other/manifold/glm/glm/common.hpp @@ -0,0 +1,539 @@ +/// @ref core +/// @file glm/common.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.3 Common Functions +/// +/// @defgroup core_func_common Common functions +/// @ingroup core +/// +/// Provides GLSL common functions +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/qualifier.hpp" +#include "detail/_fixes.hpp" + +namespace glm +{ + /// @addtogroup core_func_common + /// @{ + + /// Returns x if x >= 0; otherwise, it returns -x. + /// + /// @tparam genType floating-point or signed integer; scalar or vector types. + /// + /// @see GLSL abs man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x); + + /// Returns x if x >= 0; otherwise, it returns -x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL abs man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec abs(vec const& x); + + /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sign man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec sign(vec const& x); + + /// Returns a value equal to the nearest integer that is less then or equal to x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floor man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floor(vec const& x); + + /// Returns a value equal to the nearest integer to x + /// whose absolute value is not larger than the absolute value of x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL trunc man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec trunc(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// This includes the possibility that round(x) returns the + /// same value as roundEven(x) for all values of x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL round man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec round(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// A fractional part of 0.5 will round toward the nearest even + /// integer. (Both 3.5 and 4.5 for x will return 4.0.) + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL roundEven man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + /// @see New round to even technique + template + GLM_FUNC_DECL vec roundEven(vec const& x); + + /// Returns a value equal to the nearest integer + /// that is greater than or equal to x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL ceil man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec ceil(vec const& x); + + /// Return x - floor(x). + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL fract man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType fract(genType x); + + /// Return x - floor(x). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL fract man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec fract(vec const& x); + + template + GLM_FUNC_DECL genType mod(genType x, genType y); + + template + GLM_FUNC_DECL vec mod(vec const& x, T y); + + /// Modulus. Returns x - y * floor(x / y) + /// for each component in x using the floating point value y. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types, include glm/gtc/integer for integer scalar types support + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL mod man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec mod(vec const& x, vec const& y); + + /// Returns the fractional part of x and sets i to the integer + /// part (as a whole number floating point value). Both the + /// return value and the output parameter will have the same + /// sign as x. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL modf man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType modf(genType x, genType& i); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType min(genType x, genType y); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, T y); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, vec const& y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType max(genType x, genType y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, T y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, vec const& y); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, T minVal, T maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, vec const& minVal, vec const& maxVal); + + /// If genTypeU is a floating scalar or vector: + /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of + /// x and y using the floating-point value a. + /// The value for a is not restricted to the range [0, 1]. + /// + /// If genTypeU is a boolean scalar or vector: + /// Selects which vector each returned component comes + /// from. For a component of 'a' that is false, the + /// corresponding component of 'x' is returned. For a + /// component of 'a' that is true, the corresponding + /// component of 'y' is returned. Components of 'x' and 'y' that + /// are not selected are allowed to be invalid floating point + /// values and will have no effect on the results. Thus, this + /// provides different functionality than + /// genType mix(genType x, genType y, genType(a)) + /// where a is a Boolean vector. + /// + /// @see GLSL mix man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + /// + /// @param[in] x Value to interpolate. + /// @param[in] y Value to interpolate. + /// @param[in] a Interpolant. + /// + /// @tparam genTypeT Floating point scalar or vector. + /// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT. + /// + /// @code + /// #include + /// ... + /// float a; + /// bool b; + /// glm::dvec3 e; + /// glm::dvec3 f; + /// glm::vec4 g; + /// glm::vec4 h; + /// ... + /// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors. + /// glm::vec4 s = glm::mix(g, h, b); // Returns g or h; + /// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second. + /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter. + /// @endcode + template + GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a); + + template + GLM_FUNC_DECL vec mix(vec const& x, vec const& y, vec const& a); + + template + GLM_FUNC_DECL vec mix(vec const& x, vec const& y, U a); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType. + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType step(genType edge, genType x); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec step(T edge, vec const& x); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec step(vec const& edge, vec const& x); + + /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and + /// performs smooth Hermite interpolation between 0 and 1 + /// when edge0 < x < edge1. This is useful in cases where + /// you would want a threshold function with a smooth + /// transition. This is equivalent to: + /// genType t; + /// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1); + /// return t * t * (3 - 2 * t); + /// Results are undefined if edge0 >= edge1. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL smoothstep man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType smoothstep(genType edge0, genType edge1, genType x); + + template + GLM_FUNC_DECL vec smoothstep(T edge0, T edge1, vec const& x); + + template + GLM_FUNC_DECL vec smoothstep(vec const& edge0, vec const& edge1, vec const& x); + + /// Returns true if x holds a NaN (not a number) + /// representation in the underlying implementation's set of + /// floating point representations. Returns false otherwise, + /// including for implementations with no NaN + /// representations. + /// + /// /!\ When using compiler fast math, this function may fail. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL isnan man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec isnan(vec const& x); + + /// Returns true if x holds a positive infinity or negative + /// infinity representation in the underlying implementation's + /// set of floating point representations. Returns false + /// otherwise, including for implementations with no infinity + /// representations. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL isinf man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec isinf(vec const& x); + + /// Returns a signed integer value representing + /// the encoding of a floating-point value. The floating-point + /// value's bit-level representation is preserved. + /// + /// @see GLSL floatBitsToInt man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL int floatBitsToInt(float const& v); + + /// Returns a signed integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floatBitsToInt man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floatBitsToInt(vec const& v); + + /// Returns a unsigned integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @see GLSL floatBitsToUint man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL uint floatBitsToUint(float const& v); + + /// Returns a unsigned integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floatBitsToUint man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floatBitsToUint(vec const& v); + + /// Returns a floating-point value corresponding to a signed + /// integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @see GLSL intBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL float intBitsToFloat(int const& v); + + /// Returns a floating-point value corresponding to a signed + /// integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL intBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec intBitsToFloat(vec const& v); + + /// Returns a floating-point value corresponding to a + /// unsigned integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @see GLSL uintBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL float uintBitsToFloat(uint const& v); + + /// Returns a floating-point value corresponding to a + /// unsigned integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL uintBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec uintBitsToFloat(vec const& v); + + /// Computes and returns a * b + c. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL fma man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType fma(genType const& a, genType const& b, genType const& c); + + /// Splits x into a floating-point significand in the range + /// [0.5, 1.0) and an integral exponent of two, such that: + /// x = significand * exp(2, exponent) + /// + /// The significand is returned by the function and the + /// exponent is returned in the parameter exp. For a + /// floating-point value of zero, the significant and exponent + /// are both zero. For a floating-point value that is an + /// infinity or is not a number, the results are undefined. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL frexp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType frexp(genType x, int& exp); + + template + GLM_FUNC_DECL vec frexp(vec const& v, vec& exp); + + /// Builds a floating-point number from x and the + /// corresponding integral exponent of two in exp, returning: + /// significand * exp(2, exponent) + /// + /// If this product is too large to be represented in the + /// floating-point type, the result is undefined. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL ldexp man page; + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType ldexp(genType const& x, int const& exp); + + template + GLM_FUNC_DECL vec ldexp(vec const& v, vec const& exp); + + /// @} +}//namespace glm + +#include "detail/func_common.inl" + diff --git a/src/other/manifold/glm/glm/detail/_features.hpp b/src/other/manifold/glm/glm/detail/_features.hpp new file mode 100644 index 00000000000..b0cbe9ff02c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_features.hpp @@ -0,0 +1,394 @@ +#pragma once + +// #define GLM_CXX98_EXCEPTIONS +// #define GLM_CXX98_RTTI + +// #define GLM_CXX11_RVALUE_REFERENCES +// Rvalue references - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html + +// GLM_CXX11_TRAILING_RETURN +// Rvalue references for *this - GCC not supported +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm + +// GLM_CXX11_NONSTATIC_MEMBER_INIT +// Initialization of class objects by rvalues - GCC any +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html + +// GLM_CXX11_NONSTATIC_MEMBER_INIT +// Non-static data member initializers - GCC 4.7 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm + +// #define GLM_CXX11_VARIADIC_TEMPLATE +// Variadic templates - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf + +// +// Extending variadic template template parameters - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf + +// #define GLM_CXX11_GENERALIZED_INITIALIZERS +// Initializer lists - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm + +// #define GLM_CXX11_STATIC_ASSERT +// Static assertions - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html + +// #define GLM_CXX11_AUTO_TYPE +// auto-typed variables - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf + +// #define GLM_CXX11_AUTO_TYPE +// Multi-declarator auto - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf + +// #define GLM_CXX11_AUTO_TYPE +// Removal of auto as a storage-class specifier - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm + +// #define GLM_CXX11_AUTO_TYPE +// New function declarator syntax - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm + +// #define GLM_CXX11_LAMBDAS +// New wording for C++0x lambdas - GCC 4.5 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf + +// #define GLM_CXX11_DECLTYPE +// Declared type of an expression - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf + +// +// Right angle brackets - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html + +// +// Default template arguments for function templates DR226 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226 + +// +// Solving the SFINAE problem for expressions DR339 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html + +// #define GLM_CXX11_ALIAS_TEMPLATE +// Template aliases N2258 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf + +// +// Extern templates N1987 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm + +// #define GLM_CXX11_NULLPTR +// Null pointer constant N2431 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf + +// #define GLM_CXX11_STRONG_ENUMS +// Strongly-typed enums N2347 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf + +// +// Forward declarations for enums N2764 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf + +// +// Generalized attributes N2761 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf + +// +// Generalized constant expressions N2235 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf + +// +// Alignment support N2341 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf + +// #define GLM_CXX11_DELEGATING_CONSTRUCTORS +// Delegating constructors N1986 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf + +// +// Inheriting constructors N2540 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm + +// #define GLM_CXX11_EXPLICIT_CONVERSIONS +// Explicit conversion operators N2437 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf + +// +// New character types N2249 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html + +// +// Unicode string literals N2442 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm + +// +// Raw string literals N2442 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm + +// +// Universal character name literals N2170 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html + +// #define GLM_CXX11_USER_LITERALS +// User-defined literals N2765 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf + +// +// Standard Layout Types N2342 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm + +// #define GLM_CXX11_DEFAULTED_FUNCTIONS +// #define GLM_CXX11_DELETED_FUNCTIONS +// Defaulted and deleted functions N2346 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm + +// +// Extended friend declarations N1791 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf + +// +// Extending sizeof N2253 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html + +// #define GLM_CXX11_INLINE_NAMESPACES +// Inline namespaces N2535 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm + +// #define GLM_CXX11_UNRESTRICTED_UNIONS +// Unrestricted unions N2544 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf + +// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS +// Local and unnamed types as template arguments N2657 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm + +// #define GLM_CXX11_RANGE_FOR +// Range-based for N2930 GCC 4.6 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html + +// #define GLM_CXX11_OVERRIDE_CONTROL +// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm + +// +// Minimal support for garbage collection and reachability-based leak detection N2670 No +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm + +// #define GLM_CXX11_NOEXCEPT +// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only) +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html + +// +// Defining move special member functions N3053 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html + +// +// Sequence points N2239 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html + +// +// Atomic operations N2427 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html + +// +// Strong Compare and Exchange N2748 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html + +// +// Bidirectional Fences N2752 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm + +// +// Memory model N2429 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm + +// +// Data-dependency ordering: atomics and memory model N2664 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm + +// +// Propagating exceptions N2179 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html + +// +// Abandoning a process and at_quick_exit N2440 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm + +// +// Allow atomics use in signal handlers N2547 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm + +// +// Thread-local storage N2659 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm + +// +// Dynamic initialization and destruction with concurrency N2660 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm + +// +// __func__ predefined identifier N2340 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm + +// +// C99 preprocessor N1653 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm + +// +// long long N1811 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf + +// +// Extended integral types N1988 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf + +#if(GLM_COMPILER & GLM_COMPILER_GCC) + +# define GLM_CXX11_STATIC_ASSERT + +#elif(GLM_COMPILER & GLM_COMPILER_CLANG) +# if(__has_feature(cxx_exceptions)) +# define GLM_CXX98_EXCEPTIONS +# endif + +# if(__has_feature(cxx_rtti)) +# define GLM_CXX98_RTTI +# endif + +# if(__has_feature(cxx_access_control_sfinae)) +# define GLM_CXX11_ACCESS_CONTROL_SFINAE +# endif + +# if(__has_feature(cxx_alias_templates)) +# define GLM_CXX11_ALIAS_TEMPLATE +# endif + +# if(__has_feature(cxx_alignas)) +# define GLM_CXX11_ALIGNAS +# endif + +# if(__has_feature(cxx_attributes)) +# define GLM_CXX11_ATTRIBUTES +# endif + +# if(__has_feature(cxx_constexpr)) +# define GLM_CXX11_CONSTEXPR +# endif + +# if(__has_feature(cxx_decltype)) +# define GLM_CXX11_DECLTYPE +# endif + +# if(__has_feature(cxx_default_function_template_args)) +# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS +# endif + +# if(__has_feature(cxx_defaulted_functions)) +# define GLM_CXX11_DEFAULTED_FUNCTIONS +# endif + +# if(__has_feature(cxx_delegating_constructors)) +# define GLM_CXX11_DELEGATING_CONSTRUCTORS +# endif + +# if(__has_feature(cxx_deleted_functions)) +# define GLM_CXX11_DELETED_FUNCTIONS +# endif + +# if(__has_feature(cxx_explicit_conversions)) +# define GLM_CXX11_EXPLICIT_CONVERSIONS +# endif + +# if(__has_feature(cxx_generalized_initializers)) +# define GLM_CXX11_GENERALIZED_INITIALIZERS +# endif + +# if(__has_feature(cxx_implicit_moves)) +# define GLM_CXX11_IMPLICIT_MOVES +# endif + +# if(__has_feature(cxx_inheriting_constructors)) +# define GLM_CXX11_INHERITING_CONSTRUCTORS +# endif + +# if(__has_feature(cxx_inline_namespaces)) +# define GLM_CXX11_INLINE_NAMESPACES +# endif + +# if(__has_feature(cxx_lambdas)) +# define GLM_CXX11_LAMBDAS +# endif + +# if(__has_feature(cxx_local_type_template_args)) +# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS +# endif + +# if(__has_feature(cxx_noexcept)) +# define GLM_CXX11_NOEXCEPT +# endif + +# if(__has_feature(cxx_nonstatic_member_init)) +# define GLM_CXX11_NONSTATIC_MEMBER_INIT +# endif + +# if(__has_feature(cxx_nullptr)) +# define GLM_CXX11_NULLPTR +# endif + +# if(__has_feature(cxx_override_control)) +# define GLM_CXX11_OVERRIDE_CONTROL +# endif + +# if(__has_feature(cxx_reference_qualified_functions)) +# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS +# endif + +# if(__has_feature(cxx_range_for)) +# define GLM_CXX11_RANGE_FOR +# endif + +# if(__has_feature(cxx_raw_string_literals)) +# define GLM_CXX11_RAW_STRING_LITERALS +# endif + +# if(__has_feature(cxx_rvalue_references)) +# define GLM_CXX11_RVALUE_REFERENCES +# endif + +# if(__has_feature(cxx_static_assert)) +# define GLM_CXX11_STATIC_ASSERT +# endif + +# if(__has_feature(cxx_auto_type)) +# define GLM_CXX11_AUTO_TYPE +# endif + +# if(__has_feature(cxx_strong_enums)) +# define GLM_CXX11_STRONG_ENUMS +# endif + +# if(__has_feature(cxx_trailing_return)) +# define GLM_CXX11_TRAILING_RETURN +# endif + +# if(__has_feature(cxx_unicode_literals)) +# define GLM_CXX11_UNICODE_LITERALS +# endif + +# if(__has_feature(cxx_unrestricted_unions)) +# define GLM_CXX11_UNRESTRICTED_UNIONS +# endif + +# if(__has_feature(cxx_user_literals)) +# define GLM_CXX11_USER_LITERALS +# endif + +# if(__has_feature(cxx_variadic_templates)) +# define GLM_CXX11_VARIADIC_TEMPLATES +# endif + +#endif//(GLM_COMPILER & GLM_COMPILER_CLANG) diff --git a/src/other/manifold/glm/glm/detail/_fixes.hpp b/src/other/manifold/glm/glm/detail/_fixes.hpp new file mode 100644 index 00000000000..a503c7c0d04 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_fixes.hpp @@ -0,0 +1,27 @@ +#include + +//! Workaround for compatibility with other libraries +#ifdef max +#undef max +#endif + +//! Workaround for compatibility with other libraries +#ifdef min +#undef min +#endif + +//! Workaround for Android +#ifdef isnan +#undef isnan +#endif + +//! Workaround for Android +#ifdef isinf +#undef isinf +#endif + +//! Workaround for Chrone Native Client +#ifdef log2 +#undef log2 +#endif + diff --git a/src/other/manifold/glm/glm/detail/_noise.hpp b/src/other/manifold/glm/glm/detail/_noise.hpp new file mode 100644 index 00000000000..5a874a02221 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_noise.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "../common.hpp" + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER T mod289(T const& x) + { + return x - floor(x * (static_cast(1.0) / static_cast(289.0))) * static_cast(289.0); + } + + template + GLM_FUNC_QUALIFIER T permute(T const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> permute(vec<2, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> permute(vec<3, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> permute(vec<4, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER T taylorInvSqrt(T const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> taylorInvSqrt(vec<2, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> taylorInvSqrt(vec<3, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> taylorInvSqrt(vec<4, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> fade(vec<2, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> fade(vec<3, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> fade(vec<4, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } +}//namespace detail +}//namespace glm + diff --git a/src/other/manifold/glm/glm/detail/_swizzle.hpp b/src/other/manifold/glm/glm/detail/_swizzle.hpp new file mode 100644 index 00000000000..87896ef4f6f --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_swizzle.hpp @@ -0,0 +1,804 @@ +#pragma once + +namespace glm{ +namespace detail +{ + // Internal class for implementing swizzle operators + template + struct _swizzle_base0 + { + protected: + GLM_FUNC_QUALIFIER T& elem(size_t i){ return (reinterpret_cast(_buffer))[i]; } + GLM_FUNC_QUALIFIER T const& elem(size_t i) const{ return (reinterpret_cast(_buffer))[i]; } + + // Use an opaque buffer to *ensure* the compiler doesn't call a constructor. + // The size 1 buffer is assumed to aligned to the actual members so that the + // elem() + char _buffer[1]; + }; + + template + struct _swizzle_base1 : public _swizzle_base0 + { + }; + + template + struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<2, T, Q> operator ()() const { return vec<2, T, Q>(this->elem(E0), this->elem(E1)); } + }; + + template + struct _swizzle_base1<3, T, Q, E0,E1,E2,-1, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<3, T, Q> operator ()() const { return vec<3, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2)); } + }; + + template + struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, T, Q> operator ()() const { return vec<4, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } + }; + + // Internal class for implementing swizzle operators + /* + Template parameters: + + T = type of scalar values (e.g. float, double) + N = number of components in the vector (e.g. 3) + E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec + + DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles + containing duplicate elements so that they cannot be used as r-values). + */ + template + struct _swizzle_base2 : public _swizzle_base1::value> + { + struct op_equal + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e = t; } + }; + + struct op_minus + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e -= t; } + }; + + struct op_plus + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e += t; } + }; + + struct op_mul + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e *= t; } + }; + + struct op_div + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e /= t; } + }; + + public: + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const T& t) + { + for (int i = 0; i < N; ++i) + (*this)[i] = t; + return *this; + } + + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vec const& that) + { + _apply_op(that, op_equal()); + return *this; + } + + GLM_FUNC_QUALIFIER void operator -= (vec const& that) + { + _apply_op(that, op_minus()); + } + + GLM_FUNC_QUALIFIER void operator += (vec const& that) + { + _apply_op(that, op_plus()); + } + + GLM_FUNC_QUALIFIER void operator *= (vec const& that) + { + _apply_op(that, op_mul()); + } + + GLM_FUNC_QUALIFIER void operator /= (vec const& that) + { + _apply_op(that, op_div()); + } + + GLM_FUNC_QUALIFIER T& operator[](size_t i) + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + GLM_FUNC_QUALIFIER T operator[](size_t i) const + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + + protected: + template + GLM_FUNC_QUALIFIER void _apply_op(vec const& that, const U& op) + { + // Make a copy of the data in this == &that. + // The copier should optimize out the copy in cases where the function is + // properly inlined and the copy is not necessary. + T t[N]; + for (int i = 0; i < N; ++i) + t[i] = that[i]; + for (int i = 0; i < N; ++i) + op( (*this)[i], t[i] ); + } + }; + + // Specialization for swizzles containing duplicate elements. These cannot be modified. + template + struct _swizzle_base2 : public _swizzle_base1::value> + { + struct Stub {}; + + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const&) { return *this; } + + GLM_FUNC_QUALIFIER T operator[] (size_t i) const + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + }; + + template + struct _swizzle : public _swizzle_base2 + { + typedef _swizzle_base2 base_type; + + using base_type::operator=; + + GLM_FUNC_QUALIFIER operator vec () const { return (*this)(); } + }; + +// +// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros +// +#define GLM_SWIZZLE_TEMPLATE1 template +#define GLM_SWIZZLE_TEMPLATE2 template +#define GLM_SWIZZLE_TYPE1 _swizzle +#define GLM_SWIZZLE_TYPE2 _swizzle + +// +// Wrapper for a binary operator (e.g. u.yy + v.zy) +// +#define GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \ + { \ + return a() OPERAND b(); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const vec& b) \ + { \ + return a() OPERAND b; \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const vec& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return a OPERAND b(); \ + } + +// +// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz) +// +#define GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const T& b) \ + { \ + return a() OPERAND b; \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const T& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return a OPERAND b(); \ + } + +// +// Macro for wrapping a function taking one argument (e.g. abs()) +// +#define GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a) \ + { \ + return FUNCTION(a()); \ + } + +// +// Macro for wrapping a function taking two vector arguments (e.g. dot()). +// +#define GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \ + { \ + return FUNCTION(a(), b()); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return FUNCTION(a(), b()); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename V& b) \ + { \ + return FUNCTION(a(), b); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return FUNCTION(a, b()); \ + } + +// +// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()). +// +#define GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b, const T& c) \ + { \ + return FUNCTION(a(), b(), c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \ + { \ + return FUNCTION(a(), b(), c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\ + { \ + return FUNCTION(a(), b, c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \ + { \ + return FUNCTION(a, b(), c); \ + } + +}//namespace detail +}//namespace glm + +namespace glm +{ + namespace detail + { + GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-) + GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/) + } + + // + // Swizzles are distinct types from the unswizzled type. The below macros will + // provide template specializations for the swizzle types for the given functions + // so that the compiler does not have any ambiguity to choosing how to handle + // the function. + // + // The alternative is to use the operator()() when calling the function in order + // to explicitly convert the swizzled type to the unswizzled type. + // + + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any); + + //GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot); + //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross); + //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step); + //GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix); +} + +#define GLM_SWIZZLE2_2_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<2, T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2, T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2, T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2, T, Q, 1,1,-1,-2> E1 ## E1; }; + +#define GLM_SWIZZLE2_3_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<3,T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; + +#define GLM_SWIZZLE2_4_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; + +#define GLM_SWIZZLE3_2_MEMBERS(T, Q, E0,E1,E2) \ + struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; + +#define GLM_SWIZZLE3_3_MEMBERS(T, Q ,E0,E1,E2) \ + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; + +#define GLM_SWIZZLE3_4_MEMBERS(T, Q, E0,E1,E2) \ + struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; + +#define GLM_SWIZZLE4_2_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 0,3,-1,-2> E0 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 1,3,-1,-2> E1 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 2,3,-1,-2> E2 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 3,0,-1,-2> E3 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 3,1,-1,-2> E3 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 3,2,-1,-2> E3 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 3,3,-1,-2> E3 ## E3; }; + +#define GLM_SWIZZLE4_3_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,3,-1> E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,3,-1> E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,3,-1> E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,0,-1> E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,1,-1> E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,2,-1> E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,3,-1> E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,3,-1> E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,3,-1> E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,3,-1> E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,0,-1> E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,1,-1> E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,2,-1> E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,3,-1> E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,3,-1> E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,3,-1> E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,3,-1> E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,0,-1> E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,1,-1> E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,2,-1> E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,3,-1> E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,0,-1> E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,1,-1> E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,2,-1> E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,3,-1> E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,0,-1> E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,1,-1> E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,2,-1> E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,3,-1> E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,0,-1> E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,1,-1> E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,2,-1> E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,3,-1> E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,0,-1> E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,1,-1> E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,2,-1> E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,3,-1> E3 ## E3 ## E3; }; + +#define GLM_SWIZZLE4_4_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<4, T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; diff --git a/src/other/manifold/glm/glm/detail/_swizzle_func.hpp b/src/other/manifold/glm/glm/detail/_swizzle_func.hpp new file mode 100644 index 00000000000..d93c6afd5b7 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_swizzle_func.hpp @@ -0,0 +1,682 @@ +#pragma once + +#define GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, CONST, A, B) \ + vec<2, T, Q> A ## B() CONST \ + { \ + return vec<2, T, Q>(this->A, this->B); \ + } + +#define GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, CONST, A, B, C) \ + vec<3, T, Q> A ## B ## C() CONST \ + { \ + return vec<3, T, Q>(this->A, this->B, this->C); \ + } + +#define GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, CONST, A, B, C, D) \ + vec<4, T, Q> A ## B ## C ## D() CONST \ + { \ + return vec<4, T, Q>(this->A, this->B, this->C, this->D); \ + } + +#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(T, P, L, CONST, A, B) \ + template \ + vec vec::A ## B() CONST \ + { \ + return vec<2, T, Q>(this->A, this->B); \ + } + +#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(T, P, L, CONST, A, B, C) \ + template \ + vec<3, T, Q> vec::A ## B ## C() CONST \ + { \ + return vec<3, T, Q>(this->A, this->B, this->C); \ + } + +#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(T, P, L, CONST, A, B, C, D) \ + template \ + vec<4, T, Q> vec::A ## B ## C ## D() CONST \ + { \ + return vec<4, T, Q>(this->A, this->B, this->C, this->D); \ + } + +#define GLM_MUTABLE + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, B, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(T, P) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, x, y) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, r, g) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, s, t) + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B) + +#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, B, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(T, P) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, x, y, z) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, r, g, b) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, s, t, p) + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, C) + +#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, B) + +#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, C, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(T, P) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, x, y, z, w) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, r, g, b, a) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, s, t, p, q) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, x, y) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, r, g) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, s, t) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, x, y, z) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, r, g, b) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, s, t, p) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, D) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, D) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, D) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, x, y, z, w) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, r, g, b, a) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, s, t, p, q) + diff --git a/src/other/manifold/glm/glm/detail/_vectorize.hpp b/src/other/manifold/glm/glm/detail/_vectorize.hpp new file mode 100644 index 00000000000..1fcaec31528 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/_vectorize.hpp @@ -0,0 +1,162 @@ +#pragma once + +namespace glm{ +namespace detail +{ + template class vec, length_t L, typename R, typename T, qualifier Q> + struct functor1{}; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, R, Q> call(R (*Func) (T x), vec<1, T, Q> const& v) + { + return vec<1, R, Q>(Func(v.x)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, R, Q> call(R (*Func) (T x), vec<2, T, Q> const& v) + { + return vec<2, R, Q>(Func(v.x), Func(v.y)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, R, Q> call(R (*Func) (T x), vec<3, T, Q> const& v) + { + return vec<3, R, Q>(Func(v.x), Func(v.y), Func(v.z)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, R, Q> call(R (*Func) (T x), vec<4, T, Q> const& v) + { + return vec<4, R, Q>(Func(v.x), Func(v.y), Func(v.z), Func(v.w)); + } + }; + + template class vec, length_t L, typename T, qualifier Q> + struct functor2{}; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, vec<1, T, Q> const& b) + { + return vec<1, T, Q>(Func(a.x, b.x)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, vec<2, T, Q> const& b) + { + return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); + } + }; + + template class vec, length_t L, typename T, qualifier Q> + struct functor2_vec_sca{}; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, T b) + { + return vec<1, T, Q>(Func(a.x, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, T b) + { + return vec<2, T, Q>(Func(a.x, b), Func(a.y, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, T b) + { + return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, T b) + { + return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); + } + }; + + template + struct functor2_vec_int {}; + + template + struct functor2_vec_int<1, T, Q> + { + GLM_FUNC_QUALIFIER static vec<1, int, Q> call(int (*Func) (T x, int y), vec<1, T, Q> const& a, vec<1, int, Q> const& b) + { + return vec<1, int, Q>(Func(a.x, b.x)); + } + }; + + template + struct functor2_vec_int<2, T, Q> + { + GLM_FUNC_QUALIFIER static vec<2, int, Q> call(int (*Func) (T x, int y), vec<2, T, Q> const& a, vec<2, int, Q> const& b) + { + return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y)); + } + }; + + template + struct functor2_vec_int<3, T, Q> + { + GLM_FUNC_QUALIFIER static vec<3, int, Q> call(int (*Func) (T x, int y), vec<3, T, Q> const& a, vec<3, int, Q> const& b) + { + return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); + } + }; + + template + struct functor2_vec_int<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(int (*Func) (T x, int y), vec<4, T, Q> const& a, vec<4, int, Q> const& b) + { + return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); + } + }; +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/compute_common.hpp b/src/other/manifold/glm/glm/detail/compute_common.hpp new file mode 100644 index 00000000000..cc24b9e62f5 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/compute_common.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "setup.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_abs + {}; + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || std::numeric_limits::is_signed, + "'abs' only accept floating-point and integer scalar or vector inputs"); + + return x >= genFIType(0) ? x : -x; + // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff; + } + }; + +#if GLM_COMPILER & GLM_COMPILER_CUDA + template<> + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static float call(float x) + { + return fabsf(x); + } + }; +#endif + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + (!std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'abs' only accept floating-point and integer scalar or vector inputs"); + return x; + } + }; +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/compute_vector_relational.hpp b/src/other/manifold/glm/glm/detail/compute_vector_relational.hpp new file mode 100644 index 00000000000..167b6345dd3 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/compute_vector_relational.hpp @@ -0,0 +1,30 @@ +#pragma once + +//#include "compute_common.hpp" +#include "setup.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b) + { + return a == b; + } + }; +/* + template + struct compute_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b) + { + return detail::compute_abs::is_signed>::call(b - a) <= static_cast(0); + //return std::memcmp(&a, &b, sizeof(T)) == 0; + } + }; +*/ +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/func_common.inl b/src/other/manifold/glm/glm/detail/func_common.inl new file mode 100644 index 00000000000..4b5f14410ff --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_common.inl @@ -0,0 +1,792 @@ +/// @ref core +/// @file glm/detail/func_common.inl + +#include "../vector_relational.hpp" +#include "compute_common.hpp" +#include "type_vec1.hpp" +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include "_vectorize.hpp" +#include + +namespace glm +{ + // min + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType min(genType x, genType y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return (y < x) ? y : x; + } + + // max + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType max(genType x, genType y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + + return (x < y) ? y : x; + } + + // abs + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR int abs(int x) + { + int const y = x >> (sizeof(int) * 8 - 1); + return (x ^ y) - y; + } + + // round +# if GLM_HAS_CXX11_STL + using ::std::round; +# else + template + GLM_FUNC_QUALIFIER genType round(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + + return x < static_cast(0) ? static_cast(int(x - static_cast(0.5))) : static_cast(int(x + static_cast(0.5))); + } +# endif + + // trunc +# if GLM_HAS_CXX11_STL + using ::std::trunc; +# else + template + GLM_FUNC_QUALIFIER genType trunc(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + + return x < static_cast(0) ? -std::floor(-x) : std::floor(x); + } +# endif + +}//namespace glm + +namespace glm{ +namespace detail +{ + template + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x) + { + return detail::functor1::call(abs, x); + } + }; + + template + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vec(vec(x) * (static_cast(1) - a) + vec(y) * a); + } + }; + + template + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + { + vec Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = a[i] ? y[i] : x[i]; + return Result; + } + }; + + template + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vec(vec(x) * (static_cast(1) - a) + vec(y) * a); + } + }; + + template + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return static_cast(static_cast(x) * (static_cast(1) - a) + static_cast(y) * a); + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_sign + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return vec(glm::lessThan(vec(0), x)) - vec(glm::lessThan(x, vec(0))); + } + }; + +# if GLM_ARCH == GLM_ARCH_X86 + template + struct compute_sign + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + T const Shift(static_cast(sizeof(T) * 8 - 1)); + vec const y(vec::type, Q>(-x) >> typename detail::make_unsigned::type(Shift)); + + return (x >> Shift) | y; + } + }; +# endif + + template + struct compute_floor + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::floor, x); + } + }; + + template + struct compute_ceil + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::ceil, x); + } + }; + + template + struct compute_fract + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return x - floor(x); + } + }; + + template + struct compute_trunc + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(trunc, x); + } + }; + + template + struct compute_round + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(round, x); + } + }; + + template + struct compute_mod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mod' only accept floating-point inputs. Include for integer inputs."); + return a - b * floor(a / b); + } + }; + + template + struct compute_min_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) + { + return detail::functor2::call(min, x, y); + } + }; + + template + struct compute_max_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) + { + return detail::functor2::call(max, x, y); + } + }; + + template + struct compute_clamp_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& minVal, vec const& maxVal) + { + return min(max(x, minVal), maxVal); + } + }; + + template + struct compute_step_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& edge, vec const& x) + { + return mix(vec(1), vec(0), glm::lessThan(x, edge)); + } + }; + + template + struct compute_smoothstep_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& edge0, vec const& edge1, vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs"); + vec const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast(0), static_cast(1))); + return tmp * tmp * (static_cast(3) - static_cast(2) * tmp); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genFIType abs(genFIType x) + { + return detail::compute_abs::is_signed>::call(x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec abs(vec const& x) + { + return detail::compute_abs_vector::value>::call(x); + } + + // sign + // fast and works for any type + template + GLM_FUNC_QUALIFIER genFIType sign(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign<1, genFIType, defaultp, + std::numeric_limits::is_iec559, detail::is_aligned::value>::call(vec<1, genFIType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec sign(vec const& x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign::is_iec559, detail::is_aligned::value>::call(x); + } + + // floor + using ::std::floor; + template + GLM_FUNC_QUALIFIER vec floor(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'floor' only accept floating-point inputs."); + return detail::compute_floor::value>::call(x); + } + + template + GLM_FUNC_QUALIFIER vec trunc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + return detail::compute_trunc::value>::call(x); + } + + template + GLM_FUNC_QUALIFIER vec round(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + return detail::compute_round::value>::call(x); + } + +/* + // roundEven + template + GLM_FUNC_QUALIFIER genType roundEven(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + + return genType(int(x + genType(int(x) % 2))); + } +*/ + + // roundEven + template + GLM_FUNC_QUALIFIER genType roundEven(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + + int Integer = static_cast(x); + genType IntegerPart = static_cast(Integer); + genType FractionalPart = fract(x); + + if(FractionalPart > static_cast(0.5) || FractionalPart < static_cast(0.5)) + { + return round(x); + } + else if((Integer % 2) == 0) + { + return IntegerPart; + } + else if(x <= static_cast(0)) // Work around... + { + return IntegerPart - static_cast(1); + } + else + { + return IntegerPart + static_cast(1); + } + //else // Bug on MinGW 4.5.2 + //{ + // return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0)); + //} + } + + template + GLM_FUNC_QUALIFIER vec roundEven(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + return detail::functor1::call(roundEven, x); + } + + // ceil + using ::std::ceil; + template + GLM_FUNC_QUALIFIER vec ceil(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ceil' only accept floating-point inputs"); + return detail::compute_ceil::value>::call(x); + } + + // fract + template + GLM_FUNC_QUALIFIER genType fract(genType x) + { + return fract(vec<1, genType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec fract(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); + return detail::compute_fract::value>::call(x); + } + + // mod + template + GLM_FUNC_QUALIFIER genType mod(genType x, genType y) + { +# if GLM_COMPILER & GLM_COMPILER_CUDA + // Another Cuda compiler bug https://github.com/g-truc/glm/issues/530 + vec<1, genType, defaultp> Result(mod(vec<1, genType, defaultp>(x), y)); + return Result.x; +# else + return mod(vec<1, genType, defaultp>(x), y).x; +# endif + } + + template + GLM_FUNC_QUALIFIER vec mod(vec const& x, T y) + { + return detail::compute_mod::value>::call(x, vec(y)); + } + + template + GLM_FUNC_QUALIFIER vec mod(vec const& x, vec const& y) + { + return detail::compute_mod::value>::call(x, y); + } + + // modf + template + GLM_FUNC_QUALIFIER genType modf(genType x, genType & i) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'modf' only accept floating-point inputs"); + return std::modf(x, &i); + } + + template + GLM_FUNC_QUALIFIER vec<1, T, Q> modf(vec<1, T, Q> const& x, vec<1, T, Q> & i) + { + return vec<1, T, Q>( + modf(x.x, i.x)); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> modf(vec<2, T, Q> const& x, vec<2, T, Q> & i) + { + return vec<2, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> modf(vec<3, T, Q> const& x, vec<3, T, Q> & i) + { + return vec<3, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y), + modf(x.z, i.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> modf(vec<4, T, Q> const& x, vec<4, T, Q> & i) + { + return vec<4, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y), + modf(x.z, i.z), + modf(x.w, i.w)); + } + + //// Only valid if (INT_MIN <= x-y <= INT_MAX) + //// min(x,y) + //r = y + ((x - y) & ((x - y) >> (sizeof(int) * + //CHAR_BIT - 1))); + //// max(x,y) + //r = x - ((x - y) & ((x - y) >> (sizeof(int) * + //CHAR_BIT - 1))); + + // min + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return detail::compute_min_vector::value>::call(a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& a, vec const& b) + { + return detail::compute_min_vector::value>::call(a, b); + } + + // max + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + return detail::compute_max_vector::value>::call(a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& a, vec const& b) + { + return detail::compute_max_vector::value>::call(a, b); + } + + // clamp + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return min(max(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec clamp(vec const& x, T minVal, T maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, vec(minVal), vec(maxVal)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec clamp(vec const& x, vec const& minVal, vec const& maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, minVal, maxVal); + } + + template + GLM_FUNC_QUALIFIER genTypeT mix(genTypeT x, genTypeT y, genTypeU a) + { + return detail::compute_mix::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER vec mix(vec const& x, vec const& y, U a) + { + return detail::compute_mix_scalar::value>::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER vec mix(vec const& x, vec const& y, vec const& a) + { + return detail::compute_mix_vector::value>::call(x, y, a); + } + + // step + template + GLM_FUNC_QUALIFIER genType step(genType edge, genType x) + { + return mix(static_cast(1), static_cast(0), x < edge); + } + + template + GLM_FUNC_QUALIFIER vec step(T edge, vec const& x) + { + return detail::compute_step_vector::value>::call(vec(edge), x); + } + + template + GLM_FUNC_QUALIFIER vec step(vec const& edge, vec const& x) + { + return detail::compute_step_vector::value>::call(edge, x); + } + + // smoothstep + template + GLM_FUNC_QUALIFIER genType smoothstep(genType edge0, genType edge1, genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs"); + + genType const tmp(clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1))); + return tmp * tmp * (genType(3) - genType(2) * tmp); + } + + template + GLM_FUNC_QUALIFIER vec smoothstep(T edge0, T edge1, vec const& x) + { + return detail::compute_smoothstep_vector::value>::call(vec(edge0), vec(edge1), x); + } + + template + GLM_FUNC_QUALIFIER vec smoothstep(vec const& edge0, vec const& edge1, vec const& x) + { + return detail::compute_smoothstep_vector::value>::call(edge0, edge1, x); + } + +# if GLM_HAS_CXX11_STL + using std::isnan; +# else + template + GLM_FUNC_QUALIFIER bool isnan(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::isnan(x); +# elif GLM_COMPILER & GLM_COMPILER_VC + return _isnan(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# if GLM_PLATFORM & GLM_PLATFORM_WINDOWS + return _isnan(x) != 0; +# else + return ::isnan(x) != 0; +# endif +# elif (GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG)) && (GLM_PLATFORM & GLM_PLATFORM_ANDROID) && __cplusplus < 201103L + return _isnan(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_CUDA + return ::isnan(x) != 0; +# else + return std::isnan(x); +# endif + } +# endif + + template + GLM_FUNC_QUALIFIER vec isnan(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = glm::isnan(v[l]); + return Result; + } + +# if GLM_HAS_CXX11_STL + using std::isinf; +# else + template + GLM_FUNC_QUALIFIER bool isinf(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::isinf(x); +# elif GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC) +# if(GLM_PLATFORM & GLM_PLATFORM_WINDOWS) + return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF; +# else + return ::isinf(x); +# endif +# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG) +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L) + return _isinf(x) != 0; +# else + return std::isinf(x); +# endif +# elif GLM_COMPILER & GLM_COMPILER_CUDA + // http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MATH__DOUBLE_g13431dd2b40b51f9139cbb7f50c18fab.html#g13431dd2b40b51f9139cbb7f50c18fab + return ::isinf(double(x)) != 0; +# else + return std::isinf(x); +# endif + } +# endif + + template + GLM_FUNC_QUALIFIER vec isinf(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = glm::isinf(v[l]); + return Result; + } + + GLM_FUNC_QUALIFIER int floatBitsToInt(float const& v) + { + union + { + float in; + int out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToInt(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER uint floatBitsToUint(float const& v) + { + union + { + float in; + uint out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToUint(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER float intBitsToFloat(int const& v) + { + union + { + int in; + float out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec intBitsToFloat(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const& v) + { + union + { + uint in; + float out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec uintBitsToFloat(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + +# if GLM_HAS_CXX11_STL + using std::fma; +# else + template + GLM_FUNC_QUALIFIER genType fma(genType const& a, genType const& b, genType const& c) + { + return a * b + c; + } +# endif + + template + GLM_FUNC_QUALIFIER genType frexp(genType x, int& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'frexp' only accept floating-point inputs"); + + return std::frexp(x, &exp); + } + + template + GLM_FUNC_QUALIFIER vec frexp(vec const& v, vec& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'frexp' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = std::frexp(v[l], &exp[l]); + return Result; + } + + template + GLM_FUNC_QUALIFIER genType ldexp(genType const& x, int const& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ldexp' only accept floating-point inputs"); + + return std::ldexp(x, exp); + } + + template + GLM_FUNC_QUALIFIER vec ldexp(vec const& v, vec const& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ldexp' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = std::ldexp(v[l], exp[l]); + return Result; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_common_simd.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/func_common_simd.inl b/src/other/manifold/glm/glm/detail/func_common_simd.inl new file mode 100644 index 00000000000..ce0032d33fe --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_common_simd.inl @@ -0,0 +1,231 @@ +/// @ref core +/// @file glm/detail/func_common_simd.inl + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#include "../simd/common.h" + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_abs_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_abs(v.data); + return result; + } + }; + + template + struct compute_abs_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v) + { + vec<4, int, Q> result; + result.data = glm_ivec4_abs(v.data); + return result; + } + }; + + template + struct compute_floor<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_floor(v.data); + return result; + } + }; + + template + struct compute_ceil<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_ceil(v.data); + return result; + } + }; + + template + struct compute_fract<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_fract(v.data); + return result; + } + }; + + template + struct compute_round<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_round(v.data); + return result; + } + }; + + template + struct compute_mod<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { + vec<4, float, Q> result; + result.data = glm_vec4_mod(x.data, y.data); + return result; + } + }; + + template + struct compute_min_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + vec<4, float, Q> result; + result.data = _mm_min_ps(v1.data, v2.data); + return result; + } + }; + + template + struct compute_min_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + vec<4, int, Q> result; + result.data = _mm_min_epi32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_min_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + vec<4, uint, Q> result; + result.data = _mm_min_epu32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + vec<4, float, Q> result; + result.data = _mm_max_ps(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + vec<4, int, Q> result; + result.data = _mm_max_epi32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + vec<4, uint, Q> result; + result.data = _mm_max_epu32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& minVal, vec<4, float, Q> const& maxVal) + { + vec<4, float, Q> result; + result.data = _mm_min_ps(_mm_max_ps(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& x, vec<4, int, Q> const& minVal, vec<4, int, Q> const& maxVal) + { + vec<4, int, Q> result; + result.data = _mm_min_epi32(_mm_max_epi32(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& x, vec<4, uint, Q> const& minVal, vec<4, uint, Q> const& maxVal) + { + vec<4, uint, Q> result; + result.data = _mm_min_epu32(_mm_max_epu32(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_mix_vector<4, float, bool, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y, vec<4, bool, Q> const& a) + { + __m128i const Load = _mm_set_epi32(-static_cast(a.w), -static_cast(a.z), -static_cast(a.y), -static_cast(a.x)); + __m128 const Mask = _mm_castsi128_ps(Load); + + vec<4, float, Q> Result; +# if 0 && GLM_ARCH & GLM_ARCH_AVX + Result.data = _mm_blendv_ps(x.data, y.data, Mask); +# else + Result.data = _mm_or_ps(_mm_and_ps(Mask, y.data), _mm_andnot_ps(Mask, x.data)); +# endif + return Result; + } + }; +/* FIXME + template + struct compute_step_vector + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge, vec<4, float, Q> const& x) + { + vec<4, float, Q> Result; + result.data = glm_vec4_step(edge.data, x.data); + return result; + } + }; +*/ + template + struct compute_smoothstep_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge0, vec<4, float, Q> const& edge1, vec<4, float, Q> const& x) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_smoothstep(edge0.data, edge1.data, x.data); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/detail/func_exponential.inl b/src/other/manifold/glm/glm/detail/func_exponential.inl new file mode 100644 index 00000000000..2040d41f8a3 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_exponential.inl @@ -0,0 +1,152 @@ +/// @ref core +/// @file glm/detail/func_exponential.inl + +#include "../vector_relational.hpp" +#include "_vectorize.hpp" +#include +#include +#include + +namespace glm{ +namespace detail +{ +# if GLM_HAS_CXX11_STL + using std::log2; +# else + template + genType log2(genType Value) + { + return std::log(Value) * static_cast(1.4426950408889634073599246810019); + } +# endif + + template + struct compute_log2 + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'log2' only accept floating-point inputs. Include for integer inputs."); + + return detail::functor1::call(log2, v); + } + }; + + template + struct compute_sqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::sqrt, x); + } + }; + + template + struct compute_inversesqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return static_cast(1) / sqrt(x); + } + }; + + template + struct compute_inversesqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + vec tmp(x); + vec xhalf(tmp * 0.5f); + vec* p = reinterpret_cast*>(const_cast*>(&x)); + vec i = vec(0x5f375a86) - (*p >> vec(1)); + vec* ptmp = reinterpret_cast*>(&i); + tmp = *ptmp; + tmp = tmp * (1.5f - xhalf * tmp * tmp); + return tmp; + } + }; +}//namespace detail + + // pow + using std::pow; + template + GLM_FUNC_QUALIFIER vec pow(vec const& base, vec const& exponent) + { + return detail::functor2::call(pow, base, exponent); + } + + // exp + using std::exp; + template + GLM_FUNC_QUALIFIER vec exp(vec const& x) + { + return detail::functor1::call(exp, x); + } + + // log + using std::log; + template + GLM_FUNC_QUALIFIER vec log(vec const& x) + { + return detail::functor1::call(log, x); + } + +# if GLM_HAS_CXX11_STL + using std::exp2; +# else + //exp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType exp2(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'exp2' only accept floating-point inputs"); + + return std::exp(static_cast(0.69314718055994530941723212145818) * x); + } +# endif + + template + GLM_FUNC_QUALIFIER vec exp2(vec const& x) + { + return detail::functor1::call(exp2, x); + } + + // log2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType log2(genType x) + { + return log2(vec<1, genType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec log2(vec const& x) + { + return detail::compute_log2::is_iec559, detail::is_aligned::value>::call(x); + } + + // sqrt + using std::sqrt; + template + GLM_FUNC_QUALIFIER vec sqrt(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sqrt' only accept floating-point inputs"); + return detail::compute_sqrt::value>::call(x); + } + + // inversesqrt + template + GLM_FUNC_QUALIFIER genType inversesqrt(genType x) + { + return static_cast(1) / sqrt(x); + } + + template + GLM_FUNC_QUALIFIER vec inversesqrt(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'inversesqrt' only accept floating-point inputs"); + return detail::compute_inversesqrt::value>::call(x); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_exponential_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/func_exponential_simd.inl b/src/other/manifold/glm/glm/detail/func_exponential_simd.inl new file mode 100644 index 00000000000..fb78951727f --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_exponential_simd.inl @@ -0,0 +1,37 @@ +/// @ref core +/// @file glm/detail/func_exponential_simd.inl + +#include "../simd/exponential.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_sqrt<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> Result; + Result.data = _mm_sqrt_ps(v.data); + return Result; + } + }; + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + struct compute_sqrt<4, float, aligned_lowp, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& v) + { + vec<4, float, aligned_lowp> Result; + Result.data = glm_vec4_sqrt_lowp(v.data); + return Result; + } + }; +# endif +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/detail/func_geometric.inl b/src/other/manifold/glm/glm/detail/func_geometric.inl new file mode 100644 index 00000000000..9cde28fed18 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_geometric.inl @@ -0,0 +1,243 @@ +#include "../exponential.hpp" +#include "../common.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_length + { + GLM_FUNC_QUALIFIER static T call(vec const& v) + { + return sqrt(dot(v, v)); + } + }; + + template + struct compute_distance + { + GLM_FUNC_QUALIFIER static T call(vec const& p0, vec const& p1) + { + return length(p1 - p0); + } + }; + + template + struct compute_dot{}; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER static T call(vec<1, T, Q> const& a, vec<1, T, Q> const& b) + { + return a.x * b.x; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER static T call(vec<2, T, Q> const& a, vec<2, T, Q> const& b) + { + vec<2, T, Q> tmp(a * b); + return tmp.x + tmp.y; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER static T call(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + vec<3, T, Q> tmp(a * b); + return tmp.x + tmp.y + tmp.z; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> tmp(a * b); + return (tmp.x + tmp.y) + (tmp.z + tmp.w); + } + }; + + template + struct compute_cross + { + GLM_FUNC_QUALIFIER static vec<3, T, Q> call(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cross' accepts only floating-point inputs"); + + return vec<3, T, Q>( + x.y * y.z - y.y * x.z, + x.z * y.x - y.z * x.x, + x.x * y.y - y.x * x.y); + } + }; + + template + struct compute_normalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return v * inversesqrt(dot(v, v)); + } + }; + + template + struct compute_faceforward + { + GLM_FUNC_QUALIFIER static vec call(vec const& N, vec const& I, vec const& Nref) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return dot(Nref, I) < static_cast(0) ? N : -N; + } + }; + + template + struct compute_reflect + { + GLM_FUNC_QUALIFIER static vec call(vec const& I, vec const& N) + { + return I - N * dot(N, I) * static_cast(2); + } + }; + + template + struct compute_refract + { + GLM_FUNC_QUALIFIER static vec call(vec const& I, vec const& N, T eta) + { + T const dotValue(dot(N, I)); + T const k(static_cast(1) - eta * eta * (static_cast(1) - dotValue * dotValue)); + vec const Result = + (k >= static_cast(0)) ? (eta * I - (eta * dotValue + std::sqrt(k)) * N) : vec(0); + return Result; + } + }; +}//namespace detail + + // length + template + GLM_FUNC_QUALIFIER genType length(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length' accepts only floating-point inputs"); + + return abs(x); + } + + template + GLM_FUNC_QUALIFIER T length(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length' accepts only floating-point inputs"); + + return detail::compute_length::value>::call(v); + } + + // distance + template + GLM_FUNC_QUALIFIER genType distance(genType const& p0, genType const& p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance' accepts only floating-point inputs"); + + return length(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T distance(vec const& p0, vec const& p1) + { + return detail::compute_distance::value>::call(p0, p1); + } + + // dot + template + GLM_FUNC_QUALIFIER T dot(T x, T y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return x * y; + } + + template + GLM_FUNC_QUALIFIER T dot(vec const& x, vec const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return detail::compute_dot, T, detail::is_aligned::value>::call(x, y); + } + + // cross + template + GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + return detail::compute_cross::value>::call(x, y); + } +/* + // normalize + template + GLM_FUNC_QUALIFIER genType normalize(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return x < genType(0) ? genType(-1) : genType(1); + } +*/ + template + GLM_FUNC_QUALIFIER vec normalize(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return detail::compute_normalize::value>::call(x); + } + + // faceforward + template + GLM_FUNC_QUALIFIER genType faceforward(genType const& N, genType const& I, genType const& Nref) + { + return dot(Nref, I) < static_cast(0) ? N : -N; + } + + template + GLM_FUNC_QUALIFIER vec faceforward(vec const& N, vec const& I, vec const& Nref) + { + return detail::compute_faceforward::value>::call(N, I, Nref); + } + + // reflect + template + GLM_FUNC_QUALIFIER genType reflect(genType const& I, genType const& N) + { + return I - N * dot(N, I) * genType(2); + } + + template + GLM_FUNC_QUALIFIER vec reflect(vec const& I, vec const& N) + { + return detail::compute_reflect::value>::call(I, N); + } + + // refract + template + GLM_FUNC_QUALIFIER genType refract(genType const& I, genType const& N, genType eta) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'refract' accepts only floating-point inputs"); + genType const dotValue(dot(N, I)); + genType const k(static_cast(1) - eta * eta * (static_cast(1) - dotValue * dotValue)); + return (eta * I - (eta * dotValue + sqrt(k)) * N) * static_cast(k >= static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER vec refract(vec const& I, vec const& N, T eta) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'refract' accepts only floating-point inputs"); + return detail::compute_refract::value>::call(I, N, eta); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_geometric_simd.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/func_geometric_simd.inl b/src/other/manifold/glm/glm/detail/func_geometric_simd.inl new file mode 100644 index 00000000000..2076dae055c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_geometric_simd.inl @@ -0,0 +1,163 @@ +/// @ref core +/// @file glm/detail/func_geometric_simd.inl + +#include "../simd/geometric.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_length<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v) + { + return _mm_cvtss_f32(glm_vec4_length(v.data)); + } + }; + + template + struct compute_distance<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1) + { + return _mm_cvtss_f32(glm_vec4_distance(p0.data, p1.data)); + } + }; + + template + struct compute_dot, float, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { + return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data)); + } + }; + + template + struct compute_cross + { + GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b) + { + __m128 const set0 = _mm_set_ps(0.0f, a.z, a.y, a.x); + __m128 const set1 = _mm_set_ps(0.0f, b.z, b.y, b.x); + __m128 const xpd0 = glm_vec4_cross(set0, set1); + + vec<4, float, Q> Result; + Result.data = xpd0; + return vec<3, float, Q>(Result); + } + }; + + template + struct compute_normalize<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_normalize(v.data); + return Result; + } + }; + + template + struct compute_faceforward<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& N, vec<4, float, Q> const& I, vec<4, float, Q> const& Nref) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_faceforward(N.data, I.data, Nref.data); + return Result; + } + }; + + template + struct compute_reflect<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_reflect(I.data, N.data); + return Result; + } + }; + + template + struct compute_refract<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N, float eta) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_refract(I.data, N.data, _mm_set1_ps(eta)); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#elif GLM_ARCH & GLM_ARCH_NEON_BIT +namespace glm{ +namespace detail +{ + template + struct compute_length<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v) + { + return sqrt(compute_dot, float, true>::call(v, v)); + } + }; + + template + struct compute_distance<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1) + { + return compute_length<4, float, Q, true>::call(p1 - p0); + } + }; + + + template + struct compute_dot, float, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + float32x4_t v = vmulq_f32(x.data, y.data); + return vaddvq_f32(v); +#else // Armv7a with Neon + float32x4_t p = vmulq_f32(x.data, y.data); + float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p)); + v = vpadd_f32(v, v); + return vget_lane_f32(v, 0); +#endif + } + }; + + template + struct compute_normalize<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + float32x4_t p = vmulq_f32(v.data, v.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + p = vpaddq_f32(p, p); + p = vpaddq_f32(p, p); +#else + float32x2_t t = vpadd_f32(vget_low_f32(p), vget_high_f32(p)); + t = vpadd_f32(t, t); + p = vcombine_f32(t, t); +#endif + + float32x4_t vd = vrsqrteq_f32(p); + vec<4, float, Q> Result; + Result.data = vmulq_f32(v.data, vd); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/detail/func_integer.inl b/src/other/manifold/glm/glm/detail/func_integer.inl new file mode 100644 index 00000000000..091e1e0c202 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_integer.inl @@ -0,0 +1,372 @@ +/// @ref core + +#include "_vectorize.hpp" +#if(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC) +# include +# pragma intrinsic(_BitScanReverse) +#endif//(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC) +#include + +#if !GLM_HAS_EXTENDED_INTEGER_TYPE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic ignored "-Wc++11-long-long" +# endif +#endif + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER T mask(T Bits) + { + return Bits >= static_cast(sizeof(T) * 8) ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); + } + + template + struct compute_bitfieldReverseStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T, T) + { + return v; + } + }; + + template + struct compute_bitfieldReverseStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Mask, T Shift) + { + return (v & Mask) << Shift | (v & (~Mask)) >> Shift; + } + }; + + template + struct compute_bitfieldBitCountStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T, T) + { + return v; + } + }; + + template + struct compute_bitfieldBitCountStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Mask, T Shift) + { + return (v & Mask) + ((v >> Shift) & Mask); + } + }; + + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + if(Value == 0) + return -1; + + return glm::bitCount(~Value & (Value - static_cast(1))); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanForward(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + }; + +# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32)) + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanForward64(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + }; +# endif +# endif//GLM_HAS_BITSCAN_WINDOWS + + template + struct compute_findMSB_step_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, T Shift) + { + return x | (x >> Shift); + } + }; + + template + struct compute_findMSB_step_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, T) + { + return x; + } + }; + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + vec x(v); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 1)); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 2)); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 4)); + x = compute_findMSB_step_vec= 16>::call(x, static_cast( 8)); + x = compute_findMSB_step_vec= 32>::call(x, static_cast(16)); + x = compute_findMSB_step_vec= 64>::call(x, static_cast(32)); + return vec(sizeof(T) * 8 - 1) - glm::bitCount(~x); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + GLM_FUNC_QUALIFIER int compute_findMSB_32(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanReverse(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(compute_findMSB_32, x); + } + }; + +# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32)) + template + GLM_FUNC_QUALIFIER int compute_findMSB_64(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanReverse64(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(compute_findMSB_64, x); + } + }; +# endif +# endif//GLM_HAS_BITSCAN_WINDOWS +}//namespace detail + + // uaddCarry + GLM_FUNC_QUALIFIER uint uaddCarry(uint const& x, uint const& y, uint & Carry) + { + detail::uint64 const Value64(static_cast(x) + static_cast(y)); + detail::uint64 const Max32((static_cast(1) << static_cast(32)) - static_cast(1)); + Carry = Value64 > Max32 ? 1u : 0u; + return static_cast(Value64 % (Max32 + static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER vec uaddCarry(vec const& x, vec const& y, vec& Carry) + { + vec Value64(vec(x) + vec(y)); + vec Max32((static_cast(1) << static_cast(32)) - static_cast(1)); + Carry = mix(vec(0), vec(1), greaterThan(Value64, Max32)); + return vec(Value64 % (Max32 + static_cast(1))); + } + + // usubBorrow + GLM_FUNC_QUALIFIER uint usubBorrow(uint const& x, uint const& y, uint & Borrow) + { + Borrow = x >= y ? static_cast(0) : static_cast(1); + if(y >= x) + return y - x; + else + return static_cast((static_cast(1) << static_cast(32)) + (static_cast(y) - static_cast(x))); + } + + template + GLM_FUNC_QUALIFIER vec usubBorrow(vec const& x, vec const& y, vec& Borrow) + { + Borrow = mix(vec(1), vec(0), greaterThanEqual(x, y)); + vec const YgeX(y - x); + vec const XgeY(vec((static_cast(1) << static_cast(32)) + (vec(y) - vec(x)))); + return mix(XgeY, YgeX, greaterThanEqual(y, x)); + } + + // umulExtended + GLM_FUNC_QUALIFIER void umulExtended(uint const& x, uint const& y, uint & msb, uint & lsb) + { + detail::uint64 Value64 = static_cast(x) * static_cast(y); + msb = static_cast(Value64 >> static_cast(32)); + lsb = static_cast(Value64); + } + + template + GLM_FUNC_QUALIFIER void umulExtended(vec const& x, vec const& y, vec& msb, vec& lsb) + { + vec Value64(vec(x) * vec(y)); + msb = vec(Value64 >> static_cast(32)); + lsb = vec(Value64); + } + + // imulExtended + GLM_FUNC_QUALIFIER void imulExtended(int x, int y, int& msb, int& lsb) + { + detail::int64 Value64 = static_cast(x) * static_cast(y); + msb = static_cast(Value64 >> static_cast(32)); + lsb = static_cast(Value64); + } + + template + GLM_FUNC_QUALIFIER void imulExtended(vec const& x, vec const& y, vec& msb, vec& lsb) + { + vec Value64(vec(x) * vec(y)); + lsb = vec(Value64 & static_cast(0xFFFFFFFF)); + msb = vec((Value64 >> static_cast(32)) & static_cast(0xFFFFFFFF)); + } + + // bitfieldExtract + template + GLM_FUNC_QUALIFIER genIUType bitfieldExtract(genIUType Value, int Offset, int Bits) + { + return bitfieldExtract(vec<1, genIUType>(Value), Offset, Bits).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldExtract(vec const& Value, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldExtract' only accept integer inputs"); + + return (Value >> static_cast(Offset)) & static_cast(detail::mask(Bits)); + } + + // bitfieldInsert + template + GLM_FUNC_QUALIFIER genIUType bitfieldInsert(genIUType const& Base, genIUType const& Insert, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldInsert' only accept integer values"); + + return bitfieldInsert(vec<1, genIUType>(Base), vec<1, genIUType>(Insert), Offset, Bits).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldInsert(vec const& Base, vec const& Insert, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldInsert' only accept integer values"); + + T const Mask = static_cast(detail::mask(Bits) << Offset); + return (Base & ~Mask) | ((Insert << static_cast(Offset)) & Mask); + } + + // bitfieldReverse + template + GLM_FUNC_QUALIFIER genIUType bitfieldReverse(genIUType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldReverse' only accept integer values"); + + return bitfieldReverse(glm::vec<1, genIUType, glm::defaultp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldReverse(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldReverse' only accept integer values"); + + vec x(v); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 2>::call(x, static_cast(0x5555555555555555ull), static_cast( 1)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 4>::call(x, static_cast(0x3333333333333333ull), static_cast( 2)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 8>::call(x, static_cast(0x0F0F0F0F0F0F0F0Full), static_cast( 4)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 16>::call(x, static_cast(0x00FF00FF00FF00FFull), static_cast( 8)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 32>::call(x, static_cast(0x0000FFFF0000FFFFull), static_cast(16)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 64>::call(x, static_cast(0x00000000FFFFFFFFull), static_cast(32)); + return x; + } + + // bitCount + template + GLM_FUNC_QUALIFIER int bitCount(genIUType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitCount' only accept integer values"); + + return bitCount(glm::vec<1, genIUType, glm::defaultp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec bitCount(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitCount' only accept integer values"); + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable : 4310) //cast truncates constant value +# endif + + vec::type, Q> x(*reinterpret_cast::type, Q> const *>(&v)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 2>::call(x, typename detail::make_unsigned::type(0x5555555555555555ull), typename detail::make_unsigned::type( 1)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 4>::call(x, typename detail::make_unsigned::type(0x3333333333333333ull), typename detail::make_unsigned::type( 2)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 8>::call(x, typename detail::make_unsigned::type(0x0F0F0F0F0F0F0F0Full), typename detail::make_unsigned::type( 4)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 16>::call(x, typename detail::make_unsigned::type(0x00FF00FF00FF00FFull), typename detail::make_unsigned::type( 8)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 32>::call(x, typename detail::make_unsigned::type(0x0000FFFF0000FFFFull), typename detail::make_unsigned::type(16)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 64>::call(x, typename detail::make_unsigned::type(0x00000000FFFFFFFFull), typename detail::make_unsigned::type(32)); + return vec(x); + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif + } + + // findLSB + template + GLM_FUNC_QUALIFIER int findLSB(genIUType Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findLSB' only accept integer values"); + + return detail::compute_findLSB::call(Value); + } + + template + GLM_FUNC_QUALIFIER vec findLSB(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findLSB' only accept integer values"); + + return detail::functor1::call(findLSB, x); + } + + // findMSB + template + GLM_FUNC_QUALIFIER int findMSB(genIUType v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findMSB' only accept integer values"); + + return findMSB(vec<1, genIUType>(v)).x; + } + + template + GLM_FUNC_QUALIFIER vec findMSB(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findMSB' only accept integer values"); + + return detail::compute_findMSB_vec::call(v); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_integer_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/func_integer_simd.inl b/src/other/manifold/glm/glm/detail/func_integer_simd.inl new file mode 100644 index 00000000000..8be6c9ce4dc --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_integer_simd.inl @@ -0,0 +1,65 @@ +#include "../simd/integer.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_bitfieldReverseStep<4, uint, Q, true, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift) + { + __m128i const set0 = v.data; + + __m128i const set1 = _mm_set1_epi32(static_cast(Mask)); + __m128i const and1 = _mm_and_si128(set0, set1); + __m128i const sft1 = _mm_slli_epi32(and1, Shift); + + __m128i const set2 = _mm_andnot_si128(set0, _mm_set1_epi32(-1)); + __m128i const and2 = _mm_and_si128(set0, set2); + __m128i const sft2 = _mm_srai_epi32(and2, Shift); + + __m128i const or0 = _mm_or_si128(sft1, sft2); + + return or0; + } + }; + + template + struct compute_bitfieldBitCountStep<4, uint, Q, true, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift) + { + __m128i const set0 = v.data; + + __m128i const set1 = _mm_set1_epi32(static_cast(Mask)); + __m128i const and0 = _mm_and_si128(set0, set1); + __m128i const sft0 = _mm_slli_epi32(set0, Shift); + __m128i const and1 = _mm_and_si128(sft0, set1); + __m128i const add0 = _mm_add_epi32(and0, and1); + + return add0; + } + }; +}//namespace detail + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template<> + GLM_FUNC_QUALIFIER int bitCount(uint x) + { + return _mm_popcnt_u32(x); + } + +# if(GLM_MODEL == GLM_MODEL_64) + template<> + GLM_FUNC_QUALIFIER int bitCount(detail::uint64 x) + { + return static_cast(_mm_popcnt_u64(x)); + } +# endif//GLM_MODEL +# endif//GLM_ARCH + +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/detail/func_matrix.inl b/src/other/manifold/glm/glm/detail/func_matrix.inl new file mode 100644 index 00000000000..d980c6d3888 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_matrix.inl @@ -0,0 +1,398 @@ +#include "../geometric.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_matrixCompMult + { + GLM_FUNC_QUALIFIER static mat call(mat const& x, mat const& y) + { + mat Result; + for(length_t i = 0; i < Result.length(); ++i) + Result[i] = x[i] * y[i]; + return Result; + } + }; + + template + struct compute_transpose{}; + + template + struct compute_transpose<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m) + { + mat<2, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + return Result; + } + }; + + template + struct compute_transpose<2, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 2, T, Q> call(mat<2, 3, T, Q> const& m) + { + mat<3,2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + return Result; + } + }; + + template + struct compute_transpose<2, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 2, T, Q> call(mat<2, 4, T, Q> const& m) + { + mat<4, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + return Result; + } + }; + + template + struct compute_transpose<3, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 3, T, Q> call(mat<3, 2, T, Q> const& m) + { + mat<2, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + return Result; + } + }; + + template + struct compute_transpose<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) + { + mat<3, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + return Result; + } + }; + + template + struct compute_transpose<3, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 3, T, Q> call(mat<3, 4, T, Q> const& m) + { + mat<4, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + return Result; + } + }; + + template + struct compute_transpose<4, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 4, T, Q> call(mat<4, 2, T, Q> const& m) + { + mat<2, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + return Result; + } + }; + + template + struct compute_transpose<4, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 4, T, Q> call(mat<4, 3, T, Q> const& m) + { + mat<3, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + return Result; + } + }; + + template + struct compute_transpose<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m) + { + mat<4, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + Result[3][3] = m[3][3]; + return Result; + } + }; + + template + struct compute_determinant{}; + + template + struct compute_determinant<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<2, 2, T, Q> const& m) + { + return m[0][0] * m[1][1] - m[1][0] * m[0][1]; + } + }; + + template + struct compute_determinant<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<3, 3, T, Q> const& m) + { + return + + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]); + } + }; + + template + struct compute_determinant<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<4, 4, T, Q> const& m) + { + T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + vec<4, T, Q> DetCof( + + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + return + m[0][0] * DetCof[0] + m[0][1] * DetCof[1] + + m[0][2] * DetCof[2] + m[0][3] * DetCof[3]; + } + }; + + template + struct compute_inverse{}; + + template + struct compute_inverse<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m) + { + T OneOverDeterminant = static_cast(1) / ( + + m[0][0] * m[1][1] + - m[1][0] * m[0][1]); + + mat<2, 2, T, Q> Inverse( + + m[1][1] * OneOverDeterminant, + - m[0][1] * OneOverDeterminant, + - m[1][0] * OneOverDeterminant, + + m[0][0] * OneOverDeterminant); + + return Inverse; + } + }; + + template + struct compute_inverse<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) + { + T OneOverDeterminant = static_cast(1) / ( + + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])); + + mat<3, 3, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDeterminant; + Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDeterminant; + Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDeterminant; + Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDeterminant; + Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDeterminant; + + return Inverse; + } + }; + + template + struct compute_inverse<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m) + { + T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + vec<4, T, Q> Fac0(Coef00, Coef00, Coef02, Coef03); + vec<4, T, Q> Fac1(Coef04, Coef04, Coef06, Coef07); + vec<4, T, Q> Fac2(Coef08, Coef08, Coef10, Coef11); + vec<4, T, Q> Fac3(Coef12, Coef12, Coef14, Coef15); + vec<4, T, Q> Fac4(Coef16, Coef16, Coef18, Coef19); + vec<4, T, Q> Fac5(Coef20, Coef20, Coef22, Coef23); + + vec<4, T, Q> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]); + vec<4, T, Q> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]); + vec<4, T, Q> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]); + vec<4, T, Q> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]); + + vec<4, T, Q> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2); + vec<4, T, Q> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4); + vec<4, T, Q> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5); + vec<4, T, Q> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5); + + vec<4, T, Q> SignA(+1, -1, +1, -1); + vec<4, T, Q> SignB(-1, +1, -1, +1); + mat<4, 4, T, Q> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); + + vec<4, T, Q> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]); + + vec<4, T, Q> Dot0(m[0] * Row0); + T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w); + + T OneOverDeterminant = static_cast(1) / Dot1; + + return Inverse * OneOverDeterminant; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER mat matrixCompMult(mat const& x, mat const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'matrixCompMult' only accept floating-point inputs"); + return detail::compute_matrixCompMult::value>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER typename detail::outerProduct_trait::type outerProduct(vec const& c, vec const& r) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'outerProduct' only accept floating-point inputs"); + + typename detail::outerProduct_trait::type m; + for(length_t i = 0; i < m.length(); ++i) + m[i] = c * r[i]; + return m; + } + + template + GLM_FUNC_QUALIFIER typename mat::transpose_type transpose(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'transpose' only accept floating-point inputs"); + return detail::compute_transpose::value>::call(m); + } + + template + GLM_FUNC_QUALIFIER T determinant(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'determinant' only accept floating-point inputs"); + return detail::compute_determinant::value>::call(m); + } + + template + GLM_FUNC_QUALIFIER mat inverse(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'inverse' only accept floating-point inputs"); + return detail::compute_inverse::value>::call(m); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_matrix_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/func_matrix_simd.inl b/src/other/manifold/glm/glm/detail/func_matrix_simd.inl new file mode 100644 index 00000000000..f67ac66ae22 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_matrix_simd.inl @@ -0,0 +1,249 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#include "type_mat4x4.hpp" +#include "../geometric.hpp" +#include "../simd/matrix.h" +#include + +namespace glm{ +namespace detail +{ +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template + struct compute_matrixCompMult<4, 4, float, Q, true> + { + GLM_STATIC_ASSERT(detail::is_aligned::value, "Specialization requires aligned"); + + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& x, mat<4, 4, float, Q> const& y) + { + mat<4, 4, float, Q> Result; + glm_mat4_matrixCompMult( + *static_cast(&x[0].data), + *static_cast(&y[0].data), + *static_cast(&Result[0].data)); + return Result; + } + }; +# endif + + template + struct compute_transpose<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + mat<4, 4, float, Q> Result; + glm_mat4_transpose(&m[0].data, &Result[0].data); + return Result; + } + }; + + template + struct compute_determinant<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(mat<4, 4, float, Q> const& m) + { + return _mm_cvtss_f32(glm_mat4_determinant(&m[0].data)); + } + }; + + template + struct compute_inverse<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + mat<4, 4, float, Q> Result; + glm_mat4_inverse(&m[0].data, &Result[0].data); + return Result; + } + }; +}//namespace detail + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_lowp> outerProduct<4, 4, float, aligned_lowp>(vec<4, float, aligned_lowp> const& c, vec<4, float, aligned_lowp> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_lowp> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } + + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_mediump> outerProduct<4, 4, float, aligned_mediump>(vec<4, float, aligned_mediump> const& c, vec<4, float, aligned_mediump> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_mediump> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } + + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_highp> outerProduct<4, 4, float, aligned_highp>(vec<4, float, aligned_highp> const& c, vec<4, float, aligned_highp> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_highp> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } +# endif +}//namespace glm + +#elif GLM_ARCH & GLM_ARCH_NEON_BIT + +namespace glm { +#if GLM_LANG & GLM_LANG_CXX11_FLAG + template + GLM_FUNC_QUALIFIER + typename std::enable_if::value, mat<4, 4, float, Q>>::type + operator*(mat<4, 4, float, Q> const & m1, mat<4, 4, float, Q> const & m2) + { + auto MulRow = [&](int l) { + float32x4_t const SrcA = m2[l].data; + + float32x4_t r = neon::mul_lane(m1[0].data, SrcA, 0); + r = neon::madd_lane(r, m1[1].data, SrcA, 1); + r = neon::madd_lane(r, m1[2].data, SrcA, 2); + r = neon::madd_lane(r, m1[3].data, SrcA, 3); + + return r; + }; + + mat<4, 4, float, aligned_highp> Result; + Result[0].data = MulRow(0); + Result[1].data = MulRow(1); + Result[2].data = MulRow(2); + Result[3].data = MulRow(3); + + return Result; + } +#endif // CXX11 + + template + struct detail::compute_inverse<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + float32x4_t const& m0 = m[0].data; + float32x4_t const& m1 = m[1].data; + float32x4_t const& m2 = m[2].data; + float32x4_t const& m3 = m[3].data; + + // m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + float32x4_t Fac0; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac0 = w0 * w1 - w2 * w3; + } + + // m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + float32x4_t Fac1; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac1 = w0 * w1 - w2 * w3; + } + + // m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + float32x4_t Fac2; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + Fac2 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + float32x4_t Fac3; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac3 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + float32x4_t Fac4; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + Fac4 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + float32x4_t Fac5; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + Fac5 = w0 * w1 - w2 * w3; + } + + float32x4_t Vec0 = neon::copy_lane(neon::dupq_lane(m0, 0), 0, m1, 0); // (m[1][0], m[0][0], m[0][0], m[0][0]); + float32x4_t Vec1 = neon::copy_lane(neon::dupq_lane(m0, 1), 0, m1, 1); // (m[1][1], m[0][1], m[0][1], m[0][1]); + float32x4_t Vec2 = neon::copy_lane(neon::dupq_lane(m0, 2), 0, m1, 2); // (m[1][2], m[0][2], m[0][2], m[0][2]); + float32x4_t Vec3 = neon::copy_lane(neon::dupq_lane(m0, 3), 0, m1, 3); // (m[1][3], m[0][3], m[0][3], m[0][3]); + + float32x4_t Inv0 = Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2; + float32x4_t Inv1 = Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4; + float32x4_t Inv2 = Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5; + float32x4_t Inv3 = Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5; + + float32x4_t r0 = float32x4_t{-1, +1, -1, +1} * Inv0; + float32x4_t r1 = float32x4_t{+1, -1, +1, -1} * Inv1; + float32x4_t r2 = float32x4_t{-1, +1, -1, +1} * Inv2; + float32x4_t r3 = float32x4_t{+1, -1, +1, -1} * Inv3; + + float32x4_t det = neon::mul_lane(r0, m0, 0); + det = neon::madd_lane(det, r1, m0, 1); + det = neon::madd_lane(det, r2, m0, 2); + det = neon::madd_lane(det, r3, m0, 3); + + float32x4_t rdet = vdupq_n_f32(1 / vgetq_lane_f32(det, 0)); + + mat<4, 4, float, Q> r; + r[0].data = vmulq_f32(r0, rdet); + r[1].data = vmulq_f32(r1, rdet); + r[2].data = vmulq_f32(r2, rdet); + r[3].data = vmulq_f32(r3, rdet); + return r; + } + }; +}//namespace glm +#endif diff --git a/src/other/manifold/glm/glm/detail/func_packing.inl b/src/other/manifold/glm/glm/detail/func_packing.inl new file mode 100644 index 00000000000..234b093c081 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_packing.inl @@ -0,0 +1,189 @@ +/// @ref core +/// @file glm/detail/func_packing.inl + +#include "../common.hpp" +#include "type_half.hpp" + +namespace glm +{ + GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const& v) + { + union + { + unsigned short in[2]; + uint out; + } u; + + vec<2, unsigned short, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 65535.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint p) + { + union + { + uint in; + unsigned short out[2]; + } u; + + u.in = p; + + return vec2(u.out[0], u.out[1]) * 1.5259021896696421759365224689097e-5f; + } + + GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const& v) + { + union + { + signed short in[2]; + uint out; + } u; + + vec<2, short, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 32767.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint p) + { + union + { + uint in; + signed short out[2]; + } u; + + u.in = p; + + return clamp(vec2(u.out[0], u.out[1]) * 3.0518509475997192297128208258309e-5f, -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint packUnorm4x8(vec4 const& v) + { + union + { + unsigned char in[4]; + uint out; + } u; + + vec<4, unsigned char, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + u.in[2] = result[2]; + u.in[3] = result[3]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x8(uint p) + { + union + { + uint in; + unsigned char out[4]; + } u; + + u.in = p; + + return vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0039215686274509803921568627451f; + } + + GLM_FUNC_QUALIFIER uint packSnorm4x8(vec4 const& v) + { + union + { + signed char in[4]; + uint out; + } u; + + vec<4, signed char, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 127.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + u.in[2] = result[2]; + u.in[3] = result[3]; + + return u.out; + } + + GLM_FUNC_QUALIFIER glm::vec4 unpackSnorm4x8(uint p) + { + union + { + uint in; + signed char out[4]; + } u; + + u.in = p; + + return clamp(vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0078740157480315f, -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER double packDouble2x32(uvec2 const& v) + { + union + { + uint in[2]; + double out; + } u; + + u.in[0] = v[0]; + u.in[1] = v[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER uvec2 unpackDouble2x32(double v) + { + union + { + double in; + uint out[2]; + } u; + + u.in = v; + + return uvec2(u.out[0], u.out[1]); + } + + GLM_FUNC_QUALIFIER uint packHalf2x16(vec2 const& v) + { + union + { + signed short in[2]; + uint out; + } u; + + u.in[0] = detail::toFloat16(v.x); + u.in[1] = detail::toFloat16(v.y); + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint v) + { + union + { + uint in; + signed short out[2]; + } u; + + u.in = v; + + return vec2( + detail::toFloat32(u.out[0]), + detail::toFloat32(u.out[1])); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_packing_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/func_packing_simd.inl b/src/other/manifold/glm/glm/detail/func_packing_simd.inl new file mode 100644 index 00000000000..fd0fe8b7d9b --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_packing_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/func_trigonometric.inl b/src/other/manifold/glm/glm/detail/func_trigonometric.inl new file mode 100644 index 00000000000..e129dceac5c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_trigonometric.inl @@ -0,0 +1,197 @@ +#include "_vectorize.hpp" +#include +#include + +namespace glm +{ + // radians + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType radians(genType degrees) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'radians' only accept floating-point input"); + + return degrees * static_cast(0.01745329251994329576923690768489); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec radians(vec const& v) + { + return detail::functor1::call(radians, v); + } + + // degrees + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType degrees(genType radians) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'degrees' only accept floating-point input"); + + return radians * static_cast(57.295779513082320876798154814105); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec degrees(vec const& v) + { + return detail::functor1::call(degrees, v); + } + + // sin + using ::std::sin; + + template + GLM_FUNC_QUALIFIER vec sin(vec const& v) + { + return detail::functor1::call(sin, v); + } + + // cos + using std::cos; + + template + GLM_FUNC_QUALIFIER vec cos(vec const& v) + { + return detail::functor1::call(cos, v); + } + + // tan + using std::tan; + + template + GLM_FUNC_QUALIFIER vec tan(vec const& v) + { + return detail::functor1::call(tan, v); + } + + // asin + using std::asin; + + template + GLM_FUNC_QUALIFIER vec asin(vec const& v) + { + return detail::functor1::call(asin, v); + } + + // acos + using std::acos; + + template + GLM_FUNC_QUALIFIER vec acos(vec const& v) + { + return detail::functor1::call(acos, v); + } + + // atan + template + GLM_FUNC_QUALIFIER genType atan(genType y, genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'atan' only accept floating-point input"); + + return ::std::atan2(y, x); + } + + template + GLM_FUNC_QUALIFIER vec atan(vec const& a, vec const& b) + { + return detail::functor2::call(::std::atan2, a, b); + } + + using std::atan; + + template + GLM_FUNC_QUALIFIER vec atan(vec const& v) + { + return detail::functor1::call(atan, v); + } + + // sinh + using std::sinh; + + template + GLM_FUNC_QUALIFIER vec sinh(vec const& v) + { + return detail::functor1::call(sinh, v); + } + + // cosh + using std::cosh; + + template + GLM_FUNC_QUALIFIER vec cosh(vec const& v) + { + return detail::functor1::call(cosh, v); + } + + // tanh + using std::tanh; + + template + GLM_FUNC_QUALIFIER vec tanh(vec const& v) + { + return detail::functor1::call(tanh, v); + } + + // asinh +# if GLM_HAS_CXX11_STL + using std::asinh; +# else + template + GLM_FUNC_QUALIFIER genType asinh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asinh' only accept floating-point input"); + + return (x < static_cast(0) ? static_cast(-1) : (x > static_cast(0) ? static_cast(1) : static_cast(0))) * log(std::abs(x) + sqrt(static_cast(1) + x * x)); + } +# endif + + template + GLM_FUNC_QUALIFIER vec asinh(vec const& v) + { + return detail::functor1::call(asinh, v); + } + + // acosh +# if GLM_HAS_CXX11_STL + using std::acosh; +# else + template + GLM_FUNC_QUALIFIER genType acosh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acosh' only accept floating-point input"); + + if(x < static_cast(1)) + return static_cast(0); + return log(x + sqrt(x * x - static_cast(1))); + } +# endif + + template + GLM_FUNC_QUALIFIER vec acosh(vec const& v) + { + return detail::functor1::call(acosh, v); + } + + // atanh +# if GLM_HAS_CXX11_STL + using std::atanh; +# else + template + GLM_FUNC_QUALIFIER genType atanh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'atanh' only accept floating-point input"); + + if(std::abs(x) >= static_cast(1)) + return 0; + return static_cast(0.5) * log((static_cast(1) + x) / (static_cast(1) - x)); + } +# endif + + template + GLM_FUNC_QUALIFIER vec atanh(vec const& v) + { + return detail::functor1::call(atanh, v); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_trigonometric_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/func_trigonometric_simd.inl b/src/other/manifold/glm/glm/detail/func_trigonometric_simd.inl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/other/manifold/glm/glm/detail/func_vector_relational.inl b/src/other/manifold/glm/glm/detail/func_vector_relational.inl new file mode 100644 index 00000000000..80c9e87fcb9 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_vector_relational.inl @@ -0,0 +1,87 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] < y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] <= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] > y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] >= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] == y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] != y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool any(vec const& v) + { + bool Result = false; + for(length_t i = 0; i < L; ++i) + Result = Result || v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool all(vec const& v) + { + bool Result = true; + for(length_t i = 0; i < L; ++i) + Result = Result && v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec not_(vec const& v) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = !v[i]; + return Result; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_vector_relational_simd.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/func_vector_relational_simd.inl b/src/other/manifold/glm/glm/detail/func_vector_relational_simd.inl new file mode 100644 index 00000000000..fd0fe8b7d9b --- /dev/null +++ b/src/other/manifold/glm/glm/detail/func_vector_relational_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/glm.cpp b/src/other/manifold/glm/glm/detail/glm.cpp new file mode 100644 index 00000000000..e0755bd65d4 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/glm.cpp @@ -0,0 +1,263 @@ +/// @ref core +/// @file glm/glm.cpp + +#ifndef GLM_ENABLE_EXPERIMENTAL +#define GLM_ENABLE_EXPERIMENTAL +#endif +#include +#include +#include +#include +#include +#include + +namespace glm +{ +// tvec1 type explicit instantiation +template struct vec<1, uint8, lowp>; +template struct vec<1, uint16, lowp>; +template struct vec<1, uint32, lowp>; +template struct vec<1, uint64, lowp>; +template struct vec<1, int8, lowp>; +template struct vec<1, int16, lowp>; +template struct vec<1, int32, lowp>; +template struct vec<1, int64, lowp>; +template struct vec<1, float32, lowp>; +template struct vec<1, float64, lowp>; + +template struct vec<1, uint8, mediump>; +template struct vec<1, uint16, mediump>; +template struct vec<1, uint32, mediump>; +template struct vec<1, uint64, mediump>; +template struct vec<1, int8, mediump>; +template struct vec<1, int16, mediump>; +template struct vec<1, int32, mediump>; +template struct vec<1, int64, mediump>; +template struct vec<1, float32, mediump>; +template struct vec<1, float64, mediump>; + +template struct vec<1, uint8, highp>; +template struct vec<1, uint16, highp>; +template struct vec<1, uint32, highp>; +template struct vec<1, uint64, highp>; +template struct vec<1, int8, highp>; +template struct vec<1, int16, highp>; +template struct vec<1, int32, highp>; +template struct vec<1, int64, highp>; +template struct vec<1, float32, highp>; +template struct vec<1, float64, highp>; + +// tvec2 type explicit instantiation +template struct vec<2, uint8, lowp>; +template struct vec<2, uint16, lowp>; +template struct vec<2, uint32, lowp>; +template struct vec<2, uint64, lowp>; +template struct vec<2, int8, lowp>; +template struct vec<2, int16, lowp>; +template struct vec<2, int32, lowp>; +template struct vec<2, int64, lowp>; +template struct vec<2, float32, lowp>; +template struct vec<2, float64, lowp>; + +template struct vec<2, uint8, mediump>; +template struct vec<2, uint16, mediump>; +template struct vec<2, uint32, mediump>; +template struct vec<2, uint64, mediump>; +template struct vec<2, int8, mediump>; +template struct vec<2, int16, mediump>; +template struct vec<2, int32, mediump>; +template struct vec<2, int64, mediump>; +template struct vec<2, float32, mediump>; +template struct vec<2, float64, mediump>; + +template struct vec<2, uint8, highp>; +template struct vec<2, uint16, highp>; +template struct vec<2, uint32, highp>; +template struct vec<2, uint64, highp>; +template struct vec<2, int8, highp>; +template struct vec<2, int16, highp>; +template struct vec<2, int32, highp>; +template struct vec<2, int64, highp>; +template struct vec<2, float32, highp>; +template struct vec<2, float64, highp>; + +// tvec3 type explicit instantiation +template struct vec<3, uint8, lowp>; +template struct vec<3, uint16, lowp>; +template struct vec<3, uint32, lowp>; +template struct vec<3, uint64, lowp>; +template struct vec<3, int8, lowp>; +template struct vec<3, int16, lowp>; +template struct vec<3, int32, lowp>; +template struct vec<3, int64, lowp>; +template struct vec<3, float32, lowp>; +template struct vec<3, float64, lowp>; + +template struct vec<3, uint8, mediump>; +template struct vec<3, uint16, mediump>; +template struct vec<3, uint32, mediump>; +template struct vec<3, uint64, mediump>; +template struct vec<3, int8, mediump>; +template struct vec<3, int16, mediump>; +template struct vec<3, int32, mediump>; +template struct vec<3, int64, mediump>; +template struct vec<3, float32, mediump>; +template struct vec<3, float64, mediump>; + +template struct vec<3, uint8, highp>; +template struct vec<3, uint16, highp>; +template struct vec<3, uint32, highp>; +template struct vec<3, uint64, highp>; +template struct vec<3, int8, highp>; +template struct vec<3, int16, highp>; +template struct vec<3, int32, highp>; +template struct vec<3, int64, highp>; +template struct vec<3, float32, highp>; +template struct vec<3, float64, highp>; + +// tvec4 type explicit instantiation +template struct vec<4, uint8, lowp>; +template struct vec<4, uint16, lowp>; +template struct vec<4, uint32, lowp>; +template struct vec<4, uint64, lowp>; +template struct vec<4, int8, lowp>; +template struct vec<4, int16, lowp>; +template struct vec<4, int32, lowp>; +template struct vec<4, int64, lowp>; +template struct vec<4, float32, lowp>; +template struct vec<4, float64, lowp>; + +template struct vec<4, uint8, mediump>; +template struct vec<4, uint16, mediump>; +template struct vec<4, uint32, mediump>; +template struct vec<4, uint64, mediump>; +template struct vec<4, int8, mediump>; +template struct vec<4, int16, mediump>; +template struct vec<4, int32, mediump>; +template struct vec<4, int64, mediump>; +template struct vec<4, float32, mediump>; +template struct vec<4, float64, mediump>; + +template struct vec<4, uint8, highp>; +template struct vec<4, uint16, highp>; +template struct vec<4, uint32, highp>; +template struct vec<4, uint64, highp>; +template struct vec<4, int8, highp>; +template struct vec<4, int16, highp>; +template struct vec<4, int32, highp>; +template struct vec<4, int64, highp>; +template struct vec<4, float32, highp>; +template struct vec<4, float64, highp>; + +// tmat2x2 type explicit instantiation +template struct mat<2, 2, float32, lowp>; +template struct mat<2, 2, float64, lowp>; + +template struct mat<2, 2, float32, mediump>; +template struct mat<2, 2, float64, mediump>; + +template struct mat<2, 2, float32, highp>; +template struct mat<2, 2, float64, highp>; + +// tmat2x3 type explicit instantiation +template struct mat<2, 3, float32, lowp>; +template struct mat<2, 3, float64, lowp>; + +template struct mat<2, 3, float32, mediump>; +template struct mat<2, 3, float64, mediump>; + +template struct mat<2, 3, float32, highp>; +template struct mat<2, 3, float64, highp>; + +// tmat2x4 type explicit instantiation +template struct mat<2, 4, float32, lowp>; +template struct mat<2, 4, float64, lowp>; + +template struct mat<2, 4, float32, mediump>; +template struct mat<2, 4, float64, mediump>; + +template struct mat<2, 4, float32, highp>; +template struct mat<2, 4, float64, highp>; + +// tmat3x2 type explicit instantiation +template struct mat<3, 2, float32, lowp>; +template struct mat<3, 2, float64, lowp>; + +template struct mat<3, 2, float32, mediump>; +template struct mat<3, 2, float64, mediump>; + +template struct mat<3, 2, float32, highp>; +template struct mat<3, 2, float64, highp>; + +// tmat3x3 type explicit instantiation +template struct mat<3, 3, float32, lowp>; +template struct mat<3, 3, float64, lowp>; + +template struct mat<3, 3, float32, mediump>; +template struct mat<3, 3, float64, mediump>; + +template struct mat<3, 3, float32, highp>; +template struct mat<3, 3, float64, highp>; + +// tmat3x4 type explicit instantiation +template struct mat<3, 4, float32, lowp>; +template struct mat<3, 4, float64, lowp>; + +template struct mat<3, 4, float32, mediump>; +template struct mat<3, 4, float64, mediump>; + +template struct mat<3, 4, float32, highp>; +template struct mat<3, 4, float64, highp>; + +// tmat4x2 type explicit instantiation +template struct mat<4, 2, float32, lowp>; +template struct mat<4, 2, float64, lowp>; + +template struct mat<4, 2, float32, mediump>; +template struct mat<4, 2, float64, mediump>; + +template struct mat<4, 2, float32, highp>; +template struct mat<4, 2, float64, highp>; + +// tmat4x3 type explicit instantiation +template struct mat<4, 3, float32, lowp>; +template struct mat<4, 3, float64, lowp>; + +template struct mat<4, 3, float32, mediump>; +template struct mat<4, 3, float64, mediump>; + +template struct mat<4, 3, float32, highp>; +template struct mat<4, 3, float64, highp>; + +// tmat4x4 type explicit instantiation +template struct mat<4, 4, float32, lowp>; +template struct mat<4, 4, float64, lowp>; + +template struct mat<4, 4, float32, mediump>; +template struct mat<4, 4, float64, mediump>; + +template struct mat<4, 4, float32, highp>; +template struct mat<4, 4, float64, highp>; + +// tquat type explicit instantiation +template struct qua; +template struct qua; + +template struct qua; +template struct qua; + +template struct qua; +template struct qua; + +//tdualquat type explicit instantiation +template struct tdualquat; +template struct tdualquat; + +template struct tdualquat; +template struct tdualquat; + +template struct tdualquat; +template struct tdualquat; + +}//namespace glm + diff --git a/src/other/manifold/glm/glm/detail/qualifier.hpp b/src/other/manifold/glm/glm/detail/qualifier.hpp new file mode 100644 index 00000000000..b6c9df0ce04 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/qualifier.hpp @@ -0,0 +1,230 @@ +#pragma once + +#include "setup.hpp" + +namespace glm +{ + /// Qualify GLM types in term of alignment (packed, aligned) and precision in term of ULPs (lowp, mediump, highp) + enum qualifier + { + packed_highp, ///< Typed data is tightly packed in memory and operations are executed with high precision in term of ULPs + packed_mediump, ///< Typed data is tightly packed in memory and operations are executed with medium precision in term of ULPs for higher performance + packed_lowp, ///< Typed data is tightly packed in memory and operations are executed with low precision in term of ULPs to maximize performance + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + aligned_highp, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs + aligned_mediump, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs for higher performance + aligned_lowp, // ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs to maximize performance + aligned = aligned_highp, ///< By default aligned qualifier is also high precision +# endif + + highp = packed_highp, ///< By default highp qualifier is also packed + mediump = packed_mediump, ///< By default mediump qualifier is also packed + lowp = packed_lowp, ///< By default lowp qualifier is also packed + packed = packed_highp, ///< By default packed qualifier is also high precision + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES) + defaultp = aligned_highp +# else + defaultp = highp +# endif + }; + + typedef qualifier precision; + + template struct vec; + template struct mat; + template struct qua; + +# if GLM_HAS_TEMPLATE_ALIASES + template using tvec1 = vec<1, T, Q>; + template using tvec2 = vec<2, T, Q>; + template using tvec3 = vec<3, T, Q>; + template using tvec4 = vec<4, T, Q>; + template using tmat2x2 = mat<2, 2, T, Q>; + template using tmat2x3 = mat<2, 3, T, Q>; + template using tmat2x4 = mat<2, 4, T, Q>; + template using tmat3x2 = mat<3, 2, T, Q>; + template using tmat3x3 = mat<3, 3, T, Q>; + template using tmat3x4 = mat<3, 4, T, Q>; + template using tmat4x2 = mat<4, 2, T, Q>; + template using tmat4x3 = mat<4, 3, T, Q>; + template using tmat4x4 = mat<4, 4, T, Q>; + template using tquat = qua; +# endif + +namespace detail +{ + template + struct is_aligned + { + static const bool value = false; + }; + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + struct is_aligned + { + static const bool value = true; + }; + + template<> + struct is_aligned + { + static const bool value = true; + }; + + template<> + struct is_aligned + { + static const bool value = true; + }; +# endif + + template + struct storage + { + typedef struct type { + T data[L]; + } type; + }; + +# if GLM_HAS_ALIGNOF + template + struct storage + { + typedef struct alignas(L * sizeof(T)) type { + T data[L]; + } type; + }; + + template + struct storage<3, T, true> + { + typedef struct alignas(4 * sizeof(T)) type { + T data[4]; + } type; + }; +# endif + +# if GLM_ARCH & GLM_ARCH_SSE2_BIT + template<> + struct storage<4, float, true> + { + typedef glm_f32vec4 type; + }; + + template<> + struct storage<4, int, true> + { + typedef glm_i32vec4 type; + }; + + template<> + struct storage<4, unsigned int, true> + { + typedef glm_u32vec4 type; + }; + + template<> + struct storage<2, double, true> + { + typedef glm_f64vec2 type; + }; + + template<> + struct storage<2, detail::int64, true> + { + typedef glm_i64vec2 type; + }; + + template<> + struct storage<2, detail::uint64, true> + { + typedef glm_u64vec2 type; + }; +# endif + +# if (GLM_ARCH & GLM_ARCH_AVX_BIT) + template<> + struct storage<4, double, true> + { + typedef glm_f64vec4 type; + }; +# endif + +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) + template<> + struct storage<4, detail::int64, true> + { + typedef glm_i64vec4 type; + }; + + template<> + struct storage<4, detail::uint64, true> + { + typedef glm_u64vec4 type; + }; +# endif + +# if GLM_ARCH & GLM_ARCH_NEON_BIT + template<> + struct storage<4, float, true> + { + typedef glm_f32vec4 type; + }; + + template<> + struct storage<4, int, true> + { + typedef glm_i32vec4 type; + }; + + template<> + struct storage<4, unsigned int, true> + { + typedef glm_u32vec4 type; + }; +# endif + + enum genTypeEnum + { + GENTYPE_VEC, + GENTYPE_MAT, + GENTYPE_QUAT + }; + + template + struct genTypeTrait + {}; + + template + struct genTypeTrait > + { + static const genTypeEnum GENTYPE = GENTYPE_MAT; + }; + + template + struct init_gentype + { + }; + + template + struct init_gentype + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() + { + return genType(1, 0, 0, 0); + } + }; + + template + struct init_gentype + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() + { + return genType(1); + } + }; +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/setup.hpp b/src/other/manifold/glm/glm/detail/setup.hpp new file mode 100644 index 00000000000..2c01e02fb46 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/setup.hpp @@ -0,0 +1,1135 @@ +#ifndef GLM_SETUP_INCLUDED + +#include +#include + +#define GLM_VERSION_MAJOR 0 +#define GLM_VERSION_MINOR 9 +#define GLM_VERSION_PATCH 9 +#define GLM_VERSION_REVISION 8 +#define GLM_VERSION 998 +#define GLM_VERSION_MESSAGE "GLM: version 0.9.9.8" + +#define GLM_SETUP_INCLUDED GLM_VERSION + +/////////////////////////////////////////////////////////////////////////////////// +// Active states + +#define GLM_DISABLE 0 +#define GLM_ENABLE 1 + +/////////////////////////////////////////////////////////////////////////////////// +// Messages + +#if defined(GLM_FORCE_MESSAGES) +# define GLM_MESSAGES GLM_ENABLE +#else +# define GLM_MESSAGES GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Detect the platform + +#include "../simd/platform.h" + +/////////////////////////////////////////////////////////////////////////////////// +// Build model + +#if defined(_M_ARM64) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__) +# define GLM_MODEL GLM_MODEL_64 +#elif defined(__i386__) || defined(__ppc__) || defined(__ILP32__) || defined(_M_ARM) +# define GLM_MODEL GLM_MODEL_32 +#else +# define GLM_MODEL GLM_MODEL_32 +#endif// + +#if !defined(GLM_MODEL) && GLM_COMPILER != 0 +# error "GLM_MODEL undefined, your compiler may not be supported by GLM. Add #define GLM_MODEL 0 to ignore this message." +#endif//GLM_MODEL + +/////////////////////////////////////////////////////////////////////////////////// +// C++ Version + +// User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14, GLM_FORCE_CXX17, GLM_FORCE_CXX2A + +#define GLM_LANG_CXX98_FLAG (1 << 1) +#define GLM_LANG_CXX03_FLAG (1 << 2) +#define GLM_LANG_CXX0X_FLAG (1 << 3) +#define GLM_LANG_CXX11_FLAG (1 << 4) +#define GLM_LANG_CXX14_FLAG (1 << 5) +#define GLM_LANG_CXX17_FLAG (1 << 6) +#define GLM_LANG_CXX2A_FLAG (1 << 7) +#define GLM_LANG_CXXMS_FLAG (1 << 8) +#define GLM_LANG_CXXGNU_FLAG (1 << 9) + +#define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG +#define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG) +#define GLM_LANG_CXX0X (GLM_LANG_CXX03 | GLM_LANG_CXX0X_FLAG) +#define GLM_LANG_CXX11 (GLM_LANG_CXX0X | GLM_LANG_CXX11_FLAG) +#define GLM_LANG_CXX14 (GLM_LANG_CXX11 | GLM_LANG_CXX14_FLAG) +#define GLM_LANG_CXX17 (GLM_LANG_CXX14 | GLM_LANG_CXX17_FLAG) +#define GLM_LANG_CXX2A (GLM_LANG_CXX17 | GLM_LANG_CXX2A_FLAG) +#define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG +#define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG + +#if (defined(_MSC_EXTENSIONS)) +# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG +#elif ((GLM_COMPILER & (GLM_COMPILER_CLANG | GLM_COMPILER_GCC)) && (GLM_ARCH & GLM_ARCH_SIMD_BIT)) +# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG +#else +# define GLM_LANG_EXT 0 +#endif + +#if (defined(GLM_FORCE_CXX_UNKNOWN)) +# define GLM_LANG 0 +#elif defined(GLM_FORCE_CXX2A) +# define GLM_LANG (GLM_LANG_CXX2A | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX17) +# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX14) +# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX11) +# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX03) +# define GLM_LANG (GLM_LANG_CXX03 | GLM_LANG_EXT) +#elif defined(GLM_FORCE_CXX98) +# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_EXT) +#else +# if GLM_COMPILER & GLM_COMPILER_VC && defined(_MSVC_LANG) +# if GLM_COMPILER >= GLM_COMPILER_VC15_7 +# define GLM_LANG_PLATFORM _MSVC_LANG +# elif GLM_COMPILER >= GLM_COMPILER_VC15 +# if _MSVC_LANG > 201402L +# define GLM_LANG_PLATFORM 201402L +# else +# define GLM_LANG_PLATFORM _MSVC_LANG +# endif +# else +# define GLM_LANG_PLATFORM 0 +# endif +# else +# define GLM_LANG_PLATFORM 0 +# endif + +# if __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L +# define GLM_LANG (GLM_LANG_CXX2A | GLM_LANG_EXT) +# elif __cplusplus == 201703L || GLM_LANG_PLATFORM == 201703L +# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT) +# elif __cplusplus == 201402L || __cplusplus == 201500L || GLM_LANG_PLATFORM == 201402L +# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_EXT) +# elif __cplusplus == 201103L || GLM_LANG_PLATFORM == 201103L +# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_EXT) +# elif defined(__INTEL_CXX11_MODE__) || defined(_MSC_VER) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define GLM_LANG (GLM_LANG_CXX0X | GLM_LANG_EXT) +# elif __cplusplus == 199711L +# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_EXT) +# else +# define GLM_LANG (0 | GLM_LANG_EXT) +# endif +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Has of C++ features + +// http://clang.llvm.org/cxx_status.html +// http://gcc.gnu.org/projects/cxx0x.html +// http://msdn.microsoft.com/en-us/library/vstudio/hh567368(v=vs.120).aspx + +// Android has multiple STLs but C++11 STL detection doesn't always work #284 #564 +#if GLM_PLATFORM == GLM_PLATFORM_ANDROID && !defined(GLM_LANG_STL11_FORCED) +# define GLM_HAS_CXX11_STL 0 +#elif GLM_COMPILER & GLM_COMPILER_CLANG +# if (defined(_LIBCPP_VERSION) || (GLM_LANG & GLM_LANG_CXX11_FLAG) || defined(GLM_LANG_STL11_FORCED)) +# define GLM_HAS_CXX11_STL 1 +# else +# define GLM_HAS_CXX11_STL 0 +# endif +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_CXX11_STL 1 +#else +# define GLM_HAS_CXX11_STL ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC48)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_PLATFORM != GLM_PLATFORM_WINDOWS) && (GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL15)))) +#endif + +// N1720 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_STATIC_ASSERT __has_feature(cxx_static_assert) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_STATIC_ASSERT 1 +#else +# define GLM_HAS_STATIC_ASSERT ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC)))) +#endif + +// N1988 +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_EXTENDED_INTEGER_TYPE 1 +#else +# define GLM_HAS_EXTENDED_INTEGER_TYPE (\ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_CLANG))) +#endif + +// N2672 Initializer lists http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_INITIALIZER_LISTS __has_feature(cxx_generalized_initializers) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_INITIALIZER_LISTS 1 +#else +# define GLM_HAS_INITIALIZER_LISTS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)) || \ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL14)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2544 Unrestricted unions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_UNRESTRICTED_UNIONS __has_feature(cxx_unrestricted_unions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_UNRESTRICTED_UNIONS 1 +#else +# define GLM_HAS_UNRESTRICTED_UNIONS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + (GLM_COMPILER & GLM_COMPILER_VC) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA))) +#endif + +// N2346 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_DEFAULTED_FUNCTIONS __has_feature(cxx_defaulted_functions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_DEFAULTED_FUNCTIONS 1 +#else +# define GLM_HAS_DEFAULTED_FUNCTIONS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + (GLM_COMPILER & GLM_COMPILER_CUDA))) +#endif + +// N2118 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_RVALUE_REFERENCES __has_feature(cxx_rvalue_references) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_RVALUE_REFERENCES 1 +#else +# define GLM_HAS_RVALUE_REFERENCES ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2437 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS __has_feature(cxx_explicit_conversions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS 1 +#else +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL14)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2258 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_TEMPLATE_ALIASES __has_feature(cxx_alias_templates) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_TEMPLATE_ALIASES 1 +#else +# define GLM_HAS_TEMPLATE_ALIASES ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2930 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_RANGE_FOR __has_feature(cxx_range_for) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_RANGE_FOR 1 +#else +# define GLM_HAS_RANGE_FOR ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2341 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_ALIGNOF __has_feature(cxx_alignas) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_ALIGNOF 1 +#else +# define GLM_HAS_ALIGNOF ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL15)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC14)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// N2235 Generalized Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf +// N3652 Extended Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html +#if (GLM_ARCH & GLM_ARCH_SIMD_BIT) // Compiler SIMD intrinsics don't support constexpr... +# define GLM_HAS_CONSTEXPR 0 +#elif (GLM_COMPILER & GLM_COMPILER_CLANG) +# define GLM_HAS_CONSTEXPR __has_feature(cxx_relaxed_constexpr) +#elif (GLM_LANG & GLM_LANG_CXX14_FLAG) +# define GLM_HAS_CONSTEXPR 1 +#else +# define GLM_HAS_CONSTEXPR ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && GLM_HAS_INITIALIZER_LISTS && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL17)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)))) +#endif + +#if GLM_HAS_CONSTEXPR +# define GLM_CONSTEXPR constexpr +#else +# define GLM_CONSTEXPR +#endif + +// +#if GLM_HAS_CONSTEXPR +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# if __has_feature(cxx_if_constexpr) +# define GLM_HAS_IF_CONSTEXPR 1 +# else +# define GLM_HAS_IF_CONSTEXPR 0 +# endif +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) +# define GLM_HAS_IF_CONSTEXPR 1 +# else +# define GLM_HAS_IF_CONSTEXPR 0 +# endif +#else +# define GLM_HAS_IF_CONSTEXPR 0 +#endif + +#if GLM_HAS_IF_CONSTEXPR +# define GLM_IF_CONSTEXPR if constexpr +#else +# define GLM_IF_CONSTEXPR if +#endif + +// +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_ASSIGNABLE 1 +#else +# define GLM_HAS_ASSIGNABLE ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)) || \ + ((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC49)))) +#endif + +// +#define GLM_HAS_TRIVIAL_QUERIES 0 + +// +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_MAKE_SIGNED 1 +#else +# define GLM_HAS_MAKE_SIGNED ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)))) +#endif + +// +#if defined(GLM_FORCE_INTRINSICS) +# define GLM_HAS_BITSCAN_WINDOWS ((GLM_PLATFORM & GLM_PLATFORM_WINDOWS) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC14) && (GLM_ARCH & GLM_ARCH_X86_BIT)))) +#else +# define GLM_HAS_BITSCAN_WINDOWS 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// OpenMP +#ifdef _OPENMP +# if GLM_COMPILER & GLM_COMPILER_GCC +# if GLM_COMPILER >= GLM_COMPILER_GCC61 +# define GLM_HAS_OPENMP 45 +# elif GLM_COMPILER >= GLM_COMPILER_GCC49 +# define GLM_HAS_OPENMP 40 +# elif GLM_COMPILER >= GLM_COMPILER_GCC47 +# define GLM_HAS_OPENMP 31 +# else +# define GLM_HAS_OPENMP 0 +# endif +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# if GLM_COMPILER >= GLM_COMPILER_CLANG38 +# define GLM_HAS_OPENMP 31 +# else +# define GLM_HAS_OPENMP 0 +# endif +# elif GLM_COMPILER & GLM_COMPILER_VC +# define GLM_HAS_OPENMP 20 +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# if GLM_COMPILER >= GLM_COMPILER_INTEL16 +# define GLM_HAS_OPENMP 40 +# else +# define GLM_HAS_OPENMP 0 +# endif +# else +# define GLM_HAS_OPENMP 0 +# endif +#else +# define GLM_HAS_OPENMP 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// nullptr + +#if GLM_LANG & GLM_LANG_CXX0X_FLAG +# define GLM_CONFIG_NULLPTR GLM_ENABLE +#else +# define GLM_CONFIG_NULLPTR GLM_DISABLE +#endif + +#if GLM_CONFIG_NULLPTR == GLM_ENABLE +# define GLM_NULLPTR nullptr +#else +# define GLM_NULLPTR 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Static assert + +#if GLM_HAS_STATIC_ASSERT +# define GLM_STATIC_ASSERT(x, message) static_assert(x, message) +#elif GLM_COMPILER & GLM_COMPILER_VC +# define GLM_STATIC_ASSERT(x, message) typedef char __CASSERT__##__LINE__[(x) ? 1 : -1] +#else +# define GLM_STATIC_ASSERT(x, message) assert(x) +#endif//GLM_LANG + +/////////////////////////////////////////////////////////////////////////////////// +// Qualifiers + +#if GLM_COMPILER & GLM_COMPILER_CUDA +# define GLM_CUDA_FUNC_DEF __device__ __host__ +# define GLM_CUDA_FUNC_DECL __device__ __host__ +#else +# define GLM_CUDA_FUNC_DEF +# define GLM_CUDA_FUNC_DECL +#endif + +#if defined(GLM_FORCE_INLINE) +# if GLM_COMPILER & GLM_COMPILER_VC +# define GLM_INLINE __forceinline +# define GLM_NEVER_INLINE __declspec((noinline)) +# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG) +# define GLM_INLINE inline __attribute__((__always_inline__)) +# define GLM_NEVER_INLINE __attribute__((__noinline__)) +# elif GLM_COMPILER & GLM_COMPILER_CUDA +# define GLM_INLINE __forceinline__ +# define GLM_NEVER_INLINE __noinline__ +# else +# define GLM_INLINE inline +# define GLM_NEVER_INLINE +# endif//GLM_COMPILER +#else +# define GLM_INLINE inline +# define GLM_NEVER_INLINE +#endif//defined(GLM_FORCE_INLINE) + +#define GLM_FUNC_DECL GLM_CUDA_FUNC_DECL +#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE + +/////////////////////////////////////////////////////////////////////////////////// +// Swizzle operators + +// User defines: GLM_FORCE_SWIZZLE + +#define GLM_SWIZZLE_DISABLED 0 +#define GLM_SWIZZLE_OPERATOR 1 +#define GLM_SWIZZLE_FUNCTION 2 + +#if defined(GLM_FORCE_XYZW_ONLY) +# undef GLM_FORCE_SWIZZLE +#endif + +#if defined(GLM_SWIZZLE) +# pragma message("GLM: GLM_SWIZZLE is deprecated, use GLM_FORCE_SWIZZLE instead.") +# define GLM_FORCE_SWIZZLE +#endif + +#if defined(GLM_FORCE_SWIZZLE) && (GLM_LANG & GLM_LANG_CXXMS_FLAG) +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_OPERATOR +#elif defined(GLM_FORCE_SWIZZLE) +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_FUNCTION +#else +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_DISABLED +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Allows using not basic types as genType + +// #define GLM_FORCE_UNRESTRICTED_GENTYPE + +#ifdef GLM_FORCE_UNRESTRICTED_GENTYPE +# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_ENABLE +#else +# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Clip control, define GLM_FORCE_DEPTH_ZERO_TO_ONE before including GLM +// to use a clip space between 0 to 1. +// Coordinate system, define GLM_FORCE_LEFT_HANDED before including GLM +// to use left handed coordinate system by default. + +#define GLM_CLIP_CONTROL_ZO_BIT (1 << 0) // ZERO_TO_ONE +#define GLM_CLIP_CONTROL_NO_BIT (1 << 1) // NEGATIVE_ONE_TO_ONE +#define GLM_CLIP_CONTROL_LH_BIT (1 << 2) // LEFT_HANDED, For DirectX, Metal, Vulkan +#define GLM_CLIP_CONTROL_RH_BIT (1 << 3) // RIGHT_HANDED, For OpenGL, default in GLM + +#define GLM_CLIP_CONTROL_LH_ZO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_ZO_BIT) +#define GLM_CLIP_CONTROL_LH_NO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_NO_BIT) +#define GLM_CLIP_CONTROL_RH_ZO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_ZO_BIT) +#define GLM_CLIP_CONTROL_RH_NO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_NO_BIT) + +#ifdef GLM_FORCE_DEPTH_ZERO_TO_ONE +# ifdef GLM_FORCE_LEFT_HANDED +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_ZO +# else +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_ZO +# endif +#else +# ifdef GLM_FORCE_LEFT_HANDED +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_NO +# else +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_NO +# endif +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Qualifiers + +#if (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)) +# define GLM_DEPRECATED __declspec(deprecated) +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef __declspec(align(alignment)) type name +#elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG | GLM_COMPILER_INTEL) +# define GLM_DEPRECATED __attribute__((__deprecated__)) +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __attribute__((aligned(alignment))) +#elif GLM_COMPILER & GLM_COMPILER_CUDA +# define GLM_DEPRECATED +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __align__(x) +#else +# define GLM_DEPRECATED +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +#ifdef GLM_FORCE_EXPLICIT_CTOR +# define GLM_EXPLICIT explicit +#else +# define GLM_EXPLICIT +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// SYCL + +#if GLM_COMPILER==GLM_COMPILER_SYCL + +#include +#include + +namespace glm { +namespace std { + // Import SYCL's functions into the namespace glm::std to force their usages. + // It's important to use the math built-in function (sin, exp, ...) + // of SYCL instead the std ones. + using namespace cl::sycl; + + /////////////////////////////////////////////////////////////////////////////// + // Import some "harmless" std's stuffs used by glm into + // the new glm::std namespace. + template + using numeric_limits = ::std::numeric_limits; + + using ::std::size_t; + + using ::std::uint8_t; + using ::std::uint16_t; + using ::std::uint32_t; + using ::std::uint64_t; + + using ::std::int8_t; + using ::std::int16_t; + using ::std::int32_t; + using ::std::int64_t; + + using ::std::make_unsigned; + /////////////////////////////////////////////////////////////////////////////// +} //namespace std +} //namespace glm + +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////// +// Length type: all length functions returns a length_t type. +// When GLM_FORCE_SIZE_T_LENGTH is defined, length_t is a typedef of size_t otherwise +// length_t is a typedef of int like GLSL defines it. + +#define GLM_LENGTH_INT 1 +#define GLM_LENGTH_SIZE_T 2 + +#ifdef GLM_FORCE_SIZE_T_LENGTH +# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_SIZE_T +#else +# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_INT +#endif + +namespace glm +{ + using std::size_t; +# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T + typedef size_t length_t; +# else + typedef int length_t; +# endif +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// constexpr + +#if GLM_HAS_CONSTEXPR +# define GLM_CONFIG_CONSTEXP GLM_ENABLE + + namespace glm + { + template + constexpr std::size_t countof(T const (&)[N]) + { + return N; + } + }//namespace glm +# define GLM_COUNTOF(arr) glm::countof(arr) +#elif defined(_MSC_VER) +# define GLM_CONFIG_CONSTEXP GLM_DISABLE + +# define GLM_COUNTOF(arr) _countof(arr) +#else +# define GLM_CONFIG_CONSTEXP GLM_DISABLE + +# define GLM_COUNTOF(arr) sizeof(arr) / sizeof(arr[0]) +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// uint + +namespace glm{ +namespace detail +{ + template + struct is_int + { + enum test {value = 0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + typedef unsigned int uint; +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// 64-bit int + +#if GLM_HAS_EXTENDED_INTEGER_TYPE +# include +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::uint64_t uint64; + typedef std::int64_t int64; +# elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) // C99 detected, 64 bit types available + typedef uint64_t uint64; + typedef int64_t int64; +# elif GLM_COMPILER & GLM_COMPILER_VC + typedef unsigned __int64 uint64; + typedef signed __int64 int64; +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic ignored "-Wlong-long" + __extension__ typedef unsigned long long uint64; + __extension__ typedef signed long long int64; +# elif (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic ignored "-Wc++11-long-long" + typedef unsigned long long uint64; + typedef signed long long int64; +# else//unknown compiler + typedef unsigned long long uint64; + typedef signed long long int64; +# endif +}//namespace detail +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// make_unsigned + +#if GLM_HAS_MAKE_SIGNED +# include + +namespace glm{ +namespace detail +{ + using std::make_unsigned; +}//namespace detail +}//namespace glm + +#else + +namespace glm{ +namespace detail +{ + template + struct make_unsigned + {}; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned short type; + }; + + template<> + struct make_unsigned + { + typedef unsigned int type; + }; + + template<> + struct make_unsigned + { + typedef unsigned long type; + }; + + template<> + struct make_unsigned + { + typedef uint64 type; + }; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned short type; + }; + + template<> + struct make_unsigned + { + typedef unsigned int type; + }; + + template<> + struct make_unsigned + { + typedef unsigned long type; + }; + + template<> + struct make_unsigned + { + typedef uint64 type; + }; +}//namespace detail +}//namespace glm +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Only use x, y, z, w as vector type components + +#ifdef GLM_FORCE_XYZW_ONLY +# define GLM_CONFIG_XYZW_ONLY GLM_ENABLE +#else +# define GLM_CONFIG_XYZW_ONLY GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of defaulted initialized types + +#define GLM_CTOR_INIT_DISABLE 0 +#define GLM_CTOR_INITIALIZER_LIST 1 +#define GLM_CTOR_INITIALISATION 2 + +#if defined(GLM_FORCE_CTOR_INIT) && GLM_HAS_INITIALIZER_LISTS +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INITIALIZER_LIST +#elif defined(GLM_FORCE_CTOR_INIT) && !GLM_HAS_INITIALIZER_LISTS +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INITIALISATION +#else +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INIT_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Use SIMD instruction sets + +#if GLM_HAS_ALIGNOF && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (GLM_ARCH & GLM_ARCH_SIMD_BIT) +# define GLM_CONFIG_SIMD GLM_ENABLE +#else +# define GLM_CONFIG_SIMD GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of defaulted function + +#if GLM_HAS_DEFAULTED_FUNCTIONS && GLM_CONFIG_CTOR_INIT == GLM_CTOR_INIT_DISABLE +# define GLM_CONFIG_DEFAULTED_FUNCTIONS GLM_ENABLE +# define GLM_DEFAULT = default +#else +# define GLM_CONFIG_DEFAULTED_FUNCTIONS GLM_DISABLE +# define GLM_DEFAULT +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of aligned gentypes + +#ifdef GLM_FORCE_ALIGNED // Legacy define +# define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +#endif + +#ifdef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +# define GLM_FORCE_ALIGNED_GENTYPES +#endif + +#if GLM_HAS_ALIGNOF && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (defined(GLM_FORCE_ALIGNED_GENTYPES) || (GLM_CONFIG_SIMD == GLM_ENABLE)) +# define GLM_CONFIG_ALIGNED_GENTYPES GLM_ENABLE +#else +# define GLM_CONFIG_ALIGNED_GENTYPES GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of anonymous structure as implementation detail + +#if ((GLM_CONFIG_SIMD == GLM_ENABLE) || (GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR) || (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE)) +# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_ENABLE +#else +# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Silent warnings + +#ifdef GLM_FORCE_SILENT_WARNINGS +# define GLM_SILENT_WARNINGS GLM_ENABLE +#else +# define GLM_SILENT_WARNINGS GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Precision + +#define GLM_HIGHP 1 +#define GLM_MEDIUMP 2 +#define GLM_LOWP 3 + +#if defined(GLM_FORCE_PRECISION_HIGHP_BOOL) || defined(GLM_PRECISION_HIGHP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_BOOL) || defined(GLM_PRECISION_MEDIUMP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_BOOL) || defined(GLM_PRECISION_LOWP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_INT) || defined(GLM_PRECISION_HIGHP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_INT) || defined(GLM_PRECISION_MEDIUMP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_INT) || defined(GLM_PRECISION_LOWP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_INT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_UINT) || defined(GLM_PRECISION_HIGHP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_UINT) || defined(GLM_PRECISION_MEDIUMP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_UINT) || defined(GLM_PRECISION_LOWP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_FLOAT) || defined(GLM_PRECISION_HIGHP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_FLOAT) || defined(GLM_PRECISION_MEDIUMP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_FLOAT) || defined(GLM_PRECISION_LOWP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_DOUBLE) || defined(GLM_PRECISION_HIGHP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_DOUBLE) || defined(GLM_PRECISION_MEDIUMP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_DOUBLE) || defined(GLM_PRECISION_LOWP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Check inclusions of different versions of GLM + +#elif ((GLM_SETUP_INCLUDED != GLM_VERSION) && !defined(GLM_FORCE_IGNORE_VERSION)) +# error "GLM error: A different version of GLM is already included. Define GLM_FORCE_IGNORE_VERSION before including GLM headers to ignore this error." +#elif GLM_SETUP_INCLUDED == GLM_VERSION + +/////////////////////////////////////////////////////////////////////////////////// +// Messages + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_MESSAGE_DISPLAYED) +# define GLM_MESSAGE_DISPLAYED +# define GLM_STR_HELPER(x) #x +# define GLM_STR(x) GLM_STR_HELPER(x) + + // Report GLM version +# pragma message (GLM_STR(GLM_VERSION_MESSAGE)) + + // Report C++ language +# if (GLM_LANG & GLM_LANG_CXX2A_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 2A with extensions") +# elif (GLM_LANG & GLM_LANG_CXX2A_FLAG) +# pragma message("GLM: C++ 2A") +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 17 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) +# pragma message("GLM: C++ 17") +# elif (GLM_LANG & GLM_LANG_CXX14_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 14 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX14_FLAG) +# pragma message("GLM: C++ 14") +# elif (GLM_LANG & GLM_LANG_CXX11_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 11 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX11_FLAG) +# pragma message("GLM: C++ 11") +# elif (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 0x with extensions") +# elif (GLM_LANG & GLM_LANG_CXX0X_FLAG) +# pragma message("GLM: C++ 0x") +# elif (GLM_LANG & GLM_LANG_CXX03_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 03 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX03_FLAG) +# pragma message("GLM: C++ 03") +# elif (GLM_LANG & GLM_LANG_CXX98_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 98 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX98_FLAG) +# pragma message("GLM: C++ 98") +# else +# pragma message("GLM: C++ language undetected") +# endif//GLM_LANG + + // Report compiler detection +# if GLM_COMPILER & GLM_COMPILER_CUDA +# pragma message("GLM: CUDA compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma message("GLM: Visual C++ compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma message("GLM: Clang compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# pragma message("GLM: Intel Compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma message("GLM: GCC compiler detected") +# else +# pragma message("GLM: Compiler not detected") +# endif + + // Report build target +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with AVX2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with AVX2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with AVX instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with AVX instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE4.2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE4.2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE4.1 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE4.1 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSSE3 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSSE3 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE3 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE3 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: ARM 64 bits with Neon instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: ARM 32 bits with Neon instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: ARM 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: ARM 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: MIPS 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: MIPS 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: PowerPC 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: PowerPC 32 bits build target") +# else +# pragma message("GLM: Unknown build target") +# endif//GLM_ARCH + + // Report platform name +# if(GLM_PLATFORM & GLM_PLATFORM_QNXNTO) +# pragma message("GLM: QNX platform detected") +//# elif(GLM_PLATFORM & GLM_PLATFORM_IOS) +//# pragma message("GLM: iOS platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_APPLE) +# pragma message("GLM: Apple platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_WINCE) +# pragma message("GLM: WinCE platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_WINDOWS) +# pragma message("GLM: Windows platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_CHROME_NACL) +# pragma message("GLM: Native Client detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# pragma message("GLM: Android platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_LINUX) +# pragma message("GLM: Linux platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_UNIX) +# pragma message("GLM: UNIX platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_UNKNOWN) +# pragma message("GLM: platform unknown") +# else +# pragma message("GLM: platform not detected") +# endif + + // Report whether only xyzw component are used +# if defined GLM_FORCE_XYZW_ONLY +# pragma message("GLM: GLM_FORCE_XYZW_ONLY is defined. Only x, y, z and w component are available in vector type. This define disables swizzle operators and SIMD instruction sets.") +# endif + + // Report swizzle operator support +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling operators enabled.") +# elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling functions enabled. Enable compiler C++ language extensions to enable swizzle operators.") +# else +# pragma message("GLM: GLM_FORCE_SWIZZLE is undefined. swizzling functions or operators are disabled.") +# endif + + // Report .length() type +# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T +# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is defined. .length() returns a glm::length_t, a typedef of std::size_t.") +# else +# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is undefined. .length() returns a glm::length_t, a typedef of int following GLSL.") +# endif + +# if GLM_CONFIG_UNRESTRICTED_GENTYPE == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is defined. Removes GLSL restrictions on valid function genTypes.") +# else +# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes.") +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is defined. Ignores C++ warnings from using C++ language extensions.") +# else +# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is undefined. Shows C++ warnings from using C++ language extensions.") +# endif + +# ifdef GLM_FORCE_SINGLE_ONLY +# pragma message("GLM: GLM_FORCE_SINGLE_ONLY is defined. Using only single precision floating-point types.") +# endif + +# if defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE) +# undef GLM_FORCE_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined, allowing aligned types. This prevents the use of C++ constexpr.") +# elif defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE) +# undef GLM_FORCE_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.") +# endif + +# if defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES) +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE +# undef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.") +# elif GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined. All gentypes (e.g. vec3) will be aligned and padded by default.") +# endif +# endif + +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT +# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is defined. Using zero to one depth clip space.") +# else +# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space.") +# endif + +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT +# pragma message("GLM: GLM_FORCE_LEFT_HANDED is defined. Using left handed coordinate system.") +# else +# pragma message("GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system.") +# endif +#endif//GLM_MESSAGES + +#endif//GLM_SETUP_INCLUDED diff --git a/src/other/manifold/glm/glm/detail/type_float.hpp b/src/other/manifold/glm/glm/detail/type_float.hpp new file mode 100644 index 00000000000..c8037ebd7aa --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_float.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "setup.hpp" + +#if GLM_COMPILER == GLM_COMPILER_VC12 +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace glm{ +namespace detail +{ + template + union float_t + {}; + + // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + template <> + union float_t + { + typedef int int_type; + typedef float float_type; + + GLM_CONSTEXPR float_t(float_type Num = 0.0f) : f(Num) {} + + GLM_CONSTEXPR float_t& operator=(float_t const& x) + { + f = x.f; + return *this; + } + + // Portable extraction of components. + GLM_CONSTEXPR bool negative() const { return i < 0; } + GLM_CONSTEXPR int_type mantissa() const { return i & ((1 << 23) - 1); } + GLM_CONSTEXPR int_type exponent() const { return (i >> 23) & ((1 << 8) - 1); } + + int_type i; + float_type f; + }; + + template <> + union float_t + { + typedef detail::int64 int_type; + typedef double float_type; + + GLM_CONSTEXPR float_t(float_type Num = static_cast(0)) : f(Num) {} + + GLM_CONSTEXPR float_t& operator=(float_t const& x) + { + f = x.f; + return *this; + } + + // Portable extraction of components. + GLM_CONSTEXPR bool negative() const { return i < 0; } + GLM_CONSTEXPR int_type mantissa() const { return i & ((int_type(1) << 52) - 1); } + GLM_CONSTEXPR int_type exponent() const { return (i >> 52) & ((int_type(1) << 11) - 1); } + + int_type i; + float_type f; + }; +}//namespace detail +}//namespace glm + +#if GLM_COMPILER == GLM_COMPILER_VC12 +# pragma warning(pop) +#endif diff --git a/src/other/manifold/glm/glm/detail/type_half.hpp b/src/other/manifold/glm/glm/detail/type_half.hpp new file mode 100644 index 00000000000..40b8bec00d3 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_half.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "setup.hpp" + +namespace glm{ +namespace detail +{ + typedef short hdata; + + GLM_FUNC_DECL float toFloat32(hdata value); + GLM_FUNC_DECL hdata toFloat16(float const& value); + +}//namespace detail +}//namespace glm + +#include "type_half.inl" diff --git a/src/other/manifold/glm/glm/detail/type_half.inl b/src/other/manifold/glm/glm/detail/type_half.inl new file mode 100644 index 00000000000..b0723e362d5 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_half.inl @@ -0,0 +1,241 @@ +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER float overflow() + { + volatile float f = 1e10; + + for(int i = 0; i < 10; ++i) + f *= f; // this will overflow before the for loop terminates + return f; + } + + union uif32 + { + GLM_FUNC_QUALIFIER uif32() : + i(0) + {} + + GLM_FUNC_QUALIFIER uif32(float f_) : + f(f_) + {} + + GLM_FUNC_QUALIFIER uif32(unsigned int i_) : + i(i_) + {} + + float f; + unsigned int i; + }; + + GLM_FUNC_QUALIFIER float toFloat32(hdata value) + { + int s = (value >> 15) & 0x00000001; + int e = (value >> 10) & 0x0000001f; + int m = value & 0x000003ff; + + if(e == 0) + { + if(m == 0) + { + // + // Plus or minus zero + // + + detail::uif32 result; + result.i = static_cast(s << 31); + return result.f; + } + else + { + // + // Denormalized number -- renormalize it + // + + while(!(m & 0x00000400)) + { + m <<= 1; + e -= 1; + } + + e += 1; + m &= ~0x00000400; + } + } + else if(e == 31) + { + if(m == 0) + { + // + // Positive or negative infinity + // + + uif32 result; + result.i = static_cast((s << 31) | 0x7f800000); + return result.f; + } + else + { + // + // Nan -- preserve sign and significand bits + // + + uif32 result; + result.i = static_cast((s << 31) | 0x7f800000 | (m << 13)); + return result.f; + } + } + + // + // Normalized number + // + + e = e + (127 - 15); + m = m << 13; + + // + // Assemble s, e and m. + // + + uif32 Result; + Result.i = static_cast((s << 31) | (e << 23) | m); + return Result.f; + } + + GLM_FUNC_QUALIFIER hdata toFloat16(float const& f) + { + uif32 Entry; + Entry.f = f; + int i = static_cast(Entry.i); + + // + // Our floating point number, f, is represented by the bit + // pattern in integer i. Disassemble that bit pattern into + // the sign, s, the exponent, e, and the significand, m. + // Shift s into the position where it will go in the + // resulting half number. + // Adjust e, accounting for the different exponent bias + // of float and half (127 versus 15). + // + + int s = (i >> 16) & 0x00008000; + int e = ((i >> 23) & 0x000000ff) - (127 - 15); + int m = i & 0x007fffff; + + // + // Now reassemble s, e and m into a half: + // + + if(e <= 0) + { + if(e < -10) + { + // + // E is less than -10. The absolute value of f is + // less than half_MIN (f may be a small normalized + // float, a denormalized float or a zero). + // + // We convert f to a half zero. + // + + return hdata(s); + } + + // + // E is between -10 and 0. F is a normalized float, + // whose magnitude is less than __half_NRM_MIN. + // + // We convert f to a denormalized half. + // + + m = (m | 0x00800000) >> (1 - e); + + // + // Round to nearest, round "0.5" up. + // + // Rounding may cause the significand to overflow and make + // our number normalized. Because of the way a half's bits + // are laid out, we don't have to treat this case separately; + // the code below will handle it correctly. + // + + if(m & 0x00001000) + m += 0x00002000; + + // + // Assemble the half from s, e (zero) and m. + // + + return hdata(s | (m >> 13)); + } + else if(e == 0xff - (127 - 15)) + { + if(m == 0) + { + // + // F is an infinity; convert f to a half + // infinity with the same sign as f. + // + + return hdata(s | 0x7c00); + } + else + { + // + // F is a NAN; we produce a half NAN that preserves + // the sign bit and the 10 leftmost bits of the + // significand of f, with one exception: If the 10 + // leftmost bits are all zero, the NAN would turn + // into an infinity, so we have to set at least one + // bit in the significand. + // + + m >>= 13; + + return hdata(s | 0x7c00 | m | (m == 0)); + } + } + else + { + // + // E is greater than zero. F is a normalized float. + // We try to convert f to a normalized half. + // + + // + // Round to nearest, round "0.5" up + // + + if(m & 0x00001000) + { + m += 0x00002000; + + if(m & 0x00800000) + { + m = 0; // overflow in significand, + e += 1; // adjust exponent + } + } + + // + // Handle exponent overflow + // + + if (e > 30) + { + overflow(); // Cause a hardware floating point overflow; + + return hdata(s | 0x7c00); + // if this returns, the half becomes an + } // infinity with the same sign as f. + + // + // Assemble the half from s, e and m. + // + + return hdata(s | (e << 10) | (m >> 13)); + } + } + +}//namespace detail +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat2x2.hpp b/src/other/manifold/glm/glm/detail/type_mat2x2.hpp new file mode 100644 index 00000000000..033908f4495 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x2.hpp @@ -0,0 +1,177 @@ +/// @ref core +/// @file glm/detail/type_mat2x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 2, T, Q> type; + typedef mat<2, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x1, T const& y1, + T const& x2, T const& y2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + U const& x1, V const& y1, + M const& x2, N const& y2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, U, Q> const& v1, + vec<2, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator+=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator*=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator/=(mat<2, 2, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::col_type operator*(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::row_type operator*(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); +} //namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x2.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat2x2.inl b/src/other/manifold/glm/glm/detail/type_mat2x2.inl new file mode 100644 index 00000000000..fe5d1aa3133 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x2.inl @@ -0,0 +1,536 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m[0], m[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(T scalar) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(scalar, 0), col_type(0, scalar)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(scalar, 0); + this->value[1] = col_type(0, scalar); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat + ( + T const& x0, T const& y0, + T const& x1, T const& y1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{v0, v1} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; +# endif + } + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat + ( + X1 const& x1, Y1 const& y1, + X2 const& x2, Y2 const& y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(static_cast(x1), value_type(y1)), col_type(static_cast(x2), value_type(y2)) } +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(static_cast(x1), value_type(y1)); + this->value[1] = col_type(static_cast(x2), value_type(y2)); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- mat2x2 matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type const& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator=(mat<2, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(U scalar) + { + this->value[0] += scalar; + this->value[1] += scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(mat<2, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(U scalar) + { + this->value[0] -= scalar; + this->value[1] -= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(mat<2, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(U scalar) + { + this->value[0] *= scalar; + this->value[1] *= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(mat<2, 2, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(U scalar) + { + this->value[0] /= scalar; + this->value[1] /= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(mat<2, 2, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> mat<2, 2, T, Q>::operator++(int) + { + mat<2, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> mat<2, 2, T, Q>::operator--(int) + { + mat<2, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + scalar - m[0], + scalar - m[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type operator* + ( + mat<2, 2, T, Q> const& m, + typename mat<2, 2, T, Q>::row_type const& v + ) + { + return vec<2, T, Q>( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::row_type operator* + ( + typename mat<2, 2, T, Q>::col_type const& v, + mat<2, 2, T, Q> const& m + ) + { + return vec<2, T, Q>( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + mat<2, 2, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat2x3.hpp b/src/other/manifold/glm/glm/detail/type_mat2x3.hpp new file mode 100644 index 00000000000..d6596e469b8 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x3.hpp @@ -0,0 +1,159 @@ +/// @ref core +/// @file glm/detail/type_mat2x3.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 3, T, Q> type; + typedef mat<3, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, + T x1, T y1, T z1); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1); + + // -- Conversions -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, U, Q> const& v1, + vec<3, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator+=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 3, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 3, T, Q>::col_type operator*(mat<2, 3, T, Q> const& m, typename mat<2, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 3, T, Q>::row_type operator*(typename mat<2, 3, T, Q>::col_type const& v, mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x3.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat2x3.inl b/src/other/manifold/glm/glm/detail/type_mat2x3.inl new file mode 100644 index 00000000000..5fec17e5dbb --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x3.inl @@ -0,0 +1,510 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m.value[0], m.value[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m.value[0]; + this->value[1] = m.value[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(T scalar) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(scalar, 0, 0), col_type(0, scalar, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(scalar, 0, 0); + this->value[1] = col_type(0, scalar, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat + ( + T x0, T y0, T z0, + T x1, T y1, T z1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1), col_type(x2, y2, z2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1); + this->value[1] = col_type(x2, y2, z2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::col_type & mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type const& mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator=(mat<2, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator+=(mat<2, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(mat<2, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> mat<2, 3, T, Q>::operator++(int) + { + mat<2, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> mat<2, 3, T, Q>::operator--(int) + { + mat<2, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::col_type operator* + ( + mat<2, 3, T, Q> const& m, + typename mat<2, 3, T, Q>::row_type const& v) + { + return typename mat<2, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y, + m[0][2] * v.x + m[1][2] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::row_type operator* + ( + typename mat<2, 3, T, Q>::col_type const& v, + mat<2, 3, T, Q> const& m) + { + return typename mat<2, 3, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + T SrcA00 = m1[0][0]; + T SrcA01 = m1[0][1]; + T SrcA02 = m1[0][2]; + T SrcA10 = m1[1][0]; + T SrcA11 = m1[1][1]; + T SrcA12 = m1[1][2]; + + T SrcB00 = m2[0][0]; + T SrcB01 = m2[0][1]; + T SrcB10 = m2[1][0]; + T SrcB11 = m2[1][1]; + T SrcB20 = m2[2][0]; + T SrcB21 = m2[2][1]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat2x4.hpp b/src/other/manifold/glm/glm/detail/type_mat2x4.hpp new file mode 100644 index 00000000000..ff03e215e5e --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x4.hpp @@ -0,0 +1,161 @@ +/// @ref core +/// @file glm/detail/type_mat2x4.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 4, T, Q> type; + typedef mat<4, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, U, Q> const& v1, + vec<4, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator+=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 4, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x4.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat2x4.inl b/src/other/manifold/glm/glm/detail/type_mat2x4.inl new file mode 100644 index 00000000000..b6d2b9ddfd1 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat2x4.inl @@ -0,0 +1,520 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m[0], m[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat + ( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0, w0), col_type(x1, y1, z1, w1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1, w1); + this->value[1] = col_type(x2, y2, z2, w2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::col_type & mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type const& mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator=(mat<2, 4, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(mat<2, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(mat<2, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> & mat<2, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat<2, 4, T, Q>::operator++(int) + { + mat<2, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat<2, 4, T, Q>::operator--(int) + { + mat<2, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v) + { + return typename mat<2, 4, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y, + m[0][2] * v.x + m[1][2] * v.y, + m[0][3] * v.x + m[1][3] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m) + { + return typename mat<2, 4, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + T SrcA00 = m1[0][0]; + T SrcA01 = m1[0][1]; + T SrcA02 = m1[0][2]; + T SrcA03 = m1[0][3]; + T SrcA10 = m1[1][0]; + T SrcA11 = m1[1][1]; + T SrcA12 = m1[1][2]; + T SrcA13 = m1[1][3]; + + T SrcB00 = m2[0][0]; + T SrcB01 = m2[0][1]; + T SrcB10 = m2[1][0]; + T SrcB11 = m2[1][1]; + T SrcB20 = m2[2][0]; + T SrcB21 = m2[2][1]; + T SrcB30 = m2[3][0]; + T SrcB31 = m2[3][1]; + + mat<4, 4, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01; + Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11; + Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21; + Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21; + Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31; + Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31; + Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31; + Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat3x2.hpp b/src/other/manifold/glm/glm/detail/type_mat3x2.hpp new file mode 100644 index 00000000000..e16658131fd --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x2.hpp @@ -0,0 +1,167 @@ +/// @ref core +/// @file glm/detail/type_mat3x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 2, T, Q> type; + typedef mat<2, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, + T x1, T y1, + T x2, T y2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, V1, Q> const& v1, + vec<2, V2, Q> const& v2, + vec<2, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator+=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<3, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x2.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat3x2.inl b/src/other/manifold/glm/glm/detail/type_mat3x2.inl new file mode 100644 index 00000000000..b4b948b7261 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x2.inl @@ -0,0 +1,532 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1), col_type(0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); + this->value[2] = col_type(0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0), col_type(0, s), col_type(0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0); + this->value[1] = col_type(0, s); + this->value[2] = col_type(0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat + ( + T x0, T y0, + T x1, T y1, + T x2, T y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat + ( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(vec<2, V0, Q> const& v0, vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::col_type & mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type const& mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator=(mat<3, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(mat<3, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(mat<3, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> & mat<3, 2, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> mat<3, 2, T, Q>::operator++(int) + { + mat<3, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> mat<3, 2, T, Q>::operator--(int) + { + mat<3, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v) + { + return typename mat<3, 2, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m) + { + return typename mat<3, 2, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1], + v.x * m[2][0] + v.y * m[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + const T SrcA00 = m1[0][0]; + const T SrcA01 = m1[0][1]; + const T SrcA10 = m1[1][0]; + const T SrcA11 = m1[1][1]; + const T SrcA20 = m1[2][0]; + const T SrcA21 = m1[2][1]; + + const T SrcB00 = m2[0][0]; + const T SrcB01 = m2[0][1]; + const T SrcB02 = m2[0][2]; + const T SrcB10 = m2[1][0]; + const T SrcB11 = m2[1][1]; + const T SrcB12 = m2[1][2]; + + mat<2, 2, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat3x3.hpp b/src/other/manifold/glm/glm/detail/type_mat3x3.hpp new file mode 100644 index 00000000000..3174872eb7c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x3.hpp @@ -0,0 +1,184 @@ +/// @ref core +/// @file glm/detail/type_mat3x3.hpp + +#pragma once + +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 3, T, Q> type; + typedef mat<3, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, + T x1, T y1, T z1, + T x2, T y2, T z2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2, + X3 x3, Y3 y3, Z3 z3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, V1, Q> const& v1, + vec<3, V2, Q> const& v2, + vec<3, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator+=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator-=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator*=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator/=(mat<3, 3, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 3, T, Q> & operator++(); + GLM_FUNC_DECL mat<3, 3, T, Q> & operator--(); + GLM_FUNC_DECL mat<3, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x3.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat3x3.inl b/src/other/manifold/glm/glm/detail/type_mat3x3.inl new file mode 100644 index 00000000000..1ddaf99d581 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x3.inl @@ -0,0 +1,601 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0), col_type(0, 0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); + this->value[2] = col_type(0, 0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0), col_type(0, s, 0), col_type(0, 0, s)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0); + this->value[1] = col_type(0, s, 0); + this->value[2] = col_type(0, 0, s); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat + ( + T x0, T y0, T z0, + T x1, T y1, T z1, + T x2, T y2, T z2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2, + X3 x3, Y3 y3, Z3 z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1); + this->value[1] = col_type(x2, y2, z2); + this->value[2] = col_type(x3, y3, z3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2, vec<3, V3, Q> const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type & mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type const& mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator=(mat<3, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(mat<3, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(mat<3, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(mat<3, 3, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(mat<3, 3, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat<3, 3, T, Q>::operator++(int) + { + mat<3, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat<3, 3, T, Q>::operator--(int) + { + mat<3, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + scalar - m[0], + scalar - m[1], + scalar - m[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v) + { + return typename mat<3, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m) + { + return typename mat<3, 3, T, Q>::row_type( + m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, + m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z, + m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA02 = m1[0][2]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA12 = m1[1][2]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA22 = m1[2][2]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB20 = m2[2][0]; + T const SrcB21 = m2[2][1]; + T const SrcB22 = m2[2][2]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + mat<3, 3, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat3x4.hpp b/src/other/manifold/glm/glm/detail/type_mat3x4.hpp new file mode 100644 index 00000000000..6e40b90305e --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x4.hpp @@ -0,0 +1,166 @@ +/// @ref core +/// @file glm/detail/type_mat3x4.hpp + +#pragma once + +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 4, T, Q> type; + typedef mat<4, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1, + T x2, T y2, T z2, T w2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2, + X3 x3, Y3 y3, Z3 z3, W3 w3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, V1, Q> const& v1, + vec<4, V2, Q> const& v2, + vec<4, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator+=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator-=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 4, T, Q> & operator++(); + GLM_FUNC_DECL mat<3, 4, T, Q> & operator--(); + GLM_FUNC_DECL mat<3, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 4, T, Q>::col_type operator*(mat<3, 4, T, Q> const& m, typename mat<3, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 4, T, Q>::row_type operator*(typename mat<3, 4, T, Q>::col_type const& v, mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x4.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat3x4.inl b/src/other/manifold/glm/glm/detail/type_mat3x4.inl new file mode 100644 index 00000000000..6ee416cfd65 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat3x4.inl @@ -0,0 +1,578 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); + this->value[2] = col_type(0, 0, s, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat + ( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1, + T x2, T y2, T z2, T w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, typename Z0, typename W0, + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat + ( + X0 x0, Y0 y0, Z0 z0, W0 w0, + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(vec<4, V1, Q> const& v0, vec<4, V2, Q> const& v1, vec<4, V3, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::col_type & mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type const& mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator=(mat<3, 4, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(mat<3, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(mat<3, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> & mat<3, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat<3, 4, T, Q>::operator++(int) + { + mat<3, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat<3, 4, T, Q>::operator--(int) + { + mat<3, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::col_type operator* + ( + mat<3, 4, T, Q> const& m, + typename mat<3, 4, T, Q>::row_type const& v + ) + { + return typename mat<3, 4, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z, + m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::row_type operator* + ( + typename mat<3, 4, T, Q>::col_type const& v, + mat<3, 4, T, Q> const& m + ) + { + return typename mat<3, 4, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3], + v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + const T SrcA00 = m1[0][0]; + const T SrcA01 = m1[0][1]; + const T SrcA02 = m1[0][2]; + const T SrcA03 = m1[0][3]; + const T SrcA10 = m1[1][0]; + const T SrcA11 = m1[1][1]; + const T SrcA12 = m1[1][2]; + const T SrcA13 = m1[1][3]; + const T SrcA20 = m1[2][0]; + const T SrcA21 = m1[2][1]; + const T SrcA22 = m1[2][2]; + const T SrcA23 = m1[2][3]; + + const T SrcB00 = m2[0][0]; + const T SrcB01 = m2[0][1]; + const T SrcB02 = m2[0][2]; + const T SrcB10 = m2[1][0]; + const T SrcB11 = m2[1][1]; + const T SrcB12 = m2[1][2]; + const T SrcB20 = m2[2][0]; + const T SrcB21 = m2[2][1]; + const T SrcB22 = m2[2][2]; + const T SrcB30 = m2[3][0]; + const T SrcB31 = m2[3][1]; + const T SrcB32 = m2[3][2]; + + mat<4, 4, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02; + Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12; + Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22; + Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22; + Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32; + Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32; + Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32; + Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat4x2.hpp b/src/other/manifold/glm/glm/detail/type_mat4x2.hpp new file mode 100644 index 00000000000..8d343527111 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x2.hpp @@ -0,0 +1,171 @@ +/// @ref core +/// @file glm/detail/type_mat4x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 2, T, Q> type; + typedef mat<2, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, + T x1, T y1, + T x2, T y2, + T x3, T y3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, V1, Q> const& v1, + vec<2, V2, Q> const& v2, + vec<2, V3, Q> const& v3, + vec<2, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator+=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<4, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 2, T, Q>::col_type operator*(mat<4, 2, T, Q> const& m, typename mat<4, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 2, T, Q>::row_type operator*(typename mat<4, 2, T, Q>::col_type const& v, mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x2.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat4x2.inl b/src/other/manifold/glm/glm/detail/type_mat4x2.inl new file mode 100644 index 00000000000..419c80c42cf --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x2.inl @@ -0,0 +1,574 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1), col_type(0, 0), col_type(0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); + this->value[2] = col_type(0, 0); + this->value[3] = col_type(0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0), col_type(0, s), col_type(0, 0), col_type(0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0); + this->value[1] = col_type(0, s); + this->value[2] = col_type(0, 0); + this->value[3] = col_type(0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat + ( + T x0, T y0, + T x1, T y1, + T x2, T y2, + T x3, T y3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2), col_type(x3, y3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); + this->value[3] = col_type(x3, y3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat + ( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2), col_type(x3, y3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); + this->value[3] = col_type(x3, y3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(vec<2, V0, Q> const& v0, vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2, vec<2, V3, Q> const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); + this->value[3] = col_type(v3); +# endif + } + + // -- Conversion -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::col_type & mat<4, 2, T, Q>::operator[](typename mat<4, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 2, T, Q>::col_type const& mat<4, 2, T, Q>::operator[](typename mat<4, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q>& mat<4, 2, T, Q>::operator=(mat<4, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator+=(mat<4, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator-=(mat<4, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> mat<4, 2, T, Q>::operator++(int) + { + mat<4, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> mat<4, 2, T, Q>::operator--(int) + { + mat<4, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar, + m[3] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar, + m[3] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::col_type operator*(mat<4, 2, T, Q> const& m, typename mat<4, 2, T, Q>::row_type const& v) + { + return typename mat<4, 2, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::row_type operator*(typename mat<4, 2, T, Q>::col_type const& v, mat<4, 2, T, Q> const& m) + { + return typename mat<4, 2, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1], + v.x * m[2][0] + v.y * m[2][1], + v.x * m[3][0] + v.y * m[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA30 = m1[3][0]; + T const SrcA31 = m1[3][1]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB03 = m2[0][3]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB13 = m2[1][3]; + + mat<2, 2, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2] + m1[3][0] * m2[3][3], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2] + m1[3][1] * m2[3][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar, + m[3] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2], + scalar / m[3]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat4x3.hpp b/src/other/manifold/glm/glm/detail/type_mat4x3.hpp new file mode 100644 index 00000000000..16e42705185 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x3.hpp @@ -0,0 +1,171 @@ +/// @ref core +/// @file glm/detail/type_mat4x3.hpp + +#pragma once + +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 3, T, Q> type; + typedef mat<3, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T const& x); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x0, T const& y0, T const& z0, + T const& x1, T const& y1, T const& z1, + T const& x2, T const& y2, T const& z2, + T const& x3, T const& y3, T const& z3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3, + typename X4, typename Y4, typename Z4> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 const& x1, Y1 const& y1, Z1 const& z1, + X2 const& x2, Y2 const& y2, Z2 const& z2, + X3 const& x3, Y3 const& y3, Z3 const& z3, + X4 const& x4, Y4 const& y4, Z4 const& z4); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, V1, Q> const& v1, + vec<3, V2, Q> const& v2, + vec<3, V3, Q> const& v3, + vec<3, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator+=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator-=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 3, T, Q>& operator++(); + GLM_FUNC_DECL mat<4, 3, T, Q>& operator--(); + GLM_FUNC_DECL mat<4, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(T const& s, mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 3, T, Q>::col_type operator*(mat<4, 3, T, Q> const& m, typename mat<4, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 3, T, Q>::row_type operator*(typename mat<4, 3, T, Q>::col_type const& v, mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator/(T const& s, mat<4, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x3.inl" +#endif //GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_mat4x3.inl b/src/other/manifold/glm/glm/detail/type_mat4x3.inl new file mode 100644 index 00000000000..11b1ee35d8a --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x3.inl @@ -0,0 +1,598 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0), col_type(0, 0, 1), col_type(0, 0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0, 0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(T const& s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0), col_type(0, s, 0), col_type(0, 0, s), col_type(0, 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0); + this->value[1] = col_type(0, s, 0); + this->value[2] = col_type(0, 0, s); + this->value[3] = col_type(0, 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat + ( + T const& x0, T const& y0, T const& z0, + T const& x1, T const& y1, T const& z1, + T const& x2, T const& y2, T const& z2, + T const& x3, T const& y3, T const& z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); + this->value[3] = col_type(x3, y3, z3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, typename Z0, + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat + ( + X0 const& x0, Y0 const& y0, Z0 const& z0, + X1 const& x1, Y1 const& y1, Z1 const& z1, + X2 const& x2, Y2 const& y2, Z2 const& z2, + X3 const& x3, Y3 const& y3, Z3 const& z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); + this->value[3] = col_type(x3, y3, z3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2, vec<3, V3, Q> const& v3, vec<3, V4, Q> const& v4) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3), col_type(v4)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); + this->value[3] = col_type(v4); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1), col_type(m[3], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); + this->value[3] = col_type(m[3], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::col_type & mat<4, 3, T, Q>::operator[](typename mat<4, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 3, T, Q>::col_type const& mat<4, 3, T, Q>::operator[](typename mat<4, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q>& mat<4, 3, T, Q>::operator=(mat<4, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator+=(mat<4, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator-=(mat<4, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> mat<4, 3, T, Q>::operator++(int) + { + mat<4, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> mat<4, 3, T, Q>::operator--(int) + { + mat<4, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] - s, + m[1] - s, + m[2] - s, + m[3] - s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(T const& s, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::col_type operator* + ( + mat<4, 3, T, Q> const& m, + typename mat<4, 3, T, Q>::row_type const& v) + { + return typename mat<4, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::row_type operator* + ( + typename mat<4, 3, T, Q>::col_type const& v, + mat<4, 3, T, Q> const& m) + { + return typename mat<4, 3, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2], + v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2], + v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA02 = m1[0][2]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA12 = m1[1][2]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA22 = m1[2][2]; + T const SrcA30 = m1[3][0]; + T const SrcA31 = m1[3][1]; + T const SrcA32 = m1[3][2]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB03 = m2[0][3]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB13 = m2[1][3]; + T const SrcB20 = m2[2][0]; + T const SrcB21 = m2[2][1]; + T const SrcB22 = m2[2][2]; + T const SrcB23 = m2[2][3]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2] + m1[3][0] * m2[3][3], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2] + m1[3][1] * m2[3][3], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2] + m1[3][2] * m2[3][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] / s, + m[1] / s, + m[2] / s, + m[3] / s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator/(T const& s, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + s / m[0], + s / m[1], + s / m[2], + s / m[3]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_mat4x4.hpp b/src/other/manifold/glm/glm/detail/type_mat4x4.hpp new file mode 100644 index 00000000000..3517f9f527d --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x4.hpp @@ -0,0 +1,189 @@ +/// @ref core +/// @file glm/detail/type_mat4x4.hpp + +#pragma once + +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 4, T, Q> type; + typedef mat<4, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T const& x); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x0, T const& y0, T const& z0, T const& w0, + T const& x1, T const& y1, T const& z1, T const& w1, + T const& x2, T const& y2, T const& z2, T const& w2, + T const& x3, T const& y3, T const& z3, T const& w3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3, + typename X4, typename Y4, typename Z4, typename W4> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 const& x1, Y1 const& y1, Z1 const& z1, W1 const& w1, + X2 const& x2, Y2 const& y2, Z2 const& z2, W2 const& w2, + X3 const& x3, Y3 const& y3, Z3 const& z3, W3 const& w3, + X4 const& x4, Y4 const& y4, Z4 const& z4, W4 const& w4); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, V1, Q> const& v1, + vec<4, V2, Q> const& v2, + vec<4, V3, Q> const& v3, + vec<4, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator+=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator-=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator*=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator/=(mat<4, 4, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 4, T, Q> & operator++(); + GLM_FUNC_DECL mat<4, 4, T, Q> & operator--(); + GLM_FUNC_DECL mat<4, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::col_type operator*(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::row_type operator*(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::col_type operator/(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::row_type operator/(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x4.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_mat4x4.inl b/src/other/manifold/glm/glm/detail/type_mat4x4.inl new file mode 100644 index 00000000000..e38b87f77e7 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x4.inl @@ -0,0 +1,706 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(T const& s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0), col_type(0, 0, 0, s)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); + this->value[2] = col_type(0, 0, s, 0); + this->value[3] = col_type(0, 0, 0, s); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat + ( + T const& x0, T const& y0, T const& z0, T const& w0, + T const& x1, T const& y1, T const& z1, T const& w1, + T const& x2, T const& y2, T const& z2, T const& w2, + T const& x3, T const& y3, T const& z3, T const& w3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2), + col_type(x3, y3, z3, w3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); + this->value[3] = col_type(x3, y3, z3, w3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + // -- Conversions -- + + template + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3, + typename X4, typename Y4, typename Z4, typename W4> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat + ( + X1 const& x1, Y1 const& y1, Z1 const& z1, W1 const& w1, + X2 const& x2, Y2 const& y2, Z2 const& z2, W2 const& w2, + X3 const& x3, Y3 const& y3, Z3 const& z3, W3 const& w3, + X4 const& x4, Y4 const& y4, Z4 const& z4, W4 const& w4 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1, w1), col_type(x2, y2, z2, w2), col_type(x3, y3, z3, w3), col_type(x4, y4, z4, w4)} +# endif + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 5th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 6th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 7th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 8th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 9th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 10th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 11th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 12th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 13th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 14th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 15th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 16th parameter type invalid."); + +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1, w1); + this->value[1] = col_type(x2, y2, z2, w2); + this->value[2] = col_type(x3, y3, z3, w3); + this->value[3] = col_type(x4, y4, z4, w4); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2, vec<4, V3, Q> const& v3, vec<4, V4, Q> const& v4) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3), col_type(v4)} +# endif + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); + +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); + this->value[3] = col_type(v4); +# endif + } + + // -- Matrix conversions -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(m[3], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); + this->value[3] = col_type(m[3], 1); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type & mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type const& mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary arithmetic operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator=(mat<4, 4, U, Q> const& m) + { + //memcpy could be faster + //memcpy(&this->value, &m.value, 16 * sizeof(valType)); + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(mat<4, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(mat<4, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(mat<4, 4, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(mat<4, 4, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat<4, 4, T, Q>::operator++(int) + { + mat<4, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat<4, 4, T, Q>::operator--(int) + { + mat<4, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] - s, + m[1] - s, + m[2] - s, + m[3] - s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + s - m[0], + s - m[1], + s - m[2], + s - m[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T const & s) + { + return mat<4, 4, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type operator* + ( + mat<4, 4, T, Q> const& m, + typename mat<4, 4, T, Q>::row_type const& v + ) + { +/* + __m128 v0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 v1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 v2 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 v3 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(m[0].data, v0); + __m128 m1 = _mm_mul_ps(m[1].data, v1); + __m128 a0 = _mm_add_ps(m0, m1); + + __m128 m2 = _mm_mul_ps(m[2].data, v2); + __m128 m3 = _mm_mul_ps(m[3].data, v3); + __m128 a1 = _mm_add_ps(m2, m3); + + __m128 a2 = _mm_add_ps(a0, a1); + + return typename mat<4, 4, T, Q>::col_type(a2); +*/ + + typename mat<4, 4, T, Q>::col_type const Mov0(v[0]); + typename mat<4, 4, T, Q>::col_type const Mov1(v[1]); + typename mat<4, 4, T, Q>::col_type const Mul0 = m[0] * Mov0; + typename mat<4, 4, T, Q>::col_type const Mul1 = m[1] * Mov1; + typename mat<4, 4, T, Q>::col_type const Add0 = Mul0 + Mul1; + typename mat<4, 4, T, Q>::col_type const Mov2(v[2]); + typename mat<4, 4, T, Q>::col_type const Mov3(v[3]); + typename mat<4, 4, T, Q>::col_type const Mul2 = m[2] * Mov2; + typename mat<4, 4, T, Q>::col_type const Mul3 = m[3] * Mov3; + typename mat<4, 4, T, Q>::col_type const Add1 = Mul2 + Mul3; + typename mat<4, 4, T, Q>::col_type const Add2 = Add0 + Add1; + return Add2; + +/* + return typename mat<4, 4, T, Q>::col_type( + m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3], + m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3], + m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3], + m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3]); +*/ + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::row_type operator* + ( + typename mat<4, 4, T, Q>::col_type const& v, + mat<4, 4, T, Q> const& m + ) + { + return typename mat<4, 4, T, Q>::row_type( + m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3], + m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3], + m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3], + m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0]; + typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1]; + typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2]; + typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3]; + + typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0]; + typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1]; + typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2]; + typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3]; + + mat<4, 4, T, Q> Result; + Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3]; + Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3]; + Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3]; + Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] / s, + m[1] / s, + m[2] / s, + m[3] / s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + s / m[0], + s / m[1], + s / m[2], + s / m[3]); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type operator/(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::row_type operator/(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + mat<4, 4, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_mat4x4_simd.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_mat4x4_simd.inl b/src/other/manifold/glm/glm/detail/type_mat4x4_simd.inl new file mode 100644 index 00000000000..fb3a16f0629 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_mat4x4_simd.inl @@ -0,0 +1,6 @@ +/// @ref core + +namespace glm +{ + +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_quat.hpp b/src/other/manifold/glm/glm/detail/type_quat.hpp new file mode 100644 index 00000000000..0e60bc33c48 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_quat.hpp @@ -0,0 +1,186 @@ +/// @ref core +/// @file glm/detail/type_quat.hpp + +#pragma once + +// Dependency: +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat4x4.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" +#include "../ext/vector_relational.hpp" +#include "../ext/quaternion_relational.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/matrix_transform.hpp" + +namespace glm +{ + template + struct qua + { + // -- Implementation detail -- + + typedef qua type; + typedef T value_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_LANG & GLM_LANG_CXXMS_FLAG + union + { +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + struct { T w, x, y, z; }; +# else + struct { T x, y, z, w; }; +# endif + + typename detail::storage<4, T, detail::is_aligned::value>::type data; + }; +# else +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + T w, x, y, z; +# else + T x, y, z, w; +# endif +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + typedef length_t length_type; + + /// Return the count of components of a quaternion + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR qua(qua const& q) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR qua(qua const& q); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua(T s, vec<3, T, Q> const& v); + GLM_FUNC_DECL GLM_CONSTEXPR qua(T w, T x, T y, T z); + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(qua const& q); + + /// Explicit conversion operators +# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + GLM_FUNC_DECL explicit operator mat<3, 3, T, Q>() const; + GLM_FUNC_DECL explicit operator mat<4, 4, T, Q>() const; +# endif + + /// Create a quaternion from two normalized axis + /// + /// @param u A first normalized axis + /// @param v A second normalized axis + /// @see gtc_quaternion + /// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors + GLM_FUNC_DECL qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v); + + /// Build a quaternion from euler angles (pitch, yaw, roll), in radians. + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles); + GLM_FUNC_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q); + GLM_FUNC_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q); + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator=(qua const& q) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator+=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator-=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator*=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator*=(U s); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator/=(U s); + }; + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator+(qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator-(qua const& q); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator+(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator-(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(qua const& q, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(qua const& q, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(qua const& q, T const& s); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(T const& s, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator/(qua const& q, T const& s); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(qua const& q1, qua const& q2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(qua const& q1, qua const& q2); +} //namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_quat.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_quat.inl b/src/other/manifold/glm/glm/detail/type_quat.inl new file mode 100644 index 00000000000..67b9310ac2c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_quat.inl @@ -0,0 +1,408 @@ +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include "../ext/quaternion_geometric.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct genTypeTrait > + { + static const genTypeEnum GENTYPE = GENTYPE_QUAT; + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(qua const& a, qua const& b) + { + vec<4, T, Q> tmp(a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z); + return (tmp.x + tmp.y) + (tmp.z + tmp.w); + } + }; + + template + struct compute_quat_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, qua const& p) + { + return qua(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z); + } + }; + + template + struct compute_quat_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, qua const& p) + { + return qua(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z); + } + }; + + template + struct compute_quat_mul_scalar + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, T s) + { + return qua(q.w * s, q.x * s, q.y * s, q.z * s); + } + }; + + template + struct compute_quat_div_scalar + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, T s) + { + return qua(q.w / s, q.x / s, q.y / s, q.z / s); + } + }; + + template + struct compute_quat_mul_vec4 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(qua const& q, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w); + } + }; +}//namespace detail + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua::operator[](typename qua::length_type i) + { + assert(i >= 0 && i < this->length()); +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + return (&w)[i]; +# else + return (&x)[i]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua::operator[](typename qua::length_type i) const + { + assert(i >= 0 && i < this->length()); +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + return (&w)[i]; +# else + return (&x)[i]; +# endif + } + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(1), x(0), y(0), z(0) +# else + : x(0), y(0), z(0), w(1) +# endif +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(q.w), x(q.x), y(q.y), z(q.z) +# else + : x(q.x), y(q.y), z(q.z), w(q.w) +# endif + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(q.w), x(q.x), y(q.y), z(q.z) +# else + : x(q.x), y(q.y), z(q.z), w(q.w) +# endif + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T s, vec<3, T, Q> const& v) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(s), x(v.x), y(v.y), z(v.z) +# else + : x(v.x), y(v.y), z(v.z), w(s) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T _w, T _x, T _y, T _z) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(_w), x(_x), y(_y), z(_z) +# else + : x(_x), y(_y), z(_z), w(_w) +# endif + {} + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(static_cast(q.w)), x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)) +# else + : x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)), w(static_cast(q.w)) +# endif + {} + + //template + //GLM_FUNC_QUALIFIER qua::qua + //( + // valType const& pitch, + // valType const& yaw, + // valType const& roll + //) + //{ + // vec<3, valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5)); + // vec<3, valType> c = glm::cos(eulerAngle * valType(0.5)); + // vec<3, valType> s = glm::sin(eulerAngle * valType(0.5)); + // + // this->w = c.x * c.y * c.z + s.x * s.y * s.z; + // this->x = s.x * c.y * c.z - c.x * s.y * s.z; + // this->y = c.x * s.y * c.z + s.x * c.y * s.z; + // this->z = c.x * c.y * s.z - s.x * s.y * c.z; + //} + + template + GLM_FUNC_QUALIFIER qua::qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v) + { + T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v)); + T real_part = norm_u_norm_v + dot(u, v); + vec<3, T, Q> t; + + if(real_part < static_cast(1.e-6f) * norm_u_norm_v) + { + // If u and v are exactly opposite, rotate 180 degrees + // around an arbitrary orthogonal axis. Axis normalisation + // can happen later, when we normalise the quaternion. + real_part = static_cast(0); + t = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast(0)) : vec<3, T, Q>(static_cast(0), -u.z, u.y); + } + else + { + // Otherwise, build quaternion the standard way. + t = cross(u, v); + } + + *this = normalize(qua(real_part, t.x, t.y, t.z)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(vec<3, T, Q> const& eulerAngle) + { + vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5)); + vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5)); + + this->w = c.x * c.y * c.z + s.x * s.y * s.z; + this->x = s.x * c.y * c.z - c.x * s.y * s.z; + this->y = c.x * s.y * c.z + s.x * c.y * s.z; + this->z = c.x * c.y * s.z - s.x * s.y * c.z; + } + + template + GLM_FUNC_QUALIFIER qua::qua(mat<3, 3, T, Q> const& m) + { + *this = quat_cast(m); + } + + template + GLM_FUNC_QUALIFIER qua::qua(mat<4, 4, T, Q> const& m) + { + *this = quat_cast(m); + } + +# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + template + GLM_FUNC_QUALIFIER qua::operator mat<3, 3, T, Q>() const + { + return mat3_cast(*this); + } + + template + GLM_FUNC_QUALIFIER qua::operator mat<4, 4, T, Q>() const + { + return mat4_cast(*this); + } +# endif//GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator=(qua const& q) + { + this->w = q.w; + this->x = q.x; + this->y = q.y; + this->z = q.z; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator=(qua const& q) + { + this->w = static_cast(q.w); + this->x = static_cast(q.x); + this->y = static_cast(q.y); + this->z = static_cast(q.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator+=(qua const& q) + { + return (*this = detail::compute_quat_add::value>::call(*this, qua(q))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator-=(qua const& q) + { + return (*this = detail::compute_quat_sub::value>::call(*this, qua(q))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator*=(qua const& r) + { + qua const p(*this); + qua const q(r); + + this->w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z; + this->x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y; + this->y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z; + this->z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator*=(U s) + { + return (*this = detail::compute_quat_mul_scalar::value>::call(*this, static_cast(s))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator/=(U s) + { + return (*this = detail::compute_quat_div_scalar::value>::call(*this, static_cast(s))); + } + + // -- Unary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator+(qua const& q) + { + return q; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator-(qua const& q) + { + return qua(-q.w, -q.x, -q.y, -q.z); + } + + // -- Binary operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator+(qua const& q, qua const& p) + { + return qua(q) += p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator-(qua const& q, qua const& p) + { + return qua(q) -= p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(qua const& q, qua const& p) + { + return qua(q) *= p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(qua const& q, vec<3, T, Q> const& v) + { + vec<3, T, Q> const QuatVector(q.x, q.y, q.z); + vec<3, T, Q> const uv(glm::cross(QuatVector, v)); + vec<3, T, Q> const uuv(glm::cross(QuatVector, uv)); + + return v + ((uv * q.w) + uuv) * static_cast(2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(qua const& q, vec<4, T, Q> const& v) + { + return detail::compute_quat_mul_vec4::value>::call(q, v); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(qua const& q, T const& s) + { + return qua( + q.w * s, q.x * s, q.y * s, q.z * s); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(T const& s, qua const& q) + { + return q * s; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator/(qua const& q, T const& s) + { + return qua( + q.w / s, q.x / s, q.y / s, q.z / s); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(qua const& q1, qua const& q2) + { + return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(qua const& q1, qua const& q2) + { + return q1.x != q2.x || q1.y != q2.y || q1.z != q2.z || q1.w != q2.w; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_quat_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/detail/type_quat_simd.inl b/src/other/manifold/glm/glm/detail/type_quat_simd.inl new file mode 100644 index 00000000000..3333e59f1c7 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_quat_simd.inl @@ -0,0 +1,188 @@ +/// @ref core + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ +/* + template + struct compute_quat_mul + { + static qua call(qua const& q1, qua const& q2) + { + // SSE2 STATS: 11 shuffle, 8 mul, 8 add + // SSE4 STATS: 3 shuffle, 4 mul, 4 dpps + + __m128 const mul0 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(0, 1, 2, 3))); + __m128 const mul1 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(1, 0, 3, 2))); + __m128 const mul2 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(2, 3, 0, 1))); + __m128 const mul3 = _mm_mul_ps(q1.Data, q2.Data); + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + __m128 const add0 = _mm_dp_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f), 0xff); + __m128 const add1 = _mm_dp_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f), 0xff); + __m128 const add2 = _mm_dp_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f), 0xff); + __m128 const add3 = _mm_dp_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f), 0xff); +# else + __m128 const mul4 = _mm_mul_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f)); + __m128 const add0 = _mm_add_ps(mul0, _mm_movehl_ps(mul4, mul4)); + __m128 const add4 = _mm_add_ss(add0, _mm_shuffle_ps(add0, add0, 1)); + + __m128 const mul5 = _mm_mul_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f)); + __m128 const add1 = _mm_add_ps(mul1, _mm_movehl_ps(mul5, mul5)); + __m128 const add5 = _mm_add_ss(add1, _mm_shuffle_ps(add1, add1, 1)); + + __m128 const mul6 = _mm_mul_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f)); + __m128 const add2 = _mm_add_ps(mul6, _mm_movehl_ps(mul6, mul6)); + __m128 const add6 = _mm_add_ss(add2, _mm_shuffle_ps(add2, add2, 1)); + + __m128 const mul7 = _mm_mul_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f)); + __m128 const add3 = _mm_add_ps(mul3, _mm_movehl_ps(mul7, mul7)); + __m128 const add7 = _mm_add_ss(add3, _mm_shuffle_ps(add3, add3, 1)); + #endif + + // This SIMD code is a politically correct way of doing this, but in every test I've tried it has been slower than + // the final code below. I'll keep this here for reference - maybe somebody else can do something better... + // + //__m128 xxyy = _mm_shuffle_ps(add4, add5, _MM_SHUFFLE(0, 0, 0, 0)); + //__m128 zzww = _mm_shuffle_ps(add6, add7, _MM_SHUFFLE(0, 0, 0, 0)); + // + //return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0)); + + qua Result; + _mm_store_ss(&Result.x, add4); + _mm_store_ss(&Result.y, add5); + _mm_store_ss(&Result.z, add6); + _mm_store_ss(&Result.w, add7); + return Result; + } + }; +*/ + + template + struct compute_quat_add + { + static qua call(qua const& q, qua const& p) + { + qua Result; + Result.data = _mm_add_ps(q.data, p.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_add + { + static qua call(qua const& a, qua const& b) + { + qua Result; + Result.data = _mm256_add_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_quat_sub + { + static qua call(qua const& q, qua const& p) + { + vec<4, float, Q> Result; + Result.data = _mm_sub_ps(q.data, p.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_sub + { + static qua call(qua const& a, qua const& b) + { + qua Result; + Result.data = _mm256_sub_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_quat_mul_scalar + { + static qua call(qua const& q, float s) + { + vec<4, float, Q> Result; + Result.data = _mm_mul_ps(q.data, _mm_set_ps1(s)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_mul_scalar + { + static qua call(qua const& q, double s) + { + qua Result; + Result.data = _mm256_mul_pd(q.data, _mm_set_ps1(s)); + return Result; + } + }; +# endif + + template + struct compute_quat_div_scalar + { + static qua call(qua const& q, float s) + { + vec<4, float, Q> Result; + Result.data = _mm_div_ps(q.data, _mm_set_ps1(s)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_div_scalar + { + static qua call(qua const& q, double s) + { + qua Result; + Result.data = _mm256_div_pd(q.data, _mm_set_ps1(s)); + return Result; + } + }; +# endif + + template + struct compute_quat_mul_vec4 + { + static vec<4, float, Q> call(qua const& q, vec<4, float, Q> const& v) + { + __m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3)); + __m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 1, 0, 2)); + __m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2)); + + __m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0)); + __m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2)); + __m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0)); + + __m128 const two = _mm_set1_ps(2.0f); + uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two)); + uuv = _mm_mul_ps(uuv, two); + + vec<4, float, Q> Result; + Result.data = _mm_add_ps(v.Data, _mm_add_ps(uv, uuv)); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/other/manifold/glm/glm/detail/type_vec1.hpp b/src/other/manifold/glm/glm/detail/type_vec1.hpp new file mode 100644 index 00000000000..51163f14bc8 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec1.hpp @@ -0,0 +1,308 @@ +/// @ref core +/// @file glm/detail/type_vec1.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<1, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<1, T, Q> type; + typedef vec<1, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x; +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + T x; + T r; + T s; + + typename detail::storage<1, T, detail::is_aligned::value>::type data; +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + _GLM_SWIZZLE1_2_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_2_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_2_MEMBERS(T, Q, s) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, s) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, s) +# endif +*/ + }; +# else + union {T x, r, s;}; +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC1(T, Q) +# endif +*/ +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 1;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<2, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<1, U, P> const& v); + + // -- Swizzle constructors -- +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<1, T, Q, E0, -1,-2,-3> const& that) + { + *this = that(); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +*/ + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(vec<1, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator>>=(vec<1, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator~(vec<1, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, bool, Q> operator&&(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, bool, Q> operator||(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec1.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_vec1.inl b/src/other/manifold/glm/glm/detail/type_vec1.inl new file mode 100644 index 00000000000..c5883cebc96 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec1.inl @@ -0,0 +1,551 @@ +/// @ref core + +#include "./compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, T, Q> const& v) + : x(v.x) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, T, P> const& v) + : x(v.x) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(T scalar) + : x(scalar) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<2, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type) + { + return x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type) const + { + return x; + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator=(vec<1, T, Q> const& v) + { + this->x = v.x; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator=(vec<1, U, Q> const& v) + { + this->x = static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator/=(U scalar) + { + this->x /= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator++() + { + ++this->x; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator--() + { + --this->x; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> vec<1, T, Q>::operator++(int) + { + vec<1, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> vec<1, T, Q>::operator--(int) + { + vec<1, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator%=(U scalar) + { + this->x %= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator&=(U scalar) + { + this->x &= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator|=(U scalar) + { + this->x |= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= U(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator^=(U scalar) + { + this->x ^= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator<<=(U scalar) + { + this->x <<= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + return *this; + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + -v.x); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar + v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x + v2.x); + } + + //operator- + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar - v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x - v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar * v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x * v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar / v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x / v2.x); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar % v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x % v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar & v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x & v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar | v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x | v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar ^ v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x ^ v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + static_cast(v.x << scalar)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + static_cast(scalar << v.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + static_cast(v1.x << v2.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + static_cast(v.x >> scalar)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + static_cast(scalar >> v.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + static_cast(v1.x >> v2.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator~(vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + ~v.x); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return detail::compute_equal::is_iec559>::call(v1.x, v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, bool, Q> operator&&(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2) + { + return vec<1, bool, Q>(v1.x && v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, bool, Q> operator||(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2) + { + return vec<1, bool, Q>(v1.x || v2.x); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_vec2.hpp b/src/other/manifold/glm/glm/detail/type_vec2.hpp new file mode 100644 index 00000000000..52ef408e5d2 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec2.hpp @@ -0,0 +1,399 @@ +/// @ref core +/// @file glm/detail/type_vec2.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<2, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<2, T, Q> type; + typedef vec<2, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y; +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct{ T x, y; }; + struct{ T r, g; }; + struct{ T s, t; }; + + typename detail::storage<2, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE2_2_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_2_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_2_MEMBERS(T, Q, s, t) + GLM_SWIZZLE2_3_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_3_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_3_MEMBERS(T, Q, s, t) + GLM_SWIZZLE2_4_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_4_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_4_MEMBERS(T, Q, s, t) +# endif + }; +# else + union {T x, r, s;}; + union {T y, g, t;}; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, Q) +# endif//GLM_CONFIG_SWIZZLE +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;} + + GLM_FUNC_DECL GLM_CONSTEXPR T& operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T x, T y); + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A x, B y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, Q> const& x, B y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A x, vec<1, B, Q> const& y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, Q> const& x, vec<1, B, Q> const& y); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<2, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1,-1,-2> const& that) + { + *this = that(); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<2, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(vec<2, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator~(vec<2, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, bool, Q> operator&&(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, bool, Q> operator||(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec2.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_vec2.inl b/src/other/manifold/glm/glm/detail/type_vec2.inl new file mode 100644 index 00000000000..8e65d6bb9e2 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec2.inl @@ -0,0 +1,913 @@ +/// @ref core + +#include "./compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, T, Q> const& v) + : x(v.x), y(v.y) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, T, P> const& v) + : x(v.x), y(v.y) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(T scalar) + : x(scalar), y(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(T _x, T _y) + : x(_x), y(_y) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(A _x, B _y) + : x(static_cast(_x)) + , y(static_cast(_y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, A, Q> const& _x, B _y) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(A _x, vec<1, B, Q> const& _y) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, A, Q> const& _x, vec<1, B, Q> const& _y) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator=(vec<2, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator=(vec<2, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + this->y += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(vec<2, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + this->y -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(vec<2, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + this->y *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(vec<2, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(U scalar) + { + this->x /= static_cast(scalar); + this->y /= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(vec<2, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.y); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator++() + { + ++this->x; + ++this->y; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator--() + { + --this->x; + --this->y; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> vec<2, T, Q>::operator++(int) + { + vec<2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> vec<2, T, Q>::operator--(int) + { + vec<2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(U scalar) + { + this->x %= static_cast(scalar); + this->y %= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= static_cast(v.x); + this->y %= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(vec<2, U, Q> const& v) + { + this->x %= static_cast(v.x); + this->y %= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(U scalar) + { + this->x &= static_cast(scalar); + this->y &= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= static_cast(v.x); + this->y &= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(vec<2, U, Q> const& v) + { + this->x &= static_cast(v.x); + this->y &= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(U scalar) + { + this->x |= static_cast(scalar); + this->y |= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= static_cast(v.x); + this->y |= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(vec<2, U, Q> const& v) + { + this->x |= static_cast(v.x); + this->y |= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(U scalar) + { + this->x ^= static_cast(scalar); + this->y ^= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= static_cast(v.x); + this->y ^= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(vec<2, U, Q> const& v) + { + this->x ^= static_cast(v.x); + this->y ^= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(U scalar) + { + this->x <<= static_cast(scalar); + this->y <<= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(vec<2, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + this->y >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(vec<2, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.y); + return *this; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + -v.x, + -v.y); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x + scalar, + v.y + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.y + v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar + v.x, + scalar + v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.x + v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.y + v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x - scalar, + v.y - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.y - v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar - v.x, + scalar - v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.x - v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.y - v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x * scalar, + v.y * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.y * v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar * v.x, + scalar * v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.x * v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.y * v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x / scalar, + v.y / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.y / v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar / v.x, + scalar / v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.x / v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.y / v2.y); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x % scalar, + v.y % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.y % v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar % v.x, + scalar % v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.x % v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.y % v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x & scalar, + v.y & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.y & v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar & v.x, + scalar & v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.x & v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.y & v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x | scalar, + v.y | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.y | v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar | v.x, + scalar | v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.x | v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.y | v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x ^ scalar, + v.y ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar ^ v.x, + scalar ^ v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.x ^ v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x << scalar, + v.y << scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.y << v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar << v.x, + scalar << v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.x << v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.y << v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x >> scalar, + v.y >> scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.y >> v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar >> v.x, + scalar >> v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.x >> v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.y >> v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator~(vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + ~v.x, + ~v.y); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, bool, Q> operator&&(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2) + { + return vec<2, bool, Q>(v1.x && v2.x, v1.y && v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, bool, Q> operator||(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2) + { + return vec<2, bool, Q>(v1.x || v2.x, v1.y || v2.y); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_vec3.hpp b/src/other/manifold/glm/glm/detail/type_vec3.hpp new file mode 100644 index 00000000000..d83cde678f8 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec3.hpp @@ -0,0 +1,432 @@ +/// @ref core +/// @file glm/detail/type_vec3.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<3, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<3, T, Q> type; + typedef vec<3, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# pragma warning(disable: 4324) // structure was padded due to alignment specifier +# endif +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y, z; +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct{ T x, y, z; }; + struct{ T r, g, b; }; + struct{ T s, t, p; }; + + typename detail::storage<3, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE3_2_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_2_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_2_MEMBERS(T, Q, s, t, p) + GLM_SWIZZLE3_3_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_3_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_3_MEMBERS(T, Q, s, t, p) + GLM_SWIZZLE3_4_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_4_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_4_MEMBERS(T, Q, s, t, p) +# endif + }; +# else + union { T x, r, s; }; + union { T y, g, t; }; + union { T z, b, p; }; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, Q) +# endif//GLM_CONFIG_SWIZZLE +# endif//GLM_LANG + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 3;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T a, T b, T c); + + // -- Conversion scalar constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X x, Y y, Z z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& scalar) + { + *this = vec(v(), scalar); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& scalar, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v) + { + *this = vec(scalar, v()); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q>& operator=(vec<3, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<3, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<3, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator~(vec<3, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec3.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_vec3.inl b/src/other/manifold/glm/glm/detail/type_vec3.inl new file mode 100644 index 00000000000..6532c9e6e06 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec3.inl @@ -0,0 +1,1068 @@ +/// @ref core + +#include "compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0), z(0) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, T, Q> const& v) + : x(v.x), y(v.y), z(v.z) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, T, P> const& v) + : x(v.x), y(v.y), z(v.z) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(T scalar) + : x(scalar), y(scalar), z(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(T _x, T _y, T _z) + : x(_x), y(_y), z(_z) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + , z(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, Y _y, Z _z) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<2, A, P> const& _xy, B _z) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(A _x, vec<2, B, P> const& _yz) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>& vec<3, T, Q>::operator=(vec<3, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + this->z = v.z; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>& vec<3, T, Q>::operator=(vec<3, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + this->y += static_cast(scalar); + this->z += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.x); + this->z += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<3, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.y); + this->z += static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + this->y -= static_cast(scalar); + this->z -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.x); + this->z -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<3, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.y); + this->z -= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + this->y *= static_cast(scalar); + this->z *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.x); + this->z *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<3, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.y); + this->z *= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(U v) + { + this->x /= static_cast(v); + this->y /= static_cast(v); + this->z /= static_cast(v); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.x); + this->z /= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<3, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.y); + this->z /= static_cast(v.z); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator++() + { + ++this->x; + ++this->y; + ++this->z; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator--() + { + --this->x; + --this->y; + --this->z; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> vec<3, T, Q>::operator++(int) + { + vec<3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> vec<3, T, Q>::operator--(int) + { + vec<3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(U scalar) + { + this->x %= scalar; + this->y %= scalar; + this->z %= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= v.x; + this->y %= v.x; + this->z %= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<3, U, Q> const& v) + { + this->x %= v.x; + this->y %= v.y; + this->z %= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(U scalar) + { + this->x &= scalar; + this->y &= scalar; + this->z &= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= v.x; + this->y &= v.x; + this->z &= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<3, U, Q> const& v) + { + this->x &= v.x; + this->y &= v.y; + this->z &= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(U scalar) + { + this->x |= scalar; + this->y |= scalar; + this->z |= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= v.x; + this->y |= v.x; + this->z |= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<3, U, Q> const& v) + { + this->x |= v.x; + this->y |= v.y; + this->z |= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(U scalar) + { + this->x ^= scalar; + this->y ^= scalar; + this->z ^= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= v.x; + this->y ^= v.x; + this->z ^= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<3, U, Q> const& v) + { + this->x ^= v.x; + this->y ^= v.y; + this->z ^= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(U scalar) + { + this->x <<= scalar; + this->y <<= scalar; + this->z <<= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.x); + this->z <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<3, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.y); + this->z <<= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + this->y >>= static_cast(scalar); + this->z >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.x); + this->z >>= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<3, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.y); + this->z >>= static_cast(v.z); + return *this; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + -v.x, + -v.y, + -v.z); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x + scalar, + v.y + scalar, + v.z + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x + scalar.x, + v.y + scalar.x, + v.z + scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar + v.x, + scalar + v.y, + scalar + v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x + v.x, + scalar.x + v.y, + scalar.x + v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x - scalar, + v.y - scalar, + v.z - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x - scalar.x, + v.y - scalar.x, + v.z - scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar - v.x, + scalar - v.y, + scalar - v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x - v.x, + scalar.x - v.y, + scalar.x - v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x * scalar, + v.y * scalar, + v.z * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x * scalar.x, + v.y * scalar.x, + v.z * scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar * v.x, + scalar * v.y, + scalar * v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x * v.x, + scalar.x * v.y, + scalar.x * v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x / scalar, + v.y / scalar, + v.z / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x / scalar.x, + v.y / scalar.x, + v.z / scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar / v.x, + scalar / v.y, + scalar / v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x / v.x, + scalar.x / v.y, + scalar.x / v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x % scalar, + v.y % scalar, + v.z % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x % scalar.x, + v.y % scalar.x, + v.z % scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar % v.x, + scalar % v.y, + scalar % v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x % v.x, + scalar.x % v.y, + scalar.x % v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x % v2.x, + v1.y % v2.y, + v1.z % v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x & scalar, + v.y & scalar, + v.z & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x & scalar.x, + v.y & scalar.x, + v.z & scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar & v.x, + scalar & v.y, + scalar & v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x & v.x, + scalar.x & v.y, + scalar.x & v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x & v2.x, + v1.y & v2.y, + v1.z & v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x | scalar, + v.y | scalar, + v.z | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x | scalar.x, + v.y | scalar.x, + v.z | scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar | v.x, + scalar | v.y, + scalar | v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x | v.x, + scalar.x | v.y, + scalar.x | v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x | v2.x, + v1.y | v2.y, + v1.z | v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x ^ scalar, + v.y ^ scalar, + v.z ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x ^ scalar.x, + v.y ^ scalar.x, + v.z ^ scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar ^ v.x, + scalar ^ v.y, + scalar ^ v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x ^ v.x, + scalar.x ^ v.y, + scalar.x ^ v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.y, + v1.z ^ v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x << scalar, + v.y << scalar, + v.z << scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x << scalar.x, + v.y << scalar.x, + v.z << scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar << v.x, + scalar << v.y, + scalar << v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x << v.x, + scalar.x << v.y, + scalar.x << v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x << v2.x, + v1.y << v2.y, + v1.z << v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x >> scalar, + v.y >> scalar, + v.z >> scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x >> scalar.x, + v.y >> scalar.x, + v.z >> scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar >> v.x, + scalar >> v.y, + scalar >> v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x >> v.x, + scalar.x >> v.y, + scalar.x >> v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x >> v2.x, + v1.y >> v2.y, + v1.z >> v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator~(vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + ~v.x, + ~v.y, + ~v.z); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y) && + detail::compute_equal::is_iec559>::call(v1.z, v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2) + { + return vec<3, bool, Q>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2) + { + return vec<3, bool, Q>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/detail/type_vec4.hpp b/src/other/manifold/glm/glm/detail/type_vec4.hpp new file mode 100644 index 00000000000..4a364346738 --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec4.hpp @@ -0,0 +1,505 @@ +/// @ref core +/// @file glm/detail/type_vec4.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<4, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<4, T, Q> type; + typedef vec<4, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y, z, w; +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct { T x, y, z, w; }; + struct { T r, g, b, a; }; + struct { T s, t, p, q; }; + + typename detail::storage<4, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE4_2_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_2_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_2_MEMBERS(T, Q, s, t, p, q) + GLM_SWIZZLE4_3_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_3_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_3_MEMBERS(T, Q, s, t, p, q) + GLM_SWIZZLE4_4_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_4_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_4_MEMBERS(T, Q, s, t, p, q) +# endif + }; +# else + union { T x, r, s; }; + union { T y, g, t; }; + union { T z, b, p; }; + union { T w, a, q; }; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, Q) +# endif +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + typedef length_t length_type; + + /// Return the count of components of the vector + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<4, T, Q> const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<4, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T x, T y, T z, T w); + + // -- Conversion scalar constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _Y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, B _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, B _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, A, P> const& _xyz, B _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, A, P> const& _xyz, vec<1, B, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<3, B, P> const& _yzw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<3, B, P> const& _yzw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<2, B, P> const& _zw); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<4, T, Q, E0, E1, E2, E3> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, detail::_swizzle<2, T, Q, F0, F1, -1, -2> const& u) + { + *this = vec<4, T, Q>(v(), u()); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, T const& y, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v) + { + *this = vec<4, T, Q>(x, y, v()); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& w) + { + *this = vec<4, T, Q>(x, v(), w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& z, T const& w) + { + *this = vec<4, T, Q>(v(), z, w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v, T const& w) + { + *this = vec<4, T, Q>(v(), w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v) + { + *this = vec<4, T, Q>(x, v()); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<4, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<4, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> operator&&(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> operator||(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec4.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/other/manifold/glm/glm/detail/type_vec4.inl b/src/other/manifold/glm/glm/detail/type_vec4.inl new file mode 100644 index 00000000000..3c212d98bbe --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec4.inl @@ -0,0 +1,1140 @@ +/// @ref core + +#include "compute_vector_relational.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_vec4_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + }; + + template + struct compute_vec4_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); + } + }; + + template + struct compute_vec4_mul + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); + } + }; + + template + struct compute_vec4_div + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); + } + }; + + template + struct compute_vec4_mod + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x % b.x, a.y % b.y, a.z % b.z, a.w % b.w); + } + }; + + template + struct compute_vec4_and + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w); + } + }; + + template + struct compute_vec4_or + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w); + } + }; + + template + struct compute_vec4_xor + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w); + } + }; + + template + struct compute_vec4_shift_left + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x << b.x, a.y << b.y, a.z << b.z, a.w << b.w); + } + }; + + template + struct compute_vec4_shift_right + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x >> b.x, a.y >> b.y, a.z >> b.z, a.w >> b.w); + } + }; + + template + struct compute_vec4_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y) && + detail::compute_equal::is_iec559>::call(v1.z, v2.z) && + detail::compute_equal::is_iec559>::call(v1.w, v2.w); + } + }; + + template + struct compute_vec4_nequal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return !compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + }; + + template + struct compute_vec4_bitwise_not + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + return vec<4, T, Q>(~v.x, ~v.y, ~v.z, ~v.w); + } + }; +}//namespace detail + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0), z(0), w(0) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, T, Q> const& v) + : x(v.x), y(v.y), z(v.z), w(v.w) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, T, P> const& v) + : x(v.x), y(v.y), z(v.z), w(v.w) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T scalar) + : x(scalar), y(scalar), z(scalar), w(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T _x, T _y, T _z, T _w) + : x(_x), y(_y), z(_z), w(_w) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + , z(static_cast(v.x)) + , w(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, Z _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, B _z, C _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, C _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, B _z, vec<1, C, P> const& _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, vec<1, C, P> const& _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<2, B, P> const& _yz, C _w) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, C _w) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, B _y, vec<2, C, P> const& _zw) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, B _y, vec<2, C, P> const& _zw) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<3, A, P> const& _xyz, B _w) + : x(static_cast(_xyz.x)) + , y(static_cast(_xyz.y)) + , z(static_cast(_xyz.z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<3, A, P> const& _xyz, vec<1, B, P> const& _w) + : x(static_cast(_xyz.x)) + , y(static_cast(_xyz.y)) + , z(static_cast(_xyz.z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<3, B, P> const& _yzw) + : x(static_cast(_x)) + , y(static_cast(_yzw.x)) + , z(static_cast(_yzw.y)) + , w(static_cast(_yzw.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<3, B, P> const& _yzw) + : x(static_cast(_x.x)) + , y(static_cast(_yzw.x)) + , z(static_cast(_yzw.y)) + , w(static_cast(_yzw.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<2, B, P> const& _zw) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + , w(static_cast(v.w)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>& vec<4, T, Q>::operator=(vec<4, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>& vec<4, T, Q>::operator=(vec<4, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + this->w = static_cast(v.w); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(U scalar) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(U scalar) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(U scalar) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(U scalar) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v))); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator++() + { + ++this->x; + ++this->y; + ++this->z; + ++this->w; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator--() + { + --this->x; + --this->y; + --this->z; + --this->w; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> vec<4, T, Q>::operator++(int) + { + vec<4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> vec<4, T, Q>::operator--(int) + { + vec<4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(U scalar) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(U scalar) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(U scalar) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(U scalar) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(U scalar) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(U scalar) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v) + { + return vec<4, T, Q>(0) -= v; + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) += scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) += v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(v) += scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v2) += v1; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) += v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) -= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) -= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) *= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) *= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(v) *= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v2) *= v1; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) *= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) /= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) /= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) /= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) /= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) /= v2; + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) %= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) %= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) %= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar.x) %= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) %= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) &= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<4, T, Q>(v) &= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) &= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) &= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) &= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) |= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) |= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) |= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) |= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) |= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) ^= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) ^= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) ^= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) ^= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) ^= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) <<= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) <<= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) <<= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) <<= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) <<= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) >>= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) >>= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) >>= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) >>= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) >>= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v) + { + return detail::compute_vec4_bitwise_not::value, sizeof(T) * 8, detail::is_aligned::value>::call(v); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return detail::compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return detail::compute_vec4_nequal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> operator&&(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2) + { + return vec<4, bool, Q>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z, v1.w && v2.w); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> operator||(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2) + { + return vec<4, bool, Q>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z, v1.w || v2.w); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_vec4_simd.inl" +#endif diff --git a/src/other/manifold/glm/glm/detail/type_vec4_simd.inl b/src/other/manifold/glm/glm/detail/type_vec4_simd.inl new file mode 100644 index 00000000000..29559b5350c --- /dev/null +++ b/src/other/manifold/glm/glm/detail/type_vec4_simd.inl @@ -0,0 +1,775 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + struct _swizzle_base1<4, float, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const + { + __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer); + + vec<4, float, Q> Result; +# if GLM_ARCH & GLM_ARCH_AVX_BIT + Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0)); +# else + Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0)); +# endif + return Result; + } + }; + + template + struct _swizzle_base1<4, int, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, int, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; + + template + struct _swizzle_base1<4, uint, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, uint, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; +# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + template + struct compute_vec4_add + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_add_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_add + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_add_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_sub_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_sub + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_sub_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_mul_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_mul + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_mul_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_div_ps(a.data, b.data); + return Result; + } + }; + + # if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_div + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_div_pd(a.data, b.data); + return Result; + } + }; +# endif + + template<> + struct compute_vec4_div + { + static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b) + { + vec<4, float, aligned_lowp> Result; + Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data)); + return Result; + } + }; + + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_and_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_and_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_or_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_or_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_sll_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_sll_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_srl_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_srl_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; +# endif + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpeq_ps(v1.data, v2.data)) != 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) == 0; + } + }; +# endif + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) != 0; + } + }; +# endif +}//namespace detail + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + +#if GLM_ARCH & GLM_ARCH_NEON_BIT +namespace glm { +namespace detail { + + template + struct compute_vec4_add + { + static + vec<4, float, Q> + call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vaddq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, uint, Q> + call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vaddq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, int, Q> + call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vaddq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vsubq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vsubq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vsubq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vmulq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vmulq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vmulq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vdivq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + uint32x4_t cmp = vceqq_f32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + uint32x4_t cmp = vceqq_u32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + uint32x4_t cmp = vceqq_s32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + +}//namespace detail + +#if !GLM_CONFIG_XYZW_ONLY + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_lowp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_mediump>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_highp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& rhs) : + data(rhs.data) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, int, aligned_highp>& rhs) : + data(vcvtq_f32_s32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, uint, aligned_highp>& rhs) : + data(vcvtq_f32_u32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_highp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_highp>(_x, _y, _z, _w).data)) + {} + +#endif +}//namespace glm + +#endif diff --git a/src/other/manifold/glm/glm/exponential.hpp b/src/other/manifold/glm/glm/exponential.hpp new file mode 100644 index 00000000000..f8fb886f6ed --- /dev/null +++ b/src/other/manifold/glm/glm/exponential.hpp @@ -0,0 +1,110 @@ +/// @ref core +/// @file glm/exponential.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions +/// +/// @defgroup core_func_exponential Exponential functions +/// @ingroup core +/// +/// Provides GLSL exponential functions +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/type_vec1.hpp" +#include "detail/type_vec2.hpp" +#include "detail/type_vec3.hpp" +#include "detail/type_vec4.hpp" +#include + +namespace glm +{ + /// @addtogroup core_func_exponential + /// @{ + + /// Returns 'base' raised to the power 'exponent'. + /// + /// @param base Floating point value. pow function is defined for input values of 'base' defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @param exponent Floating point value representing the 'exponent'. + /// + /// @see GLSL pow man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec pow(vec const& base, vec const& exponent); + + /// Returns the natural exponentiation of x, i.e., e^x. + /// + /// @param v exp function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL exp man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec exp(vec const& v); + + /// Returns the natural logarithm of v, i.e., + /// returns the value y which satisfies the equation x = e^y. + /// Results are undefined if v <= 0. + /// + /// @param v log function is defined for input values of v defined in the range (0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL log man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec log(vec const& v); + + /// Returns 2 raised to the v power. + /// + /// @param v exp2 function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL exp2 man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec exp2(vec const& v); + + /// Returns the base 2 log of x, i.e., returns the value y, + /// which satisfies the equation x = 2 ^ y. + /// + /// @param v log2 function is defined for input values of v defined in the range (0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL log2 man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec log2(vec const& v); + + /// Returns the positive square root of v. + /// + /// @param v sqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL sqrt man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec sqrt(vec const& v); + + /// Returns the reciprocal of the positive square root of v. + /// + /// @param v inversesqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL inversesqrt man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec inversesqrt(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_exponential.inl" diff --git a/src/other/manifold/glm/glm/ext.hpp b/src/other/manifold/glm/glm/ext.hpp new file mode 100644 index 00000000000..3249fb991ce --- /dev/null +++ b/src/other/manifold/glm/glm/ext.hpp @@ -0,0 +1,253 @@ +/// @file glm/ext.hpp +/// +/// @ref core (Dependence) + +#include "detail/setup.hpp" + +#pragma once + +#include "glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_MESSAGE_EXT_INCLUDED_DISPLAYED) +# define GLM_MESSAGE_EXT_INCLUDED_DISPLAYED +# pragma message("GLM: All extensions included (not recommended)") +#endif//GLM_MESSAGES + +#include "./ext/matrix_clip_space.hpp" +#include "./ext/matrix_common.hpp" + +#include "./ext/matrix_double2x2.hpp" +#include "./ext/matrix_double2x2_precision.hpp" +#include "./ext/matrix_double2x3.hpp" +#include "./ext/matrix_double2x3_precision.hpp" +#include "./ext/matrix_double2x4.hpp" +#include "./ext/matrix_double2x4_precision.hpp" +#include "./ext/matrix_double3x2.hpp" +#include "./ext/matrix_double3x2_precision.hpp" +#include "./ext/matrix_double3x3.hpp" +#include "./ext/matrix_double3x3_precision.hpp" +#include "./ext/matrix_double3x4.hpp" +#include "./ext/matrix_double3x4_precision.hpp" +#include "./ext/matrix_double4x2.hpp" +#include "./ext/matrix_double4x2_precision.hpp" +#include "./ext/matrix_double4x3.hpp" +#include "./ext/matrix_double4x3_precision.hpp" +#include "./ext/matrix_double4x4.hpp" +#include "./ext/matrix_double4x4_precision.hpp" + +#include "./ext/matrix_float2x2.hpp" +#include "./ext/matrix_float2x2_precision.hpp" +#include "./ext/matrix_float2x3.hpp" +#include "./ext/matrix_float2x3_precision.hpp" +#include "./ext/matrix_float2x4.hpp" +#include "./ext/matrix_float2x4_precision.hpp" +#include "./ext/matrix_float3x2.hpp" +#include "./ext/matrix_float3x2_precision.hpp" +#include "./ext/matrix_float3x3.hpp" +#include "./ext/matrix_float3x3_precision.hpp" +#include "./ext/matrix_float3x4.hpp" +#include "./ext/matrix_float3x4_precision.hpp" +#include "./ext/matrix_float4x2.hpp" +#include "./ext/matrix_float4x2_precision.hpp" +#include "./ext/matrix_float4x3.hpp" +#include "./ext/matrix_float4x3_precision.hpp" +#include "./ext/matrix_float4x4.hpp" +#include "./ext/matrix_float4x4_precision.hpp" + +#include "./ext/matrix_int2x2.hpp" +#include "./ext/matrix_int2x2_sized.hpp" +#include "./ext/matrix_int2x3.hpp" +#include "./ext/matrix_int2x3_sized.hpp" +#include "./ext/matrix_int2x4.hpp" +#include "./ext/matrix_int2x4_sized.hpp" +#include "./ext/matrix_int3x2.hpp" +#include "./ext/matrix_int3x2_sized.hpp" +#include "./ext/matrix_int3x3.hpp" +#include "./ext/matrix_int3x3_sized.hpp" +#include "./ext/matrix_int3x4.hpp" +#include "./ext/matrix_int3x4_sized.hpp" +#include "./ext/matrix_int4x2.hpp" +#include "./ext/matrix_int4x2_sized.hpp" +#include "./ext/matrix_int4x3.hpp" +#include "./ext/matrix_int4x3_sized.hpp" +#include "./ext/matrix_int4x4.hpp" +#include "./ext/matrix_int4x4_sized.hpp" + +#include "./ext/matrix_uint2x2.hpp" +#include "./ext/matrix_uint2x2_sized.hpp" +#include "./ext/matrix_uint2x3.hpp" +#include "./ext/matrix_uint2x3_sized.hpp" +#include "./ext/matrix_uint2x4.hpp" +#include "./ext/matrix_uint2x4_sized.hpp" +#include "./ext/matrix_uint3x2.hpp" +#include "./ext/matrix_uint3x2_sized.hpp" +#include "./ext/matrix_uint3x3.hpp" +#include "./ext/matrix_uint3x3_sized.hpp" +#include "./ext/matrix_uint3x4.hpp" +#include "./ext/matrix_uint3x4_sized.hpp" +#include "./ext/matrix_uint4x2.hpp" +#include "./ext/matrix_uint4x2_sized.hpp" +#include "./ext/matrix_uint4x3.hpp" +#include "./ext/matrix_uint4x3_sized.hpp" +#include "./ext/matrix_uint4x4.hpp" +#include "./ext/matrix_uint4x4_sized.hpp" + +#include "./ext/matrix_projection.hpp" +#include "./ext/matrix_relational.hpp" +#include "./ext/matrix_transform.hpp" + +#include "./ext/quaternion_common.hpp" +#include "./ext/quaternion_double.hpp" +#include "./ext/quaternion_double_precision.hpp" +#include "./ext/quaternion_float.hpp" +#include "./ext/quaternion_float_precision.hpp" +#include "./ext/quaternion_exponential.hpp" +#include "./ext/quaternion_geometric.hpp" +#include "./ext/quaternion_relational.hpp" +#include "./ext/quaternion_transform.hpp" +#include "./ext/quaternion_trigonometric.hpp" + +#include "./ext/scalar_common.hpp" +#include "./ext/scalar_constants.hpp" +#include "./ext/scalar_integer.hpp" +#include "./ext/scalar_packing.hpp" +#include "./ext/scalar_relational.hpp" +#include "./ext/scalar_ulp.hpp" + +#include "./ext/scalar_int_sized.hpp" +#include "./ext/scalar_uint_sized.hpp" + +#include "./ext/vector_common.hpp" +#include "./ext/vector_integer.hpp" +#include "./ext/vector_packing.hpp" +#include "./ext/vector_relational.hpp" +#include "./ext/vector_ulp.hpp" + +#include "./ext/vector_bool1.hpp" +#include "./ext/vector_bool1_precision.hpp" +#include "./ext/vector_bool2.hpp" +#include "./ext/vector_bool2_precision.hpp" +#include "./ext/vector_bool3.hpp" +#include "./ext/vector_bool3_precision.hpp" +#include "./ext/vector_bool4.hpp" +#include "./ext/vector_bool4_precision.hpp" + +#include "./ext/vector_double1.hpp" +#include "./ext/vector_double1_precision.hpp" +#include "./ext/vector_double2.hpp" +#include "./ext/vector_double2_precision.hpp" +#include "./ext/vector_double3.hpp" +#include "./ext/vector_double3_precision.hpp" +#include "./ext/vector_double4.hpp" +#include "./ext/vector_double4_precision.hpp" + +#include "./ext/vector_float1.hpp" +#include "./ext/vector_float1_precision.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float2_precision.hpp" +#include "./ext/vector_float3.hpp" +#include "./ext/vector_float3_precision.hpp" +#include "./ext/vector_float4.hpp" +#include "./ext/vector_float4_precision.hpp" + +#include "./ext/vector_int1.hpp" +#include "./ext/vector_int1_sized.hpp" +#include "./ext/vector_int2.hpp" +#include "./ext/vector_int2_sized.hpp" +#include "./ext/vector_int3.hpp" +#include "./ext/vector_int3_sized.hpp" +#include "./ext/vector_int4.hpp" +#include "./ext/vector_int4_sized.hpp" + +#include "./ext/vector_uint1.hpp" +#include "./ext/vector_uint1_sized.hpp" +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_uint2_sized.hpp" +#include "./ext/vector_uint3.hpp" +#include "./ext/vector_uint3_sized.hpp" +#include "./ext/vector_uint4.hpp" +#include "./ext/vector_uint4_sized.hpp" + +#include "./gtc/bitfield.hpp" +#include "./gtc/color_space.hpp" +#include "./gtc/constants.hpp" +#include "./gtc/epsilon.hpp" +#include "./gtc/integer.hpp" +#include "./gtc/matrix_access.hpp" +#include "./gtc/matrix_integer.hpp" +#include "./gtc/matrix_inverse.hpp" +#include "./gtc/matrix_transform.hpp" +#include "./gtc/noise.hpp" +#include "./gtc/packing.hpp" +#include "./gtc/quaternion.hpp" +#include "./gtc/random.hpp" +#include "./gtc/reciprocal.hpp" +#include "./gtc/round.hpp" +#include "./gtc/type_precision.hpp" +#include "./gtc/type_ptr.hpp" +#include "./gtc/ulp.hpp" +#include "./gtc/vec1.hpp" +#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# include "./gtc/type_aligned.hpp" +#endif + +#ifdef GLM_ENABLE_EXPERIMENTAL +#include "./gtx/associated_min_max.hpp" +#include "./gtx/bit.hpp" +#include "./gtx/closest_point.hpp" +#include "./gtx/color_encoding.hpp" +#include "./gtx/color_space.hpp" +#include "./gtx/color_space_YCoCg.hpp" +#include "./gtx/compatibility.hpp" +#include "./gtx/component_wise.hpp" +#include "./gtx/dual_quaternion.hpp" +#include "./gtx/euler_angles.hpp" +#include "./gtx/extend.hpp" +#include "./gtx/extended_min_max.hpp" +#include "./gtx/fast_exponential.hpp" +#include "./gtx/fast_square_root.hpp" +#include "./gtx/fast_trigonometry.hpp" +#include "./gtx/functions.hpp" +#include "./gtx/gradient_paint.hpp" +#include "./gtx/handed_coordinate_space.hpp" +#include "./gtx/integer.hpp" +#include "./gtx/intersect.hpp" +#include "./gtx/log_base.hpp" +#include "./gtx/matrix_cross_product.hpp" +#include "./gtx/matrix_interpolation.hpp" +#include "./gtx/matrix_major_storage.hpp" +#include "./gtx/matrix_operation.hpp" +#include "./gtx/matrix_query.hpp" +#include "./gtx/mixed_product.hpp" +#include "./gtx/norm.hpp" +#include "./gtx/normal.hpp" +#include "./gtx/normalize_dot.hpp" +#include "./gtx/number_precision.hpp" +#include "./gtx/optimum_pow.hpp" +#include "./gtx/orthonormalize.hpp" +#include "./gtx/perpendicular.hpp" +#include "./gtx/polar_coordinates.hpp" +#include "./gtx/projection.hpp" +#include "./gtx/quaternion.hpp" +#include "./gtx/raw_data.hpp" +#include "./gtx/rotate_vector.hpp" +#include "./gtx/spline.hpp" +#include "./gtx/std_based_type.hpp" +#if !(GLM_COMPILER & GLM_COMPILER_CUDA) +# include "./gtx/string_cast.hpp" +#endif +#include "./gtx/transform.hpp" +#include "./gtx/transform2.hpp" +#include "./gtx/vec_swizzle.hpp" +#include "./gtx/vector_angle.hpp" +#include "./gtx/vector_query.hpp" +#include "./gtx/wrap.hpp" + +#if GLM_HAS_TEMPLATE_ALIASES +# include "./gtx/scalar_multiplication.hpp" +#endif + +#if GLM_HAS_RANGE_FOR +# include "./gtx/range.hpp" +#endif +#endif//GLM_ENABLE_EXPERIMENTAL diff --git a/src/other/manifold/glm/glm/ext/matrix_clip_space.hpp b/src/other/manifold/glm/glm/ext/matrix_clip_space.hpp new file mode 100644 index 00000000000..c3874f2f8d7 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_clip_space.hpp @@ -0,0 +1,522 @@ +/// @ref ext_matrix_clip_space +/// @file glm/ext/matrix_clip_space.hpp +/// +/// @defgroup ext_matrix_clip_space GLM_EXT_matrix_clip_space +/// @ingroup ext +/// +/// Defines functions that generate clip space transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_transform +/// @see ext_matrix_projection + +#pragma once + +// Dependencies +#include "../ext/scalar_constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_clip_space extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_clip_space + /// @{ + + /// Creates a matrix for projecting two-dimensional coordinates onto the screen. + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top, T const& zNear, T const& zFar) + /// @see gluOrtho2D man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho( + T left, T right, T bottom, T top); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_ZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_NO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_ZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_NO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoNO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + /// @see glOrtho man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a left handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_ZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a left handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_NO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_ZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_NO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumNO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a left handed frustum matrix. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix with default handedness, using the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @tparam T A floating-point scalar type + /// @see glFrustum man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustum( + T left, T right, T bottom, T top, T near, T far); + + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_ZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_NO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_ZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_NO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveNO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum based on the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param fovy Specifies the field of view angle in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + /// @see gluPerspective man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspective( + T fovy, T aspect, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_ZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_NO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_ZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_NO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovNO( + T fov, T width, T height, T near, T far); + + /// Builds a right handed perspective projection matrix based on a field of view. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH( + T fov, T width, T height, T near, T far); + + /// Builds a left handed perspective projection matrix based on a field of view. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view and the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFov( + T fov, T width, T height, T near, T far); + + /// Creates a matrix for a left handed, symmetric perspective-view frustum with far plane at infinite. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH( + T fovy, T aspect, T near); + + /// Creates a matrix for a right handed, symmetric perspective-view frustum with far plane at infinite. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspective( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param ep Epsilon + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective( + T fovy, T aspect, T near, T ep); + + /// @} +}//namespace glm + +#include "matrix_clip_space.inl" diff --git a/src/other/manifold/glm/glm/ext/matrix_clip_space.inl b/src/other/manifold/glm/glm/ext/matrix_clip_space.inl new file mode 100644 index 00000000000..7e4df33004e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_clip_space.inl @@ -0,0 +1,555 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top) + { + mat<4, 4, T, defaultp> Result(static_cast(1)); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(1); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_ZO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = static_cast(1) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - zNear / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_NO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = static_cast(2) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - (zFar + zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_ZO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(1) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - zNear / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_NO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(2) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - (zFar + zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# endif + + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = farVal / (farVal - nearVal); + Result[2][3] = static_cast(1); + Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_NO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = (farVal + nearVal) / (farVal - nearVal); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = farVal / (nearVal - farVal); + Result[2][3] = static_cast(-1); + Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_NO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = - (farVal + nearVal) / (farVal - nearVal); + Result[2][3] = static_cast(-1); + Result[3][2] = - (static_cast(2) * farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_ZO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = zFar / (zNear - zFar); + Result[2][3] = - static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_NO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = - (zFar + zNear) / (zFar - zNear); + Result[2][3] = - static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_ZO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = zFar / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_NO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = (zFar + zNear) / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# endif + + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_ZO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = zFar / (zNear - zFar); + Result[2][3] = - static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_NO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = - (zFar + zNear) / (zFar - zNear); + Result[2][3] = - static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_ZO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = zFar / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_NO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = (zFar + zNear) / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = - static_cast(1); + Result[2][3] = - static_cast(1); + Result[3][2] = - static_cast(2) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(T(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = static_cast(1); + Result[2][3] = static_cast(1); + Result[3][2] = - static_cast(2) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return infinitePerspectiveLH(fovy, aspect, zNear); +# else + return infinitePerspectiveRH(fovy, aspect, zNear); +# endif + } + + // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = ep - static_cast(1); + Result[2][3] = static_cast(-1); + Result[3][2] = (ep - static_cast(2)) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear) + { + return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon()); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_common.hpp b/src/other/manifold/glm/glm/ext/matrix_common.hpp new file mode 100644 index 00000000000..05c37991c5d --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_common.hpp @@ -0,0 +1,36 @@ +/// @ref ext_matrix_common +/// @file glm/ext/matrix_common.hpp +/// +/// @defgroup ext_matrix_common GLM_EXT_matrix_common +/// @ingroup ext +/// +/// Defines functions for common matrix operations. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_common + +#pragma once + +#include "../detail/qualifier.hpp" +#include "../detail/_fixes.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_common + /// @{ + + template + GLM_FUNC_DECL mat mix(mat const& x, mat const& y, mat const& a); + + template + GLM_FUNC_DECL mat mix(mat const& x, mat const& y, U a); + + /// @} +}//namespace glm + +#include "matrix_common.inl" diff --git a/src/other/manifold/glm/glm/ext/matrix_common.inl b/src/other/manifold/glm/glm/ext/matrix_common.inl new file mode 100644 index 00000000000..9d508485b86 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_common.inl @@ -0,0 +1,16 @@ +#include "../matrix.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat mix(mat const& x, mat const& y, U a) + { + return mat(x) * (static_cast(1) - a) + mat(y) * a; + } + + template + GLM_FUNC_QUALIFIER mat mix(mat const& x, mat const& y, mat const& a) + { + return matrixCompMult(mat(x), static_cast(1) - a) + matrixCompMult(mat(y), a); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x2.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x2.hpp new file mode 100644 index 00000000000..94dca54b59b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x2.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double2x2.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, double, defaultp> dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, double, defaultp> dmat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x2_precision.hpp new file mode 100644 index 00000000000..9e2c174e43b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x2_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, lowp> lowp_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, mediump> mediump_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, highp> highp_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, lowp> lowp_dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, mediump> mediump_dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, highp> highp_dmat2x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x3.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x3.hpp new file mode 100644 index 00000000000..bfef87a666c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double2x3.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 3, double, defaultp> dmat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x3_precision.hpp new file mode 100644 index 00000000000..098fb6046e8 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double2x3_precision.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, lowp> lowp_dmat2x3; + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, mediump> mediump_dmat2x3; + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, highp> highp_dmat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x4.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x4.hpp new file mode 100644 index 00000000000..499284bce16 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double2x4.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 4, double, defaultp> dmat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double2x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double2x4_precision.hpp new file mode 100644 index 00000000000..9b61ebcee1e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double2x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double2x4_precision.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, lowp> lowp_dmat2x4; + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, mediump> mediump_dmat2x4; + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, highp> highp_dmat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x2.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x2.hpp new file mode 100644 index 00000000000..dd23f36cdbb --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double3x2.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 2, double, defaultp> dmat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x2_precision.hpp new file mode 100644 index 00000000000..068d9e91172 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double3x2_precision.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, lowp> lowp_dmat3x2; + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, mediump> mediump_dmat3x2; + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, highp> highp_dmat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x3.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x3.hpp new file mode 100644 index 00000000000..53572b73562 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x3.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double3x3.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, double, defaultp> dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, double, defaultp> dmat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x3_precision.hpp new file mode 100644 index 00000000000..8691e7808dc --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x3_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double3x3_precision.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, lowp> lowp_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, mediump> mediump_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, highp> highp_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, lowp> lowp_dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, mediump> mediump_dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, highp> highp_dmat3x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x4.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x4.hpp new file mode 100644 index 00000000000..c572d637cd2 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double3x4.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 4, double, defaultp> dmat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double3x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double3x4_precision.hpp new file mode 100644 index 00000000000..f040217e748 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double3x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double3x4_precision.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, lowp> lowp_dmat3x4; + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, mediump> mediump_dmat3x4; + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, highp> highp_dmat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x2.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x2.hpp new file mode 100644 index 00000000000..9b229f471e8 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double4x2.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 2, double, defaultp> dmat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x2_precision.hpp new file mode 100644 index 00000000000..6ad18ba9e65 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double4x2_precision.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, lowp> lowp_dmat4x2; + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, mediump> mediump_dmat4x2; + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, highp> highp_dmat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x3.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x3.hpp new file mode 100644 index 00000000000..dca4cf956f9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double4x3.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 3, double, defaultp> dmat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x3_precision.hpp new file mode 100644 index 00000000000..f7371de8494 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double4x3_precision.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, lowp> lowp_dmat4x3; + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, mediump> mediump_dmat4x3; + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, highp> highp_dmat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x4.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x4.hpp new file mode 100644 index 00000000000..81e1bf65cb5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x4.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double4x4.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, double, defaultp> dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, double, defaultp> dmat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_double4x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_double4x4_precision.hpp new file mode 100644 index 00000000000..4c36a8486c7 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_double4x4_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double4x4_precision.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, lowp> lowp_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, mediump> mediump_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, highp> highp_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, lowp> lowp_dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, mediump> mediump_dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, highp> highp_dmat4x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x2.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x2.hpp new file mode 100644 index 00000000000..53df921fe21 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x2.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, float, defaultp> mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, float, defaultp> mat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x2_precision.hpp new file mode 100644 index 00000000000..898b6db7140 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x2_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, lowp> lowp_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, mediump> mediump_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, highp> highp_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, lowp> lowp_mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, mediump> mediump_mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, highp> highp_mat2x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x3.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x3.hpp new file mode 100644 index 00000000000..6f68822dbf1 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float2x3.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 3, float, defaultp> mat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x3_precision.hpp new file mode 100644 index 00000000000..50c103245c3 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x3_precision.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, lowp> lowp_mat2x3; + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, mediump> mediump_mat2x3; + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, highp> highp_mat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x4.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x4.hpp new file mode 100644 index 00000000000..30f30de3cbd --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float2x4.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 4, float, defaultp> mat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float2x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float2x4_precision.hpp new file mode 100644 index 00000000000..079d6382863 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float2x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x4_precision.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, lowp> lowp_mat2x4; + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, mediump> mediump_mat2x4; + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, highp> highp_mat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x2.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x2.hpp new file mode 100644 index 00000000000..d39dd2fedd6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float3x2.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core + /// @{ + + /// 3 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 2, float, defaultp> mat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x2_precision.hpp new file mode 100644 index 00000000000..8572c2a1b20 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float3x2_precision.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, lowp> lowp_mat3x2; + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, mediump> mediump_mat3x2; + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, highp> highp_mat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x3.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x3.hpp new file mode 100644 index 00000000000..177d809ff9f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x3.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float3x3.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, float, defaultp> mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, float, defaultp> mat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x3_precision.hpp new file mode 100644 index 00000000000..8a900c16420 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x3_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float3x3_precision.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, lowp> lowp_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, mediump> mediump_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, highp> highp_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, lowp> lowp_mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, mediump> mediump_mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, highp> highp_mat3x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x4.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x4.hpp new file mode 100644 index 00000000000..64b8459dcdd --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float3x4.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 4, float, defaultp> mat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float3x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float3x4_precision.hpp new file mode 100644 index 00000000000..bc36bf13a1e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float3x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float3x4_precision.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, lowp> lowp_mat3x4; + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, mediump> mediump_mat3x4; + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, highp> highp_mat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x2.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x2.hpp new file mode 100644 index 00000000000..1ed5227bf58 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float4x2.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 2, float, defaultp> mat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x2_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x2_precision.hpp new file mode 100644 index 00000000000..88fd069630a --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, lowp> lowp_mat4x2; + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, mediump> mediump_mat4x2; + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, highp> highp_mat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x3.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x3.hpp new file mode 100644 index 00000000000..5dbe7657043 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float4x3.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 3, float, defaultp> mat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x3_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x3_precision.hpp new file mode 100644 index 00000000000..846ed4fc8d9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float4x3_precision.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, lowp> lowp_mat4x3; + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, mediump> mediump_mat4x3; + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, highp> highp_mat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x4.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x4.hpp new file mode 100644 index 00000000000..5ba111de048 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x4.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float4x4.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @ingroup core_matrix + /// @{ + + /// 4 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, float, defaultp> mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, float, defaultp> mat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_float4x4_precision.hpp b/src/other/manifold/glm/glm/ext/matrix_float4x4_precision.hpp new file mode 100644 index 00000000000..597149bcf90 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_float4x4_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float4x4_precision.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, lowp> lowp_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, mediump> mediump_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, highp> highp_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, lowp> lowp_mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, mediump> mediump_mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, highp> highp_mat4x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x2.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x2.hpp new file mode 100644 index 00000000000..c6aa0686ae7 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x2.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int2x2 +/// @file glm/ext/matrix_int2x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x2 GLM_EXT_matrix_int2x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x2 + /// @{ + + /// Signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2 + typedef mat<2, 2, int, defaultp> imat2x2; + + /// Signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2 + typedef mat<2, 2, int, defaultp> imat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x2_sized.hpp new file mode 100644 index 00000000000..70c0c2106ac --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x2_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int2x2_sized +/// @file glm/ext/matrix_int2x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x2_sized GLM_EXT_matrix_int2x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x2_sized + /// @{ + + /// 8 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int8, defaultp> i8mat2x2; + + /// 16 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int16, defaultp> i16mat2x2; + + /// 32 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int32, defaultp> i32mat2x2; + + /// 64 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int64, defaultp> i64mat2x2; + + + /// 8 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int8, defaultp> i8mat2; + + /// 16 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int16, defaultp> i16mat2; + + /// 32 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int32, defaultp> i32mat2; + + /// 64 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int64, defaultp> i64mat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x3.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x3.hpp new file mode 100644 index 00000000000..aee415caa6e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int2x3 +/// @file glm/ext/matrix_int2x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3 GLM_EXT_matrix_int2x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x3 + /// @{ + + /// Signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3 + typedef mat<2, 3, int, defaultp> imat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x3_sized.hpp new file mode 100644 index 00000000000..b5526fe5514 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int2x3_sized +/// @file glm/ext/matrix_int2x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3_sized GLM_EXT_matrix_int2x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x3_sized + /// @{ + + /// 8 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int8, defaultp> i8mat2x3; + + /// 16 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int16, defaultp> i16mat2x3; + + /// 32 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int32, defaultp> i32mat2x3; + + /// 64 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int64, defaultp> i64mat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x4.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x4.hpp new file mode 100644 index 00000000000..4f36331d660 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int2x4 +/// @file glm/ext/matrix_int2x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x4 GLM_EXT_matrix_int2x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x4 + /// @{ + + /// Signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4 + typedef mat<2, 4, int, defaultp> imat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int2x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int2x4_sized.hpp new file mode 100644 index 00000000000..a66a5e72688 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int2x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int2x4_sized +/// @file glm/ext/matrix_int2x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x4_sized GLM_EXT_matrix_int2x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x4_sized + /// @{ + + /// 8 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int8, defaultp> i8mat2x4; + + /// 16 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int16, defaultp> i16mat2x4; + + /// 32 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int32, defaultp> i32mat2x4; + + /// 64 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int64, defaultp> i64mat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x2.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x2.hpp new file mode 100644 index 00000000000..3bd563b7de9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int3x2 +/// @file glm/ext/matrix_int3x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2 GLM_EXT_matrix_int3x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x2 + /// @{ + + /// Signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2 + typedef mat<3, 2, int, defaultp> imat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x2_sized.hpp new file mode 100644 index 00000000000..7e34c5240f4 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int3x2_sized +/// @file glm/ext/matrix_int3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2_sized GLM_EXT_matrix_int3x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x2_sized + /// @{ + + /// 8 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int8, defaultp> i8mat3x2; + + /// 16 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int16, defaultp> i16mat3x2; + + /// 32 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int32, defaultp> i32mat3x2; + + /// 64 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int64, defaultp> i64mat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x3.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x3.hpp new file mode 100644 index 00000000000..287488da034 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x3.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int3x3 +/// @file glm/ext/matrix_int3x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x3 GLM_EXT_matrix_int3x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x3 + /// @{ + + /// Signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3 + typedef mat<3, 3, int, defaultp> imat3x3; + + /// Signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3 + typedef mat<3, 3, int, defaultp> imat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x3_sized.hpp new file mode 100644 index 00000000000..577e305aa7f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x3_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int3x3_sized +/// @file glm/ext/matrix_int3x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x3_sized GLM_EXT_matrix_int3x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x3_sized + /// @{ + + /// 8 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int8, defaultp> i8mat3x3; + + /// 16 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int16, defaultp> i16mat3x3; + + /// 32 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int32, defaultp> i32mat3x3; + + /// 64 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int64, defaultp> i64mat3x3; + + + /// 8 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int8, defaultp> i8mat3; + + /// 16 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int16, defaultp> i16mat3; + + /// 32 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int32, defaultp> i32mat3; + + /// 64 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int64, defaultp> i64mat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x4.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x4.hpp new file mode 100644 index 00000000000..08e534d9c4d --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int3x4 +/// @file glm/ext/matrix_int3x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x4 GLM_EXT_matrix_int3x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x4 + /// @{ + + /// Signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4 + typedef mat<3, 4, int, defaultp> imat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int3x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int3x4_sized.hpp new file mode 100644 index 00000000000..692c48c439e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int3x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int3x4_sized +/// @file glm/ext/matrix_int3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x4_sized GLM_EXT_matrix_int3x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x4_sized + /// @{ + + /// 8 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int8, defaultp> i8mat3x4; + + /// 16 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int16, defaultp> i16mat3x4; + + /// 32 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int32, defaultp> i32mat3x4; + + /// 64 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int64, defaultp> i64mat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x2.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x2.hpp new file mode 100644 index 00000000000..f756ef2804c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int4x2 +/// @file glm/ext/matrix_int4x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x2 GLM_EXT_matrix_int4x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x2 + /// @{ + + /// Signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2 + typedef mat<4, 2, int, defaultp> imat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x2_sized.hpp new file mode 100644 index 00000000000..63a99d604dc --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int4x2_sized +/// @file glm/ext/matrix_int4x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x2_sized GLM_EXT_matrix_int4x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x2_sized + /// @{ + + /// 8 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int8, defaultp> i8mat4x2; + + /// 16 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int16, defaultp> i16mat4x2; + + /// 32 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int32, defaultp> i32mat4x2; + + /// 64 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int64, defaultp> i64mat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x3.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x3.hpp new file mode 100644 index 00000000000..d5d97a7a37c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int4x3 +/// @file glm/ext/matrix_int4x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x3 GLM_EXT_matrix_int4x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x3 + /// @{ + + /// Signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3 + typedef mat<4, 3, int, defaultp> imat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x3_sized.hpp new file mode 100644 index 00000000000..55078fadc60 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int4x3_sized +/// @file glm/ext/matrix_int4x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x3_sized GLM_EXT_matrix_int4x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x3_sized + /// @{ + + /// 8 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int8, defaultp> i8mat4x3; + + /// 16 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int16, defaultp> i16mat4x3; + + /// 32 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int32, defaultp> i32mat4x3; + + /// 64 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int64, defaultp> i64mat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x4.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x4.hpp new file mode 100644 index 00000000000..e17cff17f9f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x4.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int4x4 +/// @file glm/ext/matrix_int4x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x4 GLM_EXT_matrix_int4x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x4 + /// @{ + + /// Signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4 + typedef mat<4, 4, int, defaultp> imat4x4; + + /// Signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4 + typedef mat<4, 4, int, defaultp> imat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_int4x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_int4x4_sized.hpp new file mode 100644 index 00000000000..4a11203eb25 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_int4x4_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int4x4_sized +/// @file glm/ext/matrix_int4x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x4_sized GLM_EXT_matrix_int4x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x4_sized + /// @{ + + /// 8 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int8, defaultp> i8mat4x4; + + /// 16 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int16, defaultp> i16mat4x4; + + /// 32 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int32, defaultp> i32mat4x4; + + /// 64 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int64, defaultp> i64mat4x4; + + + /// 8 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int8, defaultp> i8mat4; + + /// 16 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int16, defaultp> i16mat4; + + /// 32 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int32, defaultp> i32mat4; + + /// 64 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int64, defaultp> i64mat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_projection.hpp b/src/other/manifold/glm/glm/ext/matrix_projection.hpp new file mode 100644 index 00000000000..51fd01bd8ee --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_projection.hpp @@ -0,0 +1,149 @@ +/// @ref ext_matrix_projection +/// @file glm/ext/matrix_projection.hpp +/// +/// @defgroup ext_matrix_projection GLM_EXT_matrix_projection +/// @ingroup ext +/// +/// Functions that generate common projection transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_transform +/// @see ext_matrix_clip_space + +#pragma once + +// Dependencies +#include "../gtc/constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_projection extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_projection + /// @{ + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> projectZO( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> projectNO( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates using default near and far clip planes definition. + /// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> project( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProjectZO( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProjectNO( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using default near and far clip planes definition. + /// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProject( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Define a picking region + /// + /// @param center Specify the center of a picking region in window coordinates. + /// @param delta Specify the width and height, respectively, of the picking region in window coordinates. + /// @param viewport Rendering viewport + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluPickMatrix man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> pickMatrix( + vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport); + + /// @} +}//namespace glm + +#include "matrix_projection.inl" diff --git a/src/other/manifold/glm/glm/ext/matrix_projection.inl b/src/other/manifold/glm/glm/ext/matrix_projection.inl new file mode 100644 index 00000000000..2f2c196aac5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_projection.inl @@ -0,0 +1,106 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> projectZO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); + tmp = model * tmp; + tmp = proj * tmp; + + tmp /= tmp.w; + tmp.x = tmp.x * static_cast(0.5) + static_cast(0.5); + tmp.y = tmp.y * static_cast(0.5) + static_cast(0.5); + + tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); + tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); + + return vec<3, T, Q>(tmp); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> projectNO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); + tmp = model * tmp; + tmp = proj * tmp; + + tmp /= tmp.w; + tmp = tmp * static_cast(0.5) + static_cast(0.5); + tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); + tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); + + return vec<3, T, Q>(tmp); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> project(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return projectZO(obj, model, proj, viewport); +# else + return projectNO(obj, model, proj, viewport); +# endif + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectZO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + mat<4, 4, T, Q> Inverse = inverse(proj * model); + + vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); + tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); + tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); + tmp.x = tmp.x * static_cast(2) - static_cast(1); + tmp.y = tmp.y * static_cast(2) - static_cast(1); + + vec<4, T, Q> obj = Inverse * tmp; + obj /= obj.w; + + return vec<3, T, Q>(obj); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectNO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + mat<4, 4, T, Q> Inverse = inverse(proj * model); + + vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); + tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); + tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); + tmp = tmp * static_cast(2) - static_cast(1); + + vec<4, T, Q> obj = Inverse * tmp; + obj /= obj.w; + + return vec<3, T, Q>(obj); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProject(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return unProjectZO(win, model, proj, viewport); +# else + return unProjectNO(win, model, proj, viewport); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> pickMatrix(vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport) + { + assert(delta.x > static_cast(0) && delta.y > static_cast(0)); + mat<4, 4, T, Q> Result(static_cast(1)); + + if(!(delta.x > static_cast(0) && delta.y > static_cast(0))) + return Result; // Error + + vec<3, T, Q> Temp( + (static_cast(viewport[2]) - static_cast(2) * (center.x - static_cast(viewport[0]))) / delta.x, + (static_cast(viewport[3]) - static_cast(2) * (center.y - static_cast(viewport[1]))) / delta.y, + static_cast(0)); + + // Translate and scale the picked region to the entire window + Result = translate(Result, Temp); + return scale(Result, vec<3, T, Q>(static_cast(viewport[2]) / delta.x, static_cast(viewport[3]) / delta.y, static_cast(1))); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_relational.hpp b/src/other/manifold/glm/glm/ext/matrix_relational.hpp new file mode 100644 index 00000000000..20023ad89a0 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_relational.hpp @@ -0,0 +1,132 @@ +/// @ref ext_matrix_relational +/// @file glm/ext/matrix_relational.hpp +/// +/// @defgroup ext_matrix_relational GLM_EXT_matrix_relational +/// @ingroup ext +/// +/// Exposes comparison functions for matrix types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_relational +/// @see ext_scalar_relational +/// @see ext_quaternion_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_relational + /// @{ + + /// Perform a component-wise equal-to comparison of two matrices. + /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y); + + /// Perform a component-wise not-equal-to comparison of two matrices. + /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, vec const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, vec const& epsilon); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, vec const& ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, vec const& ULPs); + + /// @} +}//namespace glm + +#include "matrix_relational.inl" diff --git a/src/other/manifold/glm/glm/ext/matrix_relational.inl b/src/other/manifold/glm/glm/ext/matrix_relational.inl new file mode 100644 index 00000000000..b2b875309de --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_relational.inl @@ -0,0 +1,82 @@ +/// @ref ext_vector_relational +/// @file glm/ext/vector_relational.inl + +// Dependency: +#include "../ext/vector_relational.hpp" +#include "../common.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b) + { + return equal(a, b, static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, T Epsilon) + { + return equal(a, b, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& Epsilon) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i], Epsilon[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y) + { + return notEqual(x, y, static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, T Epsilon) + { + return notEqual(x, y, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& Epsilon) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i], Epsilon[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, int MaxULPs) + { + return equal(a, b, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& MaxULPs) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i], MaxULPs[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, int MaxULPs) + { + return notEqual(x, y, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& MaxULPs) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i], MaxULPs[i])); + return Result; + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_transform.hpp b/src/other/manifold/glm/glm/ext/matrix_transform.hpp new file mode 100644 index 00000000000..cbd187efd85 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_transform.hpp @@ -0,0 +1,144 @@ +/// @ref ext_matrix_transform +/// @file glm/ext/matrix_transform.hpp +/// +/// @defgroup ext_matrix_transform GLM_EXT_matrix_transform +/// @ingroup ext +/// +/// Defines functions that generate common transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_projection +/// @see ext_matrix_clip_space + +#pragma once + +// Dependencies +#include "../gtc/constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_transform + /// @{ + + /// Builds an identity matrix. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType identity(); + + /// Builds a translation 4 * 4 matrix created from a vector of 3 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a translation vector. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @code + /// #include + /// #include + /// ... + /// glm::mat4 m = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f)); + /// // m[0][0] == 1.0f, m[0][1] == 0.0f, m[0][2] == 0.0f, m[0][3] == 0.0f + /// // m[1][0] == 0.0f, m[1][1] == 1.0f, m[1][2] == 0.0f, m[1][3] == 0.0f + /// // m[2][0] == 0.0f, m[2][1] == 0.0f, m[2][2] == 1.0f, m[2][3] == 0.0f + /// // m[3][0] == 1.0f, m[3][1] == 1.0f, m[3][2] == 1.0f, m[3][3] == 1.0f + /// @endcode + /// + /// @see - translate(mat<4, 4, T, Q> const& m, T x, T y, T z) + /// @see - translate(vec<3, T, Q> const& v) + /// @see glTranslate man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> translate( + mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v); + + /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. + /// + /// @param m Input matrix multiplied by this rotation matrix. + /// @param angle Rotation angle expressed in radians. + /// @param axis Rotation axis, recommended to be normalized. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - rotate(mat<4, 4, T, Q> const& m, T angle, T x, T y, T z) + /// @see - rotate(T angle, vec<3, T, Q> const& v) + /// @see glRotate man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotate( + mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& axis); + + /// Builds a scale 4 * 4 matrix created from 3 scalars. + /// + /// @param m Input matrix multiplied by this scale matrix. + /// @param v Ratio of scaling for each axis. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - scale(mat<4, 4, T, Q> const& m, T x, T y, T z) + /// @see - scale(vec<3, T, Q> const& v) + /// @see glScale man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> scale( + mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v); + + /// Build a right handed look at view matrix. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAtRH( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// Build a left handed look at view matrix. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAtLH( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// Build a look at view matrix based on the default handedness. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + /// @see gluLookAt man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAt( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// @} +}//namespace glm + +#include "matrix_transform.inl" diff --git a/src/other/manifold/glm/glm/ext/matrix_transform.inl b/src/other/manifold/glm/glm/ext/matrix_transform.inl new file mode 100644 index 00000000000..a415157e0d9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_transform.inl @@ -0,0 +1,152 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType identity() + { + return detail::init_gentype::GENTYPE>::identity(); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result(m); + Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + vec<3, T, Q> axis(normalize(v)); + vec<3, T, Q> temp((T(1) - c) * axis); + + mat<4, 4, T, Q> Rotate; + Rotate[0][0] = c + temp[0] * axis[0]; + Rotate[0][1] = temp[0] * axis[1] + s * axis[2]; + Rotate[0][2] = temp[0] * axis[2] - s * axis[1]; + + Rotate[1][0] = temp[1] * axis[0] - s * axis[2]; + Rotate[1][1] = c + temp[1] * axis[1]; + Rotate[1][2] = temp[1] * axis[2] + s * axis[0]; + + Rotate[2][0] = temp[2] * axis[0] + s * axis[1]; + Rotate[2][1] = temp[2] * axis[1] - s * axis[0]; + Rotate[2][2] = c + temp[2] * axis[2]; + + mat<4, 4, T, Q> Result; + Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate_slow(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + mat<4, 4, T, Q> Result; + + vec<3, T, Q> axis = normalize(v); + + Result[0][0] = c + (static_cast(1) - c) * axis.x * axis.x; + Result[0][1] = (static_cast(1) - c) * axis.x * axis.y + s * axis.z; + Result[0][2] = (static_cast(1) - c) * axis.x * axis.z - s * axis.y; + Result[0][3] = static_cast(0); + + Result[1][0] = (static_cast(1) - c) * axis.y * axis.x - s * axis.z; + Result[1][1] = c + (static_cast(1) - c) * axis.y * axis.y; + Result[1][2] = (static_cast(1) - c) * axis.y * axis.z + s * axis.x; + Result[1][3] = static_cast(0); + + Result[2][0] = (static_cast(1) - c) * axis.z * axis.x + s * axis.y; + Result[2][1] = (static_cast(1) - c) * axis.z * axis.y - s * axis.x; + Result[2][2] = c + (static_cast(1) - c) * axis.z * axis.z; + Result[2][3] = static_cast(0); + + Result[3] = vec<4, T, Q>(0, 0, 0, 1); + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result; + Result[0] = m[0] * v[0]; + Result[1] = m[1] * v[1]; + Result[2] = m[2] * v[2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale_slow(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result(T(1)); + Result[0][0] = v.x; + Result[1][1] = v.y; + Result[2][2] = v.z; + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { + vec<3, T, Q> const f(normalize(center - eye)); + vec<3, T, Q> const s(normalize(cross(f, up))); + vec<3, T, Q> const u(cross(s, f)); + + mat<4, 4, T, Q> Result(1); + Result[0][0] = s.x; + Result[1][0] = s.y; + Result[2][0] = s.z; + Result[0][1] = u.x; + Result[1][1] = u.y; + Result[2][1] = u.z; + Result[0][2] =-f.x; + Result[1][2] =-f.y; + Result[2][2] =-f.z; + Result[3][0] =-dot(s, eye); + Result[3][1] =-dot(u, eye); + Result[3][2] = dot(f, eye); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { + vec<3, T, Q> const f(normalize(center - eye)); + vec<3, T, Q> const s(normalize(cross(up, f))); + vec<3, T, Q> const u(cross(f, s)); + + mat<4, 4, T, Q> Result(1); + Result[0][0] = s.x; + Result[1][0] = s.y; + Result[2][0] = s.z; + Result[0][1] = u.x; + Result[1][1] = u.y; + Result[2][1] = u.z; + Result[0][2] = f.x; + Result[1][2] = f.y; + Result[2][2] = f.z; + Result[3][0] = -dot(s, eye); + Result[3][1] = -dot(u, eye); + Result[3][2] = -dot(f, eye); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAt(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { + GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) + return lookAtLH(eye, center, up); + else + return lookAtRH(eye, center, up); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x2.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x2.hpp new file mode 100644 index 00000000000..034771ae522 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x2.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint2x2 +/// @file glm/ext/matrix_uint2x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x2 GLM_EXT_matrix_uint2x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x2 + /// @{ + + /// Unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2 + typedef mat<2, 2, uint, defaultp> umat2x2; + + /// Unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2 + typedef mat<2, 2, uint, defaultp> umat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x2_sized.hpp new file mode 100644 index 00000000000..4555324d2b5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x2_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint2x2_sized +/// @file glm/ext/matrix_uint2x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x2_sized GLM_EXT_matrix_uint2x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x2_sized + /// @{ + + /// 8 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint8, defaultp> u8mat2x2; + + /// 16 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint16, defaultp> u16mat2x2; + + /// 32 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint32, defaultp> u32mat2x2; + + /// 64 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint64, defaultp> u64mat2x2; + + + /// 8 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint8, defaultp> u8mat2; + + /// 16 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint16, defaultp> u16mat2; + + /// 32 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint32, defaultp> u32mat2; + + /// 64 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint64, defaultp> u64mat2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x3.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x3.hpp new file mode 100644 index 00000000000..7de62f6ff5c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint2x3 +/// @file glm/ext/matrix_uint2x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3 GLM_EXT_matrix_uint2x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x3 + /// @{ + + /// Unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3 + typedef mat<2, 3, uint, defaultp> umat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x3_sized.hpp new file mode 100644 index 00000000000..db7939c9465 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint2x3_sized +/// @file glm/ext/matrix_uint2x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x3_sized GLM_EXT_matrix_uint2x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x3_sized + /// @{ + + /// 8 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint8, defaultp> u8mat2x3; + + /// 16 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint16, defaultp> u16mat2x3; + + /// 32 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint32, defaultp> u32mat2x3; + + /// 64 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint64, defaultp> u64mat2x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x4.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x4.hpp new file mode 100644 index 00000000000..0f993509c23 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint2x4 +/// @file glm/ext/matrix_uint2x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x4 GLM_EXT_matrix_int2x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x4 + /// @{ + + /// Unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4 + typedef mat<2, 4, uint, defaultp> umat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint2x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint2x4_sized.hpp new file mode 100644 index 00000000000..5cb8e546fe4 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint2x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint2x4_sized +/// @file glm/ext/matrixu_uint2x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x4_sized GLM_EXT_matrix_uint2x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x4_sized + /// @{ + + /// 8 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint8, defaultp> u8mat2x4; + + /// 16 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint16, defaultp> u16mat2x4; + + /// 32 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint32, defaultp> u32mat2x4; + + /// 64 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint64, defaultp> u64mat2x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x2.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x2.hpp new file mode 100644 index 00000000000..47f48737cce --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint3x2 +/// @file glm/ext/matrix_uint3x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2 GLM_EXT_matrix_uint3x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x2 + /// @{ + + /// Unsigned integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2 + typedef mat<3, 2, uint, defaultp> umat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x2_sized.hpp new file mode 100644 index 00000000000..c81af8f968d --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint3x2_sized +/// @file glm/ext/matrix_uint3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x2_sized GLM_EXT_matrix_uint3x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x2_sized + /// @{ + + /// 8 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint8, defaultp> u8mat3x2; + + /// 16 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint16, defaultp> u16mat3x2; + + /// 32 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint32, defaultp> u32mat3x2; + + /// 64 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint64, defaultp> u64mat3x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x3.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x3.hpp new file mode 100644 index 00000000000..1004c0d2d54 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x3.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint3x3 +/// @file glm/ext/matrix_uint3x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x3 GLM_EXT_matrix_uint3x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x3 + /// @{ + + /// Unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3 + typedef mat<3, 3, uint, defaultp> umat3x3; + + /// Unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3 + typedef mat<3, 3, uint, defaultp> umat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x3_sized.hpp new file mode 100644 index 00000000000..41a8be74866 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x3_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint3x3_sized +/// @file glm/ext/matrix_uint3x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x3_sized GLM_EXT_matrix_uint3x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x3_sized + /// @{ + + /// 8 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint8, defaultp> u8mat3x3; + + /// 16 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint16, defaultp> u16mat3x3; + + /// 32 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint32, defaultp> u32mat3x3; + + /// 64 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint64, defaultp> u64mat3x3; + + + /// 8 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint8, defaultp> u8mat3; + + /// 16 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint16, defaultp> u16mat3; + + /// 32 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint32, defaultp> u32mat3; + + /// 64 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint64, defaultp> u64mat3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x4.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x4.hpp new file mode 100644 index 00000000000..c6dd78c4a05 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint3x4 +/// @file glm/ext/matrix_uint3x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x4 GLM_EXT_matrix_uint3x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x4 + /// @{ + + /// Signed integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4 + typedef mat<3, 4, uint, defaultp> umat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint3x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint3x4_sized.hpp new file mode 100644 index 00000000000..2ce28ad816f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint3x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint3x4_sized +/// @file glm/ext/matrix_uint3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x4_sized GLM_EXT_matrix_uint3x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x4_sized + /// @{ + + /// 8 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint8, defaultp> u8mat3x4; + + /// 16 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint16, defaultp> u16mat3x4; + + /// 32 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint32, defaultp> u32mat3x4; + + /// 64 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint64, defaultp> u64mat3x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x2.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x2.hpp new file mode 100644 index 00000000000..0446f5745bd --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint4x2 +/// @file glm/ext/matrix_uint4x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x2 GLM_EXT_matrix_uint4x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x2 + /// @{ + + /// Unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2 + typedef mat<4, 2, uint, defaultp> umat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x2_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x2_sized.hpp new file mode 100644 index 00000000000..57a66bf9b8b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint4x2_sized +/// @file glm/ext/matrix_uint4x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x2_sized GLM_EXT_matrix_uint4x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x2_sized + /// @{ + + /// 8 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint8, defaultp> u8mat4x2; + + /// 16 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint16, defaultp> u16mat4x2; + + /// 32 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint32, defaultp> u32mat4x2; + + /// 64 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint64, defaultp> u64mat4x2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x3.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x3.hpp new file mode 100644 index 00000000000..54c24e4e50b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint4x3 +/// @file glm/ext/matrix_uint4x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x3 GLM_EXT_matrix_uint4x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x3 + /// @{ + + /// Unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3 + typedef mat<4, 3, uint, defaultp> umat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x3_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x3_sized.hpp new file mode 100644 index 00000000000..2e61124d63b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint4x3_sized +/// @file glm/ext/matrix_uint4x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x3_sized GLM_EXT_matrix_uint4x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x3_sized + /// @{ + + /// 8 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint8, defaultp> u8mat4x3; + + /// 16 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint16, defaultp> u16mat4x3; + + /// 32 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint32, defaultp> u32mat4x3; + + /// 64 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint64, defaultp> u64mat4x3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x4.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x4.hpp new file mode 100644 index 00000000000..5cc84553d93 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x4.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint4x4 +/// @file glm/ext/matrix_uint4x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x4 GLM_EXT_matrix_uint4x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x4 + /// @{ + + /// Unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4 + typedef mat<4, 4, uint, defaultp> umat4x4; + + /// Unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4 + typedef mat<4, 4, uint, defaultp> umat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/matrix_uint4x4_sized.hpp b/src/other/manifold/glm/glm/ext/matrix_uint4x4_sized.hpp new file mode 100644 index 00000000000..bb10bd2b77d --- /dev/null +++ b/src/other/manifold/glm/glm/ext/matrix_uint4x4_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint4x4_sized +/// @file glm/ext/matrix_uint4x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x4_sized GLM_EXT_matrix_uint4x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x4_sized + /// @{ + + /// 8 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint8, defaultp> u8mat4x4; + + /// 16 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint16, defaultp> u16mat4x4; + + /// 32 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint32, defaultp> u32mat4x4; + + /// 64 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint64, defaultp> u64mat4x4; + + + /// 8 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint8, defaultp> u8mat4; + + /// 16 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint16, defaultp> u16mat4; + + /// 32 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint32, defaultp> u32mat4; + + /// 64 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint64, defaultp> u64mat4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/quaternion_common.hpp b/src/other/manifold/glm/glm/ext/quaternion_common.hpp new file mode 100644 index 00000000000..f519d559185 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_common.hpp @@ -0,0 +1,135 @@ +/// @ref ext_quaternion_common +/// @file glm/ext/quaternion_common.hpp +/// +/// @defgroup ext_quaternion_common GLM_EXT_quaternion_common +/// @ingroup ext +/// +/// Provides common functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_common +/// @see ext_vector_common +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_trigonometric +/// @see ext_quaternion_transform + +#pragma once + +// Dependency: +#include "../ext/scalar_constants.hpp" +#include "../ext/quaternion_geometric.hpp" +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_common + /// @{ + + /// Spherical linear interpolation of two quaternions. + /// The interpolation is oriented and the rotation is performed at constant speed. + /// For short path spherical linear interpolation, use the slerp function. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - slerp(qua const& x, qua const& y, T const& a) + template + GLM_FUNC_DECL qua mix(qua const& x, qua const& y, T a); + + /// Linear interpolation of two quaternions. + /// The interpolation is oriented. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined in the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua lerp(qua const& x, qua const& y, T a); + + /// Spherical linear interpolation of two quaternions. + /// The interpolation always take the short path and the rotation is performed at constant speed. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua slerp(qua const& x, qua const& y, T a); + + /// Spherical linear interpolation of two quaternions with multiple spins over rotation axis. + /// The interpolation always take the short path when the spin count is positive and long path + /// when count is negative. Rotation is performed at constant speed. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// @param k Additional spin count. If Value is negative interpolation will be on "long" path. + /// + /// @tparam T A floating-point scalar type + /// @tparam S An integer scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua slerp(qua const& x, qua const& y, T a, S k); + + /// Returns the q conjugate. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua conjugate(qua const& q); + + /// Returns the q inverse. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua inverse(qua const& q); + + /// Returns true if x holds a NaN (not a number) + /// representation in the underlying implementation's set of + /// floating point representations. Returns false otherwise, + /// including for implementations with no NaN + /// representations. + /// + /// /!\ When using compiler fast math, this function may fail. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> isnan(qua const& x); + + /// Returns true if x holds a positive infinity or negative + /// infinity representation in the underlying implementation's + /// set of floating point representations. Returns false + /// otherwise, including for implementations with no infinity + /// representations. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> isinf(qua const& x); + + /// @} +} //namespace glm + +#include "quaternion_common.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_common.inl b/src/other/manifold/glm/glm/ext/quaternion_common.inl new file mode 100644 index 00000000000..0e4a3bb2a3c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_common.inl @@ -0,0 +1,144 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua mix(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mix' only accept floating-point inputs"); + + T const cosTheta = dot(x, y); + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if(cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, y.w, a), + mix(x.x, y.x, a), + mix(x.y, y.y, a), + mix(x.z, y.z, a)); + } + else + { + // Essential Mathematics, page 467 + T angle = acos(cosTheta); + return (sin((static_cast(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua lerp(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'lerp' only accept floating-point inputs"); + + // Lerp is only defined in [0, 1] + assert(a >= static_cast(0)); + assert(a <= static_cast(1)); + + return x * (static_cast(1) - a) + (y * a); + } + + template + GLM_FUNC_QUALIFIER qua slerp(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'slerp' only accept floating-point inputs"); + + qua z = y; + + T cosTheta = dot(x, y); + + // If cosTheta < 0, the interpolation will take the long way around the sphere. + // To fix this, one quat must be negated. + if(cosTheta < static_cast(0)) + { + z = -y; + cosTheta = -cosTheta; + } + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if(cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, z.w, a), + mix(x.x, z.x, a), + mix(x.y, z.y, a), + mix(x.z, z.z, a)); + } + else + { + // Essential Mathematics, page 467 + T angle = acos(cosTheta); + return (sin((static_cast(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua slerp(qua const& x, qua const& y, T a, S k) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'slerp' only accept floating-point inputs"); + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'slerp' only accept integer for spin count"); + + qua z = y; + + T cosTheta = dot(x, y); + + // If cosTheta < 0, the interpolation will take the long way around the sphere. + // To fix this, one quat must be negated. + if (cosTheta < static_cast(0)) + { + z = -y; + cosTheta = -cosTheta; + } + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if (cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, z.w, a), + mix(x.x, z.x, a), + mix(x.y, z.y, a), + mix(x.z, z.z, a)); + } + else + { + // Graphics Gems III, page 96 + T angle = acos(cosTheta); + T phi = angle + k * glm::pi(); + return (sin(angle - a * phi)* x + sin(a * phi) * z) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua conjugate(qua const& q) + { + return qua(q.w, -q.x, -q.y, -q.z); + } + + template + GLM_FUNC_QUALIFIER qua inverse(qua const& q) + { + return conjugate(q) / dot(q, q); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua const& q) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + + return vec<4, bool, Q>(isnan(q.x), isnan(q.y), isnan(q.z), isnan(q.w)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(qua const& q) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + + return vec<4, bool, Q>(isinf(q.x), isinf(q.y), isinf(q.z), isinf(q.w)); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "quaternion_common_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/ext/quaternion_common_simd.inl b/src/other/manifold/glm/glm/ext/quaternion_common_simd.inl new file mode 100644 index 00000000000..ddfc8a44f6a --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_common_simd.inl @@ -0,0 +1,18 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_dot, float, true> + { + static GLM_FUNC_QUALIFIER float call(qua const& x, qua const& y) + { + return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data)); + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/other/manifold/glm/glm/ext/quaternion_double.hpp b/src/other/manifold/glm/glm/ext/quaternion_double.hpp new file mode 100644 index 00000000000..63b24de4d52 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_double.hpp @@ -0,0 +1,39 @@ +/// @ref ext_quaternion_double +/// @file glm/ext/quaternion_double.hpp +/// +/// @defgroup ext_quaternion_double GLM_EXT_quaternion_double +/// @ingroup ext +/// +/// Exposes double-precision floating point quaternion type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double_precision +/// @see ext_quaternion_common +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_double extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_double + /// @{ + + /// Quaternion of double-precision floating-point numbers. + typedef qua dquat; + + /// @} +} //namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_double_precision.hpp b/src/other/manifold/glm/glm/ext/quaternion_double_precision.hpp new file mode 100644 index 00000000000..8aa24a17752 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_double_precision.hpp @@ -0,0 +1,42 @@ +/// @ref ext_quaternion_double_precision +/// @file glm/ext/quaternion_double_precision.hpp +/// +/// @defgroup ext_quaternion_double_precision GLM_EXT_quaternion_double_precision +/// @ingroup ext +/// +/// Exposes double-precision floating point quaternion type with various precision in term of ULPs. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_double_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_double_precision + /// @{ + + /// Quaternion of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua lowp_dquat; + + /// Quaternion of medium double-qualifier floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua mediump_dquat; + + /// Quaternion of high double-qualifier floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua highp_dquat; + + /// @} +} //namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_exponential.hpp b/src/other/manifold/glm/glm/ext/quaternion_exponential.hpp new file mode 100644 index 00000000000..affe2979aad --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_exponential.hpp @@ -0,0 +1,63 @@ +/// @ref ext_quaternion_exponential +/// @file glm/ext/quaternion_exponential.hpp +/// +/// @defgroup ext_quaternion_exponential GLM_EXT_quaternion_exponential +/// @ingroup ext +/// +/// Provides exponential functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see core_exponential +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../geometric.hpp" +#include "../ext/scalar_constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_exponential extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_transform + /// @{ + + /// Returns a exponential of a quaternion. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua exp(qua const& q); + + /// Returns a logarithm of a quaternion + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua log(qua const& q); + + /// Returns a quaternion raised to a power. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua pow(qua const& q, T y); + + /// Returns the square root of a quaternion + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua sqrt(qua const& q); + + /// @} +} //namespace glm + +#include "quaternion_exponential.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_exponential.inl b/src/other/manifold/glm/glm/ext/quaternion_exponential.inl new file mode 100644 index 00000000000..8456c00aff6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_exponential.inl @@ -0,0 +1,85 @@ +#include "scalar_constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua exp(qua const& q) + { + vec<3, T, Q> u(q.x, q.y, q.z); + T const Angle = glm::length(u); + if (Angle < epsilon()) + return qua(); + + vec<3, T, Q> const v(u / Angle); + return qua(cos(Angle), sin(Angle) * v); + } + + template + GLM_FUNC_QUALIFIER qua log(qua const& q) + { + vec<3, T, Q> u(q.x, q.y, q.z); + T Vec3Len = length(u); + + if (Vec3Len < epsilon()) + { + if(q.w > static_cast(0)) + return qua(log(q.w), static_cast(0), static_cast(0), static_cast(0)); + else if(q.w < static_cast(0)) + return qua(log(-q.w), pi(), static_cast(0), static_cast(0)); + else + return qua(std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()); + } + else + { + T t = atan(Vec3Len, T(q.w)) / Vec3Len; + T QuatLen2 = Vec3Len * Vec3Len + q.w * q.w; + return qua(static_cast(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z); + } + } + + template + GLM_FUNC_QUALIFIER qua pow(qua const& x, T y) + { + //Raising to the power of 0 should yield 1 + //Needed to prevent a division by 0 error later on + if(y > -epsilon() && y < epsilon()) + return qua(1,0,0,0); + + //To deal with non-unit quaternions + T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w); + + T Angle; + if(abs(x.w / magnitude) > cos_one_over_two()) + { + //Scalar component is close to 1; using it to recover angle would lose precision + //Instead, we use the non-scalar components since sin() is accurate around 0 + + //Prevent a division by 0 error later on + T VectorMagnitude = x.x * x.x + x.y * x.y + x.z * x.z; + if (glm::abs(VectorMagnitude - static_cast(0)) < glm::epsilon()) { + //Equivalent to raising a real number to a power + return qua(pow(x.w, y), 0, 0, 0); + } + + Angle = asin(sqrt(VectorMagnitude) / magnitude); + } + else + { + //Scalar component is small, shouldn't cause loss of precision + Angle = acos(x.w / magnitude); + } + + T NewAngle = Angle * y; + T Div = sin(NewAngle) / sin(Angle); + T Mag = pow(magnitude, y - static_cast(1)); + return qua(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag); + } + + template + GLM_FUNC_QUALIFIER qua sqrt(qua const& x) + { + return pow(x, static_cast(0.5)); + } +}//namespace glm + + diff --git a/src/other/manifold/glm/glm/ext/quaternion_float.hpp b/src/other/manifold/glm/glm/ext/quaternion_float.hpp new file mode 100644 index 00000000000..ca42a60597f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_float.hpp @@ -0,0 +1,39 @@ +/// @ref ext_quaternion_float +/// @file glm/ext/quaternion_float.hpp +/// +/// @defgroup ext_quaternion_float GLM_EXT_quaternion_float +/// @ingroup ext +/// +/// Exposes single-precision floating point quaternion type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_double +/// @see ext_quaternion_float_precision +/// @see ext_quaternion_common +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_float extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_float + /// @{ + + /// Quaternion of single-precision floating-point numbers. + typedef qua quat; + + /// @} +} //namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_float_precision.hpp b/src/other/manifold/glm/glm/ext/quaternion_float_precision.hpp new file mode 100644 index 00000000000..f9e4f5c21d9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_float_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_quaternion_float_precision +/// @file glm/ext/quaternion_float_precision.hpp +/// +/// @defgroup ext_quaternion_float_precision GLM_EXT_quaternion_float_precision +/// @ingroup ext +/// +/// Exposes single-precision floating point quaternion type with various precision in term of ULPs. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_float_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_float_precision + /// @{ + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua lowp_quat; + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua mediump_quat; + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua highp_quat; + + /// @} +} //namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_geometric.hpp b/src/other/manifold/glm/glm/ext/quaternion_geometric.hpp new file mode 100644 index 00000000000..6d98bbe93fc --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_geometric.hpp @@ -0,0 +1,70 @@ +/// @ref ext_quaternion_geometric +/// @file glm/ext/quaternion_geometric.hpp +/// +/// @defgroup ext_quaternion_geometric GLM_EXT_quaternion_geometric +/// @ingroup ext +/// +/// Provides geometric functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see core_geometric +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "../ext/vector_relational.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_geometric extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_geometric + /// @{ + + /// Returns the norm of a quaternions + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL T length(qua const& q); + + /// Returns the normalized quaternion. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL qua normalize(qua const& q); + + /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ... + /// + /// @tparam T Floating-point scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL T dot(qua const& x, qua const& y); + + /// Compute a cross product. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_QUALIFIER qua cross(qua const& q1, qua const& q2); + + /// @} +} //namespace glm + +#include "quaternion_geometric.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_geometric.inl b/src/other/manifold/glm/glm/ext/quaternion_geometric.inl new file mode 100644 index 00000000000..e155ac52180 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_geometric.inl @@ -0,0 +1,36 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER T dot(qua const& x, qua const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return detail::compute_dot, T, detail::is_aligned::value>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER T length(qua const& q) + { + return glm::sqrt(dot(q, q)); + } + + template + GLM_FUNC_QUALIFIER qua normalize(qua const& q) + { + T len = length(q); + if(len <= static_cast(0)) // Problem + return qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + T oneOverLen = static_cast(1) / len; + return qua(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen); + } + + template + GLM_FUNC_QUALIFIER qua cross(qua const& q1, qua const& q2) + { + return qua( + q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, + q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, + q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z, + q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_relational.hpp b/src/other/manifold/glm/glm/ext/quaternion_relational.hpp new file mode 100644 index 00000000000..7aa121da0a1 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_relational.hpp @@ -0,0 +1,62 @@ +/// @ref ext_quaternion_relational +/// @file glm/ext/quaternion_relational.hpp +/// +/// @defgroup ext_quaternion_relational GLM_EXT_quaternion_relational +/// @ingroup ext +/// +/// Exposes comparison functions for quaternion types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_vector_relational +/// @see ext_matrix_relational +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../vector_relational.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_relational + /// @{ + + /// Returns the component-wise comparison of result x == y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> equal(qua const& x, qua const& y); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> equal(qua const& x, qua const& y, T epsilon); + + /// Returns the component-wise comparison of result x != y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua const& x, qua const& y); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua const& x, qua const& y, T epsilon); + + /// @} +} //namespace glm + +#include "quaternion_relational.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_relational.inl b/src/other/manifold/glm/glm/ext/quaternion_relational.inl new file mode 100644 index 00000000000..b1713e95c6c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_relational.inl @@ -0,0 +1,35 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] == y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua const& x, qua const& y, T epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return lessThan(abs(v), vec<4, T, Q>(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] != y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua const& x, qua const& y, T epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon)); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_transform.hpp b/src/other/manifold/glm/glm/ext/quaternion_transform.hpp new file mode 100644 index 00000000000..a9cc5c2b59f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_transform.hpp @@ -0,0 +1,47 @@ +/// @ref ext_quaternion_transform +/// @file glm/ext/quaternion_transform.hpp +/// +/// @defgroup ext_quaternion_transform GLM_EXT_quaternion_transform +/// @ingroup ext +/// +/// Provides transformation functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_transform + /// @{ + + /// Rotates a quaternion from a vector of 3 components axis and an angle. + /// + /// @param q Source orientation + /// @param angle Angle expressed in radians. + /// @param axis Axis of the rotation + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL qua rotate(qua const& q, T const& angle, vec<3, T, Q> const& axis); + /// @} +} //namespace glm + +#include "quaternion_transform.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_transform.inl b/src/other/manifold/glm/glm/ext/quaternion_transform.inl new file mode 100644 index 00000000000..b87ecb65d9f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_transform.inl @@ -0,0 +1,24 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua rotate(qua const& q, T const& angle, vec<3, T, Q> const& v) + { + vec<3, T, Q> Tmp = v; + + // Axis of rotation must be normalised + T len = glm::length(Tmp); + if(abs(len - static_cast(1)) > static_cast(0.001)) + { + T oneOverLen = static_cast(1) / len; + Tmp.x *= oneOverLen; + Tmp.y *= oneOverLen; + Tmp.z *= oneOverLen; + } + + T const AngleRad(angle); + T const Sin = sin(AngleRad * static_cast(0.5)); + + return q * qua(cos(AngleRad * static_cast(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/ext/quaternion_trigonometric.hpp b/src/other/manifold/glm/glm/ext/quaternion_trigonometric.hpp new file mode 100644 index 00000000000..76cea27add6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_trigonometric.hpp @@ -0,0 +1,63 @@ +/// @ref ext_quaternion_trigonometric +/// @file glm/ext/quaternion_trigonometric.hpp +/// +/// @defgroup ext_quaternion_trigonometric GLM_EXT_quaternion_trigonometric +/// @ingroup ext +/// +/// Provides trigonometric functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform + +#pragma once + +// Dependency: +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include "scalar_constants.hpp" +#include "vector_relational.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_trigonometric extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_trigonometric + /// @{ + + /// Returns the quaternion rotation angle. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL T angle(qua const& x); + + /// Returns the q rotation axis. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<3, T, Q> axis(qua const& x); + + /// Build a quaternion from an angle and a normalized axis. + /// + /// @param angle Angle expressed in radians. + /// @param axis Axis of the quaternion, must be normalized. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua angleAxis(T const& angle, vec<3, T, Q> const& axis); + + /// @} +} //namespace glm + +#include "quaternion_trigonometric.inl" diff --git a/src/other/manifold/glm/glm/ext/quaternion_trigonometric.inl b/src/other/manifold/glm/glm/ext/quaternion_trigonometric.inl new file mode 100644 index 00000000000..06b7c4c3c98 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/quaternion_trigonometric.inl @@ -0,0 +1,34 @@ +#include "scalar_constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T angle(qua const& x) + { + if (abs(x.w) > cos_one_over_two()) + { + return asin(sqrt(x.x * x.x + x.y * x.y + x.z * x.z)) * static_cast(2); + } + + return acos(x.w) * static_cast(2); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> axis(qua const& x) + { + T const tmp1 = static_cast(1) - x.w * x.w; + if(tmp1 <= static_cast(0)) + return vec<3, T, Q>(0, 0, 1); + T const tmp2 = static_cast(1) / sqrt(tmp1); + return vec<3, T, Q>(x.x * tmp2, x.y * tmp2, x.z * tmp2); + } + + template + GLM_FUNC_QUALIFIER qua angleAxis(T const& angle, vec<3, T, Q> const& v) + { + T const a(angle); + T const s = glm::sin(a * static_cast(0.5)); + + return qua(glm::cos(a * static_cast(0.5)), v * s); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_common.hpp b/src/other/manifold/glm/glm/ext/scalar_common.hpp new file mode 100644 index 00000000000..aa5a180797d --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_common.hpp @@ -0,0 +1,157 @@ +/// @ref ext_scalar_common +/// @file glm/ext/scalar_common.hpp +/// +/// @defgroup ext_scalar_common GLM_EXT_scalar_common +/// @ingroup ext +/// +/// Exposes min and max functions for 3 to 4 scalar parameters. +/// +/// Include to use the features of this extension. +/// +/// @see core_func_common +/// @see ext_vector_common + +#pragma once + +// Dependency: +#include "../common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_common + /// @{ + + /// Returns the minimum component-wise values of 3 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T min(T a, T b, T c); + + /// Returns the minimum component-wise values of 4 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T min(T a, T b, T c, T d); + + /// Returns the maximum component-wise values of 3 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T max(T a, T b, T c); + + /// Returns the maximum component-wise values of 4 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T max(T a, T b, T c, T d); + + /// Returns the minimum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b); + + /// Returns the minimum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b, T c); + + /// Returns the minimum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b, T c, T d); + + /// Returns the maximum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b); + + /// Returns the maximum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b, T C); + + /// Returns the maximum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b, T C, T D); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL genType fclamp(genType x, genType minVal, genType maxVal); + + /// Simulate GL_CLAMP OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType clamp(genType const& Texcoord); + + /// Simulate GL_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType repeat(genType const& Texcoord); + + /// Simulate GL_MIRRORED_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType mirrorClamp(genType const& Texcoord); + + /// Simulate GL_MIRROR_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType mirrorRepeat(genType const& Texcoord); + + /// @} +}//namespace glm + +#include "scalar_common.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_common.inl b/src/other/manifold/glm/glm/ext/scalar_common.inl new file mode 100644 index 00000000000..7d9207afccf --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_common.inl @@ -0,0 +1,152 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER T min(T a, T b, T c) + { + return glm::min(glm::min(a, b), c); + } + + template + GLM_FUNC_QUALIFIER T min(T a, T b, T c, T d) + { + return glm::min(glm::min(a, b), glm::min(c, d)); + } + + template + GLM_FUNC_QUALIFIER T max(T a, T b, T c) + { + return glm::max(glm::max(a, b), c); + } + + template + GLM_FUNC_QUALIFIER T max(T a, T b, T c, T d) + { + return glm::max(glm::max(a, b), glm::max(c, d)); + } + +# if GLM_HAS_CXX11_STL + using std::fmin; +# else + template + GLM_FUNC_QUALIFIER T fmin(T a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return b; + return min(a, b); + } +# endif + + template + GLM_FUNC_QUALIFIER T fmin(T a, T b, T c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return fmin(b, c); + if (isnan(b)) + return fmin(a, c); + if (isnan(c)) + return min(a, b); + return min(a, b, c); + } + + template + GLM_FUNC_QUALIFIER T fmin(T a, T b, T c, T d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return fmin(b, c, d); + if (isnan(b)) + return min(a, fmin(c, d)); + if (isnan(c)) + return fmin(min(a, b), d); + if (isnan(d)) + return min(a, b, c); + return min(a, b, c, d); + } + + +# if GLM_HAS_CXX11_STL + using std::fmax; +# else + template + GLM_FUNC_QUALIFIER T fmax(T a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return b; + return max(a, b); + } +# endif + + template + GLM_FUNC_QUALIFIER T fmax(T a, T b, T c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return fmax(b, c); + if (isnan(b)) + return fmax(a, c); + if (isnan(c)) + return max(a, b); + return max(a, b, c); + } + + template + GLM_FUNC_QUALIFIER T fmax(T a, T b, T c, T d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return fmax(b, c, d); + if (isnan(b)) + return max(a, fmax(c, d)); + if (isnan(c)) + return fmax(max(a, b), d); + if (isnan(d)) + return max(a, b, c); + return max(a, b, c, d); + } + + // fclamp + template + GLM_FUNC_QUALIFIER genType fclamp(genType x, genType minVal, genType maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fclamp' only accept floating-point or integer inputs"); + return fmin(fmax(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER genType clamp(genType const& Texcoord) + { + return glm::clamp(Texcoord, static_cast(0), static_cast(1)); + } + + template + GLM_FUNC_QUALIFIER genType repeat(genType const& Texcoord) + { + return glm::fract(Texcoord); + } + + template + GLM_FUNC_QUALIFIER genType mirrorClamp(genType const& Texcoord) + { + return glm::fract(glm::abs(Texcoord)); + } + + template + GLM_FUNC_QUALIFIER genType mirrorRepeat(genType const& Texcoord) + { + genType const Abs = glm::abs(Texcoord); + genType const Clamp = glm::mod(glm::floor(Abs), static_cast(2)); + genType const Floor = glm::floor(Abs); + genType const Rest = Abs - Floor; + genType const Mirror = Clamp + Rest; + return mix(Rest, static_cast(1) - Rest, Mirror >= static_cast(1)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_constants.hpp b/src/other/manifold/glm/glm/ext/scalar_constants.hpp new file mode 100644 index 00000000000..74e210d9c09 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_constants.hpp @@ -0,0 +1,40 @@ +/// @ref ext_scalar_constants +/// @file glm/ext/scalar_constants.hpp +/// +/// @defgroup ext_scalar_constants GLM_EXT_scalar_constants +/// @ingroup ext +/// +/// Provides a list of constants and precomputed useful values. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_constants extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_constants + /// @{ + + /// Return the epsilon constant for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType epsilon(); + + /// Return the pi constant for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType pi(); + + /// Return the value of cos(1 / 2) for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType cos_one_over_two(); + + /// @} +} //namespace glm + +#include "scalar_constants.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_constants.inl b/src/other/manifold/glm/glm/ext/scalar_constants.inl new file mode 100644 index 00000000000..b475adf83b6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_constants.inl @@ -0,0 +1,24 @@ +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType epsilon() + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'epsilon' only accepts floating-point inputs"); + return std::numeric_limits::epsilon(); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType pi() + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'pi' only accepts floating-point inputs"); + return static_cast(3.14159265358979323846264338327950288); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType cos_one_over_two() + { + return genType(0.877582561890372716130286068203503191); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_int_sized.hpp b/src/other/manifold/glm/glm/ext/scalar_int_sized.hpp new file mode 100644 index 00000000000..8e9c511c9cb --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_int_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_scalar_int_sized +/// @file glm/ext/scalar_int_sized.hpp +/// +/// @defgroup ext_scalar_int_sized GLM_EXT_scalar_int_sized +/// @ingroup ext +/// +/// Exposes sized signed integer scalar types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_int_sized extension included") +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::int8_t int8; + typedef std::int16_t int16; + typedef std::int32_t int32; +# else + typedef signed char int8; + typedef signed short int16; + typedef signed int int32; +#endif// + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + + /// @addtogroup ext_scalar_int_sized + /// @{ + + /// 8 bit signed integer type. + typedef detail::int8 int8; + + /// 16 bit signed integer type. + typedef detail::int16 int16; + + /// 32 bit signed integer type. + typedef detail::int32 int32; + + /// 64 bit signed integer type. + typedef detail::int64 int64; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_integer.hpp b/src/other/manifold/glm/glm/ext/scalar_integer.hpp new file mode 100644 index 00000000000..a2ca8a2ae37 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_integer.hpp @@ -0,0 +1,92 @@ +/// @ref ext_scalar_integer +/// @file glm/ext/scalar_integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_scalar_integer GLM_EXT_scalar_integer +/// @ingroup ext +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../detail/type_float.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_integer + /// @{ + + /// Return true if the value is a power of two number. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL bool isPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType nextPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType prevPowerOfTwo(genIUType v); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL bool isMultiple(genIUType v, genIUType Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam genIUType Integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType nextMultiple(genIUType v, genIUType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genIUType Integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType prevMultiple(genIUType v, genIUType Multiple); + + /// Returns the bit number of the Nth significant bit set to + /// 1 in the binary representation of value. + /// If value bitcount is less than the Nth significant bit, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL int findNSB(genIUType x, int significantBitCount); + + /// @} +} //namespace glm + +#include "scalar_integer.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_integer.inl b/src/other/manifold/glm/glm/ext/scalar_integer.inl new file mode 100644 index 00000000000..efba9600975 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_integer.inl @@ -0,0 +1,243 @@ +#include "../integer.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_ceilShift + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T) + { + return v; + } + }; + + template + struct compute_ceilShift + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Shift) + { + return v | (v >> Shift); + } + }; + + template + struct compute_ceilPowerOfTwo + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); + + vec const Sign(sign(x)); + + vec v(abs(x)); + + v = v - static_cast(1); + v = v | (v >> static_cast(1)); + v = v | (v >> static_cast(2)); + v = v | (v >> static_cast(4)); + v = compute_ceilShift= 2>::call(v, 8); + v = compute_ceilShift= 4>::call(v, 16); + v = compute_ceilShift= 8>::call(v, 32); + return (v + static_cast(1)) * Sign; + } + }; + + template + struct compute_ceilPowerOfTwo + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); + + vec v(x); + + v = v - static_cast(1); + v = v | (v >> static_cast(1)); + v = v | (v >> static_cast(2)); + v = v | (v >> static_cast(4)); + v = compute_ceilShift= 2>::call(v, 8); + v = compute_ceilShift= 4>::call(v, 16); + v = compute_ceilShift= 8>::call(v, 32); + return v + static_cast(1); + } + }; + + template + struct compute_ceilMultiple{}; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source > genType(0)) + return Source + (Multiple - std::fmod(Source, Multiple)); + else + return Source + std::fmod(-Source, Multiple); + } + }; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + genType Tmp = Source - genType(1); + return Tmp + (Multiple - (Tmp % Multiple)); + } + }; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + assert(Multiple > genType(0)); + if(Source > genType(0)) + { + genType Tmp = Source - genType(1); + return Tmp + (Multiple - (Tmp % Multiple)); + } + else + return Source + (-Source % Multiple); + } + }; + + template + struct compute_floorMultiple{}; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - std::fmod(Source, Multiple); + else + return Source - std::fmod(Source, Multiple) - Multiple; + } + }; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool isPowerOfTwo(genIUType Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isPowerOfTwo' only accept integer inputs"); + + genIUType const Result = glm::abs(Value); + return !(Result & (Result - 1)); + } + + template + GLM_FUNC_QUALIFIER genIUType nextPowerOfTwo(genIUType value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextPowerOfTwo' only accept integer inputs"); + + return detail::compute_ceilPowerOfTwo<1, genIUType, defaultp, std::numeric_limits::is_signed>::call(vec<1, genIUType, defaultp>(value)).x; + } + + template + GLM_FUNC_QUALIFIER genIUType prevPowerOfTwo(genIUType value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevPowerOfTwo' only accept integer inputs"); + + return isPowerOfTwo(value) ? value : static_cast(static_cast(1) << static_cast(findMSB(value))); + } + + template + GLM_FUNC_QUALIFIER bool isMultiple(genIUType Value, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return isMultiple(vec<1, genIUType>(Value), vec<1, genIUType>(Multiple)).x; + } + + template + GLM_FUNC_QUALIFIER genIUType nextMultiple(genIUType Source, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::compute_ceilMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER genIUType prevMultiple(genIUType Source, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::compute_floorMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER int findNSB(genIUType x, int significantBitCount) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findNSB' only accept integer inputs"); + + if(bitCount(x) < significantBitCount) + return -1; + + genIUType const One = static_cast(1); + int bitPos = 0; + + genIUType key = x; + int nBitCount = significantBitCount; + int Step = sizeof(x) * 8 / 2; + while (key > One) + { + genIUType Mask = static_cast((One << Step) - One); + genIUType currentKey = key & Mask; + int currentBitCount = bitCount(currentKey); + if (nBitCount > currentBitCount) + { + nBitCount -= currentBitCount; + bitPos += Step; + key >>= static_cast(Step); + } + else + { + key = key & Mask; + } + + Step >>= 1; + } + + return static_cast(bitPos); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_packing.hpp b/src/other/manifold/glm/glm/ext/scalar_packing.hpp new file mode 100644 index 00000000000..18b85b72a40 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_packing.hpp @@ -0,0 +1,32 @@ +/// @ref ext_scalar_packing +/// @file glm/ext/scalar_packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_scalar_packing GLM_EXT_scalar_packing +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert scalar values to packed +/// formats. + +#pragma once + +// Dependency: +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_packing + /// @{ + + + /// @} +}// namespace glm + +#include "scalar_packing.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_packing.inl b/src/other/manifold/glm/glm/ext/scalar_packing.inl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/other/manifold/glm/glm/ext/scalar_relational.hpp b/src/other/manifold/glm/glm/ext/scalar_relational.hpp new file mode 100644 index 00000000000..3076a5e63f9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_relational.hpp @@ -0,0 +1,65 @@ +/// @ref ext_scalar_relational +/// @file glm/ext/scalar_relational.hpp +/// +/// @defgroup ext_scalar_relational GLM_EXT_scalar_relational +/// @ingroup ext +/// +/// Exposes comparison functions for scalar types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_vector_relational +/// @see ext_matrix_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_relational extension included") +#endif + +namespace glm +{ + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison between two scalars in term of ULPs. + /// True if this expression is satisfied. + /// + /// @param x First operand. + /// @param y Second operand. + /// @param ULPs Maximum difference in ULPs between the two operators to consider them equal. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool equal(genType const& x, genType const& y, int ULPs); + + /// Returns the component-wise comparison between two scalars in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @param x First operand. + /// @param y Second operand. + /// @param ULPs Maximum difference in ULPs between the two operators to consider them not equal. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, int ULPs); + + /// @} +}//namespace glm + +#include "scalar_relational.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_relational.inl b/src/other/manifold/glm/glm/ext/scalar_relational.inl new file mode 100644 index 00000000000..c85583ef5bb --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_relational.inl @@ -0,0 +1,40 @@ +#include "../common.hpp" +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/type_float.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon) + { + return abs(x - y) <= epsilon; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, genType const& epsilon) + { + return abs(x - y) > epsilon; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, int MaxULPs) + { + detail::float_t const a(x); + detail::float_t const b(y); + + // Different signs means they do not match. + if(a.negative() != b.negative()) + return false; + + // Find the difference in ULPs. + typename detail::float_t::int_type const DiffULPs = abs(a.i - b.i); + return DiffULPs <= MaxULPs; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, int ULPs) + { + return !equal(x, y, ULPs); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_uint_sized.hpp b/src/other/manifold/glm/glm/ext/scalar_uint_sized.hpp new file mode 100644 index 00000000000..fd5267fad7c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_uint_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_scalar_uint_sized +/// @file glm/ext/scalar_uint_sized.hpp +/// +/// @defgroup ext_scalar_uint_sized GLM_EXT_scalar_uint_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer scalar types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_uint_sized extension included") +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::uint8_t uint8; + typedef std::uint16_t uint16; + typedef std::uint32_t uint32; +# else + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; +#endif + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + + /// @addtogroup ext_scalar_uint_sized + /// @{ + + /// 8 bit unsigned integer type. + typedef detail::uint8 uint8; + + /// 16 bit unsigned integer type. + typedef detail::uint16 uint16; + + /// 32 bit unsigned integer type. + typedef detail::uint32 uint32; + + /// 64 bit unsigned integer type. + typedef detail::uint64 uint64; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/scalar_ulp.hpp b/src/other/manifold/glm/glm/ext/scalar_ulp.hpp new file mode 100644 index 00000000000..941ada3e8cb --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_ulp.hpp @@ -0,0 +1,74 @@ +/// @ref ext_scalar_ulp +/// @file glm/ext/scalar_ulp.hpp +/// +/// @defgroup ext_scalar_ulp GLM_EXT_scalar_ulp +/// @ingroup ext +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_ulp +/// @see ext_scalar_relational + +#pragma once + +// Dependencies +#include "../ext/scalar_int_sized.hpp" +#include "../common.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType nextFloat(genType x); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType prevFloat(genType x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType nextFloat(genType x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType prevFloat(genType x, int ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @see ext_scalar_ulp + GLM_FUNC_DECL int floatDistance(float x, float y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @see ext_scalar_ulp + GLM_FUNC_DECL int64 floatDistance(double x, double y); + + /// @} +}//namespace glm + +#include "scalar_ulp.inl" diff --git a/src/other/manifold/glm/glm/ext/scalar_ulp.inl b/src/other/manifold/glm/glm/ext/scalar_ulp.inl new file mode 100644 index 00000000000..308df150687 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/scalar_ulp.inl @@ -0,0 +1,284 @@ +/// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +/// +/// Developed at SunPro, a Sun Microsystems, Inc. business. +/// Permission to use, copy, modify, and distribute this +/// software is freely granted, provided that this notice +/// is preserved. + +#include "../detail/type_float.hpp" +#include "../ext/scalar_constants.hpp" +#include +#include + +#if(GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(push) +# pragma warning(disable : 4127) +#endif + +typedef union +{ + float value; + /* FIXME: Assumes 32 bit int. */ + unsigned int word; +} ieee_float_shape_type; + +typedef union +{ + double value; + struct + { + int lsw; + int msw; + } parts; +} ieee_double_shape_type; + +#define GLM_EXTRACT_WORDS(ix0,ix1,d) \ + do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ + } while (0) + +#define GLM_GET_FLOAT_WORD(i,d) \ + do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ + } while (0) + +#define GLM_SET_FLOAT_WORD(d,i) \ + do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ + } while (0) + +#define GLM_INSERT_WORDS(d,ix0,ix1) \ + do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ + } while (0) + +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER float nextafterf(float x, float y) + { + volatile float t; + int hx, hy, ix, iy; + + GLM_GET_FLOAT_WORD(hx, x); + GLM_GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; // |x| + iy = hy & 0x7fffffff; // |y| + + if((ix > 0x7f800000) || // x is nan + (iy > 0x7f800000)) // y is nan + return x + y; + if(abs(y - x) <= epsilon()) + return y; // x=y, return y + if(ix == 0) + { // x == 0 + GLM_SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);// return +-minsubnormal + t = x * x; + if(abs(t - x) <= epsilon()) + return t; + else + return x; // raise underflow flag + } + if(hx >= 0) + { // x > 0 + if(hx > hy) // x > y, x -= ulp + hx -= 1; + else // x < y, x += ulp + hx += 1; + } + else + { // x < 0 + if(hy >= 0 || hx > hy) // x < y, x -= ulp + hx -= 1; + else // x > y, x += ulp + hx += 1; + } + hy = hx & 0x7f800000; + if(hy >= 0x7f800000) + return x + x; // overflow + if(hy < 0x00800000) // underflow + { + t = x * x; + if(abs(t - x) > epsilon()) + { // raise underflow flag + GLM_SET_FLOAT_WORD(y, hx); + return y; + } + } + GLM_SET_FLOAT_WORD(x, hx); + return x; + } + + GLM_FUNC_QUALIFIER double nextafter(double x, double y) + { + volatile double t; + int hx, hy, ix, iy; + unsigned int lx, ly; + + GLM_EXTRACT_WORDS(hx, lx, x); + GLM_EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; // |x| + iy = hy & 0x7fffffff; // |y| + + if(((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0) || // x is nan + ((iy >= 0x7ff00000) && ((iy - 0x7ff00000) | ly) != 0)) // y is nan + return x + y; + if(abs(y - x) <= epsilon()) + return y; // x=y, return y + if((ix | lx) == 0) + { // x == 0 + GLM_INSERT_WORDS(x, hy & 0x80000000, 1); // return +-minsubnormal + t = x * x; + if(abs(t - x) <= epsilon()) + return t; + else + return x; // raise underflow flag + } + if(hx >= 0) { // x > 0 + if(hx > hy || ((hx == hy) && (lx > ly))) { // x > y, x -= ulp + if(lx == 0) hx -= 1; + lx -= 1; + } + else { // x < y, x += ulp + lx += 1; + if(lx == 0) hx += 1; + } + } + else { // x < 0 + if(hy >= 0 || hx > hy || ((hx == hy) && (lx > ly))){// x < y, x -= ulp + if(lx == 0) hx -= 1; + lx -= 1; + } + else { // x > y, x += ulp + lx += 1; + if(lx == 0) hx += 1; + } + } + hy = hx & 0x7ff00000; + if(hy >= 0x7ff00000) + return x + x; // overflow + if(hy < 0x00100000) + { // underflow + t = x * x; + if(abs(t - x) > epsilon()) + { // raise underflow flag + GLM_INSERT_WORDS(y, hx, lx); + return y; + } + } + GLM_INSERT_WORDS(x, hx, lx); + return x; + } +}//namespace detail +}//namespace glm + +#if(GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(pop) +#endif + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER float nextFloat(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MAX); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MAX); +# else + return nextafterf(x, FLT_MAX); +# endif + } + + template<> + GLM_FUNC_QUALIFIER double nextFloat(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafter(x, std::numeric_limits::max()); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MAX); +# else + return nextafter(x, DBL_MAX); +# endif + } + + template + GLM_FUNC_QUALIFIER T nextFloat(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'next_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for(int i = 0; i < ULPs; ++i) + temp = nextFloat(temp); + return temp; + } + + GLM_FUNC_QUALIFIER float prevFloat(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MIN); +# else + return nextafterf(x, FLT_MIN); +# endif + } + + GLM_FUNC_QUALIFIER double prevFloat(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return _nextafter(x, DBL_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MIN); +# else + return nextafter(x, DBL_MIN); +# endif + } + + template + GLM_FUNC_QUALIFIER T prevFloat(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'prev_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for(int i = 0; i < ULPs; ++i) + temp = prevFloat(temp); + return temp; + } + + GLM_FUNC_QUALIFIER int floatDistance(float x, float y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + GLM_FUNC_QUALIFIER int64 floatDistance(double x, double y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool1.hpp b/src/other/manifold/glm/glm/ext/vector_bool1.hpp new file mode 100644 index 00000000000..002c3202adf --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool1.hpp @@ -0,0 +1,30 @@ +/// @ref ext_vector_bool1 +/// @file glm/ext/vector_bool1.hpp +/// +/// @defgroup ext_vector_bool1 GLM_EXT_vector_bool1 +/// @ingroup ext +/// +/// Exposes bvec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_bool1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_bool1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_bool1 + /// @{ + + /// 1 components vector of boolean. + typedef vec<1, bool, defaultp> bvec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool1_precision.hpp b/src/other/manifold/glm/glm/ext/vector_bool1_precision.hpp new file mode 100644 index 00000000000..e62d3cfb5fd --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool1_precision.hpp @@ -0,0 +1,34 @@ +/// @ref ext_vector_bool1_precision +/// @file glm/ext/vector_bool1_precision.hpp +/// +/// @defgroup ext_vector_bool1_precision GLM_EXT_vector_bool1_precision +/// @ingroup ext +/// +/// Exposes highp_bvec1, mediump_bvec1 and lowp_bvec1 types. +/// +/// Include to use the features of this extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_bool1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_bool1_precision + /// @{ + + /// 1 component vector of bool values. + typedef vec<1, bool, highp> highp_bvec1; + + /// 1 component vector of bool values. + typedef vec<1, bool, mediump> mediump_bvec1; + + /// 1 component vector of bool values. + typedef vec<1, bool, lowp> lowp_bvec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool2.hpp b/src/other/manifold/glm/glm/ext/vector_bool2.hpp new file mode 100644 index 00000000000..52288b75c69 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, bool, defaultp> bvec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool2_precision.hpp b/src/other/manifold/glm/glm/ext/vector_bool2_precision.hpp new file mode 100644 index 00000000000..43709332c62 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, highp> highp_bvec2; + + /// 2 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, mediump> mediump_bvec2; + + /// 2 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, lowp> lowp_bvec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool3.hpp b/src/other/manifold/glm/glm/ext/vector_bool3.hpp new file mode 100644 index 00000000000..90a0b7ea5ac --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, bool, defaultp> bvec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool3_precision.hpp b/src/other/manifold/glm/glm/ext/vector_bool3_precision.hpp new file mode 100644 index 00000000000..89cd2d3207a --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, highp> highp_bvec3; + + /// 3 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, mediump> mediump_bvec3; + + /// 3 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, lowp> lowp_bvec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool4.hpp b/src/other/manifold/glm/glm/ext/vector_bool4.hpp new file mode 100644 index 00000000000..18aa71bd0f4 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, bool, defaultp> bvec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_bool4_precision.hpp b/src/other/manifold/glm/glm/ext/vector_bool4_precision.hpp new file mode 100644 index 00000000000..79786e54206 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_bool4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool4_precision.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, highp> highp_bvec4; + + /// 4 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, mediump> mediump_bvec4; + + /// 4 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, lowp> lowp_bvec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_common.hpp b/src/other/manifold/glm/glm/ext/vector_common.hpp new file mode 100644 index 00000000000..521ec01e762 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_common.hpp @@ -0,0 +1,204 @@ +/// @ref ext_vector_common +/// @file glm/ext/vector_common.hpp +/// +/// @defgroup ext_vector_common GLM_EXT_vector_common +/// @ingroup ext +/// +/// Exposes min and max functions for 3 to 4 vector parameters. +/// +/// Include to use the features of this extension. +/// +/// @see core_common +/// @see ext_scalar_common + +#pragma once + +// Dependency: +#include "../ext/scalar_common.hpp" +#include "../common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_common + /// @{ + + /// Return the minimum component-wise values of 3 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& a, vec const& b, vec const& c); + + /// Return the minimum component-wise values of 4 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Return the maximum component-wise values of 3 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z); + + /// Return the maximum component-wise values of 4 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max( vec const& x, vec const& y, vec const& z, vec const& w); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& x, T y); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& x, vec const& y); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& a, vec const& b, vec const& c); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, T b); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b, vec const& c); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common + template + GLM_FUNC_DECL vec fclamp(vec const& x, T minVal, T maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common + template + GLM_FUNC_DECL vec fclamp(vec const& x, vec const& minVal, vec const& maxVal); + + /// Simulate GL_CLAMP OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec clamp(vec const& Texcoord); + + /// Simulate GL_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec repeat(vec const& Texcoord); + + /// Simulate GL_MIRRORED_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec mirrorClamp(vec const& Texcoord); + + /// Simulate GL_MIRROR_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec mirrorRepeat(vec const& Texcoord); + + /// @} +}//namespace glm + +#include "vector_common.inl" diff --git a/src/other/manifold/glm/glm/ext/vector_common.inl b/src/other/manifold/glm/glm/ext/vector_common.inl new file mode 100644 index 00000000000..e2747be7b2b --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_common.inl @@ -0,0 +1,129 @@ +#include "../detail/_vectorize.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& x, vec const& y, vec const& z) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'min' only accept floating-point or integer inputs"); + return glm::min(glm::min(x, y), z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& x, vec const& y, vec const& z, vec const& w) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'min' only accept floating-point or integer inputs"); + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'max' only accept floating-point or integer inputs"); + return glm::max(glm::max(x, y), z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z, vec const& w) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'max' only accept floating-point or integer inputs"); + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return detail::functor2::call(fmin, a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return detail::functor2::call(fmin, a, b); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b, vec const& c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return fmin(fmin(a, b), c); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b, vec const& c, vec const& d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return fmin(fmin(a, b), fmin(c, d)); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return detail::functor2::call(fmax, a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return detail::functor2::call(fmax, a, b); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b, vec const& c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return fmax(fmax(a, b), c); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b, vec const& c, vec const& d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return fmax(fmax(a, b), fmax(c, d)); + } + + template + GLM_FUNC_QUALIFIER vec fclamp(vec const& x, T minVal, T maxVal) + { + return fmin(fmax(x, vec(minVal)), vec(maxVal)); + } + + template + GLM_FUNC_QUALIFIER vec fclamp(vec const& x, vec const& minVal, vec const& maxVal) + { + return fmin(fmax(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER vec clamp(vec const& Texcoord) + { + return glm::clamp(Texcoord, vec(0), vec(1)); + } + + template + GLM_FUNC_QUALIFIER vec repeat(vec const& Texcoord) + { + return glm::fract(Texcoord); + } + + template + GLM_FUNC_QUALIFIER vec mirrorClamp(vec const& Texcoord) + { + return glm::fract(glm::abs(Texcoord)); + } + + template + GLM_FUNC_QUALIFIER vec mirrorRepeat(vec const& Texcoord) + { + vec const Abs = glm::abs(Texcoord); + vec const Clamp = glm::mod(glm::floor(Abs), vec(2)); + vec const Floor = glm::floor(Abs); + vec const Rest = Abs - Floor; + vec const Mirror = Clamp + Rest; + return mix(Rest, vec(1) - Rest, glm::greaterThanEqual(Mirror, vec(1))); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double1.hpp b/src/other/manifold/glm/glm/ext/vector_double1.hpp new file mode 100644 index 00000000000..388266774d8 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double1.hpp @@ -0,0 +1,31 @@ +/// @ref ext_vector_double1 +/// @file glm/ext/vector_double1.hpp +/// +/// @defgroup ext_vector_double1 GLM_EXT_vector_double1 +/// @ingroup ext +/// +/// Exposes double-precision floating point vector type with one component. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_double1_precision extension. +/// @see ext_vector_float1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_double1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_double1 + /// @{ + + /// 1 components vector of double-precision floating-point numbers. + typedef vec<1, double, defaultp> dvec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double1_precision.hpp b/src/other/manifold/glm/glm/ext/vector_double1_precision.hpp new file mode 100644 index 00000000000..1d471959548 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double1_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_vector_double1_precision +/// @file glm/ext/vector_double1_precision.hpp +/// +/// @defgroup ext_vector_double1_precision GLM_EXT_vector_double1_precision +/// @ingroup ext +/// +/// Exposes highp_dvec1, mediump_dvec1 and lowp_dvec1 types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_double1 + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_double1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_double1_precision + /// @{ + + /// 1 component vector of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, highp> highp_dvec1; + + /// 1 component vector of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, mediump> mediump_dvec1; + + /// 1 component vector of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, lowp> lowp_dvec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double2.hpp b/src/other/manifold/glm/glm/ext/vector_double2.hpp new file mode 100644 index 00000000000..60e357750b6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, double, defaultp> dvec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double2_precision.hpp b/src/other/manifold/glm/glm/ext/vector_double2_precision.hpp new file mode 100644 index 00000000000..fa53940f6bb --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_double2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, highp> highp_dvec2; + + /// 2 components vector of medium double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, mediump> mediump_dvec2; + + /// 2 components vector of low double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, lowp> lowp_dvec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double3.hpp b/src/other/manifold/glm/glm/ext/vector_double3.hpp new file mode 100644 index 00000000000..6dfe4c675b5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, double, defaultp> dvec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double3_precision.hpp b/src/other/manifold/glm/glm/ext/vector_double3_precision.hpp new file mode 100644 index 00000000000..a8cfa37a8c7 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double3_precision.hpp @@ -0,0 +1,34 @@ +/// @ref core +/// @file glm/ext/vector_double3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, highp> highp_dvec3; + + /// 3 components vector of medium double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, mediump> mediump_dvec3; + + /// 3 components vector of low double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, lowp> lowp_dvec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double4.hpp b/src/other/manifold/glm/glm/ext/vector_double4.hpp new file mode 100644 index 00000000000..87f225f64d4 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, double, defaultp> dvec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_double4_precision.hpp b/src/other/manifold/glm/glm/ext/vector_double4_precision.hpp new file mode 100644 index 00000000000..09cafa1ebaf --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_double4_precision.hpp @@ -0,0 +1,35 @@ +/// @ref core +/// @file glm/ext/vector_double4_precision.hpp + +#pragma once +#include "../detail/setup.hpp" +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, highp> highp_dvec4; + + /// 4 components vector of medium double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, mediump> mediump_dvec4; + + /// 4 components vector of low double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, lowp> lowp_dvec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float1.hpp b/src/other/manifold/glm/glm/ext/vector_float1.hpp new file mode 100644 index 00000000000..28acc2c9ca5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float1.hpp @@ -0,0 +1,31 @@ +/// @ref ext_vector_float1 +/// @file glm/ext/vector_float1.hpp +/// +/// @defgroup ext_vector_float1 GLM_EXT_vector_float1 +/// @ingroup ext +/// +/// Exposes single-precision floating point vector type with one component. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_float1_precision extension. +/// @see ext_vector_double1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_float1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_float1 + /// @{ + + /// 1 components vector of single-precision floating-point numbers. + typedef vec<1, float, defaultp> vec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float1_precision.hpp b/src/other/manifold/glm/glm/ext/vector_float1_precision.hpp new file mode 100644 index 00000000000..6e8dad8d17c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float1_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_vector_float1_precision +/// @file glm/ext/vector_float1_precision.hpp +/// +/// @defgroup ext_vector_float1_precision GLM_EXT_vector_float1_precision +/// @ingroup ext +/// +/// Exposes highp_vec1, mediump_vec1 and lowp_vec1 types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_float1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_float1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_float1_precision + /// @{ + + /// 1 component vector of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, highp> highp_vec1; + + /// 1 component vector of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, mediump> mediump_vec1; + + /// 1 component vector of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, lowp> lowp_vec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float2.hpp b/src/other/manifold/glm/glm/ext/vector_float2.hpp new file mode 100644 index 00000000000..d31545dcc96 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, float, defaultp> vec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float2_precision.hpp b/src/other/manifold/glm/glm/ext/vector_float2_precision.hpp new file mode 100644 index 00000000000..23c0820d0ae --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, highp> highp_vec2; + + /// 2 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, mediump> mediump_vec2; + + /// 2 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, lowp> lowp_vec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float3.hpp b/src/other/manifold/glm/glm/ext/vector_float3.hpp new file mode 100644 index 00000000000..cd79a62004e --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, float, defaultp> vec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float3_precision.hpp b/src/other/manifold/glm/glm/ext/vector_float3_precision.hpp new file mode 100644 index 00000000000..be640b53168 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, highp> highp_vec3; + + /// 3 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, mediump> mediump_vec3; + + /// 3 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, lowp> lowp_vec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float4.hpp b/src/other/manifold/glm/glm/ext/vector_float4.hpp new file mode 100644 index 00000000000..d84adcc22fd --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, float, defaultp> vec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_float4_precision.hpp b/src/other/manifold/glm/glm/ext/vector_float4_precision.hpp new file mode 100644 index 00000000000..aede83882e5 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_float4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float4_precision.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, highp> highp_vec4; + + /// 4 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, mediump> mediump_vec4; + + /// 4 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, lowp> lowp_vec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int1.hpp b/src/other/manifold/glm/glm/ext/vector_int1.hpp new file mode 100644 index 00000000000..dc8603891a9 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int1.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_int1 +/// @file glm/ext/vector_int1.hpp +/// +/// @defgroup ext_vector_int1 GLM_EXT_vector_int1 +/// @ingroup ext +/// +/// Exposes ivec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_uint1 extension. +/// @see ext_vector_int1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int1 + /// @{ + + /// 1 component vector of signed integer numbers. + typedef vec<1, int, defaultp> ivec1; + + /// @} +}//namespace glm + diff --git a/src/other/manifold/glm/glm/ext/vector_int1_sized.hpp b/src/other/manifold/glm/glm/ext/vector_int1_sized.hpp new file mode 100644 index 00000000000..de0d4cf82e6 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int1_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int1_sized +/// @file glm/ext/vector_int1_sized.hpp +/// +/// @defgroup ext_vector_int1_sized GLM_EXT_vector_int1_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint1_sized + +#pragma once + +#include "../ext/vector_int1.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int1_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int1_sized + /// @{ + + /// 8 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int8, defaultp> i8vec1; + + /// 16 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int16, defaultp> i16vec1; + + /// 32 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int32, defaultp> i32vec1; + + /// 64 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int64, defaultp> i64vec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int2.hpp b/src/other/manifold/glm/glm/ext/vector_int2.hpp new file mode 100644 index 00000000000..aef803e91b7 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, int, defaultp> ivec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int2_sized.hpp b/src/other/manifold/glm/glm/ext/vector_int2_sized.hpp new file mode 100644 index 00000000000..1fd57eef310 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int2_sized +/// @file glm/ext/vector_int2_sized.hpp +/// +/// @defgroup ext_vector_int2_sized GLM_EXT_vector_int2_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 2 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint2_sized + +#pragma once + +#include "../ext/vector_int2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int2_sized + /// @{ + + /// 8 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int8, defaultp> i8vec2; + + /// 16 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int16, defaultp> i16vec2; + + /// 32 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int32, defaultp> i32vec2; + + /// 64 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int64, defaultp> i64vec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int3.hpp b/src/other/manifold/glm/glm/ext/vector_int3.hpp new file mode 100644 index 00000000000..4767e61e88c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, int, defaultp> ivec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int3_sized.hpp b/src/other/manifold/glm/glm/ext/vector_int3_sized.hpp new file mode 100644 index 00000000000..085a3febbff --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int3_sized +/// @file glm/ext/vector_int3_sized.hpp +/// +/// @defgroup ext_vector_int3_sized GLM_EXT_vector_int3_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 3 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint3_sized + +#pragma once + +#include "../ext/vector_int3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int3_sized + /// @{ + + /// 8 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int8, defaultp> i8vec3; + + /// 16 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int16, defaultp> i16vec3; + + /// 32 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int32, defaultp> i32vec3; + + /// 64 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int64, defaultp> i64vec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int4.hpp b/src/other/manifold/glm/glm/ext/vector_int4.hpp new file mode 100644 index 00000000000..bb23adf706c --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, int, defaultp> ivec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_int4_sized.hpp b/src/other/manifold/glm/glm/ext/vector_int4_sized.hpp new file mode 100644 index 00000000000..c63d46540b3 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_int4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int4_sized +/// @file glm/ext/vector_int4_sized.hpp +/// +/// @defgroup ext_vector_int4_sized GLM_EXT_vector_int4_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 4 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint4_sized + +#pragma once + +#include "../ext/vector_int4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int4_sized + /// @{ + + /// 8 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int8, defaultp> i8vec4; + + /// 16 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int16, defaultp> i16vec4; + + /// 32 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int32, defaultp> i32vec4; + + /// 64 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int64, defaultp> i64vec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_integer.hpp b/src/other/manifold/glm/glm/ext/vector_integer.hpp new file mode 100644 index 00000000000..1304dd8d660 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_integer.hpp @@ -0,0 +1,149 @@ +/// @ref ext_vector_integer +/// @file glm/ext/vector_integer.hpp +/// +/// @see core (dependence) +/// @see ext_vector_integer (dependence) +/// +/// @defgroup ext_vector_integer GLM_EXT_vector_integer +/// @ingroup ext +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_integer + /// @{ + + /// Return true if the value is a power of two number. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevPowerOfTwo(vec const& v); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isMultiple(vec const& v, T Multiple); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isMultiple(vec const& v, vec const& Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextMultiple(vec const& v, T Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevMultiple(vec const& v, T Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevMultiple(vec const& v, vec const& Multiple); + + /// Returns the bit number of the Nth significant bit set to + /// 1 in the binary representation of value. + /// If value bitcount is less than the Nth significant bit, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec findNSB(vec const& Source, vec SignificantBitCount); + + /// @} +} //namespace glm + +#include "vector_integer.inl" diff --git a/src/other/manifold/glm/glm/ext/vector_integer.inl b/src/other/manifold/glm/glm/ext/vector_integer.inl new file mode 100644 index 00000000000..939ff5e2aca --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_integer.inl @@ -0,0 +1,85 @@ +#include "scalar_integer.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec isPowerOfTwo(vec const& Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isPowerOfTwo' only accept integer inputs"); + + vec const Result(abs(Value)); + return equal(Result & (Result - vec(1)), vec(0)); + } + + template + GLM_FUNC_QUALIFIER vec nextPowerOfTwo(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextPowerOfTwo' only accept integer inputs"); + + return detail::compute_ceilPowerOfTwo::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER vec prevPowerOfTwo(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevPowerOfTwo' only accept integer inputs"); + + return detail::functor1::call(prevPowerOfTwo, v); + } + + template + GLM_FUNC_QUALIFIER vec isMultiple(vec const& Value, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return (Value % Multiple) == vec(0); + } + + template + GLM_FUNC_QUALIFIER vec isMultiple(vec const& Value, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return (Value % Multiple) == vec(0); + } + + template + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::functor2::call(nextMultiple, Source, vec(Multiple)); + } + + template + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::functor2::call(nextMultiple, Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::functor2::call(prevMultiple, Source, vec(Multiple)); + } + + template + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::functor2::call(prevMultiple, Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec findNSB(vec const& Source, vec SignificantBitCount) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findNSB' only accept integer inputs"); + + return detail::functor2_vec_int::call(findNSB, Source, SignificantBitCount); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_packing.hpp b/src/other/manifold/glm/glm/ext/vector_packing.hpp new file mode 100644 index 00000000000..76e5d0cc6c2 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_packing.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_packing +/// @file glm/ext/vector_packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_vector_packing GLM_EXT_vector_packing +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert vectors to packed +/// formats. + +#pragma once + +// Dependency: +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_packing + /// @{ + + + /// @} +}// namespace glm + +#include "vector_packing.inl" diff --git a/src/other/manifold/glm/glm/ext/vector_packing.inl b/src/other/manifold/glm/glm/ext/vector_packing.inl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/other/manifold/glm/glm/ext/vector_relational.hpp b/src/other/manifold/glm/glm/ext/vector_relational.hpp new file mode 100644 index 00000000000..1c2367dc023 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_relational.hpp @@ -0,0 +1,107 @@ +/// @ref ext_vector_relational +/// @file glm/ext/vector_relational.hpp +/// +/// @see core (dependence) +/// @see ext_scalar_integer (dependence) +/// +/// @defgroup ext_vector_relational GLM_EXT_vector_relational +/// @ingroup ext +/// +/// Exposes comparison functions for vector types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_scalar_relational +/// @see ext_matrix_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_relational + /// @{ + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& epsilon); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& ULPs); + + /// @} +}//namespace glm + +#include "vector_relational.inl" diff --git a/src/other/manifold/glm/glm/ext/vector_relational.inl b/src/other/manifold/glm/glm/ext/vector_relational.inl new file mode 100644 index 00000000000..7a39ab50897 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_relational.inl @@ -0,0 +1,75 @@ +#include "../vector_relational.hpp" +#include "../common.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/type_float.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T Epsilon) + { + return equal(x, y, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& Epsilon) + { + return lessThanEqual(abs(x - y), Epsilon); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T Epsilon) + { + return notEqual(x, y, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& Epsilon) + { + return greaterThan(abs(x - y), Epsilon); + } + + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, int MaxULPs) + { + return equal(x, y, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& MaxULPs) + { + vec Result(false); + for(length_t i = 0; i < L; ++i) + { + detail::float_t const a(x[i]); + detail::float_t const b(y[i]); + + // Different signs means they do not match. + if(a.negative() != b.negative()) + { + // Check for equality to make sure +0==-0 + Result[i] = a.mantissa() == b.mantissa() && a.exponent() == b.exponent(); + } + else + { + // Find the difference in ULPs. + typename detail::float_t::int_type const DiffULPs = abs(a.i - b.i); + Result[i] = DiffULPs <= MaxULPs[i]; + } + } + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, int MaxULPs) + { + return notEqual(x, y, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& MaxULPs) + { + return not_(equal(x, y, MaxULPs)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint1.hpp b/src/other/manifold/glm/glm/ext/vector_uint1.hpp new file mode 100644 index 00000000000..eb8a7049761 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint1.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_uint1 +/// @file glm/ext/vector_uint1.hpp +/// +/// @defgroup ext_vector_uint1 GLM_EXT_vector_uint1 +/// @ingroup ext +/// +/// Exposes uvec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_int1 extension. +/// @see ext_vector_uint1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint1 + /// @{ + + /// 1 component vector of unsigned integer numbers. + typedef vec<1, unsigned int, defaultp> uvec1; + + /// @} +}//namespace glm + diff --git a/src/other/manifold/glm/glm/ext/vector_uint1_sized.hpp b/src/other/manifold/glm/glm/ext/vector_uint1_sized.hpp new file mode 100644 index 00000000000..2a938bbaf61 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint1_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint1_sized +/// @file glm/ext/vector_uint1_sized.hpp +/// +/// @defgroup ext_vector_uint1_sized GLM_EXT_vector_uint1_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int1_sized + +#pragma once + +#include "../ext/vector_uint1.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint1_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint1_sized + /// @{ + + /// 8 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint8, defaultp> u8vec1; + + /// 16 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint16, defaultp> u16vec1; + + /// 32 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint32, defaultp> u32vec1; + + /// 64 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint64, defaultp> u64vec1; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint2.hpp b/src/other/manifold/glm/glm/ext/vector_uint2.hpp new file mode 100644 index 00000000000..03c00f5ff58 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, unsigned int, defaultp> uvec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint2_sized.hpp b/src/other/manifold/glm/glm/ext/vector_uint2_sized.hpp new file mode 100644 index 00000000000..620fdc6ece3 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint2_sized +/// @file glm/ext/vector_uint2_sized.hpp +/// +/// @defgroup ext_vector_uint2_sized GLM_EXT_vector_uint2_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 2 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int2_sized + +#pragma once + +#include "../ext/vector_uint2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint2_sized + /// @{ + + /// 8 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint8, defaultp> u8vec2; + + /// 16 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint16, defaultp> u16vec2; + + /// 32 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint32, defaultp> u32vec2; + + /// 64 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint64, defaultp> u64vec2; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint3.hpp b/src/other/manifold/glm/glm/ext/vector_uint3.hpp new file mode 100644 index 00000000000..f5b41c40882 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, unsigned int, defaultp> uvec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint3_sized.hpp b/src/other/manifold/glm/glm/ext/vector_uint3_sized.hpp new file mode 100644 index 00000000000..6f96b98e276 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint3_sized +/// @file glm/ext/vector_uint3_sized.hpp +/// +/// @defgroup ext_vector_uint3_sized GLM_EXT_vector_uint3_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 3 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int3_sized + +#pragma once + +#include "../ext/vector_uint3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint3_sized + /// @{ + + /// 8 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint8, defaultp> u8vec3; + + /// 16 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint16, defaultp> u16vec3; + + /// 32 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint32, defaultp> u32vec3; + + /// 64 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint64, defaultp> u64vec3; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint4.hpp b/src/other/manifold/glm/glm/ext/vector_uint4.hpp new file mode 100644 index 00000000000..32ced58a8f0 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, unsigned int, defaultp> uvec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_uint4_sized.hpp b/src/other/manifold/glm/glm/ext/vector_uint4_sized.hpp new file mode 100644 index 00000000000..da992ea2da8 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_uint4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint4_sized +/// @file glm/ext/vector_uint4_sized.hpp +/// +/// @defgroup ext_vector_uint4_sized GLM_EXT_vector_uint4_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 4 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int4_sized + +#pragma once + +#include "../ext/vector_uint4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint4_sized + /// @{ + + /// 8 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint8, defaultp> u8vec4; + + /// 16 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint16, defaultp> u16vec4; + + /// 32 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint32, defaultp> u32vec4; + + /// 64 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint64, defaultp> u64vec4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/ext/vector_ulp.hpp b/src/other/manifold/glm/glm/ext/vector_ulp.hpp new file mode 100644 index 00000000000..6210396b87f --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_ulp.hpp @@ -0,0 +1,109 @@ +/// @ref ext_vector_ulp +/// @file glm/ext/vector_ulp.hpp +/// +/// @defgroup ext_vector_ulp GLM_EXT_vector_ulp +/// @ingroup ext +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_ulp +/// @see ext_scalar_relational +/// @see ext_vector_relational + +#pragma once + +// Dependencies +#include "../ext/scalar_ulp.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x, int ULPs); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x, vec const& ULPs); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x, vec const& ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec floatDistance(vec const& x, vec const& y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec floatDistance(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "vector_ulp.inl" diff --git a/src/other/manifold/glm/glm/ext/vector_ulp.inl b/src/other/manifold/glm/glm/ext/vector_ulp.inl new file mode 100644 index 00000000000..91565ce5107 --- /dev/null +++ b/src/other/manifold/glm/glm/ext/vector_ulp.inl @@ -0,0 +1,74 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x, int ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x, vec const& ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x, int ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x, vec const& ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec floatDistance(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = floatDistance(x[i], y[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec floatDistance(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = floatDistance(x[i], y[i]); + return Result; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/fwd.hpp b/src/other/manifold/glm/glm/fwd.hpp new file mode 100644 index 00000000000..89177f46ca7 --- /dev/null +++ b/src/other/manifold/glm/glm/fwd.hpp @@ -0,0 +1,1233 @@ +#pragma once + +#include "detail/qualifier.hpp" + +namespace glm +{ +#if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::int8_t int8; + typedef std::int16_t int16; + typedef std::int32_t int32; + typedef std::int64_t int64; + + typedef std::uint8_t uint8; + typedef std::uint16_t uint16; + typedef std::uint32_t uint32; + typedef std::uint64_t uint64; +#else + typedef signed char int8; + typedef signed short int16; + typedef signed int int32; + typedef detail::int64 int64; + + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + typedef detail::uint64 uint64; +#endif + + // Scalar int + + typedef int8 lowp_i8; + typedef int8 mediump_i8; + typedef int8 highp_i8; + typedef int8 i8; + + typedef int8 lowp_int8; + typedef int8 mediump_int8; + typedef int8 highp_int8; + + typedef int8 lowp_int8_t; + typedef int8 mediump_int8_t; + typedef int8 highp_int8_t; + typedef int8 int8_t; + + typedef int16 lowp_i16; + typedef int16 mediump_i16; + typedef int16 highp_i16; + typedef int16 i16; + + typedef int16 lowp_int16; + typedef int16 mediump_int16; + typedef int16 highp_int16; + + typedef int16 lowp_int16_t; + typedef int16 mediump_int16_t; + typedef int16 highp_int16_t; + typedef int16 int16_t; + + typedef int32 lowp_i32; + typedef int32 mediump_i32; + typedef int32 highp_i32; + typedef int32 i32; + + typedef int32 lowp_int32; + typedef int32 mediump_int32; + typedef int32 highp_int32; + + typedef int32 lowp_int32_t; + typedef int32 mediump_int32_t; + typedef int32 highp_int32_t; + typedef int32 int32_t; + + typedef int64 lowp_i64; + typedef int64 mediump_i64; + typedef int64 highp_i64; + typedef int64 i64; + + typedef int64 lowp_int64; + typedef int64 mediump_int64; + typedef int64 highp_int64; + + typedef int64 lowp_int64_t; + typedef int64 mediump_int64_t; + typedef int64 highp_int64_t; + typedef int64 int64_t; + + // Scalar uint + + typedef unsigned int uint; + + typedef uint8 lowp_u8; + typedef uint8 mediump_u8; + typedef uint8 highp_u8; + typedef uint8 u8; + + typedef uint8 lowp_uint8; + typedef uint8 mediump_uint8; + typedef uint8 highp_uint8; + + typedef uint8 lowp_uint8_t; + typedef uint8 mediump_uint8_t; + typedef uint8 highp_uint8_t; + typedef uint8 uint8_t; + + typedef uint16 lowp_u16; + typedef uint16 mediump_u16; + typedef uint16 highp_u16; + typedef uint16 u16; + + typedef uint16 lowp_uint16; + typedef uint16 mediump_uint16; + typedef uint16 highp_uint16; + + typedef uint16 lowp_uint16_t; + typedef uint16 mediump_uint16_t; + typedef uint16 highp_uint16_t; + typedef uint16 uint16_t; + + typedef uint32 lowp_u32; + typedef uint32 mediump_u32; + typedef uint32 highp_u32; + typedef uint32 u32; + + typedef uint32 lowp_uint32; + typedef uint32 mediump_uint32; + typedef uint32 highp_uint32; + + typedef uint32 lowp_uint32_t; + typedef uint32 mediump_uint32_t; + typedef uint32 highp_uint32_t; + typedef uint32 uint32_t; + + typedef uint64 lowp_u64; + typedef uint64 mediump_u64; + typedef uint64 highp_u64; + typedef uint64 u64; + + typedef uint64 lowp_uint64; + typedef uint64 mediump_uint64; + typedef uint64 highp_uint64; + + typedef uint64 lowp_uint64_t; + typedef uint64 mediump_uint64_t; + typedef uint64 highp_uint64_t; + typedef uint64 uint64_t; + + // Scalar float + + typedef float lowp_f32; + typedef float mediump_f32; + typedef float highp_f32; + typedef float f32; + + typedef float lowp_float32; + typedef float mediump_float32; + typedef float highp_float32; + typedef float float32; + + typedef float lowp_float32_t; + typedef float mediump_float32_t; + typedef float highp_float32_t; + typedef float float32_t; + + + typedef double lowp_f64; + typedef double mediump_f64; + typedef double highp_f64; + typedef double f64; + + typedef double lowp_float64; + typedef double mediump_float64; + typedef double highp_float64; + typedef double float64; + + typedef double lowp_float64_t; + typedef double mediump_float64_t; + typedef double highp_float64_t; + typedef double float64_t; + + // Vector bool + + typedef vec<1, bool, lowp> lowp_bvec1; + typedef vec<2, bool, lowp> lowp_bvec2; + typedef vec<3, bool, lowp> lowp_bvec3; + typedef vec<4, bool, lowp> lowp_bvec4; + + typedef vec<1, bool, mediump> mediump_bvec1; + typedef vec<2, bool, mediump> mediump_bvec2; + typedef vec<3, bool, mediump> mediump_bvec3; + typedef vec<4, bool, mediump> mediump_bvec4; + + typedef vec<1, bool, highp> highp_bvec1; + typedef vec<2, bool, highp> highp_bvec2; + typedef vec<3, bool, highp> highp_bvec3; + typedef vec<4, bool, highp> highp_bvec4; + + typedef vec<1, bool, defaultp> bvec1; + typedef vec<2, bool, defaultp> bvec2; + typedef vec<3, bool, defaultp> bvec3; + typedef vec<4, bool, defaultp> bvec4; + + // Vector int + + typedef vec<1, int, lowp> lowp_ivec1; + typedef vec<2, int, lowp> lowp_ivec2; + typedef vec<3, int, lowp> lowp_ivec3; + typedef vec<4, int, lowp> lowp_ivec4; + + typedef vec<1, int, mediump> mediump_ivec1; + typedef vec<2, int, mediump> mediump_ivec2; + typedef vec<3, int, mediump> mediump_ivec3; + typedef vec<4, int, mediump> mediump_ivec4; + + typedef vec<1, int, highp> highp_ivec1; + typedef vec<2, int, highp> highp_ivec2; + typedef vec<3, int, highp> highp_ivec3; + typedef vec<4, int, highp> highp_ivec4; + + typedef vec<1, int, defaultp> ivec1; + typedef vec<2, int, defaultp> ivec2; + typedef vec<3, int, defaultp> ivec3; + typedef vec<4, int, defaultp> ivec4; + + typedef vec<1, i8, lowp> lowp_i8vec1; + typedef vec<2, i8, lowp> lowp_i8vec2; + typedef vec<3, i8, lowp> lowp_i8vec3; + typedef vec<4, i8, lowp> lowp_i8vec4; + + typedef vec<1, i8, mediump> mediump_i8vec1; + typedef vec<2, i8, mediump> mediump_i8vec2; + typedef vec<3, i8, mediump> mediump_i8vec3; + typedef vec<4, i8, mediump> mediump_i8vec4; + + typedef vec<1, i8, highp> highp_i8vec1; + typedef vec<2, i8, highp> highp_i8vec2; + typedef vec<3, i8, highp> highp_i8vec3; + typedef vec<4, i8, highp> highp_i8vec4; + + typedef vec<1, i8, defaultp> i8vec1; + typedef vec<2, i8, defaultp> i8vec2; + typedef vec<3, i8, defaultp> i8vec3; + typedef vec<4, i8, defaultp> i8vec4; + + typedef vec<1, i16, lowp> lowp_i16vec1; + typedef vec<2, i16, lowp> lowp_i16vec2; + typedef vec<3, i16, lowp> lowp_i16vec3; + typedef vec<4, i16, lowp> lowp_i16vec4; + + typedef vec<1, i16, mediump> mediump_i16vec1; + typedef vec<2, i16, mediump> mediump_i16vec2; + typedef vec<3, i16, mediump> mediump_i16vec3; + typedef vec<4, i16, mediump> mediump_i16vec4; + + typedef vec<1, i16, highp> highp_i16vec1; + typedef vec<2, i16, highp> highp_i16vec2; + typedef vec<3, i16, highp> highp_i16vec3; + typedef vec<4, i16, highp> highp_i16vec4; + + typedef vec<1, i16, defaultp> i16vec1; + typedef vec<2, i16, defaultp> i16vec2; + typedef vec<3, i16, defaultp> i16vec3; + typedef vec<4, i16, defaultp> i16vec4; + + typedef vec<1, i32, lowp> lowp_i32vec1; + typedef vec<2, i32, lowp> lowp_i32vec2; + typedef vec<3, i32, lowp> lowp_i32vec3; + typedef vec<4, i32, lowp> lowp_i32vec4; + + typedef vec<1, i32, mediump> mediump_i32vec1; + typedef vec<2, i32, mediump> mediump_i32vec2; + typedef vec<3, i32, mediump> mediump_i32vec3; + typedef vec<4, i32, mediump> mediump_i32vec4; + + typedef vec<1, i32, highp> highp_i32vec1; + typedef vec<2, i32, highp> highp_i32vec2; + typedef vec<3, i32, highp> highp_i32vec3; + typedef vec<4, i32, highp> highp_i32vec4; + + typedef vec<1, i32, defaultp> i32vec1; + typedef vec<2, i32, defaultp> i32vec2; + typedef vec<3, i32, defaultp> i32vec3; + typedef vec<4, i32, defaultp> i32vec4; + + typedef vec<1, i64, lowp> lowp_i64vec1; + typedef vec<2, i64, lowp> lowp_i64vec2; + typedef vec<3, i64, lowp> lowp_i64vec3; + typedef vec<4, i64, lowp> lowp_i64vec4; + + typedef vec<1, i64, mediump> mediump_i64vec1; + typedef vec<2, i64, mediump> mediump_i64vec2; + typedef vec<3, i64, mediump> mediump_i64vec3; + typedef vec<4, i64, mediump> mediump_i64vec4; + + typedef vec<1, i64, highp> highp_i64vec1; + typedef vec<2, i64, highp> highp_i64vec2; + typedef vec<3, i64, highp> highp_i64vec3; + typedef vec<4, i64, highp> highp_i64vec4; + + typedef vec<1, i64, defaultp> i64vec1; + typedef vec<2, i64, defaultp> i64vec2; + typedef vec<3, i64, defaultp> i64vec3; + typedef vec<4, i64, defaultp> i64vec4; + + // Vector uint + + typedef vec<1, uint, lowp> lowp_uvec1; + typedef vec<2, uint, lowp> lowp_uvec2; + typedef vec<3, uint, lowp> lowp_uvec3; + typedef vec<4, uint, lowp> lowp_uvec4; + + typedef vec<1, uint, mediump> mediump_uvec1; + typedef vec<2, uint, mediump> mediump_uvec2; + typedef vec<3, uint, mediump> mediump_uvec3; + typedef vec<4, uint, mediump> mediump_uvec4; + + typedef vec<1, uint, highp> highp_uvec1; + typedef vec<2, uint, highp> highp_uvec2; + typedef vec<3, uint, highp> highp_uvec3; + typedef vec<4, uint, highp> highp_uvec4; + + typedef vec<1, uint, defaultp> uvec1; + typedef vec<2, uint, defaultp> uvec2; + typedef vec<3, uint, defaultp> uvec3; + typedef vec<4, uint, defaultp> uvec4; + + typedef vec<1, u8, lowp> lowp_u8vec1; + typedef vec<2, u8, lowp> lowp_u8vec2; + typedef vec<3, u8, lowp> lowp_u8vec3; + typedef vec<4, u8, lowp> lowp_u8vec4; + + typedef vec<1, u8, mediump> mediump_u8vec1; + typedef vec<2, u8, mediump> mediump_u8vec2; + typedef vec<3, u8, mediump> mediump_u8vec3; + typedef vec<4, u8, mediump> mediump_u8vec4; + + typedef vec<1, u8, highp> highp_u8vec1; + typedef vec<2, u8, highp> highp_u8vec2; + typedef vec<3, u8, highp> highp_u8vec3; + typedef vec<4, u8, highp> highp_u8vec4; + + typedef vec<1, u8, defaultp> u8vec1; + typedef vec<2, u8, defaultp> u8vec2; + typedef vec<3, u8, defaultp> u8vec3; + typedef vec<4, u8, defaultp> u8vec4; + + typedef vec<1, u16, lowp> lowp_u16vec1; + typedef vec<2, u16, lowp> lowp_u16vec2; + typedef vec<3, u16, lowp> lowp_u16vec3; + typedef vec<4, u16, lowp> lowp_u16vec4; + + typedef vec<1, u16, mediump> mediump_u16vec1; + typedef vec<2, u16, mediump> mediump_u16vec2; + typedef vec<3, u16, mediump> mediump_u16vec3; + typedef vec<4, u16, mediump> mediump_u16vec4; + + typedef vec<1, u16, highp> highp_u16vec1; + typedef vec<2, u16, highp> highp_u16vec2; + typedef vec<3, u16, highp> highp_u16vec3; + typedef vec<4, u16, highp> highp_u16vec4; + + typedef vec<1, u16, defaultp> u16vec1; + typedef vec<2, u16, defaultp> u16vec2; + typedef vec<3, u16, defaultp> u16vec3; + typedef vec<4, u16, defaultp> u16vec4; + + typedef vec<1, u32, lowp> lowp_u32vec1; + typedef vec<2, u32, lowp> lowp_u32vec2; + typedef vec<3, u32, lowp> lowp_u32vec3; + typedef vec<4, u32, lowp> lowp_u32vec4; + + typedef vec<1, u32, mediump> mediump_u32vec1; + typedef vec<2, u32, mediump> mediump_u32vec2; + typedef vec<3, u32, mediump> mediump_u32vec3; + typedef vec<4, u32, mediump> mediump_u32vec4; + + typedef vec<1, u32, highp> highp_u32vec1; + typedef vec<2, u32, highp> highp_u32vec2; + typedef vec<3, u32, highp> highp_u32vec3; + typedef vec<4, u32, highp> highp_u32vec4; + + typedef vec<1, u32, defaultp> u32vec1; + typedef vec<2, u32, defaultp> u32vec2; + typedef vec<3, u32, defaultp> u32vec3; + typedef vec<4, u32, defaultp> u32vec4; + + typedef vec<1, u64, lowp> lowp_u64vec1; + typedef vec<2, u64, lowp> lowp_u64vec2; + typedef vec<3, u64, lowp> lowp_u64vec3; + typedef vec<4, u64, lowp> lowp_u64vec4; + + typedef vec<1, u64, mediump> mediump_u64vec1; + typedef vec<2, u64, mediump> mediump_u64vec2; + typedef vec<3, u64, mediump> mediump_u64vec3; + typedef vec<4, u64, mediump> mediump_u64vec4; + + typedef vec<1, u64, highp> highp_u64vec1; + typedef vec<2, u64, highp> highp_u64vec2; + typedef vec<3, u64, highp> highp_u64vec3; + typedef vec<4, u64, highp> highp_u64vec4; + + typedef vec<1, u64, defaultp> u64vec1; + typedef vec<2, u64, defaultp> u64vec2; + typedef vec<3, u64, defaultp> u64vec3; + typedef vec<4, u64, defaultp> u64vec4; + + // Vector float + + typedef vec<1, float, lowp> lowp_vec1; + typedef vec<2, float, lowp> lowp_vec2; + typedef vec<3, float, lowp> lowp_vec3; + typedef vec<4, float, lowp> lowp_vec4; + + typedef vec<1, float, mediump> mediump_vec1; + typedef vec<2, float, mediump> mediump_vec2; + typedef vec<3, float, mediump> mediump_vec3; + typedef vec<4, float, mediump> mediump_vec4; + + typedef vec<1, float, highp> highp_vec1; + typedef vec<2, float, highp> highp_vec2; + typedef vec<3, float, highp> highp_vec3; + typedef vec<4, float, highp> highp_vec4; + + typedef vec<1, float, defaultp> vec1; + typedef vec<2, float, defaultp> vec2; + typedef vec<3, float, defaultp> vec3; + typedef vec<4, float, defaultp> vec4; + + typedef vec<1, float, lowp> lowp_fvec1; + typedef vec<2, float, lowp> lowp_fvec2; + typedef vec<3, float, lowp> lowp_fvec3; + typedef vec<4, float, lowp> lowp_fvec4; + + typedef vec<1, float, mediump> mediump_fvec1; + typedef vec<2, float, mediump> mediump_fvec2; + typedef vec<3, float, mediump> mediump_fvec3; + typedef vec<4, float, mediump> mediump_fvec4; + + typedef vec<1, float, highp> highp_fvec1; + typedef vec<2, float, highp> highp_fvec2; + typedef vec<3, float, highp> highp_fvec3; + typedef vec<4, float, highp> highp_fvec4; + + typedef vec<1, f32, defaultp> fvec1; + typedef vec<2, f32, defaultp> fvec2; + typedef vec<3, f32, defaultp> fvec3; + typedef vec<4, f32, defaultp> fvec4; + + typedef vec<1, f32, lowp> lowp_f32vec1; + typedef vec<2, f32, lowp> lowp_f32vec2; + typedef vec<3, f32, lowp> lowp_f32vec3; + typedef vec<4, f32, lowp> lowp_f32vec4; + + typedef vec<1, f32, mediump> mediump_f32vec1; + typedef vec<2, f32, mediump> mediump_f32vec2; + typedef vec<3, f32, mediump> mediump_f32vec3; + typedef vec<4, f32, mediump> mediump_f32vec4; + + typedef vec<1, f32, highp> highp_f32vec1; + typedef vec<2, f32, highp> highp_f32vec2; + typedef vec<3, f32, highp> highp_f32vec3; + typedef vec<4, f32, highp> highp_f32vec4; + + typedef vec<1, f32, defaultp> f32vec1; + typedef vec<2, f32, defaultp> f32vec2; + typedef vec<3, f32, defaultp> f32vec3; + typedef vec<4, f32, defaultp> f32vec4; + + typedef vec<1, f64, lowp> lowp_dvec1; + typedef vec<2, f64, lowp> lowp_dvec2; + typedef vec<3, f64, lowp> lowp_dvec3; + typedef vec<4, f64, lowp> lowp_dvec4; + + typedef vec<1, f64, mediump> mediump_dvec1; + typedef vec<2, f64, mediump> mediump_dvec2; + typedef vec<3, f64, mediump> mediump_dvec3; + typedef vec<4, f64, mediump> mediump_dvec4; + + typedef vec<1, f64, highp> highp_dvec1; + typedef vec<2, f64, highp> highp_dvec2; + typedef vec<3, f64, highp> highp_dvec3; + typedef vec<4, f64, highp> highp_dvec4; + + typedef vec<1, f64, defaultp> dvec1; + typedef vec<2, f64, defaultp> dvec2; + typedef vec<3, f64, defaultp> dvec3; + typedef vec<4, f64, defaultp> dvec4; + + typedef vec<1, f64, lowp> lowp_f64vec1; + typedef vec<2, f64, lowp> lowp_f64vec2; + typedef vec<3, f64, lowp> lowp_f64vec3; + typedef vec<4, f64, lowp> lowp_f64vec4; + + typedef vec<1, f64, mediump> mediump_f64vec1; + typedef vec<2, f64, mediump> mediump_f64vec2; + typedef vec<3, f64, mediump> mediump_f64vec3; + typedef vec<4, f64, mediump> mediump_f64vec4; + + typedef vec<1, f64, highp> highp_f64vec1; + typedef vec<2, f64, highp> highp_f64vec2; + typedef vec<3, f64, highp> highp_f64vec3; + typedef vec<4, f64, highp> highp_f64vec4; + + typedef vec<1, f64, defaultp> f64vec1; + typedef vec<2, f64, defaultp> f64vec2; + typedef vec<3, f64, defaultp> f64vec3; + typedef vec<4, f64, defaultp> f64vec4; + + // Matrix NxN + + typedef mat<2, 2, f32, lowp> lowp_mat2; + typedef mat<3, 3, f32, lowp> lowp_mat3; + typedef mat<4, 4, f32, lowp> lowp_mat4; + + typedef mat<2, 2, f32, mediump> mediump_mat2; + typedef mat<3, 3, f32, mediump> mediump_mat3; + typedef mat<4, 4, f32, mediump> mediump_mat4; + + typedef mat<2, 2, f32, highp> highp_mat2; + typedef mat<3, 3, f32, highp> highp_mat3; + typedef mat<4, 4, f32, highp> highp_mat4; + + typedef mat<2, 2, f32, defaultp> mat2; + typedef mat<3, 3, f32, defaultp> mat3; + typedef mat<4, 4, f32, defaultp> mat4; + + typedef mat<2, 2, f32, lowp> lowp_fmat2; + typedef mat<3, 3, f32, lowp> lowp_fmat3; + typedef mat<4, 4, f32, lowp> lowp_fmat4; + + typedef mat<2, 2, f32, mediump> mediump_fmat2; + typedef mat<3, 3, f32, mediump> mediump_fmat3; + typedef mat<4, 4, f32, mediump> mediump_fmat4; + + typedef mat<2, 2, f32, highp> highp_fmat2; + typedef mat<3, 3, f32, highp> highp_fmat3; + typedef mat<4, 4, f32, highp> highp_fmat4; + + typedef mat<2, 2, f32, defaultp> fmat2; + typedef mat<3, 3, f32, defaultp> fmat3; + typedef mat<4, 4, f32, defaultp> fmat4; + + typedef mat<2, 2, f32, lowp> lowp_f32mat2; + typedef mat<3, 3, f32, lowp> lowp_f32mat3; + typedef mat<4, 4, f32, lowp> lowp_f32mat4; + + typedef mat<2, 2, f32, mediump> mediump_f32mat2; + typedef mat<3, 3, f32, mediump> mediump_f32mat3; + typedef mat<4, 4, f32, mediump> mediump_f32mat4; + + typedef mat<2, 2, f32, highp> highp_f32mat2; + typedef mat<3, 3, f32, highp> highp_f32mat3; + typedef mat<4, 4, f32, highp> highp_f32mat4; + + typedef mat<2, 2, f32, defaultp> f32mat2; + typedef mat<3, 3, f32, defaultp> f32mat3; + typedef mat<4, 4, f32, defaultp> f32mat4; + + typedef mat<2, 2, f64, lowp> lowp_dmat2; + typedef mat<3, 3, f64, lowp> lowp_dmat3; + typedef mat<4, 4, f64, lowp> lowp_dmat4; + + typedef mat<2, 2, f64, mediump> mediump_dmat2; + typedef mat<3, 3, f64, mediump> mediump_dmat3; + typedef mat<4, 4, f64, mediump> mediump_dmat4; + + typedef mat<2, 2, f64, highp> highp_dmat2; + typedef mat<3, 3, f64, highp> highp_dmat3; + typedef mat<4, 4, f64, highp> highp_dmat4; + + typedef mat<2, 2, f64, defaultp> dmat2; + typedef mat<3, 3, f64, defaultp> dmat3; + typedef mat<4, 4, f64, defaultp> dmat4; + + typedef mat<2, 2, f64, lowp> lowp_f64mat2; + typedef mat<3, 3, f64, lowp> lowp_f64mat3; + typedef mat<4, 4, f64, lowp> lowp_f64mat4; + + typedef mat<2, 2, f64, mediump> mediump_f64mat2; + typedef mat<3, 3, f64, mediump> mediump_f64mat3; + typedef mat<4, 4, f64, mediump> mediump_f64mat4; + + typedef mat<2, 2, f64, highp> highp_f64mat2; + typedef mat<3, 3, f64, highp> highp_f64mat3; + typedef mat<4, 4, f64, highp> highp_f64mat4; + + typedef mat<2, 2, f64, defaultp> f64mat2; + typedef mat<3, 3, f64, defaultp> f64mat3; + typedef mat<4, 4, f64, defaultp> f64mat4; + + // Matrix MxN + + typedef mat<2, 2, f32, lowp> lowp_mat2x2; + typedef mat<2, 3, f32, lowp> lowp_mat2x3; + typedef mat<2, 4, f32, lowp> lowp_mat2x4; + typedef mat<3, 2, f32, lowp> lowp_mat3x2; + typedef mat<3, 3, f32, lowp> lowp_mat3x3; + typedef mat<3, 4, f32, lowp> lowp_mat3x4; + typedef mat<4, 2, f32, lowp> lowp_mat4x2; + typedef mat<4, 3, f32, lowp> lowp_mat4x3; + typedef mat<4, 4, f32, lowp> lowp_mat4x4; + + typedef mat<2, 2, f32, mediump> mediump_mat2x2; + typedef mat<2, 3, f32, mediump> mediump_mat2x3; + typedef mat<2, 4, f32, mediump> mediump_mat2x4; + typedef mat<3, 2, f32, mediump> mediump_mat3x2; + typedef mat<3, 3, f32, mediump> mediump_mat3x3; + typedef mat<3, 4, f32, mediump> mediump_mat3x4; + typedef mat<4, 2, f32, mediump> mediump_mat4x2; + typedef mat<4, 3, f32, mediump> mediump_mat4x3; + typedef mat<4, 4, f32, mediump> mediump_mat4x4; + + typedef mat<2, 2, f32, highp> highp_mat2x2; + typedef mat<2, 3, f32, highp> highp_mat2x3; + typedef mat<2, 4, f32, highp> highp_mat2x4; + typedef mat<3, 2, f32, highp> highp_mat3x2; + typedef mat<3, 3, f32, highp> highp_mat3x3; + typedef mat<3, 4, f32, highp> highp_mat3x4; + typedef mat<4, 2, f32, highp> highp_mat4x2; + typedef mat<4, 3, f32, highp> highp_mat4x3; + typedef mat<4, 4, f32, highp> highp_mat4x4; + + typedef mat<2, 2, f32, defaultp> mat2x2; + typedef mat<3, 2, f32, defaultp> mat3x2; + typedef mat<4, 2, f32, defaultp> mat4x2; + typedef mat<2, 3, f32, defaultp> mat2x3; + typedef mat<3, 3, f32, defaultp> mat3x3; + typedef mat<4, 3, f32, defaultp> mat4x3; + typedef mat<2, 4, f32, defaultp> mat2x4; + typedef mat<3, 4, f32, defaultp> mat3x4; + typedef mat<4, 4, f32, defaultp> mat4x4; + + typedef mat<2, 2, f32, lowp> lowp_fmat2x2; + typedef mat<2, 3, f32, lowp> lowp_fmat2x3; + typedef mat<2, 4, f32, lowp> lowp_fmat2x4; + typedef mat<3, 2, f32, lowp> lowp_fmat3x2; + typedef mat<3, 3, f32, lowp> lowp_fmat3x3; + typedef mat<3, 4, f32, lowp> lowp_fmat3x4; + typedef mat<4, 2, f32, lowp> lowp_fmat4x2; + typedef mat<4, 3, f32, lowp> lowp_fmat4x3; + typedef mat<4, 4, f32, lowp> lowp_fmat4x4; + + typedef mat<2, 2, f32, mediump> mediump_fmat2x2; + typedef mat<2, 3, f32, mediump> mediump_fmat2x3; + typedef mat<2, 4, f32, mediump> mediump_fmat2x4; + typedef mat<3, 2, f32, mediump> mediump_fmat3x2; + typedef mat<3, 3, f32, mediump> mediump_fmat3x3; + typedef mat<3, 4, f32, mediump> mediump_fmat3x4; + typedef mat<4, 2, f32, mediump> mediump_fmat4x2; + typedef mat<4, 3, f32, mediump> mediump_fmat4x3; + typedef mat<4, 4, f32, mediump> mediump_fmat4x4; + + typedef mat<2, 2, f32, highp> highp_fmat2x2; + typedef mat<2, 3, f32, highp> highp_fmat2x3; + typedef mat<2, 4, f32, highp> highp_fmat2x4; + typedef mat<3, 2, f32, highp> highp_fmat3x2; + typedef mat<3, 3, f32, highp> highp_fmat3x3; + typedef mat<3, 4, f32, highp> highp_fmat3x4; + typedef mat<4, 2, f32, highp> highp_fmat4x2; + typedef mat<4, 3, f32, highp> highp_fmat4x3; + typedef mat<4, 4, f32, highp> highp_fmat4x4; + + typedef mat<2, 2, f32, defaultp> fmat2x2; + typedef mat<3, 2, f32, defaultp> fmat3x2; + typedef mat<4, 2, f32, defaultp> fmat4x2; + typedef mat<2, 3, f32, defaultp> fmat2x3; + typedef mat<3, 3, f32, defaultp> fmat3x3; + typedef mat<4, 3, f32, defaultp> fmat4x3; + typedef mat<2, 4, f32, defaultp> fmat2x4; + typedef mat<3, 4, f32, defaultp> fmat3x4; + typedef mat<4, 4, f32, defaultp> fmat4x4; + + typedef mat<2, 2, f32, lowp> lowp_f32mat2x2; + typedef mat<2, 3, f32, lowp> lowp_f32mat2x3; + typedef mat<2, 4, f32, lowp> lowp_f32mat2x4; + typedef mat<3, 2, f32, lowp> lowp_f32mat3x2; + typedef mat<3, 3, f32, lowp> lowp_f32mat3x3; + typedef mat<3, 4, f32, lowp> lowp_f32mat3x4; + typedef mat<4, 2, f32, lowp> lowp_f32mat4x2; + typedef mat<4, 3, f32, lowp> lowp_f32mat4x3; + typedef mat<4, 4, f32, lowp> lowp_f32mat4x4; + + typedef mat<2, 2, f32, mediump> mediump_f32mat2x2; + typedef mat<2, 3, f32, mediump> mediump_f32mat2x3; + typedef mat<2, 4, f32, mediump> mediump_f32mat2x4; + typedef mat<3, 2, f32, mediump> mediump_f32mat3x2; + typedef mat<3, 3, f32, mediump> mediump_f32mat3x3; + typedef mat<3, 4, f32, mediump> mediump_f32mat3x4; + typedef mat<4, 2, f32, mediump> mediump_f32mat4x2; + typedef mat<4, 3, f32, mediump> mediump_f32mat4x3; + typedef mat<4, 4, f32, mediump> mediump_f32mat4x4; + + typedef mat<2, 2, f32, highp> highp_f32mat2x2; + typedef mat<2, 3, f32, highp> highp_f32mat2x3; + typedef mat<2, 4, f32, highp> highp_f32mat2x4; + typedef mat<3, 2, f32, highp> highp_f32mat3x2; + typedef mat<3, 3, f32, highp> highp_f32mat3x3; + typedef mat<3, 4, f32, highp> highp_f32mat3x4; + typedef mat<4, 2, f32, highp> highp_f32mat4x2; + typedef mat<4, 3, f32, highp> highp_f32mat4x3; + typedef mat<4, 4, f32, highp> highp_f32mat4x4; + + typedef mat<2, 2, f32, defaultp> f32mat2x2; + typedef mat<3, 2, f32, defaultp> f32mat3x2; + typedef mat<4, 2, f32, defaultp> f32mat4x2; + typedef mat<2, 3, f32, defaultp> f32mat2x3; + typedef mat<3, 3, f32, defaultp> f32mat3x3; + typedef mat<4, 3, f32, defaultp> f32mat4x3; + typedef mat<2, 4, f32, defaultp> f32mat2x4; + typedef mat<3, 4, f32, defaultp> f32mat3x4; + typedef mat<4, 4, f32, defaultp> f32mat4x4; + + typedef mat<2, 2, double, lowp> lowp_dmat2x2; + typedef mat<2, 3, double, lowp> lowp_dmat2x3; + typedef mat<2, 4, double, lowp> lowp_dmat2x4; + typedef mat<3, 2, double, lowp> lowp_dmat3x2; + typedef mat<3, 3, double, lowp> lowp_dmat3x3; + typedef mat<3, 4, double, lowp> lowp_dmat3x4; + typedef mat<4, 2, double, lowp> lowp_dmat4x2; + typedef mat<4, 3, double, lowp> lowp_dmat4x3; + typedef mat<4, 4, double, lowp> lowp_dmat4x4; + + typedef mat<2, 2, double, mediump> mediump_dmat2x2; + typedef mat<2, 3, double, mediump> mediump_dmat2x3; + typedef mat<2, 4, double, mediump> mediump_dmat2x4; + typedef mat<3, 2, double, mediump> mediump_dmat3x2; + typedef mat<3, 3, double, mediump> mediump_dmat3x3; + typedef mat<3, 4, double, mediump> mediump_dmat3x4; + typedef mat<4, 2, double, mediump> mediump_dmat4x2; + typedef mat<4, 3, double, mediump> mediump_dmat4x3; + typedef mat<4, 4, double, mediump> mediump_dmat4x4; + + typedef mat<2, 2, double, highp> highp_dmat2x2; + typedef mat<2, 3, double, highp> highp_dmat2x3; + typedef mat<2, 4, double, highp> highp_dmat2x4; + typedef mat<3, 2, double, highp> highp_dmat3x2; + typedef mat<3, 3, double, highp> highp_dmat3x3; + typedef mat<3, 4, double, highp> highp_dmat3x4; + typedef mat<4, 2, double, highp> highp_dmat4x2; + typedef mat<4, 3, double, highp> highp_dmat4x3; + typedef mat<4, 4, double, highp> highp_dmat4x4; + + typedef mat<2, 2, double, defaultp> dmat2x2; + typedef mat<3, 2, double, defaultp> dmat3x2; + typedef mat<4, 2, double, defaultp> dmat4x2; + typedef mat<2, 3, double, defaultp> dmat2x3; + typedef mat<3, 3, double, defaultp> dmat3x3; + typedef mat<4, 3, double, defaultp> dmat4x3; + typedef mat<2, 4, double, defaultp> dmat2x4; + typedef mat<3, 4, double, defaultp> dmat3x4; + typedef mat<4, 4, double, defaultp> dmat4x4; + + typedef mat<2, 2, f64, lowp> lowp_f64mat2x2; + typedef mat<2, 3, f64, lowp> lowp_f64mat2x3; + typedef mat<2, 4, f64, lowp> lowp_f64mat2x4; + typedef mat<3, 2, f64, lowp> lowp_f64mat3x2; + typedef mat<3, 3, f64, lowp> lowp_f64mat3x3; + typedef mat<3, 4, f64, lowp> lowp_f64mat3x4; + typedef mat<4, 2, f64, lowp> lowp_f64mat4x2; + typedef mat<4, 3, f64, lowp> lowp_f64mat4x3; + typedef mat<4, 4, f64, lowp> lowp_f64mat4x4; + + typedef mat<2, 2, f64, mediump> mediump_f64mat2x2; + typedef mat<2, 3, f64, mediump> mediump_f64mat2x3; + typedef mat<2, 4, f64, mediump> mediump_f64mat2x4; + typedef mat<3, 2, f64, mediump> mediump_f64mat3x2; + typedef mat<3, 3, f64, mediump> mediump_f64mat3x3; + typedef mat<3, 4, f64, mediump> mediump_f64mat3x4; + typedef mat<4, 2, f64, mediump> mediump_f64mat4x2; + typedef mat<4, 3, f64, mediump> mediump_f64mat4x3; + typedef mat<4, 4, f64, mediump> mediump_f64mat4x4; + + typedef mat<2, 2, f64, highp> highp_f64mat2x2; + typedef mat<2, 3, f64, highp> highp_f64mat2x3; + typedef mat<2, 4, f64, highp> highp_f64mat2x4; + typedef mat<3, 2, f64, highp> highp_f64mat3x2; + typedef mat<3, 3, f64, highp> highp_f64mat3x3; + typedef mat<3, 4, f64, highp> highp_f64mat3x4; + typedef mat<4, 2, f64, highp> highp_f64mat4x2; + typedef mat<4, 3, f64, highp> highp_f64mat4x3; + typedef mat<4, 4, f64, highp> highp_f64mat4x4; + + typedef mat<2, 2, f64, defaultp> f64mat2x2; + typedef mat<3, 2, f64, defaultp> f64mat3x2; + typedef mat<4, 2, f64, defaultp> f64mat4x2; + typedef mat<2, 3, f64, defaultp> f64mat2x3; + typedef mat<3, 3, f64, defaultp> f64mat3x3; + typedef mat<4, 3, f64, defaultp> f64mat4x3; + typedef mat<2, 4, f64, defaultp> f64mat2x4; + typedef mat<3, 4, f64, defaultp> f64mat3x4; + typedef mat<4, 4, f64, defaultp> f64mat4x4; + + // Signed integer matrix MxN + + typedef mat<2, 2, int, lowp> lowp_imat2x2; + typedef mat<2, 3, int, lowp> lowp_imat2x3; + typedef mat<2, 4, int, lowp> lowp_imat2x4; + typedef mat<3, 2, int, lowp> lowp_imat3x2; + typedef mat<3, 3, int, lowp> lowp_imat3x3; + typedef mat<3, 4, int, lowp> lowp_imat3x4; + typedef mat<4, 2, int, lowp> lowp_imat4x2; + typedef mat<4, 3, int, lowp> lowp_imat4x3; + typedef mat<4, 4, int, lowp> lowp_imat4x4; + + typedef mat<2, 2, int, mediump> mediump_imat2x2; + typedef mat<2, 3, int, mediump> mediump_imat2x3; + typedef mat<2, 4, int, mediump> mediump_imat2x4; + typedef mat<3, 2, int, mediump> mediump_imat3x2; + typedef mat<3, 3, int, mediump> mediump_imat3x3; + typedef mat<3, 4, int, mediump> mediump_imat3x4; + typedef mat<4, 2, int, mediump> mediump_imat4x2; + typedef mat<4, 3, int, mediump> mediump_imat4x3; + typedef mat<4, 4, int, mediump> mediump_imat4x4; + + typedef mat<2, 2, int, highp> highp_imat2x2; + typedef mat<2, 3, int, highp> highp_imat2x3; + typedef mat<2, 4, int, highp> highp_imat2x4; + typedef mat<3, 2, int, highp> highp_imat3x2; + typedef mat<3, 3, int, highp> highp_imat3x3; + typedef mat<3, 4, int, highp> highp_imat3x4; + typedef mat<4, 2, int, highp> highp_imat4x2; + typedef mat<4, 3, int, highp> highp_imat4x3; + typedef mat<4, 4, int, highp> highp_imat4x4; + + typedef mat<2, 2, int, defaultp> imat2x2; + typedef mat<3, 2, int, defaultp> imat3x2; + typedef mat<4, 2, int, defaultp> imat4x2; + typedef mat<2, 3, int, defaultp> imat2x3; + typedef mat<3, 3, int, defaultp> imat3x3; + typedef mat<4, 3, int, defaultp> imat4x3; + typedef mat<2, 4, int, defaultp> imat2x4; + typedef mat<3, 4, int, defaultp> imat3x4; + typedef mat<4, 4, int, defaultp> imat4x4; + + + typedef mat<2, 2, int8, lowp> lowp_i8mat2x2; + typedef mat<2, 3, int8, lowp> lowp_i8mat2x3; + typedef mat<2, 4, int8, lowp> lowp_i8mat2x4; + typedef mat<3, 2, int8, lowp> lowp_i8mat3x2; + typedef mat<3, 3, int8, lowp> lowp_i8mat3x3; + typedef mat<3, 4, int8, lowp> lowp_i8mat3x4; + typedef mat<4, 2, int8, lowp> lowp_i8mat4x2; + typedef mat<4, 3, int8, lowp> lowp_i8mat4x3; + typedef mat<4, 4, int8, lowp> lowp_i8mat4x4; + + typedef mat<2, 2, int8, mediump> mediump_i8mat2x2; + typedef mat<2, 3, int8, mediump> mediump_i8mat2x3; + typedef mat<2, 4, int8, mediump> mediump_i8mat2x4; + typedef mat<3, 2, int8, mediump> mediump_i8mat3x2; + typedef mat<3, 3, int8, mediump> mediump_i8mat3x3; + typedef mat<3, 4, int8, mediump> mediump_i8mat3x4; + typedef mat<4, 2, int8, mediump> mediump_i8mat4x2; + typedef mat<4, 3, int8, mediump> mediump_i8mat4x3; + typedef mat<4, 4, int8, mediump> mediump_i8mat4x4; + + typedef mat<2, 2, int8, highp> highp_i8mat2x2; + typedef mat<2, 3, int8, highp> highp_i8mat2x3; + typedef mat<2, 4, int8, highp> highp_i8mat2x4; + typedef mat<3, 2, int8, highp> highp_i8mat3x2; + typedef mat<3, 3, int8, highp> highp_i8mat3x3; + typedef mat<3, 4, int8, highp> highp_i8mat3x4; + typedef mat<4, 2, int8, highp> highp_i8mat4x2; + typedef mat<4, 3, int8, highp> highp_i8mat4x3; + typedef mat<4, 4, int8, highp> highp_i8mat4x4; + + typedef mat<2, 2, int8, defaultp> i8mat2x2; + typedef mat<3, 2, int8, defaultp> i8mat3x2; + typedef mat<4, 2, int8, defaultp> i8mat4x2; + typedef mat<2, 3, int8, defaultp> i8mat2x3; + typedef mat<3, 3, int8, defaultp> i8mat3x3; + typedef mat<4, 3, int8, defaultp> i8mat4x3; + typedef mat<2, 4, int8, defaultp> i8mat2x4; + typedef mat<3, 4, int8, defaultp> i8mat3x4; + typedef mat<4, 4, int8, defaultp> i8mat4x4; + + + typedef mat<2, 2, int16, lowp> lowp_i16mat2x2; + typedef mat<2, 3, int16, lowp> lowp_i16mat2x3; + typedef mat<2, 4, int16, lowp> lowp_i16mat2x4; + typedef mat<3, 2, int16, lowp> lowp_i16mat3x2; + typedef mat<3, 3, int16, lowp> lowp_i16mat3x3; + typedef mat<3, 4, int16, lowp> lowp_i16mat3x4; + typedef mat<4, 2, int16, lowp> lowp_i16mat4x2; + typedef mat<4, 3, int16, lowp> lowp_i16mat4x3; + typedef mat<4, 4, int16, lowp> lowp_i16mat4x4; + + typedef mat<2, 2, int16, mediump> mediump_i16mat2x2; + typedef mat<2, 3, int16, mediump> mediump_i16mat2x3; + typedef mat<2, 4, int16, mediump> mediump_i16mat2x4; + typedef mat<3, 2, int16, mediump> mediump_i16mat3x2; + typedef mat<3, 3, int16, mediump> mediump_i16mat3x3; + typedef mat<3, 4, int16, mediump> mediump_i16mat3x4; + typedef mat<4, 2, int16, mediump> mediump_i16mat4x2; + typedef mat<4, 3, int16, mediump> mediump_i16mat4x3; + typedef mat<4, 4, int16, mediump> mediump_i16mat4x4; + + typedef mat<2, 2, int16, highp> highp_i16mat2x2; + typedef mat<2, 3, int16, highp> highp_i16mat2x3; + typedef mat<2, 4, int16, highp> highp_i16mat2x4; + typedef mat<3, 2, int16, highp> highp_i16mat3x2; + typedef mat<3, 3, int16, highp> highp_i16mat3x3; + typedef mat<3, 4, int16, highp> highp_i16mat3x4; + typedef mat<4, 2, int16, highp> highp_i16mat4x2; + typedef mat<4, 3, int16, highp> highp_i16mat4x3; + typedef mat<4, 4, int16, highp> highp_i16mat4x4; + + typedef mat<2, 2, int16, defaultp> i16mat2x2; + typedef mat<3, 2, int16, defaultp> i16mat3x2; + typedef mat<4, 2, int16, defaultp> i16mat4x2; + typedef mat<2, 3, int16, defaultp> i16mat2x3; + typedef mat<3, 3, int16, defaultp> i16mat3x3; + typedef mat<4, 3, int16, defaultp> i16mat4x3; + typedef mat<2, 4, int16, defaultp> i16mat2x4; + typedef mat<3, 4, int16, defaultp> i16mat3x4; + typedef mat<4, 4, int16, defaultp> i16mat4x4; + + + typedef mat<2, 2, int32, lowp> lowp_i32mat2x2; + typedef mat<2, 3, int32, lowp> lowp_i32mat2x3; + typedef mat<2, 4, int32, lowp> lowp_i32mat2x4; + typedef mat<3, 2, int32, lowp> lowp_i32mat3x2; + typedef mat<3, 3, int32, lowp> lowp_i32mat3x3; + typedef mat<3, 4, int32, lowp> lowp_i32mat3x4; + typedef mat<4, 2, int32, lowp> lowp_i32mat4x2; + typedef mat<4, 3, int32, lowp> lowp_i32mat4x3; + typedef mat<4, 4, int32, lowp> lowp_i32mat4x4; + + typedef mat<2, 2, int32, mediump> mediump_i32mat2x2; + typedef mat<2, 3, int32, mediump> mediump_i32mat2x3; + typedef mat<2, 4, int32, mediump> mediump_i32mat2x4; + typedef mat<3, 2, int32, mediump> mediump_i32mat3x2; + typedef mat<3, 3, int32, mediump> mediump_i32mat3x3; + typedef mat<3, 4, int32, mediump> mediump_i32mat3x4; + typedef mat<4, 2, int32, mediump> mediump_i32mat4x2; + typedef mat<4, 3, int32, mediump> mediump_i32mat4x3; + typedef mat<4, 4, int32, mediump> mediump_i32mat4x4; + + typedef mat<2, 2, int32, highp> highp_i32mat2x2; + typedef mat<2, 3, int32, highp> highp_i32mat2x3; + typedef mat<2, 4, int32, highp> highp_i32mat2x4; + typedef mat<3, 2, int32, highp> highp_i32mat3x2; + typedef mat<3, 3, int32, highp> highp_i32mat3x3; + typedef mat<3, 4, int32, highp> highp_i32mat3x4; + typedef mat<4, 2, int32, highp> highp_i32mat4x2; + typedef mat<4, 3, int32, highp> highp_i32mat4x3; + typedef mat<4, 4, int32, highp> highp_i32mat4x4; + + typedef mat<2, 2, int32, defaultp> i32mat2x2; + typedef mat<3, 2, int32, defaultp> i32mat3x2; + typedef mat<4, 2, int32, defaultp> i32mat4x2; + typedef mat<2, 3, int32, defaultp> i32mat2x3; + typedef mat<3, 3, int32, defaultp> i32mat3x3; + typedef mat<4, 3, int32, defaultp> i32mat4x3; + typedef mat<2, 4, int32, defaultp> i32mat2x4; + typedef mat<3, 4, int32, defaultp> i32mat3x4; + typedef mat<4, 4, int32, defaultp> i32mat4x4; + + + typedef mat<2, 2, int64, lowp> lowp_i64mat2x2; + typedef mat<2, 3, int64, lowp> lowp_i64mat2x3; + typedef mat<2, 4, int64, lowp> lowp_i64mat2x4; + typedef mat<3, 2, int64, lowp> lowp_i64mat3x2; + typedef mat<3, 3, int64, lowp> lowp_i64mat3x3; + typedef mat<3, 4, int64, lowp> lowp_i64mat3x4; + typedef mat<4, 2, int64, lowp> lowp_i64mat4x2; + typedef mat<4, 3, int64, lowp> lowp_i64mat4x3; + typedef mat<4, 4, int64, lowp> lowp_i64mat4x4; + + typedef mat<2, 2, int64, mediump> mediump_i64mat2x2; + typedef mat<2, 3, int64, mediump> mediump_i64mat2x3; + typedef mat<2, 4, int64, mediump> mediump_i64mat2x4; + typedef mat<3, 2, int64, mediump> mediump_i64mat3x2; + typedef mat<3, 3, int64, mediump> mediump_i64mat3x3; + typedef mat<3, 4, int64, mediump> mediump_i64mat3x4; + typedef mat<4, 2, int64, mediump> mediump_i64mat4x2; + typedef mat<4, 3, int64, mediump> mediump_i64mat4x3; + typedef mat<4, 4, int64, mediump> mediump_i64mat4x4; + + typedef mat<2, 2, int64, highp> highp_i64mat2x2; + typedef mat<2, 3, int64, highp> highp_i64mat2x3; + typedef mat<2, 4, int64, highp> highp_i64mat2x4; + typedef mat<3, 2, int64, highp> highp_i64mat3x2; + typedef mat<3, 3, int64, highp> highp_i64mat3x3; + typedef mat<3, 4, int64, highp> highp_i64mat3x4; + typedef mat<4, 2, int64, highp> highp_i64mat4x2; + typedef mat<4, 3, int64, highp> highp_i64mat4x3; + typedef mat<4, 4, int64, highp> highp_i64mat4x4; + + typedef mat<2, 2, int64, defaultp> i64mat2x2; + typedef mat<3, 2, int64, defaultp> i64mat3x2; + typedef mat<4, 2, int64, defaultp> i64mat4x2; + typedef mat<2, 3, int64, defaultp> i64mat2x3; + typedef mat<3, 3, int64, defaultp> i64mat3x3; + typedef mat<4, 3, int64, defaultp> i64mat4x3; + typedef mat<2, 4, int64, defaultp> i64mat2x4; + typedef mat<3, 4, int64, defaultp> i64mat3x4; + typedef mat<4, 4, int64, defaultp> i64mat4x4; + + + // Unsigned integer matrix MxN + + typedef mat<2, 2, uint, lowp> lowp_umat2x2; + typedef mat<2, 3, uint, lowp> lowp_umat2x3; + typedef mat<2, 4, uint, lowp> lowp_umat2x4; + typedef mat<3, 2, uint, lowp> lowp_umat3x2; + typedef mat<3, 3, uint, lowp> lowp_umat3x3; + typedef mat<3, 4, uint, lowp> lowp_umat3x4; + typedef mat<4, 2, uint, lowp> lowp_umat4x2; + typedef mat<4, 3, uint, lowp> lowp_umat4x3; + typedef mat<4, 4, uint, lowp> lowp_umat4x4; + + typedef mat<2, 2, uint, mediump> mediump_umat2x2; + typedef mat<2, 3, uint, mediump> mediump_umat2x3; + typedef mat<2, 4, uint, mediump> mediump_umat2x4; + typedef mat<3, 2, uint, mediump> mediump_umat3x2; + typedef mat<3, 3, uint, mediump> mediump_umat3x3; + typedef mat<3, 4, uint, mediump> mediump_umat3x4; + typedef mat<4, 2, uint, mediump> mediump_umat4x2; + typedef mat<4, 3, uint, mediump> mediump_umat4x3; + typedef mat<4, 4, uint, mediump> mediump_umat4x4; + + typedef mat<2, 2, uint, highp> highp_umat2x2; + typedef mat<2, 3, uint, highp> highp_umat2x3; + typedef mat<2, 4, uint, highp> highp_umat2x4; + typedef mat<3, 2, uint, highp> highp_umat3x2; + typedef mat<3, 3, uint, highp> highp_umat3x3; + typedef mat<3, 4, uint, highp> highp_umat3x4; + typedef mat<4, 2, uint, highp> highp_umat4x2; + typedef mat<4, 3, uint, highp> highp_umat4x3; + typedef mat<4, 4, uint, highp> highp_umat4x4; + + typedef mat<2, 2, uint, defaultp> umat2x2; + typedef mat<3, 2, uint, defaultp> umat3x2; + typedef mat<4, 2, uint, defaultp> umat4x2; + typedef mat<2, 3, uint, defaultp> umat2x3; + typedef mat<3, 3, uint, defaultp> umat3x3; + typedef mat<4, 3, uint, defaultp> umat4x3; + typedef mat<2, 4, uint, defaultp> umat2x4; + typedef mat<3, 4, uint, defaultp> umat3x4; + typedef mat<4, 4, uint, defaultp> umat4x4; + + + typedef mat<2, 2, uint8, lowp> lowp_u8mat2x2; + typedef mat<2, 3, uint8, lowp> lowp_u8mat2x3; + typedef mat<2, 4, uint8, lowp> lowp_u8mat2x4; + typedef mat<3, 2, uint8, lowp> lowp_u8mat3x2; + typedef mat<3, 3, uint8, lowp> lowp_u8mat3x3; + typedef mat<3, 4, uint8, lowp> lowp_u8mat3x4; + typedef mat<4, 2, uint8, lowp> lowp_u8mat4x2; + typedef mat<4, 3, uint8, lowp> lowp_u8mat4x3; + typedef mat<4, 4, uint8, lowp> lowp_u8mat4x4; + + typedef mat<2, 2, uint8, mediump> mediump_u8mat2x2; + typedef mat<2, 3, uint8, mediump> mediump_u8mat2x3; + typedef mat<2, 4, uint8, mediump> mediump_u8mat2x4; + typedef mat<3, 2, uint8, mediump> mediump_u8mat3x2; + typedef mat<3, 3, uint8, mediump> mediump_u8mat3x3; + typedef mat<3, 4, uint8, mediump> mediump_u8mat3x4; + typedef mat<4, 2, uint8, mediump> mediump_u8mat4x2; + typedef mat<4, 3, uint8, mediump> mediump_u8mat4x3; + typedef mat<4, 4, uint8, mediump> mediump_u8mat4x4; + + typedef mat<2, 2, uint8, highp> highp_u8mat2x2; + typedef mat<2, 3, uint8, highp> highp_u8mat2x3; + typedef mat<2, 4, uint8, highp> highp_u8mat2x4; + typedef mat<3, 2, uint8, highp> highp_u8mat3x2; + typedef mat<3, 3, uint8, highp> highp_u8mat3x3; + typedef mat<3, 4, uint8, highp> highp_u8mat3x4; + typedef mat<4, 2, uint8, highp> highp_u8mat4x2; + typedef mat<4, 3, uint8, highp> highp_u8mat4x3; + typedef mat<4, 4, uint8, highp> highp_u8mat4x4; + + typedef mat<2, 2, uint8, defaultp> u8mat2x2; + typedef mat<3, 2, uint8, defaultp> u8mat3x2; + typedef mat<4, 2, uint8, defaultp> u8mat4x2; + typedef mat<2, 3, uint8, defaultp> u8mat2x3; + typedef mat<3, 3, uint8, defaultp> u8mat3x3; + typedef mat<4, 3, uint8, defaultp> u8mat4x3; + typedef mat<2, 4, uint8, defaultp> u8mat2x4; + typedef mat<3, 4, uint8, defaultp> u8mat3x4; + typedef mat<4, 4, uint8, defaultp> u8mat4x4; + + + typedef mat<2, 2, uint16, lowp> lowp_u16mat2x2; + typedef mat<2, 3, uint16, lowp> lowp_u16mat2x3; + typedef mat<2, 4, uint16, lowp> lowp_u16mat2x4; + typedef mat<3, 2, uint16, lowp> lowp_u16mat3x2; + typedef mat<3, 3, uint16, lowp> lowp_u16mat3x3; + typedef mat<3, 4, uint16, lowp> lowp_u16mat3x4; + typedef mat<4, 2, uint16, lowp> lowp_u16mat4x2; + typedef mat<4, 3, uint16, lowp> lowp_u16mat4x3; + typedef mat<4, 4, uint16, lowp> lowp_u16mat4x4; + + typedef mat<2, 2, uint16, mediump> mediump_u16mat2x2; + typedef mat<2, 3, uint16, mediump> mediump_u16mat2x3; + typedef mat<2, 4, uint16, mediump> mediump_u16mat2x4; + typedef mat<3, 2, uint16, mediump> mediump_u16mat3x2; + typedef mat<3, 3, uint16, mediump> mediump_u16mat3x3; + typedef mat<3, 4, uint16, mediump> mediump_u16mat3x4; + typedef mat<4, 2, uint16, mediump> mediump_u16mat4x2; + typedef mat<4, 3, uint16, mediump> mediump_u16mat4x3; + typedef mat<4, 4, uint16, mediump> mediump_u16mat4x4; + + typedef mat<2, 2, uint16, highp> highp_u16mat2x2; + typedef mat<2, 3, uint16, highp> highp_u16mat2x3; + typedef mat<2, 4, uint16, highp> highp_u16mat2x4; + typedef mat<3, 2, uint16, highp> highp_u16mat3x2; + typedef mat<3, 3, uint16, highp> highp_u16mat3x3; + typedef mat<3, 4, uint16, highp> highp_u16mat3x4; + typedef mat<4, 2, uint16, highp> highp_u16mat4x2; + typedef mat<4, 3, uint16, highp> highp_u16mat4x3; + typedef mat<4, 4, uint16, highp> highp_u16mat4x4; + + typedef mat<2, 2, uint16, defaultp> u16mat2x2; + typedef mat<3, 2, uint16, defaultp> u16mat3x2; + typedef mat<4, 2, uint16, defaultp> u16mat4x2; + typedef mat<2, 3, uint16, defaultp> u16mat2x3; + typedef mat<3, 3, uint16, defaultp> u16mat3x3; + typedef mat<4, 3, uint16, defaultp> u16mat4x3; + typedef mat<2, 4, uint16, defaultp> u16mat2x4; + typedef mat<3, 4, uint16, defaultp> u16mat3x4; + typedef mat<4, 4, uint16, defaultp> u16mat4x4; + + + typedef mat<2, 2, uint32, lowp> lowp_u32mat2x2; + typedef mat<2, 3, uint32, lowp> lowp_u32mat2x3; + typedef mat<2, 4, uint32, lowp> lowp_u32mat2x4; + typedef mat<3, 2, uint32, lowp> lowp_u32mat3x2; + typedef mat<3, 3, uint32, lowp> lowp_u32mat3x3; + typedef mat<3, 4, uint32, lowp> lowp_u32mat3x4; + typedef mat<4, 2, uint32, lowp> lowp_u32mat4x2; + typedef mat<4, 3, uint32, lowp> lowp_u32mat4x3; + typedef mat<4, 4, uint32, lowp> lowp_u32mat4x4; + + typedef mat<2, 2, uint32, mediump> mediump_u32mat2x2; + typedef mat<2, 3, uint32, mediump> mediump_u32mat2x3; + typedef mat<2, 4, uint32, mediump> mediump_u32mat2x4; + typedef mat<3, 2, uint32, mediump> mediump_u32mat3x2; + typedef mat<3, 3, uint32, mediump> mediump_u32mat3x3; + typedef mat<3, 4, uint32, mediump> mediump_u32mat3x4; + typedef mat<4, 2, uint32, mediump> mediump_u32mat4x2; + typedef mat<4, 3, uint32, mediump> mediump_u32mat4x3; + typedef mat<4, 4, uint32, mediump> mediump_u32mat4x4; + + typedef mat<2, 2, uint32, highp> highp_u32mat2x2; + typedef mat<2, 3, uint32, highp> highp_u32mat2x3; + typedef mat<2, 4, uint32, highp> highp_u32mat2x4; + typedef mat<3, 2, uint32, highp> highp_u32mat3x2; + typedef mat<3, 3, uint32, highp> highp_u32mat3x3; + typedef mat<3, 4, uint32, highp> highp_u32mat3x4; + typedef mat<4, 2, uint32, highp> highp_u32mat4x2; + typedef mat<4, 3, uint32, highp> highp_u32mat4x3; + typedef mat<4, 4, uint32, highp> highp_u32mat4x4; + + typedef mat<2, 2, uint32, defaultp> u32mat2x2; + typedef mat<3, 2, uint32, defaultp> u32mat3x2; + typedef mat<4, 2, uint32, defaultp> u32mat4x2; + typedef mat<2, 3, uint32, defaultp> u32mat2x3; + typedef mat<3, 3, uint32, defaultp> u32mat3x3; + typedef mat<4, 3, uint32, defaultp> u32mat4x3; + typedef mat<2, 4, uint32, defaultp> u32mat2x4; + typedef mat<3, 4, uint32, defaultp> u32mat3x4; + typedef mat<4, 4, uint32, defaultp> u32mat4x4; + + + typedef mat<2, 2, uint64, lowp> lowp_u64mat2x2; + typedef mat<2, 3, uint64, lowp> lowp_u64mat2x3; + typedef mat<2, 4, uint64, lowp> lowp_u64mat2x4; + typedef mat<3, 2, uint64, lowp> lowp_u64mat3x2; + typedef mat<3, 3, uint64, lowp> lowp_u64mat3x3; + typedef mat<3, 4, uint64, lowp> lowp_u64mat3x4; + typedef mat<4, 2, uint64, lowp> lowp_u64mat4x2; + typedef mat<4, 3, uint64, lowp> lowp_u64mat4x3; + typedef mat<4, 4, uint64, lowp> lowp_u64mat4x4; + + typedef mat<2, 2, uint64, mediump> mediump_u64mat2x2; + typedef mat<2, 3, uint64, mediump> mediump_u64mat2x3; + typedef mat<2, 4, uint64, mediump> mediump_u64mat2x4; + typedef mat<3, 2, uint64, mediump> mediump_u64mat3x2; + typedef mat<3, 3, uint64, mediump> mediump_u64mat3x3; + typedef mat<3, 4, uint64, mediump> mediump_u64mat3x4; + typedef mat<4, 2, uint64, mediump> mediump_u64mat4x2; + typedef mat<4, 3, uint64, mediump> mediump_u64mat4x3; + typedef mat<4, 4, uint64, mediump> mediump_u64mat4x4; + + typedef mat<2, 2, uint64, highp> highp_u64mat2x2; + typedef mat<2, 3, uint64, highp> highp_u64mat2x3; + typedef mat<2, 4, uint64, highp> highp_u64mat2x4; + typedef mat<3, 2, uint64, highp> highp_u64mat3x2; + typedef mat<3, 3, uint64, highp> highp_u64mat3x3; + typedef mat<3, 4, uint64, highp> highp_u64mat3x4; + typedef mat<4, 2, uint64, highp> highp_u64mat4x2; + typedef mat<4, 3, uint64, highp> highp_u64mat4x3; + typedef mat<4, 4, uint64, highp> highp_u64mat4x4; + + typedef mat<2, 2, uint64, defaultp> u64mat2x2; + typedef mat<3, 2, uint64, defaultp> u64mat3x2; + typedef mat<4, 2, uint64, defaultp> u64mat4x2; + typedef mat<2, 3, uint64, defaultp> u64mat2x3; + typedef mat<3, 3, uint64, defaultp> u64mat3x3; + typedef mat<4, 3, uint64, defaultp> u64mat4x3; + typedef mat<2, 4, uint64, defaultp> u64mat2x4; + typedef mat<3, 4, uint64, defaultp> u64mat3x4; + typedef mat<4, 4, uint64, defaultp> u64mat4x4; + + // Quaternion + + typedef qua lowp_quat; + typedef qua mediump_quat; + typedef qua highp_quat; + typedef qua quat; + + typedef qua lowp_fquat; + typedef qua mediump_fquat; + typedef qua highp_fquat; + typedef qua fquat; + + typedef qua lowp_f32quat; + typedef qua mediump_f32quat; + typedef qua highp_f32quat; + typedef qua f32quat; + + typedef qua lowp_dquat; + typedef qua mediump_dquat; + typedef qua highp_dquat; + typedef qua dquat; + + typedef qua lowp_f64quat; + typedef qua mediump_f64quat; + typedef qua highp_f64quat; + typedef qua f64quat; +}//namespace glm + + diff --git a/src/other/manifold/glm/glm/geometric.hpp b/src/other/manifold/glm/glm/geometric.hpp new file mode 100644 index 00000000000..c068a3cbdb5 --- /dev/null +++ b/src/other/manifold/glm/glm/geometric.hpp @@ -0,0 +1,116 @@ +/// @ref core +/// @file glm/geometric.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions +/// +/// @defgroup core_func_geometric Geometric functions +/// @ingroup core +/// +/// These operate on vectors as vectors, not component-wise. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_func_geometric + /// @{ + + /// Returns the length of x, i.e., sqrt(x * x). + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL length man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL T length(vec const& x); + + /// Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL distance man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL T distance(vec const& p0, vec const& p1); + + /// Returns the dot product of x and y, i.e., result = x * y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL dot man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL T dot(vec const& x, vec const& y); + + /// Returns the cross product of x and y. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL cross man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + /// Returns a vector in the same direction as x but with length of 1. + /// According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefined and generate an error. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL normalize man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec normalize(vec const& x); + + /// If dot(Nref, I) < 0.0, return N, otherwise, return -N. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL faceforward man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec faceforward( + vec const& N, + vec const& I, + vec const& Nref); + + /// For the incident vector I and surface orientation N, + /// returns the reflection direction : result = I - 2.0 * dot(N, I) * N. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL reflect man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec reflect( + vec const& I, + vec const& N); + + /// For the incident vector I and surface normal N, + /// and the ratio of indices of refraction eta, + /// return the refraction vector. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL refract man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec refract( + vec const& I, + vec const& N, + T eta); + + /// @} +}//namespace glm + +#include "detail/func_geometric.inl" diff --git a/src/other/manifold/glm/glm/glm.hpp b/src/other/manifold/glm/glm/glm.hpp new file mode 100644 index 00000000000..8b610649680 --- /dev/null +++ b/src/other/manifold/glm/glm/glm.hpp @@ -0,0 +1,136 @@ +/// @ref core +/// @file glm/glm.hpp +/// +/// @defgroup core Core features +/// +/// @brief Features that implement in C++ the GLSL specification as closely as possible. +/// +/// The GLM core consists of C++ types that mirror GLSL types and +/// C++ functions that mirror the GLSL functions. +/// +/// The best documentation for GLM Core is the current GLSL specification, +/// version 4.2 +/// (pdf file). +/// +/// GLM core functionalities require to be included to be used. +/// +/// +/// @defgroup core_vector Vector types +/// +/// Vector types of two to four components with an exhaustive set of operators. +/// +/// @ingroup core +/// +/// +/// @defgroup core_vector_precision Vector types with precision qualifiers +/// +/// @brief Vector types with precision qualifiers which may result in various precision in term of ULPs +/// +/// GLSL allows defining qualifiers for particular variables. +/// With OpenGL's GLSL, these qualifiers have no effect; they are there for compatibility, +/// with OpenGL ES's GLSL, these qualifiers do have an effect. +/// +/// C++ has no language equivalent to qualifier qualifiers. So GLM provides the next-best thing: +/// a number of typedefs that use a particular qualifier. +/// +/// None of these types make any guarantees about the actual qualifier used. +/// +/// @ingroup core +/// +/// +/// @defgroup core_matrix Matrix types +/// +/// Matrix types of with C columns and R rows where C and R are values between 2 to 4 included. +/// These types have exhaustive sets of operators. +/// +/// @ingroup core +/// +/// +/// @defgroup core_matrix_precision Matrix types with precision qualifiers +/// +/// @brief Matrix types with precision qualifiers which may result in various precision in term of ULPs +/// +/// GLSL allows defining qualifiers for particular variables. +/// With OpenGL's GLSL, these qualifiers have no effect; they are there for compatibility, +/// with OpenGL ES's GLSL, these qualifiers do have an effect. +/// +/// C++ has no language equivalent to qualifier qualifiers. So GLM provides the next-best thing: +/// a number of typedefs that use a particular qualifier. +/// +/// None of these types make any guarantees about the actual qualifier used. +/// +/// @ingroup core +/// +/// +/// @defgroup ext Stable extensions +/// +/// @brief Additional features not specified by GLSL specification. +/// +/// EXT extensions are fully tested and documented. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions at once by +/// including . Otherwise, each extension needs to be included a specific file. +/// +/// +/// @defgroup gtc Recommended extensions +/// +/// @brief Additional features not specified by GLSL specification. +/// +/// GTC extensions aim to be stable with tests and documentation. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions at once by +/// including . Otherwise, each extension needs to be included a specific file. +/// +/// +/// @defgroup gtx Experimental extensions +/// +/// @brief Experimental features not specified by GLSL specification. +/// +/// Experimental extensions are useful functions and types, but the development of +/// their API and functionality is not necessarily stable. They can change +/// substantially between versions. Backwards compatibility is not much of an issue +/// for them. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions +/// at once by including . Otherwise, each extension needs to be +/// included a specific file. +/// +/// @mainpage OpenGL Mathematics (GLM) +/// - Website: glm.g-truc.net +/// - GLM API documentation +/// - GLM Manual + +#include "detail/_fixes.hpp" + +#include "detail/setup.hpp" + +#pragma once + +#include +#include +#include +#include +#include +#include "fwd.hpp" + +#include "vec2.hpp" +#include "vec3.hpp" +#include "vec4.hpp" +#include "mat2x2.hpp" +#include "mat2x3.hpp" +#include "mat2x4.hpp" +#include "mat3x2.hpp" +#include "mat3x3.hpp" +#include "mat3x4.hpp" +#include "mat4x2.hpp" +#include "mat4x3.hpp" +#include "mat4x4.hpp" + +#include "trigonometric.hpp" +#include "exponential.hpp" +#include "common.hpp" +#include "packing.hpp" +#include "geometric.hpp" +#include "matrix.hpp" +#include "vector_relational.hpp" +#include "integer.hpp" diff --git a/src/other/manifold/glm/glm/gtc/bitfield.hpp b/src/other/manifold/glm/glm/gtc/bitfield.hpp new file mode 100644 index 00000000000..084fbe75ff1 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/bitfield.hpp @@ -0,0 +1,266 @@ +/// @ref gtc_bitfield +/// @file glm/gtc/bitfield.hpp +/// +/// @see core (dependence) +/// @see gtc_bitfield (dependence) +/// +/// @defgroup gtc_bitfield GLM_GTC_bitfield +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#include "../detail/setup.hpp" + +#pragma once + +// Dependencies +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "type_precision.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_bitfield extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_bitfield + /// @{ + + /// Build a mask of 'count' bits + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType mask(genIUType Bits); + + /// Build a mask of 'count' bits + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec mask(vec const& v); + + /// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldRotateRight(genIUType In, int Shift); + + /// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldRotateRight(vec const& In, int Shift); + + /// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldRotateLeft(genIUType In, int Shift); + + /// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldRotateLeft(vec const& In, int Shift); + + /// Set to 1 a range of bits. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount); + + /// Set to 1 a range of bits. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldFillOne(vec const& Value, int FirstBit, int BitCount); + + /// Set to 0 a range of bits. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount); + + /// Set to 0 a range of bits. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldFillZero(vec const& Value, int FirstBit, int BitCount); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int16 bitfieldInterleave(int8 x, int8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint16 bitfieldInterleave(u8vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u8vec2 bitfieldDeinterleave(glm::uint16 x); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int16 x, int16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(u16vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u16vec2 bitfieldDeinterleave(glm::uint32 x); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(u32vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u32vec2 bitfieldDeinterleave(glm::uint64 x); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y, int32 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w); + + /// @} +} //namespace glm + +#include "bitfield.inl" diff --git a/src/other/manifold/glm/glm/gtc/bitfield.inl b/src/other/manifold/glm/glm/gtc/bitfield.inl new file mode 100644 index 00000000000..06cf1889cd4 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/bitfield.inl @@ -0,0 +1,626 @@ +/// @ref gtc_bitfield + +#include "../simd/integer.h" + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w); + + template<> + GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y) + { + glm::uint16 REG1(x); + glm::uint16 REG2(y); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x3333); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x3333); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x5555); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x5555); + + return REG1 | static_cast(REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x00FF00FF); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x00FF00FF); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F0F0F); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F0F0F); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x33333333); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x33333333); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x55555555); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x55555555); + + return REG1 | (REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x0000FFFF0000FFFFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x0000FFFF0000FFFFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x00FF00FF00FF00FFull); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x00FF00FF00FF00FFull); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F0F0F0F0F0F0Full); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F0F0F0F0F0F0Full); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x3333333333333333ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x3333333333333333ull); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x5555555555555555ull); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x5555555555555555ull); + + return REG1 | (REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0xFF0000FFu); + REG2 = ((REG2 << 16) | REG2) & static_cast(0xFF0000FFu); + REG3 = ((REG3 << 16) | REG3) & static_cast(0xFF0000FFu); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x0F00F00Fu); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x0F00F00Fu); + REG3 = ((REG3 << 8) | REG3) & static_cast(0x0F00F00Fu); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0xC30C30C3u); + REG2 = ((REG2 << 4) | REG2) & static_cast(0xC30C30C3u); + REG3 = ((REG3 << 4) | REG3) & static_cast(0xC30C30C3u); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x49249249u); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x49249249u); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x49249249u); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & static_cast(0xFFFF00000000FFFFull); + REG2 = ((REG2 << 32) | REG2) & static_cast(0xFFFF00000000FFFFull); + REG3 = ((REG3 << 32) | REG3) & static_cast(0xFFFF00000000FFFFull); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x00FF0000FF0000FFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x00FF0000FF0000FFull); + REG3 = ((REG3 << 16) | REG3) & static_cast(0x00FF0000FF0000FFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0xF00F00F00F00F00Full); + REG2 = ((REG2 << 8) | REG2) & static_cast(0xF00F00F00F00F00Full); + REG3 = ((REG3 << 8) | REG3) & static_cast(0xF00F00F00F00F00Full); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x30C30C30C30C30C3ull); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x30C30C30C30C30C3ull); + REG3 = ((REG3 << 4) | REG3) & static_cast(0x30C30C30C30C30C3ull); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x9249249249249249ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x9249249249249249ull); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x9249249249249249ull); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & static_cast(0xFFFF00000000FFFFull); + REG2 = ((REG2 << 32) | REG2) & static_cast(0xFFFF00000000FFFFull); + REG3 = ((REG3 << 32) | REG3) & static_cast(0xFFFF00000000FFFFull); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x00FF0000FF0000FFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x00FF0000FF0000FFull); + REG3 = ((REG3 << 16) | REG3) & static_cast(0x00FF0000FF0000FFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0xF00F00F00F00F00Full); + REG2 = ((REG2 << 8) | REG2) & static_cast(0xF00F00F00F00F00Full); + REG3 = ((REG3 << 8) | REG3) & static_cast(0xF00F00F00F00F00Full); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x30C30C30C30C30C3ull); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x30C30C30C30C30C3ull); + REG3 = ((REG3 << 4) | REG3) & static_cast(0x30C30C30C30C30C3ull); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x9249249249249249ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x9249249249249249ull); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x9249249249249249ull); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + glm::uint32 REG4(w); + + REG1 = ((REG1 << 12) | REG1) & static_cast(0x000F000Fu); + REG2 = ((REG2 << 12) | REG2) & static_cast(0x000F000Fu); + REG3 = ((REG3 << 12) | REG3) & static_cast(0x000F000Fu); + REG4 = ((REG4 << 12) | REG4) & static_cast(0x000F000Fu); + + REG1 = ((REG1 << 6) | REG1) & static_cast(0x03030303u); + REG2 = ((REG2 << 6) | REG2) & static_cast(0x03030303u); + REG3 = ((REG3 << 6) | REG3) & static_cast(0x03030303u); + REG4 = ((REG4 << 6) | REG4) & static_cast(0x03030303u); + + REG1 = ((REG1 << 3) | REG1) & static_cast(0x11111111u); + REG2 = ((REG2 << 3) | REG2) & static_cast(0x11111111u); + REG3 = ((REG3 << 3) | REG3) & static_cast(0x11111111u); + REG4 = ((REG4 << 3) | REG4) & static_cast(0x11111111u); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + glm::uint64 REG4(w); + + REG1 = ((REG1 << 24) | REG1) & static_cast(0x000000FF000000FFull); + REG2 = ((REG2 << 24) | REG2) & static_cast(0x000000FF000000FFull); + REG3 = ((REG3 << 24) | REG3) & static_cast(0x000000FF000000FFull); + REG4 = ((REG4 << 24) | REG4) & static_cast(0x000000FF000000FFull); + + REG1 = ((REG1 << 12) | REG1) & static_cast(0x000F000F000F000Full); + REG2 = ((REG2 << 12) | REG2) & static_cast(0x000F000F000F000Full); + REG3 = ((REG3 << 12) | REG3) & static_cast(0x000F000F000F000Full); + REG4 = ((REG4 << 12) | REG4) & static_cast(0x000F000F000F000Full); + + REG1 = ((REG1 << 6) | REG1) & static_cast(0x0303030303030303ull); + REG2 = ((REG2 << 6) | REG2) & static_cast(0x0303030303030303ull); + REG3 = ((REG3 << 6) | REG3) & static_cast(0x0303030303030303ull); + REG4 = ((REG4 << 6) | REG4) & static_cast(0x0303030303030303ull); + + REG1 = ((REG1 << 3) | REG1) & static_cast(0x1111111111111111ull); + REG2 = ((REG2 << 3) | REG2) & static_cast(0x1111111111111111ull); + REG3 = ((REG3 << 3) | REG3) & static_cast(0x1111111111111111ull); + REG4 = ((REG4 << 3) | REG4) & static_cast(0x1111111111111111ull); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER genIUType mask(genIUType Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'mask' accepts only integer values"); + + return Bits >= sizeof(genIUType) * 8 ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); + } + + template + GLM_FUNC_QUALIFIER vec mask(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'mask' accepts only integer values"); + + return detail::functor1::call(mask, v); + } + + template + GLM_FUNC_QUALIFIER genIType bitfieldRotateRight(genIType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateRight' accepts only integer values"); + + int const BitSize = static_cast(sizeof(genIType) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldRotateRight(vec const& In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateRight' accepts only integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER genIType bitfieldRotateLeft(genIType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateLeft' accepts only integer values"); + + int const BitSize = static_cast(sizeof(genIType) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldRotateLeft(vec const& In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateLeft' accepts only integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount) + { + return Value | static_cast(mask(BitCount) << FirstBit); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldFillOne(vec const& Value, int FirstBit, int BitCount) + { + return Value | static_cast(mask(BitCount) << FirstBit); + } + + template + GLM_FUNC_QUALIFIER genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount) + { + return Value & static_cast(~(mask(BitCount) << FirstBit)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldFillZero(vec const& Value, int FirstBit, int BitCount) + { + return Value & static_cast(~(mask(BitCount) << FirstBit)); + } + + GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y; + + union sign16 + { + int16 i; + uint16 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(u8vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER u8vec2 bitfieldDeinterleave(glm::uint16 x) + { + uint16 REG1(x); + uint16 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x5555); + REG2 = REG2 & static_cast(0x5555); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x3333); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x3333); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0xFFFF); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0xFFFF); + + return glm::u8vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(u16vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER glm::u16vec2 bitfieldDeinterleave(glm::uint32 x) + { + glm::uint32 REG1(x); + glm::uint32 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x55555555); + REG2 = REG2 & static_cast(0x55555555); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x33333333); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x33333333); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F0F0F); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F0F0F); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF00FF); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF00FF); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0x0000FFFF); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0x0000FFFF); + + return glm::u16vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y) + { + union sign32 + { + int32 i; + uint32 u; + } sign_x, sign_y; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(u32vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER glm::u32vec2 bitfieldDeinterleave(glm::uint64 x) + { + glm::uint64 REG1(x); + glm::uint64 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x5555555555555555ull); + REG2 = REG2 & static_cast(0x5555555555555555ull); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x3333333333333333ull); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x3333333333333333ull); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F0F0F0F0F0F0Full); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F0F0F0F0F0F0Full); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF00FF00FF00FFull); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF00FF00FF00FFull); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0x0000FFFF0000FFFFull); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0x0000FFFF0000FFFFull); + + REG1 = ((REG1 >> 16) | REG1) & static_cast(0x00000000FFFFFFFFull); + REG2 = ((REG2 >> 16) | REG2) & static_cast(0x00000000FFFFFFFFull); + + return glm::u32vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z) + { + union sign16 + { + int32 i; + uint32 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u32vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec4 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z, v.w); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec4 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z, v.w); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/color_space.hpp b/src/other/manifold/glm/glm/gtc/color_space.hpp new file mode 100644 index 00000000000..cffd9f093fb --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/color_space.hpp @@ -0,0 +1,56 @@ +/// @ref gtc_color_space +/// @file glm/gtc/color_space.hpp +/// +/// @see core (dependence) +/// @see gtc_color_space (dependence) +/// +/// @defgroup gtc_color_space GLM_GTC_color_space +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../exponential.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_color_space extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_color_space + /// @{ + + /// Convert a linear color to sRGB color using a standard gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertLinearToSRGB(vec const& ColorLinear); + + /// Convert a linear color to sRGB color using a custom gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertLinearToSRGB(vec const& ColorLinear, T Gamma); + + /// Convert a sRGB color to linear color using a standard gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertSRGBToLinear(vec const& ColorSRGB); + + /// Convert a sRGB color to linear color using a custom gamma correction. + // IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertSRGBToLinear(vec const& ColorSRGB, T Gamma); + + /// @} +} //namespace glm + +#include "color_space.inl" diff --git a/src/other/manifold/glm/glm/gtc/color_space.inl b/src/other/manifold/glm/glm/gtc/color_space.inl new file mode 100644 index 00000000000..2a900044e99 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/color_space.inl @@ -0,0 +1,84 @@ +/// @ref gtc_color_space + +namespace glm{ +namespace detail +{ + template + struct compute_rgbToSrgb + { + GLM_FUNC_QUALIFIER static vec call(vec const& ColorRGB, T GammaCorrection) + { + vec const ClampedColor(clamp(ColorRGB, static_cast(0), static_cast(1))); + + return mix( + pow(ClampedColor, vec(GammaCorrection)) * static_cast(1.055) - static_cast(0.055), + ClampedColor * static_cast(12.92), + lessThan(ClampedColor, vec(static_cast(0.0031308)))); + } + }; + + template + struct compute_rgbToSrgb<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorRGB, T GammaCorrection) + { + return vec<4, T, Q>(compute_rgbToSrgb<3, T, Q>::call(vec<3, T, Q>(ColorRGB), GammaCorrection), ColorRGB.w); + } + }; + + template + struct compute_srgbToRgb + { + GLM_FUNC_QUALIFIER static vec call(vec const& ColorSRGB, T Gamma) + { + return mix( + pow((ColorSRGB + static_cast(0.055)) * static_cast(0.94786729857819905213270142180095), vec(Gamma)), + ColorSRGB * static_cast(0.07739938080495356037151702786378), + lessThanEqual(ColorSRGB, vec(static_cast(0.04045)))); + } + }; + + template + struct compute_srgbToRgb<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorSRGB, T Gamma) + { + return vec<4, T, Q>(compute_srgbToRgb<3, T, Q>::call(vec<3, T, Q>(ColorSRGB), Gamma), ColorSRGB.w); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER vec convertLinearToSRGB(vec const& ColorLinear) + { + return detail::compute_rgbToSrgb::call(ColorLinear, static_cast(0.41666)); + } + + // Based on Ian Taylor http://chilliant.blogspot.fr/2012/08/srgb-approximations-for-hlsl.html + template<> + GLM_FUNC_QUALIFIER vec<3, float, lowp> convertLinearToSRGB(vec<3, float, lowp> const& ColorLinear) + { + vec<3, float, lowp> S1 = sqrt(ColorLinear); + vec<3, float, lowp> S2 = sqrt(S1); + vec<3, float, lowp> S3 = sqrt(S2); + return 0.662002687f * S1 + 0.684122060f * S2 - 0.323583601f * S3 - 0.0225411470f * ColorLinear; + } + + template + GLM_FUNC_QUALIFIER vec convertLinearToSRGB(vec const& ColorLinear, T Gamma) + { + return detail::compute_rgbToSrgb::call(ColorLinear, static_cast(1) / Gamma); + } + + template + GLM_FUNC_QUALIFIER vec convertSRGBToLinear(vec const& ColorSRGB) + { + return detail::compute_srgbToRgb::call(ColorSRGB, static_cast(2.4)); + } + + template + GLM_FUNC_QUALIFIER vec convertSRGBToLinear(vec const& ColorSRGB, T Gamma) + { + return detail::compute_srgbToRgb::call(ColorSRGB, Gamma); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/constants.hpp b/src/other/manifold/glm/glm/gtc/constants.hpp new file mode 100644 index 00000000000..99f212869e0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/constants.hpp @@ -0,0 +1,165 @@ +/// @ref gtc_constants +/// @file glm/gtc/constants.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_constants GLM_GTC_constants +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Provide a list of constants and precomputed useful values. + +#pragma once + +// Dependencies +#include "../ext/scalar_constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_constants extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_constants + /// @{ + + /// Return 0. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType zero(); + + /// Return 1. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one(); + + /// Return pi * 2. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_pi(); + + /// Return square root of pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_pi(); + + /// Return pi / 2. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType half_pi(); + + /// Return pi / 2 * 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType three_over_two_pi(); + + /// Return pi / 4. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType quarter_pi(); + + /// Return 1 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_pi(); + + /// Return 1 / (pi * 2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_two_pi(); + + /// Return 2 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_pi(); + + /// Return 4 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType four_over_pi(); + + /// Return 2 / sqrt(pi). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_root_pi(); + + /// Return 1 / sqrt(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_root_two(); + + /// Return sqrt(pi / 2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_half_pi(); + + /// Return sqrt(2 * pi). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_two_pi(); + + /// Return sqrt(ln(4)). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_ln_four(); + + /// Return e constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType e(); + + /// Return Euler's constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType euler(); + + /// Return sqrt(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_two(); + + /// Return sqrt(3). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_three(); + + /// Return sqrt(5). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_five(); + + /// Return ln(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_two(); + + /// Return ln(10). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ten(); + + /// Return ln(ln(2)). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ln_two(); + + /// Return 1 / 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType third(); + + /// Return 2 / 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_thirds(); + + /// Return the golden ratio constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType golden_ratio(); + + /// @} +} //namespace glm + +#include "constants.inl" diff --git a/src/other/manifold/glm/glm/gtc/constants.inl b/src/other/manifold/glm/glm/gtc/constants.inl new file mode 100644 index 00000000000..bb98c6bff9d --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/constants.inl @@ -0,0 +1,167 @@ +/// @ref gtc_constants + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType zero() + { + return genType(0); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one() + { + return genType(1); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_pi() + { + return genType(6.28318530717958647692528676655900576); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_pi() + { + return genType(1.772453850905516027); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType half_pi() + { + return genType(1.57079632679489661923132169163975144); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType three_over_two_pi() + { + return genType(4.71238898038468985769396507491925432); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType quarter_pi() + { + return genType(0.785398163397448309615660845819875721); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_pi() + { + return genType(0.318309886183790671537767526745028724); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_two_pi() + { + return genType(0.159154943091895335768883763372514362); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_pi() + { + return genType(0.636619772367581343075535053490057448); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType four_over_pi() + { + return genType(1.273239544735162686151070106980114898); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_root_pi() + { + return genType(1.12837916709551257389615890312154517); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_root_two() + { + return genType(0.707106781186547524400844362104849039); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_half_pi() + { + return genType(1.253314137315500251); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two_pi() + { + return genType(2.506628274631000502); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_ln_four() + { + return genType(1.17741002251547469); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType e() + { + return genType(2.71828182845904523536); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType euler() + { + return genType(0.577215664901532860606); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two() + { + return genType(1.41421356237309504880168872420969808); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_three() + { + return genType(1.73205080756887729352744634150587236); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_five() + { + return genType(2.23606797749978969640917366873127623); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_two() + { + return genType(0.693147180559945309417232121458176568); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ten() + { + return genType(2.30258509299404568401799145468436421); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ln_two() + { + return genType(-0.3665129205816643); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType third() + { + return genType(0.3333333333333333333333333333333333333333); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_thirds() + { + return genType(0.666666666666666666666666666666666666667); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType golden_ratio() + { + return genType(1.61803398874989484820458683436563811); + } + +} //namespace glm diff --git a/src/other/manifold/glm/glm/gtc/epsilon.hpp b/src/other/manifold/glm/glm/gtc/epsilon.hpp new file mode 100644 index 00000000000..640439b11c3 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/epsilon.hpp @@ -0,0 +1,60 @@ +/// @ref gtc_epsilon +/// @file glm/gtc/epsilon.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_epsilon GLM_GTC_epsilon +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Comparison functions for a user defined epsilon values. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_epsilon extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_epsilon + /// @{ + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL vec epsilonEqual(vec const& x, vec const& y, T const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL bool epsilonEqual(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is not satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL vec epsilonNotEqual(vec const& x, vec const& y, T const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL bool epsilonNotEqual(genType const& x, genType const& y, genType const& epsilon); + + /// @} +}//namespace glm + +#include "epsilon.inl" diff --git a/src/other/manifold/glm/glm/gtc/epsilon.inl b/src/other/manifold/glm/glm/gtc/epsilon.inl new file mode 100644 index 00000000000..508b9f8966f --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/epsilon.inl @@ -0,0 +1,80 @@ +/// @ref gtc_epsilon + +// Dependency: +#include "../vector_relational.hpp" +#include "../common.hpp" + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER bool epsilonEqual + ( + float const& x, + float const& y, + float const& epsilon + ) + { + return abs(x - y) < epsilon; + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonEqual + ( + double const& x, + double const& y, + double const& epsilon + ) + { + return abs(x - y) < epsilon; + } + + template + GLM_FUNC_QUALIFIER vec epsilonEqual(vec const& x, vec const& y, T const& epsilon) + { + return lessThan(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec epsilonEqual(vec const& x, vec const& y, vec const& epsilon) + { + return lessThan(abs(x - y), vec(epsilon)); + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonNotEqual(float const& x, float const& y, float const& epsilon) + { + return abs(x - y) >= epsilon; + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonNotEqual(double const& x, double const& y, double const& epsilon) + { + return abs(x - y) >= epsilon; + } + + template + GLM_FUNC_QUALIFIER vec epsilonNotEqual(vec const& x, vec const& y, T const& epsilon) + { + return greaterThanEqual(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec epsilonNotEqual(vec const& x, vec const& y, vec const& epsilon) + { + return greaterThanEqual(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonEqual(qua const& x, qua const& y, T const& epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return lessThan(abs(v), vec<4, T, Q>(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonNotEqual(qua const& x, qua const& y, T const& epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/integer.hpp b/src/other/manifold/glm/glm/gtc/integer.hpp new file mode 100644 index 00000000000..64ce10bb1bd --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/integer.hpp @@ -0,0 +1,65 @@ +/// @ref gtc_integer +/// @file glm/gtc/integer.hpp +/// +/// @see core (dependence) +/// @see gtc_integer (dependence) +/// +/// @defgroup gtc_integer GLM_GTC_integer +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../common.hpp" +#include "../integer.hpp" +#include "../exponential.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_integer + /// @{ + + /// Returns the log2 of x for integer values. Usefull to compute mipmap count from the texture size. + /// @see gtc_integer + template + GLM_FUNC_DECL genIUType log2(genIUType x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see gtc_integer + template + GLM_FUNC_DECL vec iround(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see gtc_integer + template + GLM_FUNC_DECL vec uround(vec const& x); + + /// @} +} //namespace glm + +#include "integer.inl" diff --git a/src/other/manifold/glm/glm/gtc/integer.inl b/src/other/manifold/glm/glm/gtc/integer.inl new file mode 100644 index 00000000000..f0a8b4f2578 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/integer.inl @@ -0,0 +1,68 @@ +/// @ref gtc_integer + +namespace glm{ +namespace detail +{ + template + struct compute_log2 + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + //Equivalent to return findMSB(vec); but save one function call in ASM with VC + //return findMSB(vec); + return vec(detail::compute_findMSB_vec::call(v)); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + struct compute_log2<4, int, Q, false, Aligned> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v) + { + vec<4, int, Q> Result; + _BitScanReverse(reinterpret_cast(&Result.x), v.x); + _BitScanReverse(reinterpret_cast(&Result.y), v.y); + _BitScanReverse(reinterpret_cast(&Result.z), v.z); + _BitScanReverse(reinterpret_cast(&Result.w), v.w); + return Result; + } + }; +# endif//GLM_HAS_BITSCAN_WINDOWS +}//namespace detail + template + GLM_FUNC_QUALIFIER int iround(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER vec iround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER uint uround(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER vec uround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/matrix_access.hpp b/src/other/manifold/glm/glm/gtc/matrix_access.hpp new file mode 100644 index 00000000000..4935ba755dd --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_access.hpp @@ -0,0 +1,60 @@ +/// @ref gtc_matrix_access +/// @file glm/gtc/matrix_access.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_access GLM_GTC_matrix_access +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines functions to access rows or columns of a matrix easily. + +#pragma once + +// Dependency: +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_access extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_access + /// @{ + + /// Get a specific row of a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL typename genType::row_type row( + genType const& m, + length_t index); + + /// Set a specific row to a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL genType row( + genType const& m, + length_t index, + typename genType::row_type const& x); + + /// Get a specific column of a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL typename genType::col_type column( + genType const& m, + length_t index); + + /// Set a specific column to a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL genType column( + genType const& m, + length_t index, + typename genType::col_type const& x); + + /// @} +}//namespace glm + +#include "matrix_access.inl" diff --git a/src/other/manifold/glm/glm/gtc/matrix_access.inl b/src/other/manifold/glm/glm/gtc/matrix_access.inl new file mode 100644 index 00000000000..09fcc10d3d7 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_access.inl @@ -0,0 +1,62 @@ +/// @ref gtc_matrix_access + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType row + ( + genType const& m, + length_t index, + typename genType::row_type const& x + ) + { + assert(index >= 0 && index < m[0].length()); + + genType Result = m; + for(length_t i = 0; i < m.length(); ++i) + Result[i][index] = x[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER typename genType::row_type row + ( + genType const& m, + length_t index + ) + { + assert(index >= 0 && index < m[0].length()); + + typename genType::row_type Result(0); + for(length_t i = 0; i < m.length(); ++i) + Result[i] = m[i][index]; + return Result; + } + + template + GLM_FUNC_QUALIFIER genType column + ( + genType const& m, + length_t index, + typename genType::col_type const& x + ) + { + assert(index >= 0 && index < m.length()); + + genType Result = m; + Result[index] = x; + return Result; + } + + template + GLM_FUNC_QUALIFIER typename genType::col_type column + ( + genType const& m, + length_t index + ) + { + assert(index >= 0 && index < m.length()); + + return m[index]; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/matrix_integer.hpp b/src/other/manifold/glm/glm/gtc/matrix_integer.hpp new file mode 100644 index 00000000000..d7ebdc71922 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_integer.hpp @@ -0,0 +1,433 @@ +/// @ref gtc_matrix_integer +/// @file glm/gtc/matrix_integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_integer GLM_GTC_matrix_integer +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_integer + /// @{ + + /// High-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, highp> highp_imat2; + + /// High-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, highp> highp_imat3; + + /// High-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, highp> highp_imat4; + + /// High-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, highp> highp_imat2x2; + + /// High-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, highp> highp_imat2x3; + + /// High-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, highp> highp_imat2x4; + + /// High-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, highp> highp_imat3x2; + + /// High-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, highp> highp_imat3x3; + + /// High-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, highp> highp_imat3x4; + + /// High-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, highp> highp_imat4x2; + + /// High-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, highp> highp_imat4x3; + + /// High-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, highp> highp_imat4x4; + + + /// Medium-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, mediump> mediump_imat2; + + /// Medium-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, mediump> mediump_imat3; + + /// Medium-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, mediump> mediump_imat4; + + + /// Medium-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, mediump> mediump_imat2x2; + + /// Medium-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, mediump> mediump_imat2x3; + + /// Medium-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, mediump> mediump_imat2x4; + + /// Medium-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, mediump> mediump_imat3x2; + + /// Medium-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, mediump> mediump_imat3x3; + + /// Medium-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, mediump> mediump_imat3x4; + + /// Medium-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, mediump> mediump_imat4x2; + + /// Medium-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, mediump> mediump_imat4x3; + + /// Medium-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, mediump> mediump_imat4x4; + + + /// Low-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, lowp> lowp_imat2; + + /// Low-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, lowp> lowp_imat3; + + /// Low-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, lowp> lowp_imat4; + + + /// Low-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, lowp> lowp_imat2x2; + + /// Low-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, lowp> lowp_imat2x3; + + /// Low-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, lowp> lowp_imat2x4; + + /// Low-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, lowp> lowp_imat3x2; + + /// Low-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, lowp> lowp_imat3x3; + + /// Low-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, lowp> lowp_imat3x4; + + /// Low-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, lowp> lowp_imat4x2; + + /// Low-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, lowp> lowp_imat4x3; + + /// Low-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, lowp> lowp_imat4x4; + + + /// High-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, highp> highp_umat2; + + /// High-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, highp> highp_umat3; + + /// High-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, highp> highp_umat4; + + /// High-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, highp> highp_umat2x2; + + /// High-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, highp> highp_umat2x3; + + /// High-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, highp> highp_umat2x4; + + /// High-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, highp> highp_umat3x2; + + /// High-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, highp> highp_umat3x3; + + /// High-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, highp> highp_umat3x4; + + /// High-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, highp> highp_umat4x2; + + /// High-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, highp> highp_umat4x3; + + /// High-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, highp> highp_umat4x4; + + + /// Medium-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, mediump> mediump_umat2; + + /// Medium-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, mediump> mediump_umat3; + + /// Medium-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, mediump> mediump_umat4; + + + /// Medium-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, mediump> mediump_umat2x2; + + /// Medium-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, mediump> mediump_umat2x3; + + /// Medium-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, mediump> mediump_umat2x4; + + /// Medium-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, mediump> mediump_umat3x2; + + /// Medium-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, mediump> mediump_umat3x3; + + /// Medium-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, mediump> mediump_umat3x4; + + /// Medium-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, mediump> mediump_umat4x2; + + /// Medium-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, mediump> mediump_umat4x3; + + /// Medium-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, mediump> mediump_umat4x4; + + + /// Low-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, lowp> lowp_umat2; + + /// Low-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, lowp> lowp_umat3; + + /// Low-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, lowp> lowp_umat4; + + + /// Low-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, lowp> lowp_umat2x2; + + /// Low-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, lowp> lowp_umat2x3; + + /// Low-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, lowp> lowp_umat2x4; + + /// Low-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, lowp> lowp_umat3x2; + + /// Low-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, lowp> lowp_umat3x3; + + /// Low-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, lowp> lowp_umat3x4; + + /// Low-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, lowp> lowp_umat4x2; + + /// Low-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, lowp> lowp_umat4x3; + + /// Low-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, lowp> lowp_umat4x4; + + + + /// Signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, defaultp> imat2; + + /// Signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, defaultp> imat3; + + /// Signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, defaultp> imat4; + + /// Signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, defaultp> imat2x2; + + /// Signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, defaultp> imat2x3; + + /// Signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, defaultp> imat2x4; + + /// Signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, defaultp> imat3x2; + + /// Signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, defaultp> imat3x3; + + /// Signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, defaultp> imat3x4; + + /// Signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, defaultp> imat4x2; + + /// Signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, defaultp> imat4x3; + + /// Signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, defaultp> imat4x4; + + + + /// Unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, defaultp> umat2; + + /// Unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, defaultp> umat3; + + /// Unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, defaultp> umat4; + + /// Unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, defaultp> umat2x2; + + /// Unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, defaultp> umat2x3; + + /// Unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, defaultp> umat2x4; + + /// Unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, defaultp> umat3x2; + + /// Unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, defaultp> umat3x3; + + /// Unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, defaultp> umat3x4; + + /// Unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, defaultp> umat4x2; + + /// Unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, defaultp> umat4x3; + + /// Unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, defaultp> umat4x4; + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/matrix_inverse.hpp b/src/other/manifold/glm/glm/gtc/matrix_inverse.hpp new file mode 100644 index 00000000000..a1900adcbb0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_inverse.hpp @@ -0,0 +1,50 @@ +/// @ref gtc_matrix_inverse +/// @file glm/gtc/matrix_inverse.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_inverse GLM_GTC_matrix_inverse +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines additional matrix inverting functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../matrix.hpp" +#include "../mat2x2.hpp" +#include "../mat3x3.hpp" +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_inverse extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_inverse + /// @{ + + /// Fast matrix inverse for affine matrix. + /// + /// @param m Input matrix to invert. + /// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly innacurate. + /// @see gtc_matrix_inverse + template + GLM_FUNC_DECL genType affineInverse(genType const& m); + + /// Compute the inverse transpose of a matrix. + /// + /// @param m Input matrix to invert transpose. + /// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly innacurate. + /// @see gtc_matrix_inverse + template + GLM_FUNC_DECL genType inverseTranspose(genType const& m); + + /// @} +}//namespace glm + +#include "matrix_inverse.inl" diff --git a/src/other/manifold/glm/glm/gtc/matrix_inverse.inl b/src/other/manifold/glm/glm/gtc/matrix_inverse.inl new file mode 100644 index 00000000000..c004b9e1467 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_inverse.inl @@ -0,0 +1,118 @@ +/// @ref gtc_matrix_inverse + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> affineInverse(mat<3, 3, T, Q> const& m) + { + mat<2, 2, T, Q> const Inv(inverse(mat<2, 2, T, Q>(m))); + + return mat<3, 3, T, Q>( + vec<3, T, Q>(Inv[0], static_cast(0)), + vec<3, T, Q>(Inv[1], static_cast(0)), + vec<3, T, Q>(-Inv * vec<2, T, Q>(m[2]), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> affineInverse(mat<4, 4, T, Q> const& m) + { + mat<3, 3, T, Q> const Inv(inverse(mat<3, 3, T, Q>(m))); + + return mat<4, 4, T, Q>( + vec<4, T, Q>(Inv[0], static_cast(0)), + vec<4, T, Q>(Inv[1], static_cast(0)), + vec<4, T, Q>(Inv[2], static_cast(0)), + vec<4, T, Q>(-Inv * vec<3, T, Q>(m[3]), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> inverseTranspose(mat<2, 2, T, Q> const& m) + { + T Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1]; + + mat<2, 2, T, Q> Inverse( + + m[1][1] / Determinant, + - m[0][1] / Determinant, + - m[1][0] / Determinant, + + m[0][0] / Determinant); + + return Inverse; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> inverseTranspose(mat<3, 3, T, Q> const& m) + { + T Determinant = + + m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) + - m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) + + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); + + mat<3, 3, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]); + Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]); + Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]); + Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]); + Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]); + Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]); + Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]); + Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]); + Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]); + Inverse /= Determinant; + + return Inverse; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> inverseTranspose(mat<4, 4, T, Q> const& m) + { + T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + T SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + T SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + T SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + T SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + T SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + T SubFactor11 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + T SubFactor12 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + T SubFactor13 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + T SubFactor14 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + T SubFactor15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + T SubFactor16 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + T SubFactor17 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + mat<4, 4, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02); + Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04); + Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05); + Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05); + + Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02); + Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04); + Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05); + Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05); + + Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08); + Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10); + Inverse[2][2] = + (m[0][0] * SubFactor07 - m[0][1] * SubFactor09 + m[0][3] * SubFactor11); + Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor11); + + Inverse[3][0] = - (m[0][1] * SubFactor12 - m[0][2] * SubFactor13 + m[0][3] * SubFactor14); + Inverse[3][1] = + (m[0][0] * SubFactor12 - m[0][2] * SubFactor15 + m[0][3] * SubFactor16); + Inverse[3][2] = - (m[0][0] * SubFactor13 - m[0][1] * SubFactor15 + m[0][3] * SubFactor17); + Inverse[3][3] = + (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][2] * SubFactor17); + + T Determinant = + + m[0][0] * Inverse[0][0] + + m[0][1] * Inverse[0][1] + + m[0][2] * Inverse[0][2] + + m[0][3] * Inverse[0][3]; + + Inverse /= Determinant; + + return Inverse; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/matrix_transform.hpp b/src/other/manifold/glm/glm/gtc/matrix_transform.hpp new file mode 100644 index 00000000000..612418fa51c --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_transform.hpp @@ -0,0 +1,36 @@ +/// @ref gtc_matrix_transform +/// @file glm/gtc/matrix_transform.hpp +/// +/// @see core (dependence) +/// @see gtx_transform +/// @see gtx_transform2 +/// +/// @defgroup gtc_matrix_transform GLM_GTC_matrix_transform +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines functions that generate common transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. + +#pragma once + +// Dependencies +#include "../mat4x4.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../ext/matrix_projection.hpp" +#include "../ext/matrix_clip_space.hpp" +#include "../ext/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_transform extension included") +#endif + +#include "matrix_transform.inl" diff --git a/src/other/manifold/glm/glm/gtc/matrix_transform.inl b/src/other/manifold/glm/glm/gtc/matrix_transform.inl new file mode 100644 index 00000000000..15b46bc9db6 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/matrix_transform.inl @@ -0,0 +1,3 @@ +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" diff --git a/src/other/manifold/glm/glm/gtc/noise.hpp b/src/other/manifold/glm/glm/gtc/noise.hpp new file mode 100644 index 00000000000..ab1772e7812 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/noise.hpp @@ -0,0 +1,61 @@ +/// @ref gtc_noise +/// @file glm/gtc/noise.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_noise GLM_GTC_noise +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines 2D, 3D and 4D procedural noise functions +/// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +/// https://github.com/ashima/webgl-noise +/// Following Stefan Gustavson's paper "Simplex noise demystified": +/// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_noise.hpp" +#include "../geometric.hpp" +#include "../common.hpp" +#include "../vector_relational.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_noise extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_noise + /// @{ + + /// Classic perlin noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T perlin( + vec const& p); + + /// Periodic perlin noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T perlin( + vec const& p, + vec const& rep); + + /// Simplex noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T simplex( + vec const& p); + + /// @} +}//namespace glm + +#include "noise.inl" diff --git a/src/other/manifold/glm/glm/gtc/noise.inl b/src/other/manifold/glm/glm/gtc/noise.inl new file mode 100644 index 00000000000..30d0b274d33 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/noise.inl @@ -0,0 +1,807 @@ +/// @ref gtc_noise +/// +// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +// https://github.com/ashima/webgl-noise +// Following Stefan Gustavson's paper "Simplex noise demystified": +// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + +namespace glm{ +namespace gtc +{ + template + GLM_FUNC_QUALIFIER vec<4, T, Q> grad4(T const& j, vec<4, T, Q> const& ip) + { + vec<3, T, Q> pXYZ = floor(fract(vec<3, T, Q>(j) * vec<3, T, Q>(ip)) * T(7)) * ip[2] - T(1); + T pW = static_cast(1.5) - dot(abs(pXYZ), vec<3, T, Q>(1)); + vec<4, T, Q> s = vec<4, T, Q>(lessThan(vec<4, T, Q>(pXYZ, pW), vec<4, T, Q>(0.0))); + pXYZ = pXYZ + (vec<3, T, Q>(s) * T(2) - T(1)) * s.w; + return vec<4, T, Q>(pXYZ, pW); + } +}//namespace gtc + + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position) + { + vec<4, T, Q> Pi = glm::floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + vec<4, T, Q> Pf = glm::fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation + vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z); + vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w); + vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z); + vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w); + + vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy); + + vec<4, T, Q> gx = static_cast(2) * glm::fract(i / T(41)) - T(1); + vec<4, T, Q> gy = glm::abs(gx) - T(0.5); + vec<4, T, Q> tx = glm::floor(gx + T(0.5)); + gx = gx - tx; + + vec<2, T, Q> g00(gx.x, gy.x); + vec<2, T, Q> g10(gx.y, gy.y); + vec<2, T, Q> g01(gx.z, gy.z); + vec<2, T, Q> g11(gx.w, gy.w); + + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x)); + T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y)); + T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z)); + T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w)); + + vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y)); + vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; + } + + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position) + { + vec<3, T, Q> Pi0 = floor(Position); // Integer part for indexing + vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = detail::mod289(Pi0); + Pi1 = detail::mod289(Pi1); + vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(vec<2, T, Q>(Pi0.y), vec<2, T, Q>(Pi1.y)); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 * T(1.0 / 7.0); + vec<4, T, Q> gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0)); + gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); + gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 * T(1.0 / 7.0); + vec<4, T, Q> gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = detail::fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + /* + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& P) + { + vec<3, T, Q> Pi0 = floor(P); // Integer part for indexing + vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, T(289)); + Pi1 = mod(Pi1, T(289)); + vec<3, T, Q> Pf0 = fract(P); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = permute(permute(ix) + iy); + vec<4, T, Q> ixy0 = permute(ixy + iz0); + vec<4, T, Q> ixy1 = permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 / T(7); + vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); + gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 / T(7); + vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix( + vec<2, T, Q>(n_z.x, n_z.y), + vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + */ + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position) + { + vec<4, T, Q> Pi0 = floor(Position); // Integer part for indexing + vec<4, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, vec<4, T, Q>(289)); + Pi1 = mod(Pi1, vec<4, T, Q>(289)); + vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + vec<4, T, Q> iw0(Pi0.w); + vec<4, T, Q> iw1(Pi1.w); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0); + vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1); + vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0); + vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1); + + vec<4, T, Q> gx00 = ixy00 / T(7); + vec<4, T, Q> gy00 = floor(gx00) / T(7); + vec<4, T, Q> gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0.0)); + gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); + gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); + + vec<4, T, Q> gx01 = ixy01 / T(7); + vec<4, T, Q> gy01 = floor(gx01) / T(7); + vec<4, T, Q> gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0)); + gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); + gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); + + vec<4, T, Q> gx10 = ixy10 / T(7); + vec<4, T, Q> gy10 = floor(gx10) / T(7); + vec<4, T, Q> gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0)); + gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); + gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); + + vec<4, T, Q> gx11 = ixy11 / T(7); + vec<4, T, Q> gy11 = floor(gx11) / T(7); + vec<4, T, Q> gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(0.0)); + gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); + gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); + + vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x); + vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y); + vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z); + vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w); + vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x); + vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y); + vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z); + vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w); + vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x); + vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y); + vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z); + vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w); + vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x); + vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y); + vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z); + vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + vec<4, T, Q> fade_xyzw = detail::fade(Pf0); + vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w); + vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w); + vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z); + vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; + } + + // Classic Perlin noise, periodic variant + template + GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position, vec<2, T, Q> const& rep) + { + vec<4, T, Q> Pi = floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + vec<4, T, Q> Pf = fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, vec<4, T, Q>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period + Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation + vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z); + vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w); + vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z); + vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w); + + vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy); + + vec<4, T, Q> gx = static_cast(2) * fract(i / T(41)) - T(1); + vec<4, T, Q> gy = abs(gx) - T(0.5); + vec<4, T, Q> tx = floor(gx + T(0.5)); + gx = gx - tx; + + vec<2, T, Q> g00(gx.x, gy.x); + vec<2, T, Q> g10(gx.y, gy.y); + vec<2, T, Q> g01(gx.z, gy.z); + vec<2, T, Q> g11(gx.w, gy.w); + + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x)); + T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y)); + T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z)); + T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w)); + + vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y)); + vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; + } + + // Classic Perlin noise, periodic variant + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position, vec<3, T, Q> const& rep) + { + vec<3, T, Q> Pi0 = mod(floor(Position), rep); // Integer part, modulo period + vec<3, T, Q> Pi1 = mod(Pi0 + vec<3, T, Q>(T(1)), rep); // Integer part + 1, mod period + Pi0 = mod(Pi0, vec<3, T, Q>(289)); + Pi1 = mod(Pi1, vec<3, T, Q>(289)); + vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - vec<3, T, Q>(T(1)); // Fractional part - 1.0 + vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 / T(7); + vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0)); + gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); + gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 / T(7); + vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(T(0))); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000 = vec<3, T, Q>(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100 = vec<3, T, Q>(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010 = vec<3, T, Q>(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110 = vec<3, T, Q>(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001 = vec<3, T, Q>(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101 = vec<3, T, Q>(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011 = vec<3, T, Q>(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111 = vec<3, T, Q>(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = detail::fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + + // Classic Perlin noise, periodic version + template + GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position, vec<4, T, Q> const& rep) + { + vec<4, T, Q> Pi0 = mod(floor(Position), rep); // Integer part modulo rep + vec<4, T, Q> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep + vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + vec<4, T, Q> iw0(Pi0.w); + vec<4, T, Q> iw1(Pi1.w); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0); + vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1); + vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0); + vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1); + + vec<4, T, Q> gx00 = ixy00 / T(7); + vec<4, T, Q> gy00 = floor(gx00) / T(7); + vec<4, T, Q> gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0)); + gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); + gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); + + vec<4, T, Q> gx01 = ixy01 / T(7); + vec<4, T, Q> gy01 = floor(gx01) / T(7); + vec<4, T, Q> gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0)); + gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); + gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); + + vec<4, T, Q> gx10 = ixy10 / T(7); + vec<4, T, Q> gy10 = floor(gx10) / T(7); + vec<4, T, Q> gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0.0)); + gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); + gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); + + vec<4, T, Q> gx11 = ixy11 / T(7); + vec<4, T, Q> gy11 = floor(gx11) / T(7); + vec<4, T, Q> gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(T(0))); + gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); + gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); + + vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x); + vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y); + vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z); + vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w); + vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x); + vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y); + vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z); + vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w); + vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x); + vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y); + vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z); + vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w); + vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x); + vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y); + vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z); + vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + vec<4, T, Q> fade_xyzw = detail::fade(Pf0); + vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w); + vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w); + vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z); + vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; + } + + template + GLM_FUNC_QUALIFIER T simplex(glm::vec<2, T, Q> const& v) + { + vec<4, T, Q> const C = vec<4, T, Q>( + T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 + T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) + T(-0.577350269189626), // -1.0 + 2.0 * C.x + T( 0.024390243902439)); // 1.0 / 41.0 + + // First corner + vec<2, T, Q> i = floor(v + dot(v, vec<2, T, Q>(C[1]))); + vec<2, T, Q> x0 = v - i + dot(i, vec<2, T, Q>(C[0])); + + // Other corners + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + vec<2, T, Q> i1 = (x0.x > x0.y) ? vec<2, T, Q>(1, 0) : vec<2, T, Q>(0, 1); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + vec<4, T, Q> x12 = vec<4, T, Q>(x0.x, x0.y, x0.x, x0.y) + vec<4, T, Q>(C.x, C.x, C.z, C.z); + x12 = vec<4, T, Q>(vec<2, T, Q>(x12) - i1, x12.z, x12.w); + + // Permutations + i = mod(i, vec<2, T, Q>(289)); // Avoid truncation effects in permutation + vec<3, T, Q> p = detail::permute( + detail::permute(i.y + vec<3, T, Q>(T(0), i1.y, T(1))) + + i.x + vec<3, T, Q>(T(0), i1.x, T(1))); + + vec<3, T, Q> m = max(vec<3, T, Q>(0.5) - vec<3, T, Q>( + dot(x0, x0), + dot(vec<2, T, Q>(x12.x, x12.y), vec<2, T, Q>(x12.x, x12.y)), + dot(vec<2, T, Q>(x12.z, x12.w), vec<2, T, Q>(x12.z, x12.w))), vec<3, T, Q>(0)); + m = m * m ; + m = m * m ; + + // Gradients: 41 points uniformly over a line, mapped onto a diamond. + // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) + + vec<3, T, Q> x = static_cast(2) * fract(p * C.w) - T(1); + vec<3, T, Q> h = abs(x) - T(0.5); + vec<3, T, Q> ox = floor(x + T(0.5)); + vec<3, T, Q> a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); + m *= static_cast(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); + + // Compute final noise value at P + vec<3, T, Q> g; + g.x = a0.x * x0.x + h.x * x0.y; + //g.yz = a0.yz * x12.xz + h.yz * x12.yw; + g.y = a0.y * x12.x + h.y * x12.y; + g.z = a0.z * x12.z + h.z * x12.w; + return T(130) * dot(m, g); + } + + template + GLM_FUNC_QUALIFIER T simplex(vec<3, T, Q> const& v) + { + vec<2, T, Q> const C(1.0 / 6.0, 1.0 / 3.0); + vec<4, T, Q> const D(0.0, 0.5, 1.0, 2.0); + + // First corner + vec<3, T, Q> i(floor(v + dot(v, vec<3, T, Q>(C.y)))); + vec<3, T, Q> x0(v - i + dot(i, vec<3, T, Q>(C.x))); + + // Other corners + vec<3, T, Q> g(step(vec<3, T, Q>(x0.y, x0.z, x0.x), x0)); + vec<3, T, Q> l(T(1) - g); + vec<3, T, Q> i1(min(g, vec<3, T, Q>(l.z, l.x, l.y))); + vec<3, T, Q> i2(max(g, vec<3, T, Q>(l.z, l.x, l.y))); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + vec<3, T, Q> x1(x0 - i1 + C.x); + vec<3, T, Q> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y + vec<3, T, Q> x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = detail::mod289(i); + vec<4, T, Q> p(detail::permute(detail::permute(detail::permute( + i.z + vec<4, T, Q>(T(0), i1.z, i2.z, T(1))) + + i.y + vec<4, T, Q>(T(0), i1.y, i2.y, T(1))) + + i.x + vec<4, T, Q>(T(0), i1.x, i2.x, T(1)))); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + T n_ = static_cast(0.142857142857); // 1.0/7.0 + vec<3, T, Q> ns(n_ * vec<3, T, Q>(D.w, D.y, D.z) - vec<3, T, Q>(D.x, D.z, D.x)); + + vec<4, T, Q> j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) + + vec<4, T, Q> x_(floor(j * ns.z)); + vec<4, T, Q> y_(floor(j - T(7) * x_)); // mod(j,N) + + vec<4, T, Q> x(x_ * ns.x + ns.y); + vec<4, T, Q> y(y_ * ns.x + ns.y); + vec<4, T, Q> h(T(1) - abs(x) - abs(y)); + + vec<4, T, Q> b0(x.x, x.y, y.x, y.y); + vec<4, T, Q> b1(x.z, x.w, y.z, y.w); + + // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec<4, T, Q> s0(floor(b0) * T(2) + T(1)); + vec<4, T, Q> s1(floor(b1) * T(2) + T(1)); + vec<4, T, Q> sh(-step(h, vec<4, T, Q>(0.0))); + + vec<4, T, Q> a0 = vec<4, T, Q>(b0.x, b0.z, b0.y, b0.w) + vec<4, T, Q>(s0.x, s0.z, s0.y, s0.w) * vec<4, T, Q>(sh.x, sh.x, sh.y, sh.y); + vec<4, T, Q> a1 = vec<4, T, Q>(b1.x, b1.z, b1.y, b1.w) + vec<4, T, Q>(s1.x, s1.z, s1.y, s1.w) * vec<4, T, Q>(sh.z, sh.z, sh.w, sh.w); + + vec<3, T, Q> p0(a0.x, a0.y, h.x); + vec<3, T, Q> p1(a0.z, a0.w, h.y); + vec<3, T, Q> p2(a1.x, a1.y, h.z); + vec<3, T, Q> p3(a1.z, a1.w, h.w); + + // Normalise gradients + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec<4, T, Q> m = max(T(0.6) - vec<4, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), vec<4, T, Q>(0)); + m = m * m; + return T(42) * dot(m * m, vec<4, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); + } + + template + GLM_FUNC_QUALIFIER T simplex(vec<4, T, Q> const& v) + { + vec<4, T, Q> const C( + 0.138196601125011, // (5 - sqrt(5))/20 G4 + 0.276393202250021, // 2 * G4 + 0.414589803375032, // 3 * G4 + -0.447213595499958); // -1 + 4 * G4 + + // (sqrt(5) - 1)/4 = F4, used once below + T const F4 = static_cast(0.309016994374947451); + + // First corner + vec<4, T, Q> i = floor(v + dot(v, vec<4, T, Q>(F4))); + vec<4, T, Q> x0 = v - i + dot(i, vec<4, T, Q>(C.x)); + + // Other corners + + // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec<4, T, Q> i0; + vec<3, T, Q> isX = step(vec<3, T, Q>(x0.y, x0.z, x0.w), vec<3, T, Q>(x0.x)); + vec<3, T, Q> isYZ = step(vec<3, T, Q>(x0.z, x0.w, x0.w), vec<3, T, Q>(x0.y, x0.y, x0.z)); + // i0.x = dot(isX, vec3(1.0)); + //i0.x = isX.x + isX.y + isX.z; + //i0.yzw = static_cast(1) - isX; + i0 = vec<4, T, Q>(isX.x + isX.y + isX.z, T(1) - isX); + // i0.y += dot(isYZ.xy, vec2(1.0)); + i0.y += isYZ.x + isYZ.y; + //i0.zw += 1.0 - vec<2, T, Q>(isYZ.x, isYZ.y); + i0.z += static_cast(1) - isYZ.x; + i0.w += static_cast(1) - isYZ.y; + i0.z += isYZ.z; + i0.w += static_cast(1) - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec<4, T, Q> i3 = clamp(i0, T(0), T(1)); + vec<4, T, Q> i2 = clamp(i0 - T(1), T(0), T(1)); + vec<4, T, Q> i1 = clamp(i0 - T(2), T(0), T(1)); + + // x0 = x0 - 0.0 + 0.0 * C.xxxx + // x1 = x0 - i1 + 0.0 * C.xxxx + // x2 = x0 - i2 + 0.0 * C.xxxx + // x3 = x0 - i3 + 0.0 * C.xxxx + // x4 = x0 - 1.0 + 4.0 * C.xxxx + vec<4, T, Q> x1 = x0 - i1 + C.x; + vec<4, T, Q> x2 = x0 - i2 + C.y; + vec<4, T, Q> x3 = x0 - i3 + C.z; + vec<4, T, Q> x4 = x0 + C.w; + + // Permutations + i = mod(i, vec<4, T, Q>(289)); + T j0 = detail::permute(detail::permute(detail::permute(detail::permute(i.w) + i.z) + i.y) + i.x); + vec<4, T, Q> j1 = detail::permute(detail::permute(detail::permute(detail::permute( + i.w + vec<4, T, Q>(i1.w, i2.w, i3.w, T(1))) + + i.z + vec<4, T, Q>(i1.z, i2.z, i3.z, T(1))) + + i.y + vec<4, T, Q>(i1.y, i2.y, i3.y, T(1))) + + i.x + vec<4, T, Q>(i1.x, i2.x, i3.x, T(1))); + + // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope + // 7*7*6 = 294, which is close to the ring size 17*17 = 289. + vec<4, T, Q> ip = vec<4, T, Q>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); + + vec<4, T, Q> p0 = gtc::grad4(j0, ip); + vec<4, T, Q> p1 = gtc::grad4(j1.x, ip); + vec<4, T, Q> p2 = gtc::grad4(j1.y, ip); + vec<4, T, Q> p3 = gtc::grad4(j1.z, ip); + vec<4, T, Q> p4 = gtc::grad4(j1.w, ip); + + // Normalise gradients + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= detail::taylorInvSqrt(dot(p4, p4)); + + // Mix contributions from the five corners + vec<3, T, Q> m0 = max(T(0.6) - vec<3, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), vec<3, T, Q>(0)); + vec<2, T, Q> m1 = max(T(0.6) - vec<2, T, Q>(dot(x3, x3), dot(x4, x4) ), vec<2, T, Q>(0)); + m0 = m0 * m0; + m1 = m1 * m1; + return T(49) * + (dot(m0 * m0, vec<3, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + + dot(m1 * m1, vec<2, T, Q>(dot(p3, x3), dot(p4, x4)))); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/packing.hpp b/src/other/manifold/glm/glm/gtc/packing.hpp new file mode 100644 index 00000000000..8e416b3fe1b --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/packing.hpp @@ -0,0 +1,728 @@ +/// @ref gtc_packing +/// @file glm/gtc/packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_packing GLM_GTC_packing +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert vertors to packed +/// formats. + +#pragma once + +// Dependency: +#include "type_precision.hpp" +#include "../ext/vector_packing.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_packing + /// @{ + + /// First, converts the normalized floating-point value v into a 8-bit integer value. + /// Then, the results are packed into the returned 8-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm1x8: round(clamp(c, 0, +1) * 255.0) + /// + /// @see gtc_packing + /// @see uint16 packUnorm2x8(vec2 const& v) + /// @see uint32 packUnorm4x8(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint8 packUnorm1x8(float v); + + /// Convert a single 8-bit integer to a normalized floating-point value. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x8(uint16 p) + /// @see vec4 unpackUnorm4x8(uint32 p) + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackUnorm1x8(uint8 p); + + /// First, converts each component of the normalized floating-point value v into 8-bit integer values. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm2x8: round(clamp(c, 0, +1) * 255.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint8 packUnorm1x8(float const& v) + /// @see uint32 packUnorm4x8(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packUnorm2x8(vec2 const& v); + + /// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit unsigned integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackUnorm1x8(uint8 v) + /// @see vec4 unpackUnorm4x8(uint32 p) + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackUnorm2x8(uint16 p); + + /// First, converts the normalized floating-point value v into 8-bit integer value. + /// Then, the results are packed into the returned 8-bit unsigned integer. + /// + /// The conversion to fixed point is done as follows: + /// packSnorm1x8: round(clamp(s, -1, +1) * 127.0) + /// + /// @see gtc_packing + /// @see uint16 packSnorm2x8(vec2 const& v) + /// @see uint32 packSnorm4x8(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint8 packSnorm1x8(float s); + + /// First, unpacks a single 8-bit unsigned integer p into a single 8-bit signed integers. + /// Then, the value is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm1x8: clamp(f / 127.0, -1, +1) + /// + /// @see gtc_packing + /// @see vec2 unpackSnorm2x8(uint16 p) + /// @see vec4 unpackSnorm4x8(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackSnorm1x8(uint8 p); + + /// First, converts each component of the normalized floating-point value v into 8-bit integer values. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x8: round(clamp(c, -1, +1) * 127.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint8 packSnorm1x8(float const& v) + /// @see uint32 packSnorm4x8(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packSnorm2x8(vec2 const& v); + + /// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm2x8: clamp(f / 127.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackSnorm1x8(uint8 p) + /// @see vec4 unpackSnorm4x8(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackSnorm2x8(uint16 p); + + /// First, converts the normalized floating-point value v into a 16-bit integer value. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm1x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// @see gtc_packing + /// @see uint16 packSnorm1x16(float const& v) + /// @see uint64 packSnorm4x16(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packUnorm1x16(float v); + + /// First, unpacks a single 16-bit unsigned integer p into a of 16-bit unsigned integers. + /// Then, the value is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm1x16: f / 65535.0 + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x16(uint32 p) + /// @see vec4 unpackUnorm4x16(uint64 p) + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackUnorm1x16(uint16 p); + + /// First, converts each component of the normalized floating-point value v into 16-bit integer values. + /// Then, the results are packed into the returned 64-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm4x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint16 packUnorm1x16(float const& v) + /// @see uint32 packUnorm2x16(vec2 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packUnorm4x16(vec4 const& v); + + /// First, unpacks a single 64-bit unsigned integer p into four 16-bit unsigned integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnormx4x16: f / 65535.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackUnorm1x16(uint16 p) + /// @see vec2 unpackUnorm2x16(uint32 p) + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackUnorm4x16(uint64 p); + + /// First, converts the normalized floating-point value v into 16-bit integer value. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion to fixed point is done as follows: + /// packSnorm1x8: round(clamp(s, -1, +1) * 32767.0) + /// + /// @see gtc_packing + /// @see uint32 packSnorm2x16(vec2 const& v) + /// @see uint64 packSnorm4x16(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packSnorm1x16(float v); + + /// First, unpacks a single 16-bit unsigned integer p into a single 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm1x16: clamp(f / 32767.0, -1, +1) + /// + /// @see gtc_packing + /// @see vec2 unpackSnorm2x16(uint32 p) + /// @see vec4 unpackSnorm4x16(uint64 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackSnorm1x16(uint16 p); + + /// First, converts each component of the normalized floating-point value v into 16-bit integer values. + /// Then, the results are packed into the returned 64-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x8: round(clamp(c, -1, +1) * 32767.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint16 packSnorm1x16(float const& v) + /// @see uint32 packSnorm2x16(vec2 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packSnorm4x16(vec4 const& v); + + /// First, unpacks a single 64-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm4x16: clamp(f / 32767.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackSnorm1x16(uint16 p) + /// @see vec2 unpackSnorm2x16(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackSnorm4x16(uint64 p); + + /// Returns an unsigned integer obtained by converting the components of a floating-point scalar + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing this 16-bit value into a 16-bit unsigned integer. + /// + /// @see gtc_packing + /// @see uint32 packHalf2x16(vec2 const& v) + /// @see uint64 packHalf4x16(vec4 const& v) + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packHalf1x16(float v); + + /// Returns a floating-point scalar with components obtained by unpacking a 16-bit unsigned integer into a 16-bit value, + /// interpreted as a 16-bit floating-point number according to the OpenGL Specification, + /// and converting it to 32-bit floating-point values. + /// + /// @see gtc_packing + /// @see vec2 unpackHalf2x16(uint32 const& v) + /// @see vec4 unpackHalf4x16(uint64 const& v) + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackHalf1x16(uint16 v); + + /// Returns an unsigned integer obtained by converting the components of a four-component floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing these four 16-bit values into a 64-bit unsigned integer. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see uint16 packHalf1x16(float const& v) + /// @see uint32 packHalf2x16(vec2 const& v) + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packHalf4x16(vec4 const& v); + + /// Returns a four-component floating-point vector with components obtained by unpacking a 64-bit unsigned integer into four 16-bit values, + /// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification, + /// and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see float unpackHalf1x16(uint16 const& v) + /// @see vec2 unpackHalf2x16(uint32 const& v) + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackHalf4x16(uint64 p); + + /// Returns an unsigned integer obtained by converting the components of a four-component signed integer vector + /// to the 10-10-10-2-bit signed integer representation found in the OpenGL Specification, + /// and then packing these four values into a 32-bit unsigned integer. + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see uint32 packI3x10_1x2(uvec4 const& v) + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see ivec4 unpackI3x10_1x2(uint32 const& p) + GLM_FUNC_DECL uint32 packI3x10_1x2(ivec4 const& v); + + /// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit signed integers. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p); + /// @see uvec4 unpackI3x10_1x2(uint32 const& p); + GLM_FUNC_DECL ivec4 unpackI3x10_1x2(uint32 p); + + /// Returns an unsigned integer obtained by converting the components of a four-component unsigned integer vector + /// to the 10-10-10-2-bit unsigned integer representation found in the OpenGL Specification, + /// and then packing these four values into a 32-bit unsigned integer. + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see uint32 packI3x10_1x2(ivec4 const& v) + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see ivec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL uint32 packU3x10_1x2(uvec4 const& v); + + /// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit unsigned integers. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p); + /// @see uvec4 unpackI3x10_1x2(uint32 const& p); + GLM_FUNC_DECL uvec4 unpackU3x10_1x2(uint32 p); + + /// First, converts the first three components of the normalized floating-point value v into 10-bit signed integer values. + /// Then, converts the forth component of the normalized floating-point value v into 2-bit signed integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm3x10_1x2(xyz): round(clamp(c, -1, +1) * 511.0) + /// packSnorm3x10_1x2(w): round(clamp(c, -1, +1) * 1.0) + /// + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see uint32 packI3x10_1x2(ivec4 const& v) + GLM_FUNC_DECL uint32 packSnorm3x10_1x2(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm3x10_1x2(xyz): clamp(f / 511.0, -1, +1) + /// unpackSnorm3x10_1x2(w): clamp(f / 511.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see vec4 unpackUnorm3x10_1x2(uint32 const& p)) + /// @see uvec4 unpackI3x10_1x2(uint32 const& p) + /// @see uvec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL vec4 unpackSnorm3x10_1x2(uint32 p); + + /// First, converts the first three components of the normalized floating-point value v into 10-bit unsigned integer values. + /// Then, converts the forth component of the normalized floating-point value v into 2-bit signed uninteger values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm3x10_1x2(xyz): round(clamp(c, 0, +1) * 1023.0) + /// packUnorm3x10_1x2(w): round(clamp(c, 0, +1) * 3.0) + /// + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm3x10_1x2(uint32 const& p) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see uint32 packI3x10_1x2(ivec4 const& v) + GLM_FUNC_DECL uint32 packUnorm3x10_1x2(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm3x10_1x2(xyz): clamp(f / 1023.0, 0, +1) + /// unpackSnorm3x10_1x2(w): clamp(f / 3.0, 0, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see vec4 unpackInorm3x10_1x2(uint32 const& p)) + /// @see uvec4 unpackI3x10_1x2(uint32 const& p) + /// @see uvec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL vec4 unpackUnorm3x10_1x2(uint32 p); + + /// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values. + /// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The first vector component specifies the 11 least-significant bits of the result; + /// the last component specifies the 10 most-significant bits. + /// + /// @see gtc_packing + /// @see vec3 unpackF2x11_1x10(uint32 const& p) + GLM_FUNC_DECL uint32 packF2x11_1x10(vec3 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value . + /// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packF2x11_1x10(vec3 const& v) + GLM_FUNC_DECL vec3 unpackF2x11_1x10(uint32 p); + + + /// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values. + /// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The first vector component specifies the 11 least-significant bits of the result; + /// the last component specifies the 10 most-significant bits. + /// + /// packF3x9_E1x5 allows encoding into RGBE / RGB9E5 format + /// + /// @see gtc_packing + /// @see vec3 unpackF3x9_E1x5(uint32 const& p) + GLM_FUNC_DECL uint32 packF3x9_E1x5(vec3 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value . + /// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// unpackF3x9_E1x5 allows decoding RGBE / RGB9E5 data + /// + /// @see gtc_packing + /// @see uint32 packF3x9_E1x5(vec3 const& v) + GLM_FUNC_DECL vec3 unpackF3x9_E1x5(uint32 p); + + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& p) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb); + + /// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see vec<4, T, Q> packRGBM(vec<3, float, Q> const& v) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm); + + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see vec unpackHalf(vec const& p) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec packHalf(vec const& v); + + /// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see vec packHalf(vec const& v) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec unpackHalf(vec const& p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec unpackUnorm(vec const& p); + template + GLM_FUNC_DECL vec packUnorm(vec const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see vec packUnorm(vec const& v) + template + GLM_FUNC_DECL vec unpackUnorm(vec const& v); + + /// Convert each component of the normalized floating-point vector into signed integer values. + /// + /// @see gtc_packing + /// @see vec unpackSnorm(vec const& p); + template + GLM_FUNC_DECL vec packSnorm(vec const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see vec packSnorm(vec const& v) + template + GLM_FUNC_DECL vec unpackSnorm(vec const& v); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x4(uint8 p) + GLM_FUNC_DECL uint8 packUnorm2x4(vec2 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint8 packUnorm2x4(vec2 const& v) + GLM_FUNC_DECL vec2 unpackUnorm2x4(uint8 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm4x4(uint16 p) + GLM_FUNC_DECL uint16 packUnorm4x4(vec4 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm4x4(vec4 const& v) + GLM_FUNC_DECL vec4 unpackUnorm4x4(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec3 unpackUnorm1x5_1x6_1x5(uint16 p) + GLM_FUNC_DECL uint16 packUnorm1x5_1x6_1x5(vec3 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm1x5_1x6_1x5(vec3 const& v) + GLM_FUNC_DECL vec3 unpackUnorm1x5_1x6_1x5(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm3x5_1x1(uint16 p) + GLM_FUNC_DECL uint16 packUnorm3x5_1x1(vec4 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm3x5_1x1(vec4 const& v) + GLM_FUNC_DECL vec4 unpackUnorm3x5_1x1(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec3 unpackUnorm2x3_1x2(uint8 p) + GLM_FUNC_DECL uint8 packUnorm2x3_1x2(vec3 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint8 packUnorm2x3_1x2(vec3 const& v) + GLM_FUNC_DECL vec3 unpackUnorm2x3_1x2(uint8 p); + + + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i8vec2 unpackInt2x8(int16 p) + GLM_FUNC_DECL int16 packInt2x8(i8vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int16 packInt2x8(i8vec2 const& v) + GLM_FUNC_DECL i8vec2 unpackInt2x8(int16 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u8vec2 unpackInt2x8(uint16 p) + GLM_FUNC_DECL uint16 packUint2x8(u8vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint16 packInt2x8(u8vec2 const& v) + GLM_FUNC_DECL u8vec2 unpackUint2x8(uint16 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i8vec4 unpackInt4x8(int32 p) + GLM_FUNC_DECL int32 packInt4x8(i8vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int32 packInt2x8(i8vec4 const& v) + GLM_FUNC_DECL i8vec4 unpackInt4x8(int32 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u8vec4 unpackUint4x8(uint32 p) + GLM_FUNC_DECL uint32 packUint4x8(u8vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint32 packUint4x8(u8vec2 const& v) + GLM_FUNC_DECL u8vec4 unpackUint4x8(uint32 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i16vec2 unpackInt2x16(int p) + GLM_FUNC_DECL int packInt2x16(i16vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packInt2x16(i16vec2 const& v) + GLM_FUNC_DECL i16vec2 unpackInt2x16(int p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i16vec4 unpackInt4x16(int64 p) + GLM_FUNC_DECL int64 packInt4x16(i16vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int64 packInt4x16(i16vec4 const& v) + GLM_FUNC_DECL i16vec4 unpackInt4x16(int64 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u16vec2 unpackUint2x16(uint p) + GLM_FUNC_DECL uint packUint2x16(u16vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint packUint2x16(u16vec2 const& v) + GLM_FUNC_DECL u16vec2 unpackUint2x16(uint p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u16vec4 unpackUint4x16(uint64 p) + GLM_FUNC_DECL uint64 packUint4x16(u16vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint64 packUint4x16(u16vec4 const& v) + GLM_FUNC_DECL u16vec4 unpackUint4x16(uint64 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i32vec2 unpackInt2x32(int p) + GLM_FUNC_DECL int64 packInt2x32(i32vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packInt2x16(i32vec2 const& v) + GLM_FUNC_DECL i32vec2 unpackInt2x32(int64 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u32vec2 unpackUint2x32(int p) + GLM_FUNC_DECL uint64 packUint2x32(u32vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packUint2x16(u32vec2 const& v) + GLM_FUNC_DECL u32vec2 unpackUint2x32(uint64 p); + + /// @} +}// namespace glm + +#include "packing.inl" diff --git a/src/other/manifold/glm/glm/gtc/packing.inl b/src/other/manifold/glm/glm/gtc/packing.inl new file mode 100644 index 00000000000..8c906e16c11 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/packing.inl @@ -0,0 +1,938 @@ +/// @ref gtc_packing + +#include "../ext/scalar_relational.hpp" +#include "../ext/vector_relational.hpp" +#include "../common.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../detail/type_half.hpp" +#include +#include + +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER glm::uint16 float2half(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((f >> 16) & 0x8000) | // sign + ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential + ((f >> 13) & 0x03ff); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 float2packed11(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x000007c0 => 00000000 00000000 00000111 11000000 + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential + ((f >> 17) & 0x003f); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 packed11ToFloat(glm::uint32 p) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x000007c0 => 00000000 00000000 00000111 11000000 + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((p & 0x07c0) << 17) + 0x38000000) & 0x7f800000) | // exponential + ((p & 0x003f) << 17); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 float2packed10(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x0000001F => 00000000 00000000 00000000 00011111 + // 0x0000003F => 00000000 00000000 00000000 00111111 + // 0x000003E0 => 00000000 00000000 00000011 11100000 + // 0x000007C0 => 00000000 00000000 00000111 11000000 + // 0x00007C00 => 00000000 00000000 01111100 00000000 + // 0x000003FF => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential + ((f >> 18) & 0x001f); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 packed10ToFloat(glm::uint32 p) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x0000001F => 00000000 00000000 00000000 00011111 + // 0x0000003F => 00000000 00000000 00000000 00111111 + // 0x000003E0 => 00000000 00000000 00000011 11100000 + // 0x000007C0 => 00000000 00000000 00000111 11000000 + // 0x00007C00 => 00000000 00000000 01111100 00000000 + // 0x000003FF => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((p & 0x03E0) << 18) + 0x38000000) & 0x7f800000) | // exponential + ((p & 0x001f) << 18); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint half2float(glm::uint h) + { + return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13); + } + + GLM_FUNC_QUALIFIER glm::uint floatTo11bit(float x) + { + if(x == 0.0f) + return 0u; + else if(glm::isnan(x)) + return ~0u; + else if(glm::isinf(x)) + return 0x1Fu << 6u; + + uint Pack = 0u; + memcpy(&Pack, &x, sizeof(Pack)); + return float2packed11(Pack); + } + + GLM_FUNC_QUALIFIER float packed11bitToFloat(glm::uint x) + { + if(x == 0) + return 0.0f; + else if(x == ((1 << 11) - 1)) + return ~0;//NaN + else if(x == (0x1f << 6)) + return ~0;//Inf + + uint Result = packed11ToFloat(x); + + float Temp = 0; + memcpy(&Temp, &Result, sizeof(Temp)); + return Temp; + } + + GLM_FUNC_QUALIFIER glm::uint floatTo10bit(float x) + { + if(x == 0.0f) + return 0u; + else if(glm::isnan(x)) + return ~0u; + else if(glm::isinf(x)) + return 0x1Fu << 5u; + + uint Pack = 0; + memcpy(&Pack, &x, sizeof(Pack)); + return float2packed10(Pack); + } + + GLM_FUNC_QUALIFIER float packed10bitToFloat(glm::uint x) + { + if(x == 0) + return 0.0f; + else if(x == ((1 << 10) - 1)) + return ~0;//NaN + else if(x == (0x1f << 5)) + return ~0;//Inf + + uint Result = packed10ToFloat(x); + + float Temp = 0; + memcpy(&Temp, &Result, sizeof(Temp)); + return Temp; + } + +// GLM_FUNC_QUALIFIER glm::uint f11_f11_f10(float x, float y, float z) +// { +// return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) | ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22); +// } + + union u3u3u2 + { + struct + { + uint x : 3; + uint y : 3; + uint z : 2; + } data; + uint8 pack; + }; + + union u4u4 + { + struct + { + uint x : 4; + uint y : 4; + } data; + uint8 pack; + }; + + union u4u4u4u4 + { + struct + { + uint x : 4; + uint y : 4; + uint z : 4; + uint w : 4; + } data; + uint16 pack; + }; + + union u5u6u5 + { + struct + { + uint x : 5; + uint y : 6; + uint z : 5; + } data; + uint16 pack; + }; + + union u5u5u5u1 + { + struct + { + uint x : 5; + uint y : 5; + uint z : 5; + uint w : 1; + } data; + uint16 pack; + }; + + union u10u10u10u2 + { + struct + { + uint x : 10; + uint y : 10; + uint z : 10; + uint w : 2; + } data; + uint32 pack; + }; + + union i10i10i10i2 + { + struct + { + int x : 10; + int y : 10; + int z : 10; + int w : 2; + } data; + uint32 pack; + }; + + union u9u9u9e5 + { + struct + { + uint x : 9; + uint y : 9; + uint z : 9; + uint w : 5; + } data; + uint32 pack; + }; + + template + struct compute_half + {}; + + template + struct compute_half<1, Q> + { + GLM_FUNC_QUALIFIER static vec<1, uint16, Q> pack(vec<1, float, Q> const& v) + { + int16 const Unpack(detail::toFloat16(v.x)); + u16vec1 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v) + { + i16vec1 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<1, float, Q>(detail::toFloat32(v.x)); + } + }; + + template + struct compute_half<2, Q> + { + GLM_FUNC_QUALIFIER static vec<2, uint16, Q> pack(vec<2, float, Q> const& v) + { + vec<2, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y)); + u16vec2 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<2, float, Q> unpack(vec<2, uint16, Q> const& v) + { + i16vec2 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<2, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y)); + } + }; + + template + struct compute_half<3, Q> + { + GLM_FUNC_QUALIFIER static vec<3, uint16, Q> pack(vec<3, float, Q> const& v) + { + vec<3, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z)); + u16vec3 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<3, float, Q> unpack(vec<3, uint16, Q> const& v) + { + i16vec3 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<3, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z)); + } + }; + + template + struct compute_half<4, Q> + { + GLM_FUNC_QUALIFIER static vec<4, uint16, Q> pack(vec<4, float, Q> const& v) + { + vec<4, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w)); + u16vec4 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<4, float, Q> unpack(vec<4, uint16, Q> const& v) + { + i16vec4 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<4, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z), detail::toFloat32(v.w)); + } + }; +}//namespace detail + + GLM_FUNC_QUALIFIER uint8 packUnorm1x8(float v) + { + return static_cast(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + } + + GLM_FUNC_QUALIFIER float unpackUnorm1x8(uint8 p) + { + float const Unpack(p); + return Unpack * static_cast(0.0039215686274509803921568627451); // 1 / 255 + } + + GLM_FUNC_QUALIFIER uint16 packUnorm2x8(vec2 const& v) + { + u8vec2 const Topack(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + + uint16 Unpack = 0; + memcpy(&Unpack, &Topack, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x8(uint16 p) + { + u8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return vec2(Unpack) * float(0.0039215686274509803921568627451); // 1 / 255 + } + + GLM_FUNC_QUALIFIER uint8 packSnorm1x8(float v) + { + int8 const Topack(static_cast(round(clamp(v ,-1.0f, 1.0f) * 127.0f))); + uint8 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackSnorm1x8(uint8 p) + { + int8 Unpack = 0; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + static_cast(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packSnorm2x8(vec2 const& v) + { + i8vec2 const Topack(round(clamp(v, -1.0f, 1.0f) * 127.0f)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec2 unpackSnorm2x8(uint16 p) + { + i8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + vec2(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packUnorm1x16(float s) + { + return static_cast(round(clamp(s, 0.0f, 1.0f) * 65535.0f)); + } + + GLM_FUNC_QUALIFIER float unpackUnorm1x16(uint16 p) + { + float const Unpack(p); + return Unpack * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0 + } + + GLM_FUNC_QUALIFIER uint64 packUnorm4x16(vec4 const& v) + { + u16vec4 const Topack(round(clamp(v , 0.0f, 1.0f) * 65535.0f)); + uint64 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x16(uint64 p) + { + u16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return vec4(Unpack) * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0 + } + + GLM_FUNC_QUALIFIER uint16 packSnorm1x16(float v) + { + int16 const Topack = static_cast(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackSnorm1x16(uint16 p) + { + int16 Unpack = 0; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + static_cast(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f, + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint64 packSnorm4x16(vec4 const& v) + { + i16vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); + uint64 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec4 unpackSnorm4x16(uint64 p) + { + i16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + vec4(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f, + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packHalf1x16(float v) + { + int16 const Topack(detail::toFloat16(v)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackHalf1x16(uint16 v) + { + int16 Unpack = 0; + memcpy(&Unpack, &v, sizeof(Unpack)); + return detail::toFloat32(Unpack); + } + + GLM_FUNC_QUALIFIER uint64 packHalf4x16(glm::vec4 const& v) + { + i16vec4 const Unpack( + detail::toFloat16(v.x), + detail::toFloat16(v.y), + detail::toFloat16(v.z), + detail::toFloat16(v.w)); + uint64 Packed = 0; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER glm::vec4 unpackHalf4x16(uint64 v) + { + i16vec4 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec4( + detail::toFloat32(Unpack.x), + detail::toFloat32(Unpack.y), + detail::toFloat32(Unpack.z), + detail::toFloat32(Unpack.w)); + } + + GLM_FUNC_QUALIFIER uint32 packI3x10_1x2(ivec4 const& v) + { + detail::i10i10i10i2 Result; + Result.data.x = v.x; + Result.data.y = v.y; + Result.data.z = v.z; + Result.data.w = v.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER ivec4 unpackI3x10_1x2(uint32 v) + { + detail::i10i10i10i2 Unpack; + Unpack.pack = v; + return ivec4( + Unpack.data.x, + Unpack.data.y, + Unpack.data.z, + Unpack.data.w); + } + + GLM_FUNC_QUALIFIER uint32 packU3x10_1x2(uvec4 const& v) + { + detail::u10u10u10u2 Result; + Result.data.x = v.x; + Result.data.y = v.y; + Result.data.z = v.z; + Result.data.w = v.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER uvec4 unpackU3x10_1x2(uint32 v) + { + detail::u10u10u10u2 Unpack; + Unpack.pack = v; + return uvec4( + Unpack.data.x, + Unpack.data.y, + Unpack.data.z, + Unpack.data.w); + } + + GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const& v) + { + ivec4 const Pack(round(clamp(v,-1.0f, 1.0f) * vec4(511.f, 511.f, 511.f, 1.f))); + + detail::i10i10i10i2 Result; + Result.data.x = Pack.x; + Result.data.y = Pack.y; + Result.data.z = Pack.z; + Result.data.w = Pack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackSnorm3x10_1x2(uint32 v) + { + detail::i10i10i10i2 Unpack; + Unpack.pack = v; + + vec4 const Result(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w); + + return clamp(Result * vec4(1.f / 511.f, 1.f / 511.f, 1.f / 511.f, 1.f), -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint32 packUnorm3x10_1x2(vec4 const& v) + { + uvec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(1023.f, 1023.f, 1023.f, 3.f))); + + detail::u10u10u10u2 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm3x10_1x2(uint32 v) + { + vec4 const ScaleFactors(1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 3.f); + + detail::u10u10u10u2 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactors; + } + + GLM_FUNC_QUALIFIER uint32 packF2x11_1x10(vec3 const& v) + { + return + ((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) | + ((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) | + ((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22); + } + + GLM_FUNC_QUALIFIER vec3 unpackF2x11_1x10(uint32 v) + { + return vec3( + detail::packed11bitToFloat(v >> 0), + detail::packed11bitToFloat(v >> 11), + detail::packed10bitToFloat(v >> 22)); + } + + GLM_FUNC_QUALIFIER uint32 packF3x9_E1x5(vec3 const& v) + { + float const SharedExpMax = (pow(2.0f, 9.0f - 1.0f) / pow(2.0f, 9.0f)) * pow(2.0f, 31.f - 15.f); + vec3 const Color = clamp(v, 0.0f, SharedExpMax); + float const MaxColor = max(Color.x, max(Color.y, Color.z)); + + float const ExpSharedP = max(-15.f - 1.f, floor(log2(MaxColor))) + 1.0f + 15.f; + float const MaxShared = floor(MaxColor / pow(2.0f, (ExpSharedP - 15.f - 9.f)) + 0.5f); + float const ExpShared = equal(MaxShared, pow(2.0f, 9.0f), epsilon()) ? ExpSharedP + 1.0f : ExpSharedP; + + uvec3 const ColorComp(floor(Color / pow(2.f, (ExpShared - 15.f - 9.f)) + 0.5f)); + + detail::u9u9u9e5 Unpack; + Unpack.data.x = ColorComp.x; + Unpack.data.y = ColorComp.y; + Unpack.data.z = ColorComp.z; + Unpack.data.w = uint(ExpShared); + return Unpack.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackF3x9_E1x5(uint32 v) + { + detail::u9u9u9e5 Unpack; + Unpack.pack = v; + + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f); + } + + // Based on Brian Karis http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html + template + GLM_FUNC_QUALIFIER vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb) + { + vec<3, T, Q> const Color(rgb * static_cast(1.0 / 6.0)); + T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast(1e-6))), static_cast(0), static_cast(1)); + Alpha = ceil(Alpha * static_cast(255.0)) / static_cast(255.0); + return vec<4, T, Q>(Color / Alpha, Alpha); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm) + { + return vec<3, T, Q>(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast(6); + } + + template + GLM_FUNC_QUALIFIER vec packHalf(vec const& v) + { + return detail::compute_half::pack(v); + } + + template + GLM_FUNC_QUALIFIER vec unpackHalf(vec const& v) + { + return detail::compute_half::unpack(v); + } + + template + GLM_FUNC_QUALIFIER vec packUnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(round(clamp(v, static_cast(0), static_cast(1)) * static_cast(std::numeric_limits::max()))); + } + + template + GLM_FUNC_QUALIFIER vec unpackUnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(v) * (static_cast(1) / static_cast(std::numeric_limits::max())); + } + + template + GLM_FUNC_QUALIFIER vec packSnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(round(clamp(v , static_cast(-1), static_cast(1)) * static_cast(std::numeric_limits::max()))); + } + + template + GLM_FUNC_QUALIFIER vec unpackSnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return clamp(vec(v) * (static_cast(1) / static_cast(std::numeric_limits::max())), static_cast(-1), static_cast(1)); + } + + GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const& v) + { + u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); + detail::u4u4 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v) + { + float const ScaleFactor(1.f / 15.f); + detail::u4u4 Unpack; + Unpack.pack = v; + return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const& v) + { + u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); + detail::u4u4u4u4 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v) + { + float const ScaleFactor(1.f / 15.f); + detail::u4u4u4u4 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const& v) + { + u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(31.f, 63.f, 31.f))); + detail::u5u6u5 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v) + { + vec3 const ScaleFactor(1.f / 31.f, 1.f / 63.f, 1.f / 31.f); + detail::u5u6u5 Unpack; + Unpack.pack = v; + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const& v) + { + u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(31.f, 31.f, 31.f, 1.f))); + detail::u5u5u5u1 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v) + { + vec4 const ScaleFactor(1.f / 31.f, 1.f / 31.f, 1.f / 31.f, 1.f); + detail::u5u5u5u1 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint8 packUnorm2x3_1x2(vec3 const& v) + { + u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(7.f, 7.f, 3.f))); + detail::u3u3u2 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackUnorm2x3_1x2(uint8 v) + { + vec3 const ScaleFactor(1.f / 7.f, 1.f / 7.f, 1.f / 3.f); + detail::u3u3u2 Unpack; + Unpack.pack = v; + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER int16 packInt2x8(i8vec2 const& v) + { + int16 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p) + { + i8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint16 packUint2x8(u8vec2 const& v) + { + uint16 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p) + { + u8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int32 packInt4x8(i8vec4 const& v) + { + int32 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p) + { + i8vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint32 packUint4x8(u8vec4 const& v) + { + uint32 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p) + { + u8vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int packInt2x16(i16vec2 const& v) + { + int Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p) + { + i16vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int64 packInt4x16(i16vec4 const& v) + { + int64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p) + { + i16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint packUint2x16(u16vec2 const& v) + { + uint Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p) + { + u16vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint64 packUint4x16(u16vec4 const& v) + { + uint64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p) + { + u16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int64 packInt2x32(i32vec2 const& v) + { + int64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p) + { + i32vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint64 packUint2x32(u32vec2 const& v) + { + uint64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p) + { + u32vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtc/quaternion.hpp b/src/other/manifold/glm/glm/gtc/quaternion.hpp new file mode 100644 index 00000000000..359e072b9fa --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/quaternion.hpp @@ -0,0 +1,173 @@ +/// @ref gtc_quaternion +/// @file glm/gtc/quaternion.hpp +/// +/// @see core (dependence) +/// @see gtc_constants (dependence) +/// +/// @defgroup gtc_quaternion GLM_GTC_quaternion +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines a templated quaternion type and several quaternion operations. + +#pragma once + +// Dependency: +#include "../gtc/constants.hpp" +#include "../gtc/matrix_transform.hpp" +#include "../ext/vector_relational.hpp" +#include "../ext/quaternion_common.hpp" +#include "../ext/quaternion_float.hpp" +#include "../ext/quaternion_float_precision.hpp" +#include "../ext/quaternion_double.hpp" +#include "../ext/quaternion_double_precision.hpp" +#include "../ext/quaternion_relational.hpp" +#include "../ext/quaternion_geometric.hpp" +#include "../ext/quaternion_trigonometric.hpp" +#include "../ext/quaternion_transform.hpp" +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat4x4.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_quaternion extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_quaternion + /// @{ + + /// Returns euler angles, pitch as x, yaw as y, roll as z. + /// The result is expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua const& x); + + /// Returns roll value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T roll(qua const& x); + + /// Returns pitch value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T pitch(qua const& x); + + /// Returns yaw value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T yaw(qua const& x); + + /// Converts a quaternion to a 3 * 3 matrix. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL mat<3, 3, T, Q> mat3_cast(qua const& x); + + /// Converts a quaternion to a 4 * 4 matrix. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL mat<4, 4, T, Q> mat4_cast(qua const& x); + + /// Converts a pure rotation 3 * 3 matrix to a quaternion. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL qua quat_cast(mat<3, 3, T, Q> const& x); + + /// Converts a pure rotation 4 * 4 matrix to a quaternion. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL qua quat_cast(mat<4, 4, T, Q> const& x); + + /// Returns the component-wise comparison result of x < y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> lessThan(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x <= y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> lessThanEqual(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x > y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> greaterThan(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x >= y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> greaterThanEqual(qua const& x, qua const& y); + + /// Build a look at quaternion based on the default handedness. + /// + /// @param direction Desired forward direction. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAt( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + + /// Build a right-handed look at quaternion. + /// + /// @param direction Desired forward direction onto which the -z-axis gets mapped. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAtRH( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + + /// Build a left-handed look at quaternion. + /// + /// @param direction Desired forward direction onto which the +z-axis gets mapped. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAtLH( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + /// @} +} //namespace glm + +#include "quaternion.inl" diff --git a/src/other/manifold/glm/glm/gtc/quaternion.inl b/src/other/manifold/glm/glm/gtc/quaternion.inl new file mode 100644 index 00000000000..06f9f020b86 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/quaternion.inl @@ -0,0 +1,202 @@ +#include "../trigonometric.hpp" +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "epsilon.hpp" +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua const& x) + { + return vec<3, T, Q>(pitch(x), yaw(x), roll(x)); + } + + template + GLM_FUNC_QUALIFIER T roll(qua const& q) + { + return static_cast(atan(static_cast(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z)); + } + + template + GLM_FUNC_QUALIFIER T pitch(qua const& q) + { + //return T(atan(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z)); + T const y = static_cast(2) * (q.y * q.z + q.w * q.x); + T const x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z; + + if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon()))) //avoid atan2(0,0) - handle singularity - Matiis + return static_cast(static_cast(2) * atan(q.x, q.w)); + + return static_cast(atan(y, x)); + } + + template + GLM_FUNC_QUALIFIER T yaw(qua const& q) + { + return asin(clamp(static_cast(-2) * (q.x * q.z - q.w * q.y), static_cast(-1), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat3_cast(qua const& q) + { + mat<3, 3, T, Q> Result(T(1)); + T qxx(q.x * q.x); + T qyy(q.y * q.y); + T qzz(q.z * q.z); + T qxz(q.x * q.z); + T qxy(q.x * q.y); + T qyz(q.y * q.z); + T qwx(q.w * q.x); + T qwy(q.w * q.y); + T qwz(q.w * q.z); + + Result[0][0] = T(1) - T(2) * (qyy + qzz); + Result[0][1] = T(2) * (qxy + qwz); + Result[0][2] = T(2) * (qxz - qwy); + + Result[1][0] = T(2) * (qxy - qwz); + Result[1][1] = T(1) - T(2) * (qxx + qzz); + Result[1][2] = T(2) * (qyz + qwx); + + Result[2][0] = T(2) * (qxz + qwy); + Result[2][1] = T(2) * (qyz - qwx); + Result[2][2] = T(1) - T(2) * (qxx + qyy); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat4_cast(qua const& q) + { + return mat<4, 4, T, Q>(mat3_cast(q)); + } + + template + GLM_FUNC_QUALIFIER qua quat_cast(mat<3, 3, T, Q> const& m) + { + T fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2]; + T fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2]; + T fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1]; + T fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2]; + + int biggestIndex = 0; + T fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if(fourXSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } + if(fourYSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } + if(fourZSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } + + T biggestVal = sqrt(fourBiggestSquaredMinus1 + static_cast(1)) * static_cast(0.5); + T mult = static_cast(0.25) / biggestVal; + + switch(biggestIndex) + { + case 0: + return qua(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult); + case 1: + return qua((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult); + case 2: + return qua((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult); + case 3: + return qua((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal); + default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity. + assert(false); + return qua(1, 0, 0, 0); + } + } + + template + GLM_FUNC_QUALIFIER qua quat_cast(mat<4, 4, T, Q> const& m4) + { + return quat_cast(mat<3, 3, T, Q>(m4)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] < y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] <= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] > y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] >= y[i]; + return Result; + } + + + template + GLM_FUNC_QUALIFIER qua quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return quatLookAtLH(direction, up); +# else + return quatLookAtRH(direction, up); +# endif + } + + template + GLM_FUNC_QUALIFIER qua quatLookAtRH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { + mat<3, 3, T, Q> Result; + + Result[2] = -direction; + vec<3, T, Q> const& Right = cross(up, Result[2]); + Result[0] = Right * inversesqrt(max(static_cast(0.00001), dot(Right, Right))); + Result[1] = cross(Result[2], Result[0]); + + return quat_cast(Result); + } + + template + GLM_FUNC_QUALIFIER qua quatLookAtLH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { + mat<3, 3, T, Q> Result; + + Result[2] = direction; + vec<3, T, Q> const& Right = cross(up, Result[2]); + Result[0] = Right * inversesqrt(max(static_cast(0.00001), dot(Right, Right))); + Result[1] = cross(Result[2], Result[0]); + + return quat_cast(Result); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "quaternion_simd.inl" +#endif + diff --git a/src/other/manifold/glm/glm/gtc/quaternion_simd.inl b/src/other/manifold/glm/glm/gtc/quaternion_simd.inl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/other/manifold/glm/glm/gtc/random.hpp b/src/other/manifold/glm/glm/gtc/random.hpp new file mode 100644 index 00000000000..9a859580e40 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/random.hpp @@ -0,0 +1,82 @@ +/// @ref gtc_random +/// @file glm/gtc/random.hpp +/// +/// @see core (dependence) +/// @see gtx_random (extended) +/// +/// @defgroup gtc_random GLM_GTC_random +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Generate random number from various distribution methods. + +#pragma once + +// Dependency: +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_random extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_random + /// @{ + + /// Generate random numbers in the interval [Min, Max], according a linear distribution + /// + /// @param Min Minimum value included in the sampling + /// @param Max Maximum value included in the sampling + /// @tparam genType Value type. Currently supported: float or double scalars. + /// @see gtc_random + template + GLM_FUNC_DECL genType linearRand(genType Min, genType Max); + + /// Generate random numbers in the interval [Min, Max], according a linear distribution + /// + /// @param Min Minimum value included in the sampling + /// @param Max Maximum value included in the sampling + /// @tparam T Value type. Currently supported: float or double. + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec linearRand(vec const& Min, vec const& Max); + + /// Generate random numbers in the interval [Min, Max], according a gaussian distribution + /// + /// @see gtc_random + template + GLM_FUNC_DECL genType gaussRand(genType Mean, genType Deviation); + + /// Generate a random 2D vector which coordinates are regulary distributed on a circle of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<2, T, defaultp> circularRand(T Radius); + + /// Generate a random 3D vector which coordinates are regulary distributed on a sphere of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<3, T, defaultp> sphericalRand(T Radius); + + /// Generate a random 2D vector which coordinates are regulary distributed within the area of a disk of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<2, T, defaultp> diskRand(T Radius); + + /// Generate a random 3D vector which coordinates are regulary distributed within the volume of a ball of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<3, T, defaultp> ballRand(T Radius); + + /// @} +}//namespace glm + +#include "random.inl" diff --git a/src/other/manifold/glm/glm/gtc/random.inl b/src/other/manifold/glm/glm/gtc/random.inl new file mode 100644 index 00000000000..704850987c6 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/random.inl @@ -0,0 +1,303 @@ +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "../trigonometric.hpp" +#include "../detail/type_vec1.hpp" +#include +#include +#include +#include + +namespace glm{ +namespace detail +{ + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call(); + }; + + template + struct compute_rand<1, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<1, uint8, P> call() + { + return vec<1, uint8, P>( + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<2, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<2, uint8, P> call() + { + return vec<2, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<3, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<3, uint8, P> call() + { + return vec<3, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<4, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<4, uint8, P> call() + { + return vec<4, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(8)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(16)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(32)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max); + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER genType linearRand(genType Min, genType Max) + { + return detail::compute_linearRand<1, genType, highp>::call( + vec<1, genType, highp>(Min), + vec<1, genType, highp>(Max)).x; + } + + template + GLM_FUNC_QUALIFIER vec linearRand(vec const& Min, vec const& Max) + { + return detail::compute_linearRand::call(Min, Max); + } + + template + GLM_FUNC_QUALIFIER genType gaussRand(genType Mean, genType Deviation) + { + genType w, x1, x2; + + do + { + x1 = linearRand(genType(-1), genType(1)); + x2 = linearRand(genType(-1), genType(1)); + + w = x1 * x1 + x2 * x2; + } while(w > genType(1)); + + return static_cast(x2 * Deviation * Deviation * sqrt((genType(-2) * log(w)) / w) + Mean); + } + + template + GLM_FUNC_QUALIFIER vec gaussRand(vec const& Mean, vec const& Deviation) + { + return detail::functor2::call(gaussRand, Mean, Deviation); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> diskRand(T Radius) + { + assert(Radius > static_cast(0)); + + vec<2, T, defaultp> Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = linearRand( + vec<2, T, defaultp>(-Radius), + vec<2, T, defaultp>(Radius)); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> ballRand(T Radius) + { + assert(Radius > static_cast(0)); + + vec<3, T, defaultp> Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = linearRand( + vec<3, T, defaultp>(-Radius), + vec<3, T, defaultp>(Radius)); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> circularRand(T Radius) + { + assert(Radius > static_cast(0)); + + T a = linearRand(T(0), static_cast(6.283185307179586476925286766559)); + return vec<2, T, defaultp>(glm::cos(a), glm::sin(a)) * Radius; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> sphericalRand(T Radius) + { + assert(Radius > static_cast(0)); + + T theta = linearRand(T(0), T(6.283185307179586476925286766559f)); + T phi = std::acos(linearRand(T(-1.0f), T(1.0f))); + + T x = std::sin(phi) * std::cos(theta); + T y = std::sin(phi) * std::sin(theta); + T z = std::cos(phi); + + return vec<3, T, defaultp>(x, y, z) * Radius; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/reciprocal.hpp b/src/other/manifold/glm/glm/gtc/reciprocal.hpp new file mode 100644 index 00000000000..c7d13303838 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/reciprocal.hpp @@ -0,0 +1,135 @@ +/// @ref gtc_reciprocal +/// @file glm/gtc/reciprocal.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_reciprocal GLM_GTC_reciprocal +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Define secant, cosecant and cotangent functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_reciprocal extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_reciprocal + /// @{ + + /// Secant function. + /// hypotenuse / adjacent or 1 / cos(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType sec(genType angle); + + /// Cosecant function. + /// hypotenuse / opposite or 1 / sin(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType csc(genType angle); + + /// Cotangent function. + /// adjacent / opposite or 1 / tan(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType cot(genType angle); + + /// Inverse secant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType asec(genType x); + + /// Inverse cosecant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType acsc(genType x); + + /// Inverse cotangent function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType acot(genType x); + + /// Secant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType sech(genType angle); + + /// Cosecant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType csch(genType angle); + + /// Cotangent hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType coth(genType angle); + + /// Inverse secant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType asech(genType x); + + /// Inverse cosecant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType acsch(genType x); + + /// Inverse cotangent hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see gtc_reciprocal + template + GLM_FUNC_DECL genType acoth(genType x); + + /// @} +}//namespace glm + +#include "reciprocal.inl" diff --git a/src/other/manifold/glm/glm/gtc/reciprocal.inl b/src/other/manifold/glm/glm/gtc/reciprocal.inl new file mode 100644 index 00000000000..d88729e88f4 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/reciprocal.inl @@ -0,0 +1,191 @@ +/// @ref gtc_reciprocal + +#include "../trigonometric.hpp" +#include + +namespace glm +{ + // sec + template + GLM_FUNC_QUALIFIER genType sec(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sec' only accept floating-point values"); + return genType(1) / glm::cos(angle); + } + + template + GLM_FUNC_QUALIFIER vec sec(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sec' only accept floating-point inputs"); + return detail::functor1::call(sec, x); + } + + // csc + template + GLM_FUNC_QUALIFIER genType csc(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csc' only accept floating-point values"); + return genType(1) / glm::sin(angle); + } + + template + GLM_FUNC_QUALIFIER vec csc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csc' only accept floating-point inputs"); + return detail::functor1::call(csc, x); + } + + // cot + template + GLM_FUNC_QUALIFIER genType cot(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cot' only accept floating-point values"); + + genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0); + return glm::tan(pi_over_2 - angle); + } + + template + GLM_FUNC_QUALIFIER vec cot(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cot' only accept floating-point inputs"); + return detail::functor1::call(cot, x); + } + + // asec + template + GLM_FUNC_QUALIFIER genType asec(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asec' only accept floating-point values"); + return acos(genType(1) / x); + } + + template + GLM_FUNC_QUALIFIER vec asec(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asec' only accept floating-point inputs"); + return detail::functor1::call(asec, x); + } + + // acsc + template + GLM_FUNC_QUALIFIER genType acsc(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsc' only accept floating-point values"); + return asin(genType(1) / x); + } + + template + GLM_FUNC_QUALIFIER vec acsc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsc' only accept floating-point inputs"); + return detail::functor1::call(acsc, x); + } + + // acot + template + GLM_FUNC_QUALIFIER genType acot(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acot' only accept floating-point values"); + + genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0); + return pi_over_2 - atan(x); + } + + template + GLM_FUNC_QUALIFIER vec acot(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acot' only accept floating-point inputs"); + return detail::functor1::call(acot, x); + } + + // sech + template + GLM_FUNC_QUALIFIER genType sech(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sech' only accept floating-point values"); + return genType(1) / glm::cosh(angle); + } + + template + GLM_FUNC_QUALIFIER vec sech(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sech' only accept floating-point inputs"); + return detail::functor1::call(sech, x); + } + + // csch + template + GLM_FUNC_QUALIFIER genType csch(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csch' only accept floating-point values"); + return genType(1) / glm::sinh(angle); + } + + template + GLM_FUNC_QUALIFIER vec csch(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csch' only accept floating-point inputs"); + return detail::functor1::call(csch, x); + } + + // coth + template + GLM_FUNC_QUALIFIER genType coth(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'coth' only accept floating-point values"); + return glm::cosh(angle) / glm::sinh(angle); + } + + template + GLM_FUNC_QUALIFIER vec coth(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'coth' only accept floating-point inputs"); + return detail::functor1::call(coth, x); + } + + // asech + template + GLM_FUNC_QUALIFIER genType asech(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asech' only accept floating-point values"); + return acosh(genType(1) / x); + } + + template + GLM_FUNC_QUALIFIER vec asech(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asech' only accept floating-point inputs"); + return detail::functor1::call(asech, x); + } + + // acsch + template + GLM_FUNC_QUALIFIER genType acsch(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsch' only accept floating-point values"); + return asinh(genType(1) / x); + } + + template + GLM_FUNC_QUALIFIER vec acsch(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsch' only accept floating-point inputs"); + return detail::functor1::call(acsch, x); + } + + // acoth + template + GLM_FUNC_QUALIFIER genType acoth(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acoth' only accept floating-point values"); + return atanh(genType(1) / x); + } + + template + GLM_FUNC_QUALIFIER vec acoth(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acoth' only accept floating-point inputs"); + return detail::functor1::call(acoth, x); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/round.hpp b/src/other/manifold/glm/glm/gtc/round.hpp new file mode 100644 index 00000000000..56edbbca30b --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/round.hpp @@ -0,0 +1,160 @@ +/// @ref gtc_round +/// @file glm/gtc/round.hpp +/// +/// @see core (dependence) +/// @see gtc_round (dependence) +/// +/// @defgroup gtc_round GLM_GTC_round +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Rounding value to specific boundings + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_round extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_round + /// @{ + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType ceilPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec ceilPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType floorPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec floorPowerOfTwo(vec const& v); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType roundPowerOfTwo(genIUType v); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec roundPowerOfTwo(vec const& v); + + /// Higher multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType ceilMultiple(genType v, genType Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec ceilMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType floorMultiple(genType v, genType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec floorMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType roundMultiple(genType v, genType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec roundMultiple(vec const& v, vec const& Multiple); + + /// @} +} //namespace glm + +#include "round.inl" diff --git a/src/other/manifold/glm/glm/gtc/round.inl b/src/other/manifold/glm/glm/gtc/round.inl new file mode 100644 index 00000000000..48411e41dc3 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/round.inl @@ -0,0 +1,155 @@ +/// @ref gtc_round + +#include "../integer.hpp" +#include "../ext/vector_integer.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_roundMultiple {}; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - std::fmod(Source, Multiple); + else + { + genType Tmp = Source + genType(1); + return Tmp - std::fmod(Tmp, Multiple) - Multiple; + } + } + }; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; +}//namespace detail + + ////////////////// + // ceilPowerOfTwo + + template + GLM_FUNC_QUALIFIER genType ceilPowerOfTwo(genType value) + { + return detail::compute_ceilPowerOfTwo<1, genType, defaultp, std::numeric_limits::is_signed>::call(vec<1, genType, defaultp>(value)).x; + } + + template + GLM_FUNC_QUALIFIER vec ceilPowerOfTwo(vec const& v) + { + return detail::compute_ceilPowerOfTwo::is_signed>::call(v); + } + + /////////////////// + // floorPowerOfTwo + + template + GLM_FUNC_QUALIFIER genType floorPowerOfTwo(genType value) + { + return isPowerOfTwo(value) ? value : static_cast(1) << findMSB(value); + } + + template + GLM_FUNC_QUALIFIER vec floorPowerOfTwo(vec const& v) + { + return detail::functor1::call(floorPowerOfTwo, v); + } + + /////////////////// + // roundPowerOfTwo + + template + GLM_FUNC_QUALIFIER genIUType roundPowerOfTwo(genIUType value) + { + if(isPowerOfTwo(value)) + return value; + + genIUType const prev = static_cast(1) << findMSB(value); + genIUType const next = prev << static_cast(1); + return (next - value) < (value - prev) ? next : prev; + } + + template + GLM_FUNC_QUALIFIER vec roundPowerOfTwo(vec const& v) + { + return detail::functor1::call(roundPowerOfTwo, v); + } + + ////////////////////// + // ceilMultiple + + template + GLM_FUNC_QUALIFIER genType ceilMultiple(genType Source, genType Multiple) + { + return detail::compute_ceilMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec ceilMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(ceilMultiple, Source, Multiple); + } + + ////////////////////// + // floorMultiple + + template + GLM_FUNC_QUALIFIER genType floorMultiple(genType Source, genType Multiple) + { + return detail::compute_floorMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec floorMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(floorMultiple, Source, Multiple); + } + + ////////////////////// + // roundMultiple + + template + GLM_FUNC_QUALIFIER genType roundMultiple(genType Source, genType Multiple) + { + return detail::compute_roundMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec roundMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(roundMultiple, Source, Multiple); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/type_aligned.hpp b/src/other/manifold/glm/glm/gtc/type_aligned.hpp new file mode 100644 index 00000000000..5403abf6752 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/type_aligned.hpp @@ -0,0 +1,1315 @@ +/// @ref gtc_type_aligned +/// @file glm/gtc/type_aligned.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_type_aligned GLM_GTC_type_aligned +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Aligned types allowing SIMD optimizations of vectors and matrices types + +#pragma once + +#if (GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE) +# error "GLM: Aligned gentypes require to enable C++ language extensions. Define GLM_FORCE_ALIGNED_GENTYPES before including GLM headers to use aligned types." +#endif + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_aligned extension included") +#endif + +#include "../mat4x4.hpp" +#include "../mat4x3.hpp" +#include "../mat4x2.hpp" +#include "../mat3x4.hpp" +#include "../mat3x3.hpp" +#include "../mat3x2.hpp" +#include "../mat2x4.hpp" +#include "../mat2x3.hpp" +#include "../mat2x2.hpp" +#include "../gtc/vec1.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" + +namespace glm +{ + /// @addtogroup gtc_type_aligned + /// @{ + + // -- *vec1 -- + + /// 1 component vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_highp> aligned_highp_vec1; + + /// 1 component vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_mediump> aligned_mediump_vec1; + + /// 1 component vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_lowp> aligned_lowp_vec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_highp> aligned_highp_dvec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_mediump> aligned_mediump_dvec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_lowp> aligned_lowp_dvec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_highp> aligned_highp_ivec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_mediump> aligned_mediump_ivec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_lowp> aligned_lowp_ivec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_highp> aligned_highp_uvec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_mediump> aligned_mediump_uvec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_lowp> aligned_lowp_uvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_highp> aligned_highp_bvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_mediump> aligned_mediump_bvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_lowp> aligned_lowp_bvec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, packed_highp> packed_highp_vec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, packed_mediump> packed_mediump_vec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, packed_lowp> packed_lowp_vec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, packed_highp> packed_highp_dvec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, packed_mediump> packed_mediump_dvec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, packed_lowp> packed_lowp_dvec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_highp> packed_highp_ivec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_mediump> packed_mediump_ivec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_lowp> packed_lowp_ivec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_highp> packed_highp_uvec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_mediump> packed_mediump_uvec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_lowp> packed_lowp_uvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_highp> packed_highp_bvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_mediump> packed_mediump_bvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_lowp> packed_lowp_bvec1; + + // -- *vec2 -- + + /// 2 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_highp> aligned_highp_vec2; + + /// 2 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_mediump> aligned_mediump_vec2; + + /// 2 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_lowp> aligned_lowp_vec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_highp> aligned_highp_dvec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_mediump> aligned_mediump_dvec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_lowp> aligned_lowp_dvec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_highp> aligned_highp_ivec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_mediump> aligned_mediump_ivec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_lowp> aligned_lowp_ivec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_highp> aligned_highp_uvec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_mediump> aligned_mediump_uvec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_lowp> aligned_lowp_uvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_highp> aligned_highp_bvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_mediump> aligned_mediump_bvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_lowp> aligned_lowp_bvec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, float, packed_highp> packed_highp_vec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, float, packed_mediump> packed_mediump_vec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, float, packed_lowp> packed_lowp_vec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, double, packed_highp> packed_highp_dvec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, double, packed_mediump> packed_mediump_dvec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, double, packed_lowp> packed_lowp_dvec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_highp> packed_highp_ivec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_mediump> packed_mediump_ivec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_lowp> packed_lowp_ivec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_highp> packed_highp_uvec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_mediump> packed_mediump_uvec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_lowp> packed_lowp_uvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_highp> packed_highp_bvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_mediump> packed_mediump_bvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_lowp> packed_lowp_bvec2; + + // -- *vec3 -- + + /// 3 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_highp> aligned_highp_vec3; + + /// 3 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_mediump> aligned_mediump_vec3; + + /// 3 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_lowp> aligned_lowp_vec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_highp> aligned_highp_dvec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_mediump> aligned_mediump_dvec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_lowp> aligned_lowp_dvec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_highp> aligned_highp_ivec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_mediump> aligned_mediump_ivec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_lowp> aligned_lowp_ivec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_highp> aligned_highp_uvec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_mediump> aligned_mediump_uvec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_lowp> aligned_lowp_uvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_highp> aligned_highp_bvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_mediump> aligned_mediump_bvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_lowp> aligned_lowp_bvec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, float, packed_highp> packed_highp_vec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, float, packed_mediump> packed_mediump_vec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, float, packed_lowp> packed_lowp_vec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, double, packed_highp> packed_highp_dvec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, double, packed_mediump> packed_mediump_dvec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, double, packed_lowp> packed_lowp_dvec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_highp> packed_highp_ivec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_mediump> packed_mediump_ivec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_lowp> packed_lowp_ivec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_highp> packed_highp_uvec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_mediump> packed_mediump_uvec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_lowp> packed_lowp_uvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_highp> packed_highp_bvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_mediump> packed_mediump_bvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_lowp> packed_lowp_bvec3; + + // -- *vec4 -- + + /// 4 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_highp> aligned_highp_vec4; + + /// 4 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_mediump> aligned_mediump_vec4; + + /// 4 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_lowp> aligned_lowp_vec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_highp> aligned_highp_dvec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_mediump> aligned_mediump_dvec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_lowp> aligned_lowp_dvec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_highp> aligned_highp_ivec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_mediump> aligned_mediump_ivec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_lowp> aligned_lowp_ivec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_highp> aligned_highp_uvec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_mediump> aligned_mediump_uvec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_lowp> aligned_lowp_uvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_highp> aligned_highp_bvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_mediump> aligned_mediump_bvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_lowp> aligned_lowp_bvec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, float, packed_highp> packed_highp_vec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, float, packed_mediump> packed_mediump_vec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, float, packed_lowp> packed_lowp_vec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, double, packed_highp> packed_highp_dvec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, double, packed_mediump> packed_mediump_dvec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, double, packed_lowp> packed_lowp_dvec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_highp> packed_highp_ivec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_mediump> packed_mediump_ivec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_lowp> packed_lowp_ivec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_highp> packed_highp_uvec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_mediump> packed_mediump_uvec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_lowp> packed_lowp_uvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_highp> packed_highp_bvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_mediump> packed_mediump_bvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_lowp> packed_lowp_bvec4; + + // -- *mat2 -- + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_highp> aligned_highp_mat2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_mediump> aligned_mediump_mat2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_lowp> aligned_lowp_mat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_highp> aligned_highp_dmat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_mediump> aligned_mediump_dmat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_lowp> aligned_lowp_dmat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_highp> packed_highp_mat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_mediump> packed_mediump_mat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_lowp> packed_lowp_mat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_highp> packed_highp_dmat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_mediump> packed_mediump_dmat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_lowp> packed_lowp_dmat2; + + // -- *mat3 -- + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_highp> aligned_highp_mat3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_mediump> aligned_mediump_mat3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_lowp> aligned_lowp_mat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_highp> aligned_highp_dmat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_mediump> aligned_mediump_dmat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_lowp> aligned_lowp_dmat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_highp> packed_highp_mat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_mediump> packed_mediump_mat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_lowp> packed_lowp_mat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_highp> packed_highp_dmat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_mediump> packed_mediump_dmat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_lowp> packed_lowp_dmat3; + + // -- *mat4 -- + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_highp> aligned_highp_mat4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_mediump> aligned_mediump_mat4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_lowp> aligned_lowp_mat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_highp> aligned_highp_dmat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_mediump> aligned_mediump_dmat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_lowp> aligned_lowp_dmat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_highp> packed_highp_mat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_mediump> packed_mediump_mat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_lowp> packed_lowp_mat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_highp> packed_highp_dmat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_mediump> packed_mediump_dmat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_lowp> packed_lowp_dmat4; + + // -- *mat2x2 -- + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_highp> aligned_highp_mat2x2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_mediump> aligned_mediump_mat2x2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_lowp> aligned_lowp_mat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_highp> aligned_highp_dmat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_mediump> aligned_mediump_dmat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_lowp> aligned_lowp_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_highp> packed_highp_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_mediump> packed_mediump_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_lowp> packed_lowp_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_highp> packed_highp_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_mediump> packed_mediump_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_lowp> packed_lowp_dmat2x2; + + // -- *mat2x3 -- + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_highp> aligned_highp_mat2x3; + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_mediump> aligned_mediump_mat2x3; + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_lowp> aligned_lowp_mat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_highp> aligned_highp_dmat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_mediump> aligned_mediump_dmat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_lowp> aligned_lowp_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_highp> packed_highp_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_mediump> packed_mediump_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_lowp> packed_lowp_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_highp> packed_highp_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_mediump> packed_mediump_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_lowp> packed_lowp_dmat2x3; + + // -- *mat2x4 -- + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_highp> aligned_highp_mat2x4; + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_mediump> aligned_mediump_mat2x4; + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_lowp> aligned_lowp_mat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_highp> aligned_highp_dmat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_mediump> aligned_mediump_dmat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_lowp> aligned_lowp_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_highp> packed_highp_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_mediump> packed_mediump_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_lowp> packed_lowp_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_highp> packed_highp_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_mediump> packed_mediump_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_lowp> packed_lowp_dmat2x4; + + // -- *mat3x2 -- + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_highp> aligned_highp_mat3x2; + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_mediump> aligned_mediump_mat3x2; + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_lowp> aligned_lowp_mat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_highp> aligned_highp_dmat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_mediump> aligned_mediump_dmat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_lowp> aligned_lowp_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_highp> packed_highp_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_mediump> packed_mediump_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_lowp> packed_lowp_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_highp> packed_highp_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_mediump> packed_mediump_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_lowp> packed_lowp_dmat3x2; + + // -- *mat3x3 -- + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_highp> aligned_highp_mat3x3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_mediump> aligned_mediump_mat3x3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_lowp> aligned_lowp_mat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_highp> aligned_highp_dmat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_mediump> aligned_mediump_dmat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_lowp> aligned_lowp_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_highp> packed_highp_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_mediump> packed_mediump_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_lowp> packed_lowp_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_highp> packed_highp_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_mediump> packed_mediump_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_lowp> packed_lowp_dmat3x3; + + // -- *mat3x4 -- + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_highp> aligned_highp_mat3x4; + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_mediump> aligned_mediump_mat3x4; + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_lowp> aligned_lowp_mat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_highp> aligned_highp_dmat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_mediump> aligned_mediump_dmat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_lowp> aligned_lowp_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_highp> packed_highp_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_mediump> packed_mediump_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_lowp> packed_lowp_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_highp> packed_highp_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_mediump> packed_mediump_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_lowp> packed_lowp_dmat3x4; + + // -- *mat4x2 -- + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_highp> aligned_highp_mat4x2; + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_mediump> aligned_mediump_mat4x2; + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_lowp> aligned_lowp_mat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_highp> aligned_highp_dmat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_mediump> aligned_mediump_dmat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_lowp> aligned_lowp_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_highp> packed_highp_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_mediump> packed_mediump_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_lowp> packed_lowp_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_highp> packed_highp_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_mediump> packed_mediump_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_lowp> packed_lowp_dmat4x2; + + // -- *mat4x3 -- + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_highp> aligned_highp_mat4x3; + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_mediump> aligned_mediump_mat4x3; + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_lowp> aligned_lowp_mat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_highp> aligned_highp_dmat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_mediump> aligned_mediump_dmat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_lowp> aligned_lowp_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_highp> packed_highp_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_mediump> packed_mediump_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_lowp> packed_lowp_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_highp> packed_highp_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_mediump> packed_mediump_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_lowp> packed_lowp_dmat4x3; + + // -- *mat4x4 -- + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_highp> aligned_highp_mat4x4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_mediump> aligned_mediump_mat4x4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_lowp> aligned_lowp_mat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_highp> aligned_highp_dmat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_mediump> aligned_mediump_dmat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_lowp> aligned_lowp_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_highp> packed_highp_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_mediump> packed_mediump_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_lowp> packed_lowp_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_highp> packed_highp_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_mediump> packed_mediump_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_lowp> packed_lowp_dmat4x4; + + // -- default -- + +#if(defined(GLM_PRECISION_LOWP_FLOAT)) + typedef aligned_lowp_vec1 aligned_vec1; + typedef aligned_lowp_vec2 aligned_vec2; + typedef aligned_lowp_vec3 aligned_vec3; + typedef aligned_lowp_vec4 aligned_vec4; + typedef packed_lowp_vec1 packed_vec1; + typedef packed_lowp_vec2 packed_vec2; + typedef packed_lowp_vec3 packed_vec3; + typedef packed_lowp_vec4 packed_vec4; + + typedef aligned_lowp_mat2 aligned_mat2; + typedef aligned_lowp_mat3 aligned_mat3; + typedef aligned_lowp_mat4 aligned_mat4; + typedef packed_lowp_mat2 packed_mat2; + typedef packed_lowp_mat3 packed_mat3; + typedef packed_lowp_mat4 packed_mat4; + + typedef aligned_lowp_mat2x2 aligned_mat2x2; + typedef aligned_lowp_mat2x3 aligned_mat2x3; + typedef aligned_lowp_mat2x4 aligned_mat2x4; + typedef aligned_lowp_mat3x2 aligned_mat3x2; + typedef aligned_lowp_mat3x3 aligned_mat3x3; + typedef aligned_lowp_mat3x4 aligned_mat3x4; + typedef aligned_lowp_mat4x2 aligned_mat4x2; + typedef aligned_lowp_mat4x3 aligned_mat4x3; + typedef aligned_lowp_mat4x4 aligned_mat4x4; + typedef packed_lowp_mat2x2 packed_mat2x2; + typedef packed_lowp_mat2x3 packed_mat2x3; + typedef packed_lowp_mat2x4 packed_mat2x4; + typedef packed_lowp_mat3x2 packed_mat3x2; + typedef packed_lowp_mat3x3 packed_mat3x3; + typedef packed_lowp_mat3x4 packed_mat3x4; + typedef packed_lowp_mat4x2 packed_mat4x2; + typedef packed_lowp_mat4x3 packed_mat4x3; + typedef packed_lowp_mat4x4 packed_mat4x4; +#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT)) + typedef aligned_mediump_vec1 aligned_vec1; + typedef aligned_mediump_vec2 aligned_vec2; + typedef aligned_mediump_vec3 aligned_vec3; + typedef aligned_mediump_vec4 aligned_vec4; + typedef packed_mediump_vec1 packed_vec1; + typedef packed_mediump_vec2 packed_vec2; + typedef packed_mediump_vec3 packed_vec3; + typedef packed_mediump_vec4 packed_vec4; + + typedef aligned_mediump_mat2 aligned_mat2; + typedef aligned_mediump_mat3 aligned_mat3; + typedef aligned_mediump_mat4 aligned_mat4; + typedef packed_mediump_mat2 packed_mat2; + typedef packed_mediump_mat3 packed_mat3; + typedef packed_mediump_mat4 packed_mat4; + + typedef aligned_mediump_mat2x2 aligned_mat2x2; + typedef aligned_mediump_mat2x3 aligned_mat2x3; + typedef aligned_mediump_mat2x4 aligned_mat2x4; + typedef aligned_mediump_mat3x2 aligned_mat3x2; + typedef aligned_mediump_mat3x3 aligned_mat3x3; + typedef aligned_mediump_mat3x4 aligned_mat3x4; + typedef aligned_mediump_mat4x2 aligned_mat4x2; + typedef aligned_mediump_mat4x3 aligned_mat4x3; + typedef aligned_mediump_mat4x4 aligned_mat4x4; + typedef packed_mediump_mat2x2 packed_mat2x2; + typedef packed_mediump_mat2x3 packed_mat2x3; + typedef packed_mediump_mat2x4 packed_mat2x4; + typedef packed_mediump_mat3x2 packed_mat3x2; + typedef packed_mediump_mat3x3 packed_mat3x3; + typedef packed_mediump_mat3x4 packed_mat3x4; + typedef packed_mediump_mat4x2 packed_mat4x2; + typedef packed_mediump_mat4x3 packed_mat4x3; + typedef packed_mediump_mat4x4 packed_mat4x4; +#else //defined(GLM_PRECISION_HIGHP_FLOAT) + /// 1 component vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec1 aligned_vec1; + + /// 2 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec2 aligned_vec2; + + /// 3 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec3 aligned_vec3; + + /// 4 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec4 aligned_vec4; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec1 packed_vec1; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec2 packed_vec2; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec3 packed_vec3; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec4 packed_vec4; + + /// 2 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2 aligned_mat2; + + /// 3 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3 aligned_mat3; + + /// 4 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4 aligned_mat4; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2 packed_mat2; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3 packed_mat3; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4 packed_mat4; + + /// 2 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x2 aligned_mat2x2; + + /// 2 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x3 aligned_mat2x3; + + /// 2 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x4 aligned_mat2x4; + + /// 3 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x2 aligned_mat3x2; + + /// 3 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x3 aligned_mat3x3; + + /// 3 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x4 aligned_mat3x4; + + /// 4 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x2 aligned_mat4x2; + + /// 4 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x3 aligned_mat4x3; + + /// 4 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x4 aligned_mat4x4; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x2 packed_mat2x2; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x3 packed_mat2x3; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x4 packed_mat2x4; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x2 packed_mat3x2; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x3 packed_mat3x3; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x4 packed_mat3x4; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x2 packed_mat4x2; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x3 packed_mat4x3; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x4 packed_mat4x4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef aligned_lowp_dvec1 aligned_dvec1; + typedef aligned_lowp_dvec2 aligned_dvec2; + typedef aligned_lowp_dvec3 aligned_dvec3; + typedef aligned_lowp_dvec4 aligned_dvec4; + typedef packed_lowp_dvec1 packed_dvec1; + typedef packed_lowp_dvec2 packed_dvec2; + typedef packed_lowp_dvec3 packed_dvec3; + typedef packed_lowp_dvec4 packed_dvec4; + + typedef aligned_lowp_dmat2 aligned_dmat2; + typedef aligned_lowp_dmat3 aligned_dmat3; + typedef aligned_lowp_dmat4 aligned_dmat4; + typedef packed_lowp_dmat2 packed_dmat2; + typedef packed_lowp_dmat3 packed_dmat3; + typedef packed_lowp_dmat4 packed_dmat4; + + typedef aligned_lowp_dmat2x2 aligned_dmat2x2; + typedef aligned_lowp_dmat2x3 aligned_dmat2x3; + typedef aligned_lowp_dmat2x4 aligned_dmat2x4; + typedef aligned_lowp_dmat3x2 aligned_dmat3x2; + typedef aligned_lowp_dmat3x3 aligned_dmat3x3; + typedef aligned_lowp_dmat3x4 aligned_dmat3x4; + typedef aligned_lowp_dmat4x2 aligned_dmat4x2; + typedef aligned_lowp_dmat4x3 aligned_dmat4x3; + typedef aligned_lowp_dmat4x4 aligned_dmat4x4; + typedef packed_lowp_dmat2x2 packed_dmat2x2; + typedef packed_lowp_dmat2x3 packed_dmat2x3; + typedef packed_lowp_dmat2x4 packed_dmat2x4; + typedef packed_lowp_dmat3x2 packed_dmat3x2; + typedef packed_lowp_dmat3x3 packed_dmat3x3; + typedef packed_lowp_dmat3x4 packed_dmat3x4; + typedef packed_lowp_dmat4x2 packed_dmat4x2; + typedef packed_lowp_dmat4x3 packed_dmat4x3; + typedef packed_lowp_dmat4x4 packed_dmat4x4; +#elif(defined(GLM_PRECISION_MEDIUMP_DOUBLE)) + typedef aligned_mediump_dvec1 aligned_dvec1; + typedef aligned_mediump_dvec2 aligned_dvec2; + typedef aligned_mediump_dvec3 aligned_dvec3; + typedef aligned_mediump_dvec4 aligned_dvec4; + typedef packed_mediump_dvec1 packed_dvec1; + typedef packed_mediump_dvec2 packed_dvec2; + typedef packed_mediump_dvec3 packed_dvec3; + typedef packed_mediump_dvec4 packed_dvec4; + + typedef aligned_mediump_dmat2 aligned_dmat2; + typedef aligned_mediump_dmat3 aligned_dmat3; + typedef aligned_mediump_dmat4 aligned_dmat4; + typedef packed_mediump_dmat2 packed_dmat2; + typedef packed_mediump_dmat3 packed_dmat3; + typedef packed_mediump_dmat4 packed_dmat4; + + typedef aligned_mediump_dmat2x2 aligned_dmat2x2; + typedef aligned_mediump_dmat2x3 aligned_dmat2x3; + typedef aligned_mediump_dmat2x4 aligned_dmat2x4; + typedef aligned_mediump_dmat3x2 aligned_dmat3x2; + typedef aligned_mediump_dmat3x3 aligned_dmat3x3; + typedef aligned_mediump_dmat3x4 aligned_dmat3x4; + typedef aligned_mediump_dmat4x2 aligned_dmat4x2; + typedef aligned_mediump_dmat4x3 aligned_dmat4x3; + typedef aligned_mediump_dmat4x4 aligned_dmat4x4; + typedef packed_mediump_dmat2x2 packed_dmat2x2; + typedef packed_mediump_dmat2x3 packed_dmat2x3; + typedef packed_mediump_dmat2x4 packed_dmat2x4; + typedef packed_mediump_dmat3x2 packed_dmat3x2; + typedef packed_mediump_dmat3x3 packed_dmat3x3; + typedef packed_mediump_dmat3x4 packed_dmat3x4; + typedef packed_mediump_dmat4x2 packed_dmat4x2; + typedef packed_mediump_dmat4x3 packed_dmat4x3; + typedef packed_mediump_dmat4x4 packed_dmat4x4; +#else //defined(GLM_PRECISION_HIGHP_DOUBLE) + /// 1 component vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec1 aligned_dvec1; + + /// 2 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec2 aligned_dvec2; + + /// 3 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec3 aligned_dvec3; + + /// 4 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec4 aligned_dvec4; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec1 packed_dvec1; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec2 packed_dvec2; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec3 packed_dvec3; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec4 packed_dvec4; + + /// 2 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2 aligned_dmat2; + + /// 3 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3 aligned_dmat3; + + /// 4 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4 aligned_dmat4; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2 packed_dmat2; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3 packed_dmat3; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4 packed_dmat4; + + /// 2 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x2 aligned_dmat2x2; + + /// 2 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x3 aligned_dmat2x3; + + /// 2 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x4 aligned_dmat2x4; + + /// 3 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x2 aligned_dmat3x2; + + /// 3 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x3 aligned_dmat3x3; + + /// 3 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x4 aligned_dmat3x4; + + /// 4 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x2 aligned_dmat4x2; + + /// 4 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x3 aligned_dmat4x3; + + /// 4 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x4 aligned_dmat4x4; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x2 packed_dmat2x2; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x3 packed_dmat2x3; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x4 packed_dmat2x4; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x2 packed_dmat3x2; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x3 packed_dmat3x3; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x4 packed_dmat3x4; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x2 packed_dmat4x2; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x3 packed_dmat4x3; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x4 packed_dmat4x4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_INT)) + typedef aligned_lowp_ivec1 aligned_ivec1; + typedef aligned_lowp_ivec2 aligned_ivec2; + typedef aligned_lowp_ivec3 aligned_ivec3; + typedef aligned_lowp_ivec4 aligned_ivec4; +#elif(defined(GLM_PRECISION_MEDIUMP_INT)) + typedef aligned_mediump_ivec1 aligned_ivec1; + typedef aligned_mediump_ivec2 aligned_ivec2; + typedef aligned_mediump_ivec3 aligned_ivec3; + typedef aligned_mediump_ivec4 aligned_ivec4; +#else //defined(GLM_PRECISION_HIGHP_INT) + /// 1 component vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec1 aligned_ivec1; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec2 aligned_ivec2; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec3 aligned_ivec3; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec4 aligned_ivec4; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec1 packed_ivec1; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec2 packed_ivec2; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec3 packed_ivec3; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec4 packed_ivec4; +#endif//GLM_PRECISION + + // -- Unsigned integer definition -- + +#if(defined(GLM_PRECISION_LOWP_UINT)) + typedef aligned_lowp_uvec1 aligned_uvec1; + typedef aligned_lowp_uvec2 aligned_uvec2; + typedef aligned_lowp_uvec3 aligned_uvec3; + typedef aligned_lowp_uvec4 aligned_uvec4; +#elif(defined(GLM_PRECISION_MEDIUMP_UINT)) + typedef aligned_mediump_uvec1 aligned_uvec1; + typedef aligned_mediump_uvec2 aligned_uvec2; + typedef aligned_mediump_uvec3 aligned_uvec3; + typedef aligned_mediump_uvec4 aligned_uvec4; +#else //defined(GLM_PRECISION_HIGHP_UINT) + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec1 aligned_uvec1; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec2 aligned_uvec2; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec3 aligned_uvec3; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec4 aligned_uvec4; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec1 packed_uvec1; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec2 packed_uvec2; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec3 packed_uvec3; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec4 packed_uvec4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_BOOL)) + typedef aligned_lowp_bvec1 aligned_bvec1; + typedef aligned_lowp_bvec2 aligned_bvec2; + typedef aligned_lowp_bvec3 aligned_bvec3; + typedef aligned_lowp_bvec4 aligned_bvec4; +#elif(defined(GLM_PRECISION_MEDIUMP_BOOL)) + typedef aligned_mediump_bvec1 aligned_bvec1; + typedef aligned_mediump_bvec2 aligned_bvec2; + typedef aligned_mediump_bvec3 aligned_bvec3; + typedef aligned_mediump_bvec4 aligned_bvec4; +#else //defined(GLM_PRECISION_HIGHP_BOOL) + /// 1 component vector aligned in memory of bool values. + typedef aligned_highp_bvec1 aligned_bvec1; + + /// 2 components vector aligned in memory of bool values. + typedef aligned_highp_bvec2 aligned_bvec2; + + /// 3 components vector aligned in memory of bool values. + typedef aligned_highp_bvec3 aligned_bvec3; + + /// 4 components vector aligned in memory of bool values. + typedef aligned_highp_bvec4 aligned_bvec4; + + /// 1 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec1 packed_bvec1; + + /// 2 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec2 packed_bvec2; + + /// 3 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec3 packed_bvec3; + + /// 4 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec4 packed_bvec4; +#endif//GLM_PRECISION + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtc/type_precision.hpp b/src/other/manifold/glm/glm/gtc/type_precision.hpp new file mode 100644 index 00000000000..775e2f484d7 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/type_precision.hpp @@ -0,0 +1,2094 @@ +/// @ref gtc_type_precision +/// @file glm/gtc/type_precision.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_type_precision GLM_GTC_type_precision +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines specific C++-based qualifier types. + +#pragma once + +// Dependency: +#include "../gtc/quaternion.hpp" +#include "../gtc/vec1.hpp" +#include "../ext/vector_int1_sized.hpp" +#include "../ext/vector_int2_sized.hpp" +#include "../ext/vector_int3_sized.hpp" +#include "../ext/vector_int4_sized.hpp" +#include "../ext/scalar_int_sized.hpp" +#include "../ext/vector_uint1_sized.hpp" +#include "../ext/vector_uint2_sized.hpp" +#include "../ext/vector_uint3_sized.hpp" +#include "../ext/vector_uint4_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/type_vec2.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" +#include "../detail/type_mat2x2.hpp" +#include "../detail/type_mat2x3.hpp" +#include "../detail/type_mat2x4.hpp" +#include "../detail/type_mat3x2.hpp" +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat3x4.hpp" +#include "../detail/type_mat4x2.hpp" +#include "../detail/type_mat4x3.hpp" +#include "../detail/type_mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_precision extension included") +#endif + +namespace glm +{ + /////////////////////////// + // Signed int vector types + + /// @addtogroup gtc_type_precision + /// @{ + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_int8; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_int16; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_int32; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_int64; + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_int8_t; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_int16_t; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_int32_t; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_int64_t; + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_i8; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_i16; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_i32; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_i64; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_int8; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_int16; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_int32; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_int64; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_int8_t; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_int16_t; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_int32_t; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_int64_t; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_i8; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_i16; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_i32; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_i64; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_int8; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_int16; + + /// High qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_int32; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_int64; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_int8_t; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_int16_t; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_int32_t; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_int64_t; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_i8; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_i16; + + /// High qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_i32; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_i64; + + +#if GLM_HAS_EXTENDED_INTEGER_TYPE + using std::int8_t; + using std::int16_t; + using std::int32_t; + using std::int64_t; +#else + /// 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 int8_t; + + /// 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 int16_t; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 int32_t; + + /// 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 int64_t; +#endif + + /// 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 i8; + + /// 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 i16; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 i32; + + /// 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 i64; + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_uint8; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_uint16; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_uint32; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_uint64; + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_uint8_t; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_uint16_t; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_uint32_t; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_uint64_t; + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_u8; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_u16; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_u32; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_u64; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_uint8; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_uint16; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_uint32; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_uint64; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_uint8_t; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_uint16_t; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_uint32_t; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_uint64_t; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_u8; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_u16; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_u32; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_u64; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_uint8; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_uint16; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_uint32; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_uint64; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_uint8_t; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_uint16_t; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_uint32_t; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_uint64_t; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_u8; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_u16; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_u32; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_u64; + +#if GLM_HAS_EXTENDED_INTEGER_TYPE + using std::uint8_t; + using std::uint16_t; + using std::uint32_t; + using std::uint64_t; +#else + /// Default qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 uint8_t; + + /// Default qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 uint16_t; + + /// Default qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 uint32_t; + + /// Default qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 uint64_t; +#endif + + /// Default qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 u8; + + /// Default qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 u16; + + /// Default qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 u32; + + /// Default qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 u64; + + + + + + ////////////////////// + // Float vector types + + /// Single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float float32; + + /// Double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef double float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_float32; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_float64; + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_float32_t; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_float64_t; + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_f32; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_f64; + + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_float32; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_float64; + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_float32_t; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_float64_t; + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_f32; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_f64; + + +#if(defined(GLM_PRECISION_LOWP_FLOAT)) + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_float32_t float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_float64_t float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_f32 f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_f64 f64; + +#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT)) + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float32 float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float64 float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float32 f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float64 f64; + +#else//(defined(GLM_PRECISION_HIGHP_FLOAT)) + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float32_t float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float64_t float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float32_t f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float64_t f64; +#endif + + + /// Low single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, lowp> lowp_fvec1; + + /// Low single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, lowp> lowp_fvec2; + + /// Low single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, lowp> lowp_fvec3; + + /// Low single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, lowp> lowp_fvec4; + + + /// Medium single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, mediump> mediump_fvec1; + + /// Medium Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, mediump> mediump_fvec2; + + /// Medium Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, mediump> mediump_fvec3; + + /// Medium Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, mediump> mediump_fvec4; + + + /// High single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, highp> highp_fvec1; + + /// High Single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, float, highp> highp_fvec2; + + /// High Single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, float, highp> highp_fvec3; + + /// High Single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, float, highp> highp_fvec4; + + + /// Low single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, lowp> lowp_f32vec1; + + /// Low single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, f32, lowp> lowp_f32vec2; + + /// Low single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, f32, lowp> lowp_f32vec3; + + /// Low single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, f32, lowp> lowp_f32vec4; + + /// Medium single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, mediump> mediump_f32vec1; + + /// Medium single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, f32, mediump> mediump_f32vec2; + + /// Medium single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, f32, mediump> mediump_f32vec3; + + /// Medium single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, f32, mediump> mediump_f32vec4; + + /// High single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, highp> highp_f32vec1; + + /// High single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f32, highp> highp_f32vec2; + + /// High single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f32, highp> highp_f32vec3; + + /// High single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f32, highp> highp_f32vec4; + + + /// Low double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, lowp> lowp_f64vec1; + + /// Low double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, lowp> lowp_f64vec2; + + /// Low double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, lowp> lowp_f64vec3; + + /// Low double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, lowp> lowp_f64vec4; + + /// Medium double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, mediump> mediump_f64vec1; + + /// Medium double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, mediump> mediump_f64vec2; + + /// Medium double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, mediump> mediump_f64vec3; + + /// Medium double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, mediump> mediump_f64vec4; + + /// High double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, highp> highp_f64vec1; + + /// High double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, highp> highp_f64vec2; + + /// High double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, highp> highp_f64vec3; + + /// High double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, highp> highp_f64vec4; + + + + ////////////////////// + // Float matrix types + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_f32 lowp_fmat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, lowp> lowp_fmat2x2; + + /// Low single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, lowp> lowp_fmat2x3; + + /// Low single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, lowp> lowp_fmat2x4; + + /// Low single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, lowp> lowp_fmat3x2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, lowp> lowp_fmat3x3; + + /// Low single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, lowp> lowp_fmat3x4; + + /// Low single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, lowp> lowp_fmat4x2; + + /// Low single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, lowp> lowp_fmat4x3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, lowp> lowp_fmat4x4; + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_fmat1x1 lowp_fmat1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_fmat2x2 lowp_fmat2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_fmat3x3 lowp_fmat3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_fmat4x4 lowp_fmat4; + + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_f32 mediump_fmat1x1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, mediump> mediump_fmat2x2; + + /// Medium single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, mediump> mediump_fmat2x3; + + /// Medium single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, mediump> mediump_fmat2x4; + + /// Medium single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, mediump> mediump_fmat3x2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, mediump> mediump_fmat3x3; + + /// Medium single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, mediump> mediump_fmat3x4; + + /// Medium single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, mediump> mediump_fmat4x2; + + /// Medium single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, mediump> mediump_fmat4x3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, mediump> mediump_fmat4x4; + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_fmat1x1 mediump_fmat1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_fmat2x2 mediump_fmat2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_fmat3x3 mediump_fmat3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_fmat4x4 mediump_fmat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_f32 highp_fmat1x1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, highp> highp_fmat2x2; + + /// High single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, highp> highp_fmat2x3; + + /// High single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, highp> highp_fmat2x4; + + /// High single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, highp> highp_fmat3x2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, highp> highp_fmat3x3; + + /// High single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, highp> highp_fmat3x4; + + /// High single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, highp> highp_fmat4x2; + + /// High single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, highp> highp_fmat4x3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, highp> highp_fmat4x4; + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_fmat1x1 highp_fmat1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_fmat2x2 highp_fmat2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_fmat3x3 highp_fmat3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_fmat4x4 highp_fmat4; + + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 lowp_f32mat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, lowp> lowp_f32mat2x2; + + /// Low single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, lowp> lowp_f32mat2x3; + + /// Low single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, lowp> lowp_f32mat2x4; + + /// Low single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, lowp> lowp_f32mat3x2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, lowp> lowp_f32mat3x3; + + /// Low single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, lowp> lowp_f32mat3x4; + + /// Low single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, lowp> lowp_f32mat4x2; + + /// Low single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, lowp> lowp_f32mat4x3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, lowp> lowp_f32mat4x4; + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 lowp_f32mat1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat2x2 lowp_f32mat2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat3x3 lowp_f32mat3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat4x4 lowp_f32mat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 mediump_f32mat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, mediump> mediump_f32mat2x2; + + /// Medium single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, mediump> mediump_f32mat2x3; + + /// Medium single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, mediump> mediump_f32mat2x4; + + /// Medium single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, mediump> mediump_f32mat3x2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, mediump> mediump_f32mat3x3; + + /// Medium single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, mediump> mediump_f32mat3x4; + + /// Medium single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, mediump> mediump_f32mat4x2; + + /// Medium single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, mediump> mediump_f32mat4x3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, mediump> mediump_f32mat4x4; + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat2x2 mediump_f32mat2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat3x3 mediump_f32mat3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat4x4 mediump_f32mat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 highp_f32mat1x1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, highp> highp_f32mat2x2; + + /// High single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, highp> highp_f32mat2x3; + + /// High single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, highp> highp_f32mat2x4; + + /// High single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, highp> highp_f32mat3x2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, highp> highp_f32mat3x3; + + /// High single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, highp> highp_f32mat3x4; + + /// High single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, highp> highp_f32mat4x2; + + /// High single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, highp> highp_f32mat4x3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, highp> highp_f32mat4x4; + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_f32mat2x2 highp_f32mat2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_f32mat3x3 highp_f32mat3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_f32mat4x4 highp_f32mat4; + + + /// Low double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 lowp_f64mat1x1; + + /// Low double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, lowp> lowp_f64mat2x2; + + /// Low double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, lowp> lowp_f64mat2x3; + + /// Low double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, lowp> lowp_f64mat2x4; + + /// Low double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, lowp> lowp_f64mat3x2; + + /// Low double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, lowp> lowp_f64mat3x3; + + /// Low double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, lowp> lowp_f64mat3x4; + + /// Low double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, lowp> lowp_f64mat4x2; + + /// Low double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, lowp> lowp_f64mat4x3; + + /// Low double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, lowp> lowp_f64mat4x4; + + /// Low double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_f64mat1x1 lowp_f64mat1; + + /// Low double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat2x2 lowp_f64mat2; + + /// Low double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat3x3 lowp_f64mat3; + + /// Low double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat4x4 lowp_f64mat4; + + + /// Medium double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 Highp_f64mat1x1; + + /// Medium double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, mediump> mediump_f64mat2x2; + + /// Medium double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, mediump> mediump_f64mat2x3; + + /// Medium double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, mediump> mediump_f64mat2x4; + + /// Medium double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, mediump> mediump_f64mat3x2; + + /// Medium double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, mediump> mediump_f64mat3x3; + + /// Medium double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, mediump> mediump_f64mat3x4; + + /// Medium double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, mediump> mediump_f64mat4x2; + + /// Medium double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, mediump> mediump_f64mat4x3; + + /// Medium double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, mediump> mediump_f64mat4x4; + + /// Medium double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_f64mat1x1 mediump_f64mat1; + + /// Medium double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat2x2 mediump_f64mat2; + + /// Medium double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat3x3 mediump_f64mat3; + + /// Medium double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat4x4 mediump_f64mat4; + + /// High double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 highp_f64mat1x1; + + /// High double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, highp> highp_f64mat2x2; + + /// High double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, highp> highp_f64mat2x3; + + /// High double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, highp> highp_f64mat2x4; + + /// High double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, highp> highp_f64mat3x2; + + /// High double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, highp> highp_f64mat3x3; + + /// High double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, highp> highp_f64mat3x4; + + /// High double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, highp> highp_f64mat4x2; + + /// High double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, highp> highp_f64mat4x3; + + /// High double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, highp> highp_f64mat4x4; + + /// High double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_f64mat1x1 highp_f64mat1; + + /// High double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_f64mat2x2 highp_f64mat2; + + /// High double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_f64mat3x3 highp_f64mat3; + + /// High double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_f64mat4x4 highp_f64mat4; + + + ///////////////////////////// + // Signed int vector types + + /// Low qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, lowp> lowp_ivec1; + + /// Low qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, lowp> lowp_ivec2; + + /// Low qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, lowp> lowp_ivec3; + + /// Low qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, lowp> lowp_ivec4; + + + /// Medium qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, mediump> mediump_ivec1; + + /// Medium qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, mediump> mediump_ivec2; + + /// Medium qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, mediump> mediump_ivec3; + + /// Medium qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, mediump> mediump_ivec4; + + + /// High qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, highp> highp_ivec1; + + /// High qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, highp> highp_ivec2; + + /// High qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, highp> highp_ivec3; + + /// High qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, highp> highp_ivec4; + + + /// Low qualifier 8 bit signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, i8, lowp> lowp_i8vec1; + + /// Low qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, lowp> lowp_i8vec2; + + /// Low qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, lowp> lowp_i8vec3; + + /// Low qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, lowp> lowp_i8vec4; + + + /// Medium qualifier 8 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i8, mediump> mediump_i8vec1; + + /// Medium qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, mediump> mediump_i8vec2; + + /// Medium qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, mediump> mediump_i8vec3; + + /// Medium qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, mediump> mediump_i8vec4; + + + /// High qualifier 8 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i8, highp> highp_i8vec1; + + /// High qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, highp> highp_i8vec2; + + /// High qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, highp> highp_i8vec3; + + /// High qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, highp> highp_i8vec4; + + + /// Low qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, lowp> lowp_i16vec1; + + /// Low qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, lowp> lowp_i16vec2; + + /// Low qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, lowp> lowp_i16vec3; + + /// Low qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, lowp> lowp_i16vec4; + + + /// Medium qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, mediump> mediump_i16vec1; + + /// Medium qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, mediump> mediump_i16vec2; + + /// Medium qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, mediump> mediump_i16vec3; + + /// Medium qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, mediump> mediump_i16vec4; + + + /// High qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, highp> highp_i16vec1; + + /// High qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, highp> highp_i16vec2; + + /// High qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, highp> highp_i16vec3; + + /// High qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, highp> highp_i16vec4; + + + /// Low qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, lowp> lowp_i32vec1; + + /// Low qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, lowp> lowp_i32vec2; + + /// Low qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, lowp> lowp_i32vec3; + + /// Low qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, lowp> lowp_i32vec4; + + + /// Medium qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, mediump> mediump_i32vec1; + + /// Medium qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, mediump> mediump_i32vec2; + + /// Medium qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, mediump> mediump_i32vec3; + + /// Medium qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, mediump> mediump_i32vec4; + + + /// High qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, highp> highp_i32vec1; + + /// High qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, highp> highp_i32vec2; + + /// High qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, highp> highp_i32vec3; + + /// High qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, highp> highp_i32vec4; + + + /// Low qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, lowp> lowp_i64vec1; + + /// Low qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, lowp> lowp_i64vec2; + + /// Low qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, lowp> lowp_i64vec3; + + /// Low qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, lowp> lowp_i64vec4; + + + /// Medium qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, mediump> mediump_i64vec1; + + /// Medium qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, mediump> mediump_i64vec2; + + /// Medium qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, mediump> mediump_i64vec3; + + /// Medium qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, mediump> mediump_i64vec4; + + + /// High qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, highp> highp_i64vec1; + + /// High qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, highp> highp_i64vec2; + + /// High qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, highp> highp_i64vec3; + + /// High qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, highp> highp_i64vec4; + + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, lowp> lowp_uvec1; + + /// Low qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, lowp> lowp_uvec2; + + /// Low qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, lowp> lowp_uvec3; + + /// Low qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, lowp> lowp_uvec4; + + + /// Medium qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, mediump> mediump_uvec1; + + /// Medium qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, mediump> mediump_uvec2; + + /// Medium qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, mediump> mediump_uvec3; + + /// Medium qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, mediump> mediump_uvec4; + + + /// High qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, highp> highp_uvec1; + + /// High qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, highp> highp_uvec2; + + /// High qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, highp> highp_uvec3; + + /// High qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, highp> highp_uvec4; + + + /// Low qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, lowp> lowp_u8vec1; + + /// Low qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, lowp> lowp_u8vec2; + + /// Low qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, lowp> lowp_u8vec3; + + /// Low qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, lowp> lowp_u8vec4; + + + /// Medium qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, mediump> mediump_u8vec1; + + /// Medium qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, mediump> mediump_u8vec2; + + /// Medium qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, mediump> mediump_u8vec3; + + /// Medium qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, mediump> mediump_u8vec4; + + + /// High qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, highp> highp_u8vec1; + + /// High qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, highp> highp_u8vec2; + + /// High qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, highp> highp_u8vec3; + + /// High qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, highp> highp_u8vec4; + + + /// Low qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, lowp> lowp_u16vec1; + + /// Low qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, lowp> lowp_u16vec2; + + /// Low qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, lowp> lowp_u16vec3; + + /// Low qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, lowp> lowp_u16vec4; + + + /// Medium qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, mediump> mediump_u16vec1; + + /// Medium qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, mediump> mediump_u16vec2; + + /// Medium qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, mediump> mediump_u16vec3; + + /// Medium qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, mediump> mediump_u16vec4; + + + /// High qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, highp> highp_u16vec1; + + /// High qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, highp> highp_u16vec2; + + /// High qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, highp> highp_u16vec3; + + /// High qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, highp> highp_u16vec4; + + + /// Low qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, lowp> lowp_u32vec1; + + /// Low qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, lowp> lowp_u32vec2; + + /// Low qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, lowp> lowp_u32vec3; + + /// Low qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, lowp> lowp_u32vec4; + + + /// Medium qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, mediump> mediump_u32vec1; + + /// Medium qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, mediump> mediump_u32vec2; + + /// Medium qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, mediump> mediump_u32vec3; + + /// Medium qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, mediump> mediump_u32vec4; + + + /// High qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, highp> highp_u32vec1; + + /// High qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, highp> highp_u32vec2; + + /// High qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, highp> highp_u32vec3; + + /// High qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, highp> highp_u32vec4; + + + /// Low qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, lowp> lowp_u64vec1; + + /// Low qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, lowp> lowp_u64vec2; + + /// Low qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, lowp> lowp_u64vec3; + + /// Low qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, lowp> lowp_u64vec4; + + + /// Medium qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, mediump> mediump_u64vec1; + + /// Medium qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, mediump> mediump_u64vec2; + + /// Medium qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, mediump> mediump_u64vec3; + + /// Medium qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, mediump> mediump_u64vec4; + + + /// High qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, highp> highp_u64vec1; + + /// High qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, highp> highp_u64vec2; + + /// High qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, highp> highp_u64vec3; + + /// High qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, highp> highp_u64vec4; + + + ////////////////////// + // Float vector types + + /// 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 float32_t; + + /// 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 f32; + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 float64_t; + + /// 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 f64; +# endif//GLM_FORCE_SINGLE_ONLY + + /// Single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, defaultp> fvec1; + + /// Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, defaultp> fvec2; + + /// Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, defaultp> fvec3; + + /// Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, defaultp> fvec4; + + + /// Single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, defaultp> f32vec1; + + /// Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f32, defaultp> f32vec2; + + /// Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f32, defaultp> f32vec3; + + /// Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f32, defaultp> f32vec4; + +# ifndef GLM_FORCE_SINGLE_ONLY + /// Double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, defaultp> f64vec1; + + /// Double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, defaultp> f64vec2; + + /// Double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, defaultp> f64vec3; + + /// Double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, defaultp> f64vec4; +# endif//GLM_FORCE_SINGLE_ONLY + + + ////////////////////// + // Float matrix types + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 fmat1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> fmat2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> fmat3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> fmat4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 fmat1x1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> fmat2x2; + + /// Single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, defaultp> fmat2x3; + + /// Single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, defaultp> fmat2x4; + + /// Single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, defaultp> fmat3x2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> fmat3x3; + + /// Single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, defaultp> fmat3x4; + + /// Single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, defaultp> fmat4x2; + + /// Single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, defaultp> fmat4x3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> fmat4x4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> f32mat2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> f32mat3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> f32mat4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 f32mat1x1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> f32mat2x2; + + /// Single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, defaultp> f32mat2x3; + + /// Single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, defaultp> f32mat2x4; + + /// Single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, defaultp> f32mat3x2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> f32mat3x3; + + /// Single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, defaultp> f32mat3x4; + + /// Single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, defaultp> f32mat4x2; + + /// Single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, defaultp> f32mat4x3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> f32mat4x4; + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f64mat1; + + /// Double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, defaultp> f64mat2; + + /// Double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, defaultp> f64mat3; + + /// Double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, defaultp> f64mat4; + + + /// Double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 f64mat1x1; + + /// Double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, defaultp> f64mat2x2; + + /// Double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, defaultp> f64mat2x3; + + /// Double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, defaultp> f64mat2x4; + + /// Double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, defaultp> f64mat3x2; + + /// Double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, defaultp> f64mat3x3; + + /// Double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, defaultp> f64mat3x4; + + /// Double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, defaultp> f64mat4x2; + + /// Double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, defaultp> f64mat4x3; + + /// Double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, defaultp> f64mat4x4; + +# endif//GLM_FORCE_SINGLE_ONLY + + ////////////////////////// + // Quaternion types + + /// Single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua f32quat; + + /// Low single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua lowp_f32quat; + + /// Low double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua lowp_f64quat; + + /// Medium single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua mediump_f32quat; + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Medium double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua mediump_f64quat; + + /// High single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua highp_f32quat; + + /// High double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua highp_f64quat; + + /// Double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua f64quat; + +# endif//GLM_FORCE_SINGLE_ONLY + + /// @} +}//namespace glm + +#include "type_precision.inl" diff --git a/src/other/manifold/glm/glm/gtc/type_precision.inl b/src/other/manifold/glm/glm/gtc/type_precision.inl new file mode 100644 index 00000000000..ae8091206bd --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/type_precision.inl @@ -0,0 +1,6 @@ +/// @ref gtc_precision + +namespace glm +{ + +} diff --git a/src/other/manifold/glm/glm/gtc/type_ptr.hpp b/src/other/manifold/glm/glm/gtc/type_ptr.hpp new file mode 100644 index 00000000000..d7e625aa591 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/type_ptr.hpp @@ -0,0 +1,230 @@ +/// @ref gtc_type_ptr +/// @file glm/gtc/type_ptr.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_type_ptr GLM_GTC_type_ptr +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Handles the interaction between pointers and vector, matrix types. +/// +/// This extension defines an overloaded function, glm::value_ptr. It returns +/// a pointer to the memory layout of the object. Matrix types store their values +/// in column-major order. +/// +/// This is useful for uploading data to matrices or copying data to buffer objects. +/// +/// Example: +/// @code +/// #include +/// #include +/// +/// glm::vec3 aVector(3); +/// glm::mat4 someMatrix(1.0); +/// +/// glUniform3fv(uniformLoc, 1, glm::value_ptr(aVector)); +/// glUniformMatrix4fv(uniformMatrixLoc, 1, GL_FALSE, glm::value_ptr(someMatrix)); +/// @endcode +/// +/// need to be included to use the features of this extension. + +#pragma once + +// Dependency: +#include "../gtc/quaternion.hpp" +#include "../gtc/vec1.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_ptr extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_type_ptr + /// @{ + + /// Return the constant address to the data of the input parameter. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL typename genType::value_type const * value_ptr(genType const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, defaultp> make_vec2(T const * const ptr); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, defaultp> make_vec3(T const * const ptr); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, defaultp> make_vec4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 3, T, defaultp> make_mat2x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 4, T, defaultp> make_mat2x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 2, T, defaultp> make_mat3x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 4, T, defaultp> make_mat3x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 2, T, defaultp> make_mat4x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 3, T, defaultp> make_mat4x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4(T const * const ptr); + + /// Build a quaternion from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL qua make_quat(T const * const ptr); + + /// @} +}//namespace glm + +#include "type_ptr.inl" diff --git a/src/other/manifold/glm/glm/gtc/type_ptr.inl b/src/other/manifold/glm/glm/gtc/type_ptr.inl new file mode 100644 index 00000000000..71df4d30d00 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/type_ptr.inl @@ -0,0 +1,386 @@ +/// @ref gtc_type_ptr + +#include + +namespace glm +{ + /// @addtogroup gtc_type_ptr + /// @{ + + template + GLM_FUNC_QUALIFIER T const* value_ptr(vec<2, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<2, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const * value_ptr(vec<3, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<3, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(vec<4, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<4, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T * value_ptr(mat<4, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const * value_ptr(qua const& q) + { + return &(q[0]); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(qua& q) + { + return &(q[0]); + } + + template + inline vec<1, T, Q> make_vec1(vec<1, T, Q> const& v) + { + return v; + } + + template + inline vec<1, T, Q> make_vec1(vec<2, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + inline vec<1, T, Q> make_vec1(vec<3, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + inline vec<1, T, Q> make_vec1(vec<4, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + inline vec<2, T, Q> make_vec2(vec<1, T, Q> const& v) + { + return vec<2, T, Q>(v.x, static_cast(0)); + } + + template + inline vec<2, T, Q> make_vec2(vec<2, T, Q> const& v) + { + return v; + } + + template + inline vec<2, T, Q> make_vec2(vec<3, T, Q> const& v) + { + return vec<2, T, Q>(v); + } + + template + inline vec<2, T, Q> make_vec2(vec<4, T, Q> const& v) + { + return vec<2, T, Q>(v); + } + + template + inline vec<3, T, Q> make_vec3(vec<1, T, Q> const& v) + { + return vec<3, T, Q>(v.x, static_cast(0), static_cast(0)); + } + + template + inline vec<3, T, Q> make_vec3(vec<2, T, Q> const& v) + { + return vec<3, T, Q>(v.x, v.y, static_cast(0)); + } + + template + inline vec<3, T, Q> make_vec3(vec<3, T, Q> const& v) + { + return v; + } + + template + inline vec<3, T, Q> make_vec3(vec<4, T, Q> const& v) + { + return vec<3, T, Q>(v); + } + + template + inline vec<4, T, Q> make_vec4(vec<1, T, Q> const& v) + { + return vec<4, T, Q>(v.x, static_cast(0), static_cast(0), static_cast(1)); + } + + template + inline vec<4, T, Q> make_vec4(vec<2, T, Q> const& v) + { + return vec<4, T, Q>(v.x, v.y, static_cast(0), static_cast(1)); + } + + template + inline vec<4, T, Q> make_vec4(vec<3, T, Q> const& v) + { + return vec<4, T, Q>(v.x, v.y, v.z, static_cast(1)); + } + + template + inline vec<4, T, Q> make_vec4(vec<4, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> make_vec2(T const *const ptr) + { + vec<2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> make_vec3(T const *const ptr) + { + vec<3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, defaultp> make_vec4(T const *const ptr) + { + vec<4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2x2(T const *const ptr) + { + mat<2, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, defaultp> make_mat2x3(T const *const ptr) + { + mat<2, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, defaultp> make_mat2x4(T const *const ptr) + { + mat<2, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, defaultp> make_mat3x2(T const *const ptr) + { + mat<3, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3x3(T const *const ptr) + { + mat<3, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, defaultp> make_mat3x4(T const *const ptr) + { + mat<3, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, defaultp> make_mat4x2(T const *const ptr) + { + mat<4, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, defaultp> make_mat4x3(T const *const ptr) + { + mat<4, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4x4(T const *const ptr) + { + mat<4, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2(T const *const ptr) + { + return make_mat2x2(ptr); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3(T const *const ptr) + { + return make_mat3x3(ptr); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4(T const *const ptr) + { + return make_mat4x4(ptr); + } + + template + GLM_FUNC_QUALIFIER qua make_quat(T const *const ptr) + { + qua Result; + memcpy(value_ptr(Result), ptr, sizeof(qua)); + return Result; + } + + /// @} +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtc/ulp.hpp b/src/other/manifold/glm/glm/gtc/ulp.hpp new file mode 100644 index 00000000000..0d80a75852a --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/ulp.hpp @@ -0,0 +1,152 @@ +/// @ref gtc_ulp +/// @file glm/gtc/ulp.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_ulp GLM_GTC_ulp +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType next_float(genType x); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType prev_float(genType x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType next_float(genType x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType prev_float(genType x, int ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @see gtc_ulp + GLM_FUNC_DECL int float_distance(float x, float y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @see gtc_ulp + GLM_FUNC_DECL int64 float_distance(double x, double y); + + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x, int ULPs); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x, vec const& ULPs); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x, vec const& ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec float_distance(vec const& x, vec const& y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec float_distance(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "ulp.inl" diff --git a/src/other/manifold/glm/glm/gtc/ulp.inl b/src/other/manifold/glm/glm/gtc/ulp.inl new file mode 100644 index 00000000000..4ecbd3f437a --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/ulp.inl @@ -0,0 +1,173 @@ +/// @ref gtc_ulp + +#include "../ext/scalar_ulp.hpp" + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER float next_float(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MAX); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MAX); +# else + return nextafterf(x, FLT_MAX); +# endif + } + + template<> + GLM_FUNC_QUALIFIER double next_float(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafter(x, std::numeric_limits::max()); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MAX); +# else + return nextafter(x, DBL_MAX); +# endif + } + + template + GLM_FUNC_QUALIFIER T next_float(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'next_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for (int i = 0; i < ULPs; ++i) + temp = next_float(temp); + return temp; + } + + GLM_FUNC_QUALIFIER float prev_float(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MIN); +# else + return nextafterf(x, FLT_MIN); +# endif + } + + GLM_FUNC_QUALIFIER double prev_float(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return _nextafter(x, DBL_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MIN); +# else + return nextafter(x, DBL_MIN); +# endif + } + + template + GLM_FUNC_QUALIFIER T prev_float(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'prev_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for (int i = 0; i < ULPs; ++i) + temp = prev_float(temp); + return temp; + } + + GLM_FUNC_QUALIFIER int float_distance(float x, float y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + GLM_FUNC_QUALIFIER int64 float_distance(double x, double y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x, int ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x, vec const& ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x, int ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x, vec const& ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec float_distance(vec const& x, vec const& y) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = float_distance(x[i], y[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec float_distance(vec const& x, vec const& y) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = float_distance(x[i], y[i]); + return Result; + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtc/vec1.hpp b/src/other/manifold/glm/glm/gtc/vec1.hpp new file mode 100644 index 00000000000..63697a21575 --- /dev/null +++ b/src/other/manifold/glm/glm/gtc/vec1.hpp @@ -0,0 +1,30 @@ +/// @ref gtc_vec1 +/// @file glm/gtc/vec1.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_vec1 GLM_GTC_vec1 +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Add vec1, ivec1, uvec1 and bvec1 types. + +#pragma once + +// Dependency: +#include "../ext/vector_bool1.hpp" +#include "../ext/vector_bool1_precision.hpp" +#include "../ext/vector_float1.hpp" +#include "../ext/vector_float1_precision.hpp" +#include "../ext/vector_double1.hpp" +#include "../ext/vector_double1_precision.hpp" +#include "../ext/vector_int1.hpp" +#include "../ext/vector_int1_sized.hpp" +#include "../ext/vector_uint1.hpp" +#include "../ext/vector_uint1_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_vec1 extension included") +#endif + diff --git a/src/other/manifold/glm/glm/gtx/associated_min_max.hpp b/src/other/manifold/glm/glm/gtx/associated_min_max.hpp new file mode 100644 index 00000000000..d1a41c06baf --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/associated_min_max.hpp @@ -0,0 +1,207 @@ +/// @ref gtx_associated_min_max +/// @file glm/gtx/associated_min_max.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_associated_min_max GLM_GTX_associated_min_max +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Min and max functions that return associated values not the compared onces. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_associated_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_associated_min_max extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_associated_min_max + /// @{ + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin(T x, U a, T y, U b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec<2, U, Q> associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + T x, const vec& a, + T y, const vec& b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, U a, + vec const& y, U b); + + /// Minimum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin( + T x, U a, + T y, U b, + T z, U c); + + /// Minimum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin( + T x, U a, + T y, U b, + T z, U c, + T w, U d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax(T x, U a, T y, U b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec<2, U, Q> associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax( + T x, U a, + T y, U b, + T z, U c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax( + T x, U a, + T y, U b, + T z, U c, + T w, U d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d); + + /// @} +} //namespace glm + +#include "associated_min_max.inl" diff --git a/src/other/manifold/glm/glm/gtx/associated_min_max.inl b/src/other/manifold/glm/glm/gtx/associated_min_max.inl new file mode 100644 index 00000000000..5186c471c28 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/associated_min_max.inl @@ -0,0 +1,354 @@ +/// @ref gtx_associated_min_max + +namespace glm{ + +// Min comparison between 2 variables +template +GLM_FUNC_QUALIFIER U associatedMin(T x, U a, T y, U b) +{ + return x < y ? a : b; +} + +template +GLM_FUNC_QUALIFIER vec<2, U, Q> associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? a[i] : b[i]; + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + T x, const vec& a, + T y, const vec& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x < y ? a[i] : b[i]; + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, U a, + vec const& y, U b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? a : b; + return Result; +} + +// Min comparison between 3 variables +template +GLM_FUNC_QUALIFIER U associatedMin +( + T x, U a, + T y, U b, + T z, U c +) +{ + U Result = x < y ? (x < z ? a : c) : (y < z ? b : c); + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]); + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER U associatedMin +( + T x, U a, + T y, U b, + T z, U c, + T w, U d +) +{ + T Test1 = min(x, y); + T Test2 = min(z, w); + U Result1 = x < y ? a : b; + U Result2 = z < w ? c : d; + U Result = Test1 < Test2 ? Result1 : Result2; + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = min(x[i], y[i]); + T Test2 = min(z[i], w[i]); + U Result1 = x[i] < y[i] ? a[i] : b[i]; + U Result2 = z[i] < w[i] ? c[i] : d[i]; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d +) +{ + T Test1 = min(x, y); + T Test2 = min(z, w); + + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + U Result1 = x < y ? a[i] : b[i]; + U Result2 = z < w ? c[i] : d[i]; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = min(x[i], y[i]); + T Test2 = min(z[i], w[i]); + U Result1 = x[i] < y[i] ? a : b; + U Result2 = z[i] < w[i] ? c : d; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER U associatedMax(T x, U a, T y, U b) +{ + return x > y ? a : b; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec<2, U, Q> associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? a[i] : b[i]; + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x > y ? a[i] : b[i]; + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? a : b; + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER U associatedMax +( + T x, U a, + T y, U b, + T z, U c +) +{ + U Result = x > y ? (x > z ? a : c) : (y > z ? b : c); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c); + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER U associatedMax +( + T x, U a, + T y, U b, + T z, U c, + T w, U d +) +{ + T Test1 = max(x, y); + T Test2 = max(z, w); + U Result1 = x > y ? a : b; + U Result2 = z > w ? c : d; + U Result = Test1 > Test2 ? Result1 : Result2; + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = max(x[i], y[i]); + T Test2 = max(z[i], w[i]); + U Result1 = x[i] > y[i] ? a[i] : b[i]; + U Result2 = z[i] > w[i] ? c[i] : d[i]; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d +) +{ + T Test1 = max(x, y); + T Test2 = max(z, w); + + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + U Result1 = x > y ? a[i] : b[i]; + U Result2 = z > w ? c[i] : d[i]; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = max(x[i], y[i]); + T Test2 = max(z[i], w[i]); + U Result1 = x[i] > y[i] ? a : b; + U Result2 = z[i] > w[i] ? c : d; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/bit.hpp b/src/other/manifold/glm/glm/gtx/bit.hpp new file mode 100644 index 00000000000..60a7aef1b46 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/bit.hpp @@ -0,0 +1,98 @@ +/// @ref gtx_bit +/// @file glm/gtx/bit.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_bit GLM_GTX_bit +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../gtc/bitfield.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_bit is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_bit extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_bit + /// @{ + + /// @see gtx_bit + template + GLM_FUNC_DECL genIUType highestBitValue(genIUType Value); + + /// @see gtx_bit + template + GLM_FUNC_DECL genIUType lowestBitValue(genIUType Value); + + /// Find the highest bit set to 1 in a integer variable and return its value. + /// + /// @see gtx_bit + template + GLM_FUNC_DECL vec highestBitValue(vec const& value); + + /// Return the power of two number which value is just higher the input value. + /// Deprecated, use ceilPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoAbove(genIUType Value); + + /// Return the power of two number which value is just higher the input value. + /// Deprecated, use ceilPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoAbove(vec const& value); + + /// Return the power of two number which value is just lower the input value. + /// Deprecated, use floorPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoBelow(genIUType Value); + + /// Return the power of two number which value is just lower the input value. + /// Deprecated, use floorPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoBelow(vec const& value); + + /// Return the power of two number which value is the closet to the input value. + /// Deprecated, use roundPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoNearest(genIUType Value); + + /// Return the power of two number which value is the closet to the input value. + /// Deprecated, use roundPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoNearest(vec const& value); + + /// @} +} //namespace glm + + +#include "bit.inl" + diff --git a/src/other/manifold/glm/glm/gtx/bit.inl b/src/other/manifold/glm/glm/gtx/bit.inl new file mode 100644 index 00000000000..621b6262406 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/bit.inl @@ -0,0 +1,92 @@ +/// @ref gtx_bit + +namespace glm +{ + /////////////////// + // highestBitValue + + template + GLM_FUNC_QUALIFIER genIUType highestBitValue(genIUType Value) + { + genIUType tmp = Value; + genIUType result = genIUType(0); + while(tmp) + { + result = (tmp & (~tmp + 1)); // grab lowest bit + tmp &= ~result; // clear lowest bit + } + return result; + } + + template + GLM_FUNC_QUALIFIER vec highestBitValue(vec const& v) + { + return detail::functor1::call(highestBitValue, v); + } + + /////////////////// + // lowestBitValue + + template + GLM_FUNC_QUALIFIER genIUType lowestBitValue(genIUType Value) + { + return (Value & (~Value + 1)); + } + + template + GLM_FUNC_QUALIFIER vec lowestBitValue(vec const& v) + { + return detail::functor1::call(lowestBitValue, v); + } + + /////////////////// + // powerOfTwoAbove + + template + GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value) << 1; + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoAbove(vec const& v) + { + return detail::functor1::call(powerOfTwoAbove, v); + } + + /////////////////// + // powerOfTwoBelow + + template + GLM_FUNC_QUALIFIER genType powerOfTwoBelow(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value); + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoBelow(vec const& v) + { + return detail::functor1::call(powerOfTwoBelow, v); + } + + ///////////////////// + // powerOfTwoNearest + + template + GLM_FUNC_QUALIFIER genType powerOfTwoNearest(genType value) + { + if(isPowerOfTwo(value)) + return value; + + genType const prev = highestBitValue(value); + genType const next = prev << 1; + return (next - value) < (value - prev) ? next : prev; + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoNearest(vec const& v) + { + return detail::functor1::call(powerOfTwoNearest, v); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/closest_point.hpp b/src/other/manifold/glm/glm/gtx/closest_point.hpp new file mode 100644 index 00000000000..de6dbbff944 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/closest_point.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_closest_point +/// @file glm/gtx/closest_point.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_closest_point GLM_GTX_closest_point +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Find the point on a straight line which is the closet of a point. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_closest_point extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_closest_point + /// @{ + + /// Find the point on a straight line which is the closet of a point. + /// @see gtx_closest_point + template + GLM_FUNC_DECL vec<3, T, Q> closestPointOnLine( + vec<3, T, Q> const& point, + vec<3, T, Q> const& a, + vec<3, T, Q> const& b); + + /// 2d lines work as well + template + GLM_FUNC_DECL vec<2, T, Q> closestPointOnLine( + vec<2, T, Q> const& point, + vec<2, T, Q> const& a, + vec<2, T, Q> const& b); + + /// @} +}// namespace glm + +#include "closest_point.inl" diff --git a/src/other/manifold/glm/glm/gtx/closest_point.inl b/src/other/manifold/glm/glm/gtx/closest_point.inl new file mode 100644 index 00000000000..0a39b042b88 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/closest_point.inl @@ -0,0 +1,45 @@ +/// @ref gtx_closest_point + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> closestPointOnLine + ( + vec<3, T, Q> const& point, + vec<3, T, Q> const& a, + vec<3, T, Q> const& b + ) + { + T LineLength = distance(a, b); + vec<3, T, Q> Vector = point - a; + vec<3, T, Q> LineDirection = (b - a) / LineLength; + + // Project Vector to LineDirection to get the distance of point from a + T Distance = dot(Vector, LineDirection); + + if(Distance <= T(0)) return a; + if(Distance >= LineLength) return b; + return a + LineDirection * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> closestPointOnLine + ( + vec<2, T, Q> const& point, + vec<2, T, Q> const& a, + vec<2, T, Q> const& b + ) + { + T LineLength = distance(a, b); + vec<2, T, Q> Vector = point - a; + vec<2, T, Q> LineDirection = (b - a) / LineLength; + + // Project Vector to LineDirection to get the distance of point from a + T Distance = dot(Vector, LineDirection); + + if(Distance <= T(0)) return a; + if(Distance >= LineLength) return b; + return a + LineDirection * Distance; + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/color_encoding.hpp b/src/other/manifold/glm/glm/gtx/color_encoding.hpp new file mode 100644 index 00000000000..96ded2a2770 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_encoding.hpp @@ -0,0 +1,54 @@ +/// @ref gtx_color_encoding +/// @file glm/gtx/color_encoding.hpp +/// +/// @see core (dependence) +/// @see gtx_color_encoding (dependence) +/// +/// @defgroup gtx_color_encoding GLM_GTX_color_encoding +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../vec3.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTC_color_encoding is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTC_color_encoding extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_encoding + /// @{ + + /// Convert a linear sRGB color to D65 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB); + + /// Convert a linear sRGB color to D50 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB); + + /// Convert a D65 YUV color to linear sRGB. + template + GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ); + + /// Convert a D65 YUV color to D50 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ); + + /// @} +} //namespace glm + +#include "color_encoding.inl" diff --git a/src/other/manifold/glm/glm/gtx/color_encoding.inl b/src/other/manifold/glm/glm/gtx/color_encoding.inl new file mode 100644 index 00000000000..e50fa3efa42 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_encoding.inl @@ -0,0 +1,45 @@ +/// @ref gtx_color_encoding + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB) + { + vec<3, T, Q> const M(0.490f, 0.17697f, 0.2f); + vec<3, T, Q> const N(0.31f, 0.8124f, 0.01063f); + vec<3, T, Q> const O(0.490f, 0.01f, 0.99f); + + return (M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB) * static_cast(5.650675255693055f); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB) + { + vec<3, T, Q> const M(0.436030342570117f, 0.222438466210245f, 0.013897440074263f); + vec<3, T, Q> const N(0.385101860087134f, 0.716942745571917f, 0.097076381494207f); + vec<3, T, Q> const O(0.143067806654203f, 0.060618777416563f, 0.713926257896652f); + + return M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ) + { + vec<3, T, Q> const M(0.41847f, -0.091169f, 0.0009209f); + vec<3, T, Q> const N(-0.15866f, 0.25243f, 0.015708f); + vec<3, T, Q> const O(0.0009209f, -0.0025498f, 0.1786f); + + return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ) + { + vec<3, T, Q> const M(+1.047844353856414f, +0.029549007606644f, -0.009250984365223f); + vec<3, T, Q> const N(+0.022898981050086f, +0.990508028941971f, +0.015072338237051f); + vec<3, T, Q> const O(-0.050206647741605f, -0.017074711360960f, +0.751717835079977f); + + return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ; + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/color_space.hpp b/src/other/manifold/glm/glm/gtx/color_space.hpp new file mode 100644 index 00000000000..a6343921490 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_space.hpp @@ -0,0 +1,72 @@ +/// @ref gtx_color_space +/// @file glm/gtx/color_space.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_color_space GLM_GTX_color_space +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Related to RGB to HSV conversions and operations. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_color_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_color_space extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_space + /// @{ + + /// Converts a color from HSV color space to its color in RGB color space. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> rgbColor( + vec<3, T, Q> const& hsvValue); + + /// Converts a color from RGB color space to its color in HSV color space. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> hsvColor( + vec<3, T, Q> const& rgbValue); + + /// Build a saturation matrix. + /// @see gtx_color_space + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> saturation( + T const s); + + /// Modify the saturation of a color. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> saturation( + T const s, + vec<3, T, Q> const& color); + + /// Modify the saturation of a color. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<4, T, Q> saturation( + T const s, + vec<4, T, Q> const& color); + + /// Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals. + /// @see gtx_color_space + template + GLM_FUNC_DECL T luminosity( + vec<3, T, Q> const& color); + + /// @} +}//namespace glm + +#include "color_space.inl" diff --git a/src/other/manifold/glm/glm/gtx/color_space.inl b/src/other/manifold/glm/glm/gtx/color_space.inl new file mode 100644 index 00000000000..f698afe1e1b --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_space.inl @@ -0,0 +1,141 @@ +/// @ref gtx_color_space + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgbColor(const vec<3, T, Q>& hsvColor) + { + vec<3, T, Q> hsv = hsvColor; + vec<3, T, Q> rgbColor; + + if(hsv.y == static_cast(0)) + // achromatic (grey) + rgbColor = vec<3, T, Q>(hsv.z); + else + { + T sector = floor(hsv.x * (T(1) / T(60))); + T frac = (hsv.x * (T(1) / T(60))) - sector; + // factorial part of h + T o = hsv.z * (T(1) - hsv.y); + T p = hsv.z * (T(1) - hsv.y * frac); + T q = hsv.z * (T(1) - hsv.y * (T(1) - frac)); + + switch(int(sector)) + { + default: + case 0: + rgbColor.r = hsv.z; + rgbColor.g = q; + rgbColor.b = o; + break; + case 1: + rgbColor.r = p; + rgbColor.g = hsv.z; + rgbColor.b = o; + break; + case 2: + rgbColor.r = o; + rgbColor.g = hsv.z; + rgbColor.b = q; + break; + case 3: + rgbColor.r = o; + rgbColor.g = p; + rgbColor.b = hsv.z; + break; + case 4: + rgbColor.r = q; + rgbColor.g = o; + rgbColor.b = hsv.z; + break; + case 5: + rgbColor.r = hsv.z; + rgbColor.g = o; + rgbColor.b = p; + break; + } + } + + return rgbColor; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> hsvColor(const vec<3, T, Q>& rgbColor) + { + vec<3, T, Q> hsv = rgbColor; + float Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b); + float Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b); + float Delta = Max - Min; + + hsv.z = Max; + + if(Max != static_cast(0)) + { + hsv.y = Delta / hsv.z; + T h = static_cast(0); + + if(rgbColor.r == Max) + // between yellow & magenta + h = static_cast(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta; + else if(rgbColor.g == Max) + // between cyan & yellow + h = static_cast(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta; + else + // between magenta & cyan + h = static_cast(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta; + + if(h < T(0)) + hsv.x = h + T(360); + else + hsv.x = h; + } + else + { + // If r = g = b = 0 then s = 0, h is undefined + hsv.y = static_cast(0); + hsv.x = static_cast(0); + } + + return hsv; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> saturation(T const s) + { + vec<3, T, defaultp> rgbw = vec<3, T, defaultp>(T(0.2126), T(0.7152), T(0.0722)); + + vec<3, T, defaultp> const col((T(1) - s) * rgbw); + + mat<4, 4, T, defaultp> result(T(1)); + result[0][0] = col.x + s; + result[0][1] = col.x; + result[0][2] = col.x; + result[1][0] = col.y; + result[1][1] = col.y + s; + result[1][2] = col.y; + result[2][0] = col.z; + result[2][1] = col.z; + result[2][2] = col.z + s; + + return result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> saturation(const T s, const vec<3, T, Q>& color) + { + return vec<3, T, Q>(saturation(s) * vec<4, T, Q>(color, T(0))); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> saturation(const T s, const vec<4, T, Q>& color) + { + return saturation(s) * color; + } + + template + GLM_FUNC_QUALIFIER T luminosity(const vec<3, T, Q>& color) + { + const vec<3, T, Q> tmp = vec<3, T, Q>(0.33, 0.59, 0.11); + return dot(color, tmp); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/color_space_YCoCg.hpp b/src/other/manifold/glm/glm/gtx/color_space_YCoCg.hpp new file mode 100644 index 00000000000..dd2b771693f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_space_YCoCg.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_color_space_YCoCg +/// @file glm/gtx/color_space_YCoCg.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_color_space_YCoCg GLM_GTX_color_space_YCoCg +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// RGB to YCoCg conversions and operations + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_color_space_YCoCg is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_color_space_YCoCg extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_space_YCoCg + /// @{ + + /// Convert a color from RGB color space to YCoCg color space. + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCg( + vec<3, T, Q> const& rgbColor); + + /// Convert a color from YCoCg color space to RGB color space. + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> YCoCg2rgb( + vec<3, T, Q> const& YCoCgColor); + + /// Convert a color from RGB color space to YCoCgR color space. + /// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range" + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCgR( + vec<3, T, Q> const& rgbColor); + + /// Convert a color from YCoCgR color space to RGB color space. + /// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range" + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> YCoCgR2rgb( + vec<3, T, Q> const& YCoCgColor); + + /// @} +}//namespace glm + +#include "color_space_YCoCg.inl" diff --git a/src/other/manifold/glm/glm/gtx/color_space_YCoCg.inl b/src/other/manifold/glm/glm/gtx/color_space_YCoCg.inl new file mode 100644 index 00000000000..83ba857c08b --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/color_space_YCoCg.inl @@ -0,0 +1,107 @@ +/// @ref gtx_color_space_YCoCg + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCg + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.x/*Y */ = rgbColor.r / T(4) + rgbColor.g / T(2) + rgbColor.b / T(4); + result.y/*Co*/ = rgbColor.r / T(2) + rgbColor.g * T(0) - rgbColor.b / T(2); + result.z/*Cg*/ = - rgbColor.r / T(4) + rgbColor.g / T(2) - rgbColor.b / T(4); + return result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCg2rgb + ( + vec<3, T, Q> const& YCoCgColor + ) + { + vec<3, T, Q> result; + result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z; + result.g = YCoCgColor.x + YCoCgColor.z; + result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z; + return result; + } + + template + class compute_YCoCgR { + public: + static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.x/*Y */ = rgbColor.g * static_cast(0.5) + (rgbColor.r + rgbColor.b) * static_cast(0.25); + result.y/*Co*/ = rgbColor.r - rgbColor.b; + result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) * static_cast(0.5); + return result; + } + + static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + vec<3, T, Q> result; + T tmp = YCoCgRColor.x - (YCoCgRColor.z * static_cast(0.5)); + result.g = YCoCgRColor.z + tmp; + result.b = tmp - (YCoCgRColor.y * static_cast(0.5)); + result.r = result.b + YCoCgRColor.y; + return result; + } + }; + + template + class compute_YCoCgR { + public: + static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.y/*Co*/ = rgbColor.r - rgbColor.b; + T tmp = rgbColor.b + (result.y >> 1); + result.z/*Cg*/ = rgbColor.g - tmp; + result.x/*Y */ = tmp + (result.z >> 1); + return result; + } + + static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + vec<3, T, Q> result; + T tmp = YCoCgRColor.x - (YCoCgRColor.z >> 1); + result.g = YCoCgRColor.z + tmp; + result.b = tmp - (YCoCgRColor.y >> 1); + result.r = result.b + YCoCgRColor.y; + return result; + } + }; + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + return compute_YCoCgR::is_integer>::rgb2YCoCgR(rgbColor); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + return compute_YCoCgR::is_integer>::YCoCgR2rgb(YCoCgRColor); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/common.hpp b/src/other/manifold/glm/glm/gtx/common.hpp new file mode 100644 index 00000000000..254ada2d769 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/common.hpp @@ -0,0 +1,76 @@ +/// @ref gtx_common +/// @file glm/gtx/common.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_common GLM_GTX_common +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Provide functions to increase the compatibility with Cg and HLSL languages + +#pragma once + +// Dependencies: +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../gtc/vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_common is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_common extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_common + /// @{ + + /// Returns true if x is a denormalized number + /// Numbers whose absolute value is too small to be represented in the normal format are represented in an alternate, denormalized format. + /// This format is less precise but can represent values closer to zero. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL isnan man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL typename genType::bool_type isdenormal(genType const& x); + + /// Similar to 'mod' but with a different rounding and integer support. + /// Returns 'x - y * trunc(x/y)' instead of 'x - y * floor(x/y)' + /// + /// @see GLSL mod vs HLSL fmod + /// @see GLSL mod man page + template + GLM_FUNC_DECL vec fmod(vec const& v); + + /// Returns whether vector components values are within an interval. A open interval excludes its endpoints, and is denoted with square brackets. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_relational + template + GLM_FUNC_DECL vec openBounded(vec const& Value, vec const& Min, vec const& Max); + + /// Returns whether vector components values are within an interval. A closed interval includes its endpoints, and is denoted with square brackets. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_relational + template + GLM_FUNC_DECL vec closeBounded(vec const& Value, vec const& Min, vec const& Max); + + /// @} +}//namespace glm + +#include "common.inl" diff --git a/src/other/manifold/glm/glm/gtx/common.inl b/src/other/manifold/glm/glm/gtx/common.inl new file mode 100644 index 00000000000..4ad2126d965 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/common.inl @@ -0,0 +1,125 @@ +/// @ref gtx_common + +#include +#include "../gtc/epsilon.hpp" +#include "../gtc/constants.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::fmod, a, b); + } + }; + + template + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + return a % b; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool isdenormal(T const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::fpclassify(x) == FP_SUBNORMAL; +# else + return epsilonNotEqual(x, static_cast(0), epsilon()) && std::fabs(x) < std::numeric_limits::min(); +# endif + } + + template + GLM_FUNC_QUALIFIER typename vec<1, T, Q>::bool_type isdenormal + ( + vec<1, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<1, T, Q>::bool_type( + isdenormal(x.x)); + } + + template + GLM_FUNC_QUALIFIER typename vec<2, T, Q>::bool_type isdenormal + ( + vec<2, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<2, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y)); + } + + template + GLM_FUNC_QUALIFIER typename vec<3, T, Q>::bool_type isdenormal + ( + vec<3, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<3, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y), + isdenormal(x.z)); + } + + template + GLM_FUNC_QUALIFIER typename vec<4, T, Q>::bool_type isdenormal + ( + vec<4, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<4, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y), + isdenormal(x.z), + isdenormal(x.w)); + } + + // fmod + template + GLM_FUNC_QUALIFIER genType fmod(genType x, genType y) + { + return fmod(vec<1, genType>(x), y).x; + } + + template + GLM_FUNC_QUALIFIER vec fmod(vec const& x, T y) + { + return detail::compute_fmod::is_iec559>::call(x, vec(y)); + } + + template + GLM_FUNC_QUALIFIER vec fmod(vec const& x, vec const& y) + { + return detail::compute_fmod::is_iec559>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER vec openBounded(vec const& Value, vec const& Min, vec const& Max) + { + return greaterThan(Value, Min) && lessThan(Value, Max); + } + + template + GLM_FUNC_QUALIFIER vec closeBounded(vec const& Value, vec const& Min, vec const& Max) + { + return greaterThanEqual(Value, Min) && lessThanEqual(Value, Max); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/compatibility.hpp b/src/other/manifold/glm/glm/gtx/compatibility.hpp new file mode 100644 index 00000000000..f1b00a6b39c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/compatibility.hpp @@ -0,0 +1,133 @@ +/// @ref gtx_compatibility +/// @file glm/gtx/compatibility.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_compatibility GLM_GTX_compatibility +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Provide functions to increase the compatibility with Cg and HLSL languages + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_compatibility is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_compatibility extension included") +# endif +#endif + +#if GLM_COMPILER & GLM_COMPILER_VC +# include +#elif GLM_COMPILER & GLM_COMPILER_GCC +# include +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# undef isfinite +# endif +#endif//GLM_COMPILER + +namespace glm +{ + /// @addtogroup gtx_compatibility + /// @{ + + template GLM_FUNC_QUALIFIER T lerp(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, const vec<2, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, const vec<3, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, const vec<4, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> saturate(const vec<2, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> saturate(const vec<3, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> saturate(const vec<4, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER T atan2(T x, T y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> atan2(const vec<2, T, Q>& x, const vec<2, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> atan2(const vec<3, T, Q>& x, const vec<3, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> atan2(const vec<4, T, Q>& x, const vec<4, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + + template GLM_FUNC_DECL bool isfinite(genType const& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<1, bool, Q> isfinite(const vec<1, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<2, bool, Q> isfinite(const vec<2, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<3, bool, Q> isfinite(const vec<3, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<4, bool, Q> isfinite(const vec<4, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + + typedef bool bool1; //!< \brief boolean type with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, bool, highp> bool2; //!< \brief boolean type with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, bool, highp> bool3; //!< \brief boolean type with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, bool, highp> bool4; //!< \brief boolean type with 4 components. (From GLM_GTX_compatibility extension) + + typedef bool bool1x1; //!< \brief boolean matrix with 1 x 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, bool, highp> bool2x2; //!< \brief boolean matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, bool, highp> bool2x3; //!< \brief boolean matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, bool, highp> bool2x4; //!< \brief boolean matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, bool, highp> bool3x2; //!< \brief boolean matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, bool, highp> bool3x3; //!< \brief boolean matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, bool, highp> bool3x4; //!< \brief boolean matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, bool, highp> bool4x2; //!< \brief boolean matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, bool, highp> bool4x3; //!< \brief boolean matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, bool, highp> bool4x4; //!< \brief boolean matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef int int1; //!< \brief integer vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, int, highp> int2; //!< \brief integer vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, int, highp> int3; //!< \brief integer vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, int, highp> int4; //!< \brief integer vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef int int1x1; //!< \brief integer matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, int, highp> int2x2; //!< \brief integer matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, int, highp> int2x3; //!< \brief integer matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, int, highp> int2x4; //!< \brief integer matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, int, highp> int3x2; //!< \brief integer matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, int, highp> int3x3; //!< \brief integer matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, int, highp> int3x4; //!< \brief integer matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, int, highp> int4x2; //!< \brief integer matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, int, highp> int4x3; //!< \brief integer matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, int, highp> int4x4; //!< \brief integer matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef float float1; //!< \brief single-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, float, highp> float2; //!< \brief single-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, float, highp> float3; //!< \brief single-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, float, highp> float4; //!< \brief single-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef float float1x1; //!< \brief single-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, float, highp> float2x2; //!< \brief single-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, float, highp> float2x3; //!< \brief single-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, float, highp> float2x4; //!< \brief single-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, float, highp> float3x2; //!< \brief single-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, float, highp> float3x3; //!< \brief single-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, float, highp> float3x4; //!< \brief single-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, float, highp> float4x2; //!< \brief single-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, float, highp> float4x3; //!< \brief single-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, float, highp> float4x4; //!< \brief single-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef double double1; //!< \brief double-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, double, highp> double2; //!< \brief double-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, double, highp> double3; //!< \brief double-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, double, highp> double4; //!< \brief double-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef double double1x1; //!< \brief double-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, double, highp> double2x2; //!< \brief double-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, double, highp> double2x3; //!< \brief double-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, double, highp> double2x4; //!< \brief double-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, double, highp> double3x2; //!< \brief double-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, double, highp> double3x3; //!< \brief double-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, double, highp> double3x4; //!< \brief double-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, double, highp> double4x2; //!< \brief double-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, double, highp> double4x3; //!< \brief double-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, double, highp> double4x4; //!< \brief double-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + /// @} +}//namespace glm + +#include "compatibility.inl" diff --git a/src/other/manifold/glm/glm/gtx/compatibility.inl b/src/other/manifold/glm/glm/gtx/compatibility.inl new file mode 100644 index 00000000000..1d49496b6c6 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/compatibility.inl @@ -0,0 +1,62 @@ +#include + +namespace glm +{ + // isfinite + template + GLM_FUNC_QUALIFIER bool isfinite( + genType const& x) + { +# if GLM_HAS_CXX11_STL + return std::isfinite(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_VC + return _finite(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_GCC && GLM_PLATFORM & GLM_PLATFORM_ANDROID + return _isfinite(x) != 0; +# else + if (std::numeric_limits::is_integer || std::denorm_absent == std::numeric_limits::has_denorm) + return std::numeric_limits::min() <= x && std::numeric_limits::max() >= x; + else + return -std::numeric_limits::max() <= x && std::numeric_limits::max() >= x; +# endif + } + + template + GLM_FUNC_QUALIFIER vec<1, bool, Q> isfinite( + vec<1, T, Q> const& x) + { + return vec<1, bool, Q>( + isfinite(x.x)); + } + + template + GLM_FUNC_QUALIFIER vec<2, bool, Q> isfinite( + vec<2, T, Q> const& x) + { + return vec<2, bool, Q>( + isfinite(x.x), + isfinite(x.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, bool, Q> isfinite( + vec<3, T, Q> const& x) + { + return vec<3, bool, Q>( + isfinite(x.x), + isfinite(x.y), + isfinite(x.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isfinite( + vec<4, T, Q> const& x) + { + return vec<4, bool, Q>( + isfinite(x.x), + isfinite(x.y), + isfinite(x.z), + isfinite(x.w)); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/component_wise.hpp b/src/other/manifold/glm/glm/gtx/component_wise.hpp new file mode 100644 index 00000000000..34a2b0a3751 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/component_wise.hpp @@ -0,0 +1,69 @@ +/// @ref gtx_component_wise +/// @file glm/gtx/component_wise.hpp +/// @date 2007-05-21 / 2011-06-07 +/// @author Christophe Riccio +/// +/// @see core (dependence) +/// +/// @defgroup gtx_component_wise GLM_GTX_component_wise +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Operations between components of a type + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_component_wise is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_component_wise extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_component_wise + /// @{ + + /// Convert an integer vector to a normalized float vector. + /// If the parameter value type is already a floating qualifier type, the value is passed through. + /// @see gtx_component_wise + template + GLM_FUNC_DECL vec compNormalize(vec const& v); + + /// Convert a normalized float vector to an integer vector. + /// If the parameter value type is already a floating qualifier type, the value is passed through. + /// @see gtx_component_wise + template + GLM_FUNC_DECL vec compScale(vec const& v); + + /// Add all vector components together. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compAdd(genType const& v); + + /// Multiply all vector components together. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMul(genType const& v); + + /// Find the minimum value between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMin(genType const& v); + + /// Find the maximum value between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMax(genType const& v); + + /// @} +}//namespace glm + +#include "component_wise.inl" diff --git a/src/other/manifold/glm/glm/gtx/component_wise.inl b/src/other/manifold/glm/glm/gtx/component_wise.inl new file mode 100644 index 00000000000..cbbc7d41ec0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/component_wise.inl @@ -0,0 +1,127 @@ +/// @ref gtx_component_wise + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_compNormalize + {}; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + floatType const Min = static_cast(std::numeric_limits::min()); + floatType const Max = static_cast(std::numeric_limits::max()); + return (vec(v) - Min) / (Max - Min) * static_cast(2) - static_cast(1); + } + }; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return vec(v) / static_cast(std::numeric_limits::max()); + } + }; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return v; + } + }; + + template + struct compute_compScale + {}; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + floatType const Max = static_cast(std::numeric_limits::max()) + static_cast(0.5); + vec const Scaled(v * Max); + vec const Result(Scaled - static_cast(0.5)); + return Result; + } + }; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return vec(vec(v) * static_cast(std::numeric_limits::max())); + } + }; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return v; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER vec compNormalize(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compNormalize' accepts only floating-point types for 'floatType' template parameter"); + + return detail::compute_compNormalize::is_integer, std::numeric_limits::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER vec compScale(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compScale' accepts only floating-point types for 'floatType' template parameter"); + + return detail::compute_compScale::is_integer, std::numeric_limits::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER T compAdd(vec const& v) + { + T Result(0); + for(length_t i = 0, n = v.length(); i < n; ++i) + Result += v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMul(vec const& v) + { + T Result(1); + for(length_t i = 0, n = v.length(); i < n; ++i) + Result *= v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMin(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = min(Result, v[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMax(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = max(Result, v[i]); + return Result; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/dual_quaternion.hpp b/src/other/manifold/glm/glm/gtx/dual_quaternion.hpp new file mode 100644 index 00000000000..6a51ab7d39f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/dual_quaternion.hpp @@ -0,0 +1,274 @@ +/// @ref gtx_dual_quaternion +/// @file glm/gtx/dual_quaternion.hpp +/// @author Maksim Vorobiev (msomeone@gmail.com) +/// +/// @see core (dependence) +/// @see gtc_constants (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_dual_quaternion GLM_GTX_dual_quaternion +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines a templated dual-quaternion type and several dual-quaternion operations. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_dual_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_dual_quaternion extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_dual_quaternion + /// @{ + + template + struct tdualquat + { + // -- Implementation detail -- + + typedef T value_type; + typedef qua part_type; + + // -- Data -- + + qua real, dual; + + // -- Component accesses -- + + typedef length_t length_type; + /// Return the count of components of a dual quaternion + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;} + + GLM_FUNC_DECL part_type & operator[](length_type i); + GLM_FUNC_DECL part_type const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat const& d) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat const& d); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& real); + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& orientation, vec<3, T, Q> const& translation); + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& real, qua const& dual); + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT tdualquat(tdualquat const& q); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR tdualquat(mat<2, 4, T, Q> const& holder_mat); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR tdualquat(mat<3, 4, T, Q> const& aug_mat); + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL tdualquat & operator=(tdualquat const& m) GLM_DEFAULT; + + template + GLM_FUNC_DECL tdualquat & operator=(tdualquat const& m); + template + GLM_FUNC_DECL tdualquat & operator*=(U s); + template + GLM_FUNC_DECL tdualquat & operator/=(U s); + }; + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL tdualquat operator+(tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator-(tdualquat const& q); + + // -- Binary operators -- + + template + GLM_FUNC_DECL tdualquat operator+(tdualquat const& q, tdualquat const& p); + + template + GLM_FUNC_DECL tdualquat operator*(tdualquat const& q, tdualquat const& p); + + template + GLM_FUNC_DECL vec<3, T, Q> operator*(tdualquat const& q, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat const& q); + + template + GLM_FUNC_DECL vec<4, T, Q> operator*(tdualquat const& q, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator*(tdualquat const& q, T const& s); + + template + GLM_FUNC_DECL tdualquat operator*(T const& s, tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator/(tdualquat const& q, T const& s); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(tdualquat const& q1, tdualquat const& q2); + + template + GLM_FUNC_DECL bool operator!=(tdualquat const& q1, tdualquat const& q2); + + /// Creates an identity dual quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dual_quat_identity(); + + /// Returns the normalized quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat normalize(tdualquat const& q); + + /// Returns the linear interpolation of two dual quaternion. + /// + /// @see gtc_dual_quaternion + template + GLM_FUNC_DECL tdualquat lerp(tdualquat const& x, tdualquat const& y, T const& a); + + /// Returns the q inverse. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat inverse(tdualquat const& q); + + /// Converts a quaternion to a 2 * 4 matrix. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL mat<2, 4, T, Q> mat2x4_cast(tdualquat const& x); + + /// Converts a quaternion to a 3 * 4 matrix. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL mat<3, 4, T, Q> mat3x4_cast(tdualquat const& x); + + /// Converts a 2 * 4 matrix (matrix which holds real and dual parts) to a quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dualquat_cast(mat<2, 4, T, Q> const& x); + + /// Converts a 3 * 4 matrix (augmented matrix rotation + translation) to a quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dualquat_cast(mat<3, 4, T, Q> const& x); + + + /// Dual-quaternion of low single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_dualquat; + + /// Dual-quaternion of medium single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_dualquat; + + /// Dual-quaternion of high single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_dualquat; + + + /// Dual-quaternion of low single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_fdualquat; + + /// Dual-quaternion of medium single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_fdualquat; + + /// Dual-quaternion of high single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_fdualquat; + + + /// Dual-quaternion of low double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_ddualquat; + + /// Dual-quaternion of medium double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_ddualquat; + + /// Dual-quaternion of high double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_ddualquat; + + +#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + /// Dual-quaternion of floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_fdualquat dualquat; + + /// Dual-quaternion of single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_fdualquat fdualquat; +#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + typedef highp_fdualquat dualquat; + typedef highp_fdualquat fdualquat; +#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + typedef mediump_fdualquat dualquat; + typedef mediump_fdualquat fdualquat; +#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT)) + typedef lowp_fdualquat dualquat; + typedef lowp_fdualquat fdualquat; +#else +# error "GLM error: multiple default precision requested for single-precision floating-point types" +#endif + + +#if(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + /// Dual-quaternion of default double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_ddualquat ddualquat; +#elif(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef highp_ddualquat ddualquat; +#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef mediump_ddualquat ddualquat; +#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef lowp_ddualquat ddualquat; +#else +# error "GLM error: Multiple default precision requested for double-precision floating-point types" +#endif + + /// @} +} //namespace glm + +#include "dual_quaternion.inl" diff --git a/src/other/manifold/glm/glm/gtx/dual_quaternion.inl b/src/other/manifold/glm/glm/gtx/dual_quaternion.inl new file mode 100644 index 00000000000..fad07ea842c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/dual_quaternion.inl @@ -0,0 +1,352 @@ +/// @ref gtx_dual_quaternion + +#include "../geometric.hpp" +#include + +namespace glm +{ + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER typename tdualquat::part_type & tdualquat::operator[](typename tdualquat::length_type i) + { + assert(i >= 0 && i < this->length()); + return (&real)[i]; + } + + template + GLM_FUNC_QUALIFIER typename tdualquat::part_type const& tdualquat::operator[](typename tdualquat::length_type i) const + { + assert(i >= 0 && i < this->length()); + return (&real)[i]; + } + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat() +# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE + : real(qua()) + , dual(qua(0, 0, 0, 0)) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& d) + : real(d.real) + , dual(d.dual) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& d) + : real(d.real) + , dual(d.dual) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& r) + : real(r), dual(qua(0, 0, 0, 0)) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& q, vec<3, T, Q> const& p) + : real(q), dual( + T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z), + T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y), + T(+0.5) * (-p.x*q.z + p.y*q.w + p.z*q.x), + T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w)) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& r, qua const& d) + : real(r), dual(d) + {} + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& q) + : real(q.real) + , dual(q.dual) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(mat<2, 4, T, Q> const& m) + { + *this = dualquat_cast(m); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(mat<3, 4, T, Q> const& m) + { + *this = dualquat_cast(m); + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator=(tdualquat const& q) + { + this->real = q.real; + this->dual = q.dual; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator=(tdualquat const& q) + { + this->real = q.real; + this->dual = q.dual; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator*=(U s) + { + this->real *= static_cast(s); + this->dual *= static_cast(s); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator/=(U s) + { + this->real /= static_cast(s); + this->dual /= static_cast(s); + return *this; + } + + // -- Unary bit operators -- + + template + GLM_FUNC_QUALIFIER tdualquat operator+(tdualquat const& q) + { + return q; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator-(tdualquat const& q) + { + return tdualquat(-q.real, -q.dual); + } + + // -- Binary operators -- + + template + GLM_FUNC_QUALIFIER tdualquat operator+(tdualquat const& q, tdualquat const& p) + { + return tdualquat(q.real + p.real,q.dual + p.dual); + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(tdualquat const& p, tdualquat const& o) + { + return tdualquat(p.real * o.real,p.real * o.dual + p.dual * o.real); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(tdualquat const& q, vec<3, T, Q> const& v) + { + vec<3, T, Q> const real_v3(q.real.x,q.real.y,q.real.z); + vec<3, T, Q> const dual_v3(q.dual.x,q.dual.y,q.dual.z); + return (cross(real_v3, cross(real_v3,v) + v * q.real.w + dual_v3) + dual_v3 * q.real.w - real_v3 * q.dual.w) * T(2) + v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(tdualquat const& q, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(tdualquat const& q, T const& s) + { + return tdualquat(q.real * s, q.dual * s); + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(T const& s, tdualquat const& q) + { + return q * s; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator/(tdualquat const& q, T const& s) + { + return tdualquat(q.real / s, q.dual / s); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(tdualquat const& q1, tdualquat const& q2) + { + return (q1.real == q2.real) && (q1.dual == q2.dual); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(tdualquat const& q1, tdualquat const& q2) + { + return (q1.real != q2.real) || (q1.dual != q2.dual); + } + + // -- Operations -- + + template + GLM_FUNC_QUALIFIER tdualquat dual_quat_identity() + { + return tdualquat( + qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)), + qua(static_cast(0), static_cast(0), static_cast(0), static_cast(0))); + } + + template + GLM_FUNC_QUALIFIER tdualquat normalize(tdualquat const& q) + { + return q / length(q.real); + } + + template + GLM_FUNC_QUALIFIER tdualquat lerp(tdualquat const& x, tdualquat const& y, T const& a) + { + // Dual Quaternion Linear blend aka DLB: + // Lerp is only defined in [0, 1] + assert(a >= static_cast(0)); + assert(a <= static_cast(1)); + T const k = dot(x.real,y.real) < static_cast(0) ? -a : a; + T const one(1); + return tdualquat(x * (one - a) + y * k); + } + + template + GLM_FUNC_QUALIFIER tdualquat inverse(tdualquat const& q) + { + const glm::qua real = conjugate(q.real); + const glm::qua dual = conjugate(q.dual); + return tdualquat(real, dual + (real * (-2.0f * dot(real,dual)))); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat2x4_cast(tdualquat const& x) + { + return mat<2, 4, T, Q>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w ); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat3x4_cast(tdualquat const& x) + { + qua r = x.real / length2(x.real); + + qua const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z); + r *= static_cast(2); + + T const xy = r.x * x.real.y; + T const xz = r.x * x.real.z; + T const yz = r.y * x.real.z; + T const wx = r.w * x.real.x; + T const wy = r.w * x.real.y; + T const wz = r.w * x.real.z; + + vec<4, T, Q> const a( + rr.w + rr.x - rr.y - rr.z, + xy - wz, + xz + wy, + -(x.dual.w * r.x - x.dual.x * r.w + x.dual.y * r.z - x.dual.z * r.y)); + + vec<4, T, Q> const b( + xy + wz, + rr.w + rr.y - rr.x - rr.z, + yz - wx, + -(x.dual.w * r.y - x.dual.x * r.z - x.dual.y * r.w + x.dual.z * r.x)); + + vec<4, T, Q> const c( + xz - wy, + yz + wx, + rr.w + rr.z - rr.x - rr.y, + -(x.dual.w * r.z + x.dual.x * r.y - x.dual.y * r.x - x.dual.z * r.w)); + + return mat<3, 4, T, Q>(a, b, c); + } + + template + GLM_FUNC_QUALIFIER tdualquat dualquat_cast(mat<2, 4, T, Q> const& x) + { + return tdualquat( + qua( x[0].w, x[0].x, x[0].y, x[0].z ), + qua( x[1].w, x[1].x, x[1].y, x[1].z )); + } + + template + GLM_FUNC_QUALIFIER tdualquat dualquat_cast(mat<3, 4, T, Q> const& x) + { + qua real; + + T const trace = x[0].x + x[1].y + x[2].z; + if(trace > static_cast(0)) + { + T const r = sqrt(T(1) + trace); + T const invr = static_cast(0.5) / r; + real.w = static_cast(0.5) * r; + real.x = (x[2].y - x[1].z) * invr; + real.y = (x[0].z - x[2].x) * invr; + real.z = (x[1].x - x[0].y) * invr; + } + else if(x[0].x > x[1].y && x[0].x > x[2].z) + { + T const r = sqrt(T(1) + x[0].x - x[1].y - x[2].z); + T const invr = static_cast(0.5) / r; + real.x = static_cast(0.5)*r; + real.y = (x[1].x + x[0].y) * invr; + real.z = (x[0].z + x[2].x) * invr; + real.w = (x[2].y - x[1].z) * invr; + } + else if(x[1].y > x[2].z) + { + T const r = sqrt(T(1) + x[1].y - x[0].x - x[2].z); + T const invr = static_cast(0.5) / r; + real.x = (x[1].x + x[0].y) * invr; + real.y = static_cast(0.5) * r; + real.z = (x[2].y + x[1].z) * invr; + real.w = (x[0].z - x[2].x) * invr; + } + else + { + T const r = sqrt(T(1) + x[2].z - x[0].x - x[1].y); + T const invr = static_cast(0.5) / r; + real.x = (x[0].z + x[2].x) * invr; + real.y = (x[2].y + x[1].z) * invr; + real.z = static_cast(0.5) * r; + real.w = (x[1].x - x[0].y) * invr; + } + + qua dual; + dual.x = static_cast(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y); + dual.y = static_cast(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x); + dual.z = static_cast(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w); + dual.w = -static_cast(0.5) * ( x[0].w * real.x + x[1].w * real.y + x[2].w * real.z); + return tdualquat(real, dual); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/easing.hpp b/src/other/manifold/glm/glm/gtx/easing.hpp new file mode 100644 index 00000000000..57f3d61b182 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/easing.hpp @@ -0,0 +1,219 @@ +/// @ref gtx_easing +/// @file glm/gtx/easing.hpp +/// @author Robert Chisholm +/// +/// @see core (dependence) +/// +/// @defgroup gtx_easing GLM_GTX_easing +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Easing functions for animations and transitons +/// All functions take a parameter x in the range [0.0,1.0] +/// +/// Based on the AHEasing project of Warren Moore (https://github.com/warrenm/AHEasing) + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_easing is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_easing extension included") +# endif +#endif + +namespace glm{ + /// @addtogroup gtx_easing + /// @{ + + /// Modelled after the line y = x + /// @see gtx_easing + template + GLM_FUNC_DECL genType linearInterpolation(genType const & a); + + /// Modelled after the parabola y = x^2 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseIn(genType const & a); + + /// Modelled after the parabola y = -x^2 + 2x + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseOut(genType const & a); + + /// Modelled after the piecewise quadratic + /// y = (1/2)((2x)^2) ; [0, 0.5) + /// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseInOut(genType const & a); + + /// Modelled after the cubic y = x^3 + template + GLM_FUNC_DECL genType cubicEaseIn(genType const & a); + + /// Modelled after the cubic y = (x - 1)^3 + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType cubicEaseOut(genType const & a); + + /// Modelled after the piecewise cubic + /// y = (1/2)((2x)^3) ; [0, 0.5) + /// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType cubicEaseInOut(genType const & a); + + /// Modelled after the quartic x^4 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseIn(genType const & a); + + /// Modelled after the quartic y = 1 - (x - 1)^4 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseOut(genType const & a); + + /// Modelled after the piecewise quartic + /// y = (1/2)((2x)^4) ; [0, 0.5) + /// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseInOut(genType const & a); + + /// Modelled after the quintic y = x^5 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseIn(genType const & a); + + /// Modelled after the quintic y = (x - 1)^5 + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseOut(genType const & a); + + /// Modelled after the piecewise quintic + /// y = (1/2)((2x)^5) ; [0, 0.5) + /// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseInOut(genType const & a); + + /// Modelled after quarter-cycle of sine wave + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseIn(genType const & a); + + /// Modelled after quarter-cycle of sine wave (different phase) + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseOut(genType const & a); + + /// Modelled after half sine wave + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseInOut(genType const & a); + + /// Modelled after shifted quadrant IV of unit circle + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseIn(genType const & a); + + /// Modelled after shifted quadrant II of unit circle + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseOut(genType const & a); + + /// Modelled after the piecewise circular function + /// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5) + /// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseInOut(genType const & a); + + /// Modelled after the exponential function y = 2^(10(x - 1)) + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseIn(genType const & a); + + /// Modelled after the exponential function y = -2^(-10x) + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseOut(genType const & a); + + /// Modelled after the piecewise exponential + /// y = (1/2)2^(10(2x - 1)) ; [0,0.5) + /// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseInOut(genType const & a); + + /// Modelled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1)) + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseIn(genType const & a); + + /// Modelled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseOut(genType const & a); + + /// Modelled after the piecewise exponentially-damped sine wave: + /// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5) + /// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseInOut(genType const & a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseIn(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseOut(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseInOut(genType const& a); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseIn(genType const& a, genType const& o); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseOut(genType const& a, genType const& o); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseInOut(genType const& a, genType const& o); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseIn(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseOut(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseInOut(genType const& a); + + /// @} +}//namespace glm + +#include "easing.inl" diff --git a/src/other/manifold/glm/glm/gtx/easing.inl b/src/other/manifold/glm/glm/gtx/easing.inl new file mode 100644 index 00000000000..4b7d05b7196 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/easing.inl @@ -0,0 +1,436 @@ +/// @ref gtx_easing + +#include + +namespace glm{ + + template + GLM_FUNC_QUALIFIER genType linearInterpolation(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a; + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a; + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return -(a * (a - static_cast(2))); + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(2) * a * a; + } + else + { + return (-static_cast(2) * a * a) + (4 * a) - one(); + } + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = a - one(); + return f * f * f + one(); + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if (a < static_cast(0.5)) + { + return static_cast(4) * a * a * a; + } + else + { + genType const f = ((static_cast(2) * a) - static_cast(2)); + return static_cast(0.5) * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = (a - one()); + return f * f * f * (one() - a) + one(); + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(8) * a * a * a * a; + } + else + { + genType const f = (a - one()); + return -static_cast(8) * f * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = (a - one()); + return f * f * f * f * f + one(); + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(16) * a * a * a * a * a; + } + else + { + genType const f = ((static_cast(2) * a) - static_cast(2)); + return static_cast(0.5) * f * f * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType sineEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sin((a - one()) * half_pi()) + one(); + } + + template + GLM_FUNC_QUALIFIER genType sineEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sin(a * half_pi()); + } + + template + GLM_FUNC_QUALIFIER genType sineEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return static_cast(0.5) * (one() - cos(a * pi())); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return one() - sqrt(one() - (a * a)); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sqrt((static_cast(2) - a) * a); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(0.5) * (one() - std::sqrt(one() - static_cast(4) * (a * a))); + } + else + { + return static_cast(0.5) * (std::sqrt(-((static_cast(2) * a) - static_cast(3)) * ((static_cast(2) * a) - one())) + one()); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a <= zero()) + return a; + else + { + genType const Complementary = a - one(); + genType const Two = static_cast(2); + + return glm::pow(Two, Complementary * static_cast(10)); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a >= one()) + return a; + else + { + return one() - glm::pow(static_cast(2), -static_cast(10) * a); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + return static_cast(0.5) * glm::pow(static_cast(2), (static_cast(20) * a) - static_cast(10)); + else + return -static_cast(0.5) * glm::pow(static_cast(2), (-static_cast(20) * a) + static_cast(10)) + one(); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return std::sin(static_cast(13) * half_pi() * a) * glm::pow(static_cast(2), static_cast(10) * (a - one())); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return std::sin(-static_cast(13) * half_pi() * (a + one())) * glm::pow(static_cast(2), -static_cast(10) * a) + one(); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + return static_cast(0.5) * std::sin(static_cast(13) * half_pi() * (static_cast(2) * a)) * glm::pow(static_cast(2), static_cast(10) * ((static_cast(2) * a) - one())); + else + return static_cast(0.5) * (std::sin(-static_cast(13) * half_pi() * ((static_cast(2) * a - one()) + one())) * glm::pow(static_cast(2), -static_cast(10) * (static_cast(2) * a - one())) + static_cast(2)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType z = ((o + one()) * a) - o; + return (a * a * z); + } + + template + GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType n = a - one(); + genType z = ((o + one()) * n) + o; + return (n * n * z) + one(); + } + + template + GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType s = o * static_cast(1.525); + genType x = static_cast(0.5); + genType n = a / static_cast(0.5); + + if (n < static_cast(1)) + { + genType z = ((s + static_cast(1)) * n) - s; + genType m = n * n * z; + return x * m; + } + else + { + n -= static_cast(2); + genType z = ((s + static_cast(1)) * n) + s; + genType m = (n*n*z) + static_cast(2); + return x * m; + } + } + + template + GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a) + { + return backEaseIn(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a) + { + return backEaseOut(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a) + { + return backEaseInOut(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(4.0 / 11.0)) + { + return (static_cast(121) * a * a) / static_cast(16); + } + else if(a < static_cast(8.0 / 11.0)) + { + return (static_cast(363.0 / 40.0) * a * a) - (static_cast(99.0 / 10.0) * a) + static_cast(17.0 / 5.0); + } + else if(a < static_cast(9.0 / 10.0)) + { + return (static_cast(4356.0 / 361.0) * a * a) - (static_cast(35442.0 / 1805.0) * a) + static_cast(16061.0 / 1805.0); + } + else + { + return (static_cast(54.0 / 5.0) * a * a) - (static_cast(513.0 / 25.0) * a) + static_cast(268.0 / 25.0); + } + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return one() - bounceEaseOut(one() - a); + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(0.5) * (one() - bounceEaseOut(a * static_cast(2))); + } + else + { + return static_cast(0.5) * bounceEaseOut(a * static_cast(2) - one()) + static_cast(0.5); + } + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/euler_angles.hpp b/src/other/manifold/glm/glm/gtx/euler_angles.hpp new file mode 100644 index 00000000000..27236973af6 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/euler_angles.hpp @@ -0,0 +1,335 @@ +/// @ref gtx_euler_angles +/// @file glm/gtx/euler_angles.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_euler_angles GLM_GTX_euler_angles +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build matrices from Euler angles. +/// +/// Extraction of Euler angles from rotation matrix. +/// Based on the original paper 2014 Mike Day - Extracting Euler Angles from a Rotation Matrix. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_euler_angles is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_euler_angles extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_euler_angles + /// @{ + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle X. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleX( + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Y. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleY( + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Z. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZ( + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about X-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleX( + T const & angleX, T const & angularVelocityX); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Y-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleY( + T const & angleY, T const & angularVelocityY); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Z-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleZ( + T const & angleZ, T const & angularVelocityZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXY( + T const& angleX, + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYX( + T const& angleY, + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZ( + T const& angleX, + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZX( + T const& angle, + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZ( + T const& angleY, + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZY( + T const& angleZ, + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYZ( + T const& t1, + T const& t2, + T const& t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXZ( + T const& yaw, + T const& pitch, + T const& roll); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYZ( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXZ( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> yawPitchRoll( + T const& yaw, + T const& pitch, + T const& roll); + + /// Creates a 2D 2 * 2 rotation matrix from an euler angle. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> orientate2(T const& angle); + + /// Creates a 2D 4 * 4 homogeneous rotation matrix from an euler angle. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> orientate3(T const& angle); + + /// Creates a 3D 3 * 3 rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<3, 3, T, Q> orientate3(vec<3, T, Q> const& angles); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, Q> orientate4(vec<3, T, Q> const& angles); + + /// Extracts the (X * Y * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * X * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Z * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Y * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * X * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * Z * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * Y * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * X * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Z * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * Z * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * Y * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * X * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// @} +}//namespace glm + +#include "euler_angles.inl" diff --git a/src/other/manifold/glm/glm/gtx/euler_angles.inl b/src/other/manifold/glm/glm/gtx/euler_angles.inl new file mode 100644 index 00000000000..68c50124e80 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/euler_angles.inl @@ -0,0 +1,899 @@ +/// @ref gtx_euler_angles + +#include "compatibility.hpp" // glm::atan2 + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleX + ( + T const& angleX + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + + return mat<4, 4, T, defaultp>( + T(1), T(0), T(0), T(0), + T(0), cosX, sinX, T(0), + T(0),-sinX, cosX, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleY + ( + T const& angleY + ) + { + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, T(0), -sinY, T(0), + T(0), T(1), T(0), T(0), + sinY, T(0), cosY, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZ + ( + T const& angleZ + ) + { + T cosZ = glm::cos(angleZ); + T sinZ = glm::sin(angleZ); + + return mat<4, 4, T, defaultp>( + cosZ, sinZ, T(0), T(0), + -sinZ, cosZ, T(0), T(0), + T(0), T(0), T(1), T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleX + ( + T const & angleX, + T const & angularVelocityX + ) + { + T cosX = glm::cos(angleX) * angularVelocityX; + T sinX = glm::sin(angleX) * angularVelocityX; + + return mat<4, 4, T, defaultp>( + T(0), T(0), T(0), T(0), + T(0),-sinX, cosX, T(0), + T(0),-cosX,-sinX, T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleY + ( + T const & angleY, + T const & angularVelocityY + ) + { + T cosY = glm::cos(angleY) * angularVelocityY; + T sinY = glm::sin(angleY) * angularVelocityY; + + return mat<4, 4, T, defaultp>( + -sinY, T(0), -cosY, T(0), + T(0), T(0), T(0), T(0), + cosY, T(0), -sinY, T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleZ + ( + T const & angleZ, + T const & angularVelocityZ + ) + { + T cosZ = glm::cos(angleZ) * angularVelocityZ; + T sinZ = glm::sin(angleZ) * angularVelocityZ; + + return mat<4, 4, T, defaultp>( + -sinZ, cosZ, T(0), T(0), + -cosZ, -sinZ, T(0), T(0), + T(0), T(0), T(0), T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXY + ( + T const& angleX, + T const& angleY + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, -sinX * -sinY, cosX * -sinY, T(0), + T(0), cosX, sinX, T(0), + sinY, -sinX * cosY, cosX * cosY, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYX + ( + T const& angleY, + T const& angleX + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, 0, -sinY, T(0), + sinY * sinX, cosX, cosY * sinX, T(0), + sinY * cosX, -sinX, cosY * cosX, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZ + ( + T const& angleX, + T const& angleZ + ) + { + return eulerAngleX(angleX) * eulerAngleZ(angleZ); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZX + ( + T const& angleZ, + T const& angleX + ) + { + return eulerAngleZ(angleZ) * eulerAngleX(angleX); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZ + ( + T const& angleY, + T const& angleZ + ) + { + return eulerAngleY(angleY) * eulerAngleZ(angleZ); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZY + ( + T const& angleZ, + T const& angleY + ) + { + return eulerAngleZ(angleZ) * eulerAngleY(angleY); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYZ + ( + T const& t1, + T const& t2, + T const& t3 + ) + { + T c1 = glm::cos(-t1); + T c2 = glm::cos(-t2); + T c3 = glm::cos(-t3); + T s1 = glm::sin(-t1); + T s2 = glm::sin(-t2); + T s3 = glm::sin(-t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2 * c3; + Result[0][1] =-c1 * s3 + s1 * s2 * c3; + Result[0][2] = s1 * s3 + c1 * s2 * c3; + Result[0][3] = static_cast(0); + Result[1][0] = c2 * s3; + Result[1][1] = c1 * c3 + s1 * s2 * s3; + Result[1][2] =-s1 * c3 + c1 * s2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] =-s2; + Result[2][1] = s1 * c2; + Result[2][2] = c1 * c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXZ + ( + T const& yaw, + T const& pitch, + T const& roll + ) + { + T tmp_ch = glm::cos(yaw); + T tmp_sh = glm::sin(yaw); + T tmp_cp = glm::cos(pitch); + T tmp_sp = glm::sin(pitch); + T tmp_cb = glm::cos(roll); + T tmp_sb = glm::sin(roll); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; + Result[0][1] = tmp_sb * tmp_cp; + Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; + Result[0][3] = static_cast(0); + Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; + Result[1][1] = tmp_cb * tmp_cp; + Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; + Result[1][3] = static_cast(0); + Result[2][0] = tmp_sh * tmp_cp; + Result[2][1] = -tmp_sp; + Result[2][2] = tmp_ch * tmp_cp; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2; + Result[0][1] = c1 * s2; + Result[0][2] = s1 * s2; + Result[0][3] = static_cast(0); + Result[1][0] =-c3 * s2; + Result[1][1] = c1 * c2 * c3 - s1 * s3; + Result[1][2] = c1 * s3 + c2 * c3 * s1; + Result[1][3] = static_cast(0); + Result[2][0] = s2 * s3; + Result[2][1] =-c3 * s1 - c1 * c2 * s3; + Result[2][2] = c1 * c3 - c2 * s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2; + Result[0][1] = s1 * s2; + Result[0][2] =-c1 * s2; + Result[0][3] = static_cast(0); + Result[1][0] = s2 * s3; + Result[1][1] = c1 * c3 - c2 * s1 * s3; + Result[1][2] = c3 * s1 + c1 * c2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s2; + Result[2][1] =-c1 * s3 - c2 * c3 * s1; + Result[2][2] = c1 * c2 * c3 - s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - c2 * s1 * s3; + Result[0][1] = s2* s3; + Result[0][2] =-c3 * s1 - c1 * c2 * s3; + Result[0][3] = static_cast(0); + Result[1][0] = s1 * s2; + Result[1][1] = c2; + Result[1][2] = c1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s3 + c2 * c3 * s1; + Result[2][1] =-c3 * s2; + Result[2][2] = c1 * c2 * c3 - s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2 * c3 - s1 * s3; + Result[0][1] = c3 * s2; + Result[0][2] =-c1 * s3 - c2 * c3 * s1; + Result[0][3] = static_cast(0); + Result[1][0] =-c1 * s2; + Result[1][1] = c2; + Result[1][2] = s1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s1 + c1 * c2 * s3; + Result[2][1] = s2 * s3; + Result[2][2] = c1 * c3 - c2 * s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYZ + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2 * c3 - s1 * s3; + Result[0][1] = c1 * s3 + c2 * c3 * s1; + Result[0][2] =-c3 * s2; + Result[0][3] = static_cast(0); + Result[1][0] =-c3 * s1 - c1 * c2 * s3; + Result[1][1] = c1 * c3 - c2 * s1 * s3; + Result[1][2] = s2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s2; + Result[2][1] = s1 * s2; + Result[2][2] = c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXZ + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - c2 * s1 * s3; + Result[0][1] = c3 * s1 + c1 * c2 * s3; + Result[0][2] = s2 *s3; + Result[0][3] = static_cast(0); + Result[1][0] =-c1 * s3 - c2 * c3 * s1; + Result[1][1] = c1 * c2 * c3 - s1 * s3; + Result[1][2] = c3 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = s1 * s2; + Result[2][1] =-c1 * s2; + Result[2][2] = c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2 * c3; + Result[0][1] = s1 * s3 + c1 * c3 * s2; + Result[0][2] = c3 * s1 * s2 - c1 * s3; + Result[0][3] = static_cast(0); + Result[1][0] =-s2; + Result[1][1] = c1 * c2; + Result[1][2] = c2 * s1; + Result[1][3] = static_cast(0); + Result[2][0] = c2 * s3; + Result[2][1] = c1 * s2 * s3 - c3 * s1; + Result[2][2] = c1 * c3 + s1 * s2 *s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2; + Result[0][1] = s2; + Result[0][2] =-c2 * s1; + Result[0][3] = static_cast(0); + Result[1][0] = s1 * s3 - c1 * c3 * s2; + Result[1][1] = c2 * c3; + Result[1][2] = c1 * s3 + c3 * s1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s1 + c1 * s2 * s3; + Result[2][1] =-c2 * s3; + Result[2][2] = c1 * c3 - s1 * s2 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2; + Result[0][1] = c2 * s1; + Result[0][2] =-s2; + Result[0][3] = static_cast(0); + Result[1][0] = c1 * s2 * s3 - c3 * s1; + Result[1][1] = c1 * c3 + s1 * s2 * s3; + Result[1][2] = c2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = s1 * s3 + c1 * c3 * s2; + Result[2][1] = c3 * s1 * s2 - c1 * s3; + Result[2][2] = c2 * c3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - s1 * s2 * s3; + Result[0][1] = c3 * s1 + c1 * s2 * s3; + Result[0][2] =-c2 * s3; + Result[0][3] = static_cast(0); + Result[1][0] =-c2 * s1; + Result[1][1] = c1 * c2; + Result[1][2] = s2; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s3 + c3 * s1 * s2; + Result[2][1] = s1 * s3 - c1 * c3 * s2; + Result[2][2] = c2 * c3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> yawPitchRoll + ( + T const& yaw, + T const& pitch, + T const& roll + ) + { + T tmp_ch = glm::cos(yaw); + T tmp_sh = glm::sin(yaw); + T tmp_cp = glm::cos(pitch); + T tmp_sp = glm::sin(pitch); + T tmp_cb = glm::cos(roll); + T tmp_sb = glm::sin(roll); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; + Result[0][1] = tmp_sb * tmp_cp; + Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; + Result[0][3] = static_cast(0); + Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; + Result[1][1] = tmp_cb * tmp_cp; + Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; + Result[1][3] = static_cast(0); + Result[2][0] = tmp_sh * tmp_cp; + Result[2][1] = -tmp_sp; + Result[2][2] = tmp_ch * tmp_cp; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> orientate2 + ( + T const& angle + ) + { + T c = glm::cos(angle); + T s = glm::sin(angle); + + mat<2, 2, T, defaultp> Result; + Result[0][0] = c; + Result[0][1] = s; + Result[1][0] = -s; + Result[1][1] = c; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> orientate3 + ( + T const& angle + ) + { + T c = glm::cos(angle); + T s = glm::sin(angle); + + mat<3, 3, T, defaultp> Result; + Result[0][0] = c; + Result[0][1] = s; + Result[0][2] = 0.0f; + Result[1][0] = -s; + Result[1][1] = c; + Result[1][2] = 0.0f; + Result[2][0] = 0.0f; + Result[2][1] = 0.0f; + Result[2][2] = 1.0f; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orientate3 + ( + vec<3, T, Q> const& angles + ) + { + return mat<3, 3, T, Q>(yawPitchRoll(angles.z, angles.x, angles.y)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientate4 + ( + vec<3, T, Q> const& angles + ) + { + return yawPitchRoll(angles.z, angles.x, angles.y); + } + + template + GLM_FUNC_DECL void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][1], M[2][2]); + T C2 = glm::sqrt(M[0][0]*M[0][0] + M[1][0]*M[1][0]); + T T2 = glm::atan2(-M[2][0], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[0][2] - C1*M[0][1], C1*M[1][1] - S1*M[1][2 ]); + t1 = -T1; + t2 = -T2; + t3 = -T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][0], M[2][2]); + T C2 = glm::sqrt(M[0][1]*M[0][1] + M[1][1]*M[1][1]); + T T2 = glm::atan2(-M[2][1], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[1][2] - C1*M[1][0], C1*M[0][0] - S1*M[0][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][2], M[0][1]); + T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(S2, M[0][0]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[1][2] - S1*M[1][1], C1*M[2][2] - S1*M[2][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][1], -M[0][2]); + T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(S2, M[0][0]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-C1*M[2][1] - S1*M[2][2], C1*M[1][1] + S1*M[1][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][0], M[1][2]); + T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(S2, M[1][1]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[2][0] - S1*M[2][2], C1*M[0][0] - S1*M[0][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][2], -M[1][0]); + T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(S2, M[1][1]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-S1*M[0][0] - C1*M[0][2], S1*M[2][0] + C1*M[2][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][1], M[2][0]); + T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]); + T T2 = glm::atan2(S2, M[2][2]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[0][1] - S1*M[0][0], C1*M[1][1] - S1*M[1][0]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][0], -M[2][1]); + T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]); + T T2 = glm::atan2(S2, M[2][2]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-C1*M[1][0] - S1*M[1][1], C1*M[0][0] + S1*M[0][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][2], M[1][1]); + T C2 = glm::sqrt(M[0][0]*M[0][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(-M[1][0], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[0][1] - C1*M[0][2], C1*M[2][2] - S1*M[2][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(-M[0][2], M[0][0]); + T C2 = glm::sqrt(M[1][1]*M[1][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(M[0][1], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[1][0] + C1*M[1][2], S1*M[2][0] + C1*M[2][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][1], M[0][0]); + T C2 = glm::sqrt(M[1][2]*M[1][2] + M[2][2]*M[2][2]); + T T2 = glm::atan2(-M[0][2], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[2][0] - C1*M[2][1], C1*M[1][1] - S1*M[1][0]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(-M[1][0], M[1][1]); + T C2 = glm::sqrt(M[0][2]*M[0][2] + M[2][2]*M[2][2]); + T T2 = glm::atan2(M[1][2], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[2][0] + S1*M[2][1], C1*M[0][0] + S1*M[0][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/extend.hpp b/src/other/manifold/glm/glm/gtx/extend.hpp new file mode 100644 index 00000000000..28b7c5c014a --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/extend.hpp @@ -0,0 +1,42 @@ +/// @ref gtx_extend +/// @file glm/gtx/extend.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_extend GLM_GTX_extend +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extend a position from a source to a position at a defined length. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extend is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extend extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_extend + /// @{ + + /// Extends of Length the Origin position using the (Source - Origin) direction. + /// @see gtx_extend + template + GLM_FUNC_DECL genType extend( + genType const& Origin, + genType const& Source, + typename genType::value_type const Length); + + /// @} +}//namespace glm + +#include "extend.inl" diff --git a/src/other/manifold/glm/glm/gtx/extend.inl b/src/other/manifold/glm/glm/gtx/extend.inl new file mode 100644 index 00000000000..32128eb209a --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/extend.inl @@ -0,0 +1,48 @@ +/// @ref gtx_extend + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType extend + ( + genType const& Origin, + genType const& Source, + genType const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> extend + ( + vec<2, T, Q> const& Origin, + vec<2, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> extend + ( + vec<3, T, Q> const& Origin, + vec<3, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> extend + ( + vec<4, T, Q> const& Origin, + vec<4, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/extended_min_max.hpp b/src/other/manifold/glm/glm/gtx/extended_min_max.hpp new file mode 100644 index 00000000000..025eda294a8 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/extended_min_max.hpp @@ -0,0 +1,137 @@ +/// @ref gtx_extended_min_max +/// @file glm/gtx/extended_min_max.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_extended_min_max GLM_GTX_extented_min_max +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Min and max functions for 3 to 4 parameters. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/vector_common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extented_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extented_min_max extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_extended_min_max + /// @{ + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T min( + T const& x, + T const& y, + T const& z); + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + typename C::T const& y, + typename C::T const& z); + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + C const& y, + C const& z); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T min( + T const& x, + T const& y, + T const& z, + T const& w); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + C const& y, + C const& z, + C const& w); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T max( + T const& x, + T const& y, + T const& z); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + typename C::T const& y, + typename C::T const& z); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + C const& y, + C const& z); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T max( + T const& x, + T const& y, + T const& z, + T const& w); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + C const& y, + C const& z, + C const& w); + + /// @} +}//namespace glm + +#include "extended_min_max.inl" diff --git a/src/other/manifold/glm/glm/gtx/extended_min_max.inl b/src/other/manifold/glm/glm/gtx/extended_min_max.inl new file mode 100644 index 00000000000..de5998fadd6 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/extended_min_max.inl @@ -0,0 +1,138 @@ +/// @ref gtx_extended_min_max + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T min( + T const& x, + T const& y, + T const& z) + { + return glm::min(glm::min(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + typename C::T const& y, + typename C::T const& z + ) + { + return glm::min(glm::min(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + C const& y, + C const& z + ) + { + return glm::min(glm::min(x, y), z); + } + + template + GLM_FUNC_QUALIFIER T min + ( + T const& x, + T const& y, + T const& z, + T const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + C const& y, + C const& z, + C const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template + GLM_FUNC_QUALIFIER T max( + T const& x, + T const& y, + T const& z) + { + return glm::max(glm::max(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + typename C::T const& y, + typename C::T const& z + ) + { + return glm::max(glm::max(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + C const& y, + C const& z + ) + { + return glm::max(glm::max(x, y), z); + } + + template + GLM_FUNC_QUALIFIER T max + ( + T const& x, + T const& y, + T const& z, + T const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + C const& y, + C const& z, + C const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/exterior_product.hpp b/src/other/manifold/glm/glm/gtx/exterior_product.hpp new file mode 100644 index 00000000000..5522df7883c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/exterior_product.hpp @@ -0,0 +1,45 @@ +/// @ref gtx_exterior_product +/// @file glm/gtx/exterior_product.hpp +/// +/// @see core (dependence) +/// @see gtx_exterior_product (dependence) +/// +/// @defgroup gtx_exterior_product GLM_GTX_exterior_product +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_exterior_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_exterior_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_exterior_product + /// @{ + + /// Returns the cross product of x and y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see Exterior product + template + GLM_FUNC_DECL T cross(vec<2, T, Q> const& v, vec<2, T, Q> const& u); + + /// @} +} //namespace glm + +#include "exterior_product.inl" diff --git a/src/other/manifold/glm/glm/gtx/exterior_product.inl b/src/other/manifold/glm/glm/gtx/exterior_product.inl new file mode 100644 index 00000000000..93661fd3fd7 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/exterior_product.inl @@ -0,0 +1,26 @@ +/// @ref gtx_exterior_product + +#include + +namespace glm { +namespace detail +{ + template + struct compute_cross_vec2 + { + GLM_FUNC_QUALIFIER static T call(vec<2, T, Q> const& v, vec<2, T, Q> const& u) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cross' accepts only floating-point inputs"); + + return v.x * u.y - u.x * v.y; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER T cross(vec<2, T, Q> const& x, vec<2, T, Q> const& y) + { + return detail::compute_cross_vec2::value>::call(x, y); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtx/fast_exponential.hpp b/src/other/manifold/glm/glm/gtx/fast_exponential.hpp new file mode 100644 index 00000000000..6fb7286528c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_exponential.hpp @@ -0,0 +1,95 @@ +/// @ref gtx_fast_exponential +/// @file glm/gtx/fast_exponential.hpp +/// +/// @see core (dependence) +/// @see gtx_half_float (dependence) +/// +/// @defgroup gtx_fast_exponential GLM_GTX_fast_exponential +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of exponential based functions. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_exponential is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_exponential extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_exponential + /// @{ + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL genType fastPow(genType x, genType y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastPow(vec const& x, vec const& y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL genTypeT fastPow(genTypeT x, genTypeU y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastPow(vec const& x); + + /// Faster than the common exp function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastExp(T x); + + /// Faster than the common exp function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastExp(vec const& x); + + /// Faster than the common log function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastLog(T x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastLog(vec const& x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastExp2(T x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastExp2(vec const& x); + + /// Faster than the common log2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastLog2(T x); + + /// Faster than the common log2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastLog2(vec const& x); + + /// @} +}//namespace glm + +#include "fast_exponential.inl" diff --git a/src/other/manifold/glm/glm/gtx/fast_exponential.inl b/src/other/manifold/glm/glm/gtx/fast_exponential.inl new file mode 100644 index 00000000000..f139e505636 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_exponential.inl @@ -0,0 +1,136 @@ +/// @ref gtx_fast_exponential + +namespace glm +{ + // fastPow: + template + GLM_FUNC_QUALIFIER genType fastPow(genType x, genType y) + { + return exp(y * log(x)); + } + + template + GLM_FUNC_QUALIFIER vec fastPow(vec const& x, vec const& y) + { + return exp(y * log(x)); + } + + template + GLM_FUNC_QUALIFIER T fastPow(T x, int y) + { + T f = static_cast(1); + for(int i = 0; i < y; ++i) + f *= x; + return f; + } + + template + GLM_FUNC_QUALIFIER vec fastPow(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = x.length(); i < n; ++i) + Result[i] = fastPow(x[i], y[i]); + return Result; + } + + // fastExp + // Note: This function provides accurate results only for value between -1 and 1, else avoid it. + template + GLM_FUNC_QUALIFIER T fastExp(T x) + { + // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower. + // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f)))); + T x2 = x * x; + T x3 = x2 * x; + T x4 = x3 * x; + T x5 = x4 * x; + return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333)); + } + /* // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance + GLM_FUNC_QUALIFIER float fastExp(float x) + { + const float e = 2.718281828f; + const float IntegerPart = floor(x); + const float FloatPart = x - IntegerPart; + float z = 1.f; + + for(int i = 0; i < int(IntegerPart); ++i) + z *= e; + + const float x2 = FloatPart * FloatPart; + const float x3 = x2 * FloatPart; + const float x4 = x3 * FloatPart; + const float x5 = x4 * FloatPart; + return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)); + } + + // Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers + GLM_FUNC_QUALIFIER float fastExp(float x) + { + // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower. + // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f)))); + float x2 = x * x; + float x3 = x2 * x; + float x4 = x3 * x; + float x5 = x4 * x; + float x6 = x5 * x; + float x7 = x6 * x; + float x8 = x7 * x; + return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);; + } + */ + + template + GLM_FUNC_QUALIFIER vec fastExp(vec const& x) + { + return detail::functor1::call(fastExp, x); + } + + // fastLog + template + GLM_FUNC_QUALIFIER genType fastLog(genType x) + { + return std::log(x); + } + + /* Slower than the VC7.1 function... + GLM_FUNC_QUALIFIER float fastLog(float x) + { + float y1 = (x - 1.0f) / (x + 1.0f); + float y2 = y1 * y1; + return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f))); + } + */ + + template + GLM_FUNC_QUALIFIER vec fastLog(vec const& x) + { + return detail::functor1::call(fastLog, x); + } + + //fastExp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType fastExp2(genType x) + { + return fastExp(0.69314718055994530941723212145818f * x); + } + + template + GLM_FUNC_QUALIFIER vec fastExp2(vec const& x) + { + return detail::functor1::call(fastExp2, x); + } + + // fastLog2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType fastLog2(genType x) + { + return fastLog(x) / 0.69314718055994530941723212145818f; + } + + template + GLM_FUNC_QUALIFIER vec fastLog2(vec const& x) + { + return detail::functor1::call(fastLog2, x); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/fast_square_root.hpp b/src/other/manifold/glm/glm/gtx/fast_square_root.hpp new file mode 100644 index 00000000000..9fb3f2fce0a --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_square_root.hpp @@ -0,0 +1,92 @@ +/// @ref gtx_fast_square_root +/// @file glm/gtx/fast_square_root.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_fast_square_root GLM_GTX_fast_square_root +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of square root based functions. +/// - Sqrt optimisation based on Newton's method, +/// www.gamedev.net/community/forums/topic.asp?topic id=139956 + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../exponential.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_square_root is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_square_root extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_square_root + /// @{ + + /// Faster than the common sqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastSqrt(genType x); + + /// Faster than the common sqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL vec fastSqrt(vec const& x); + + /// Faster than the common inversesqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastInverseSqrt(genType x); + + /// Faster than the common inversesqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL vec fastInverseSqrt(vec const& x); + + /// Faster than the common length function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastLength(genType x); + + /// Faster than the common length function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL T fastLength(vec const& x); + + /// Faster than the common distance function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastDistance(genType x, genType y); + + /// Faster than the common distance function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL T fastDistance(vec const& x, vec const& y); + + /// Faster than the common normalize function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastNormalize(genType const& x); + + /// @} +}// namespace glm + +#include "fast_square_root.inl" diff --git a/src/other/manifold/glm/glm/gtx/fast_square_root.inl b/src/other/manifold/glm/glm/gtx/fast_square_root.inl new file mode 100644 index 00000000000..4e6c6de90e2 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_square_root.inl @@ -0,0 +1,75 @@ +/// @ref gtx_fast_square_root + +namespace glm +{ + // fastSqrt + template + GLM_FUNC_QUALIFIER genType fastSqrt(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastSqrt' only accept floating-point input"); + + return genType(1) / fastInverseSqrt(x); + } + + template + GLM_FUNC_QUALIFIER vec fastSqrt(vec const& x) + { + return detail::functor1::call(fastSqrt, x); + } + + // fastInversesqrt + template + GLM_FUNC_QUALIFIER genType fastInverseSqrt(genType x) + { + return detail::compute_inversesqrt<1, genType, lowp, detail::is_aligned::value>::call(vec<1, genType, lowp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec fastInverseSqrt(vec const& x) + { + return detail::compute_inversesqrt::value>::call(x); + } + + // fastLength + template + GLM_FUNC_QUALIFIER genType fastLength(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastLength' only accept floating-point inputs"); + + return abs(x); + } + + template + GLM_FUNC_QUALIFIER T fastLength(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastLength' only accept floating-point inputs"); + + return fastSqrt(dot(x, x)); + } + + // fastDistance + template + GLM_FUNC_QUALIFIER genType fastDistance(genType x, genType y) + { + return fastLength(y - x); + } + + template + GLM_FUNC_QUALIFIER T fastDistance(vec const& x, vec const& y) + { + return fastLength(y - x); + } + + // fastNormalize + template + GLM_FUNC_QUALIFIER genType fastNormalize(genType x) + { + return x > genType(0) ? genType(1) : -genType(1); + } + + template + GLM_FUNC_QUALIFIER vec fastNormalize(vec const& x) + { + return x * fastInverseSqrt(dot(x, x)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/fast_trigonometry.hpp b/src/other/manifold/glm/glm/gtx/fast_trigonometry.hpp new file mode 100644 index 00000000000..2650d6e4d6e --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_trigonometry.hpp @@ -0,0 +1,79 @@ +/// @ref gtx_fast_trigonometry +/// @file glm/gtx/fast_trigonometry.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_fast_trigonometry GLM_GTX_fast_trigonometry +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of trigonometric functions. + +#pragma once + +// Dependency: +#include "../gtc/constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_trigonometry is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_trigonometry extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_trigonometry + /// @{ + + /// Wrap an angle to [0 2pi[ + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T wrapAngle(T angle); + + /// Faster than the common sin function but less accurate. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastSin(T angle); + + /// Faster than the common cos function but less accurate. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastCos(T angle); + + /// Faster than the common tan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastTan(T angle); + + /// Faster than the common asin function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAsin(T angle); + + /// Faster than the common acos function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAcos(T angle); + + /// Faster than the common atan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAtan(T y, T x); + + /// Faster than the common atan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAtan(T angle); + + /// @} +}//namespace glm + +#include "fast_trigonometry.inl" diff --git a/src/other/manifold/glm/glm/gtx/fast_trigonometry.inl b/src/other/manifold/glm/glm/gtx/fast_trigonometry.inl new file mode 100644 index 00000000000..1a710cbcd08 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/fast_trigonometry.inl @@ -0,0 +1,142 @@ +/// @ref gtx_fast_trigonometry + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER vec taylorCos(vec const& x) + { + return static_cast(1) + - (x * x) * (1.f / 2.f) + + ((x * x) * (x * x)) * (1.f / 24.f) + - (((x * x) * (x * x)) * (x * x)) * (1.f / 720.f) + + (((x * x) * (x * x)) * ((x * x) * (x * x))) * (1.f / 40320.f); + } + + template + GLM_FUNC_QUALIFIER T cos_52s(T x) + { + T const xx(x * x); + return (T(0.9999932946) + xx * (T(-0.4999124376) + xx * (T(0.0414877472) + xx * T(-0.0012712095)))); + } + + template + GLM_FUNC_QUALIFIER vec cos_52s(vec const& x) + { + return detail::functor1::call(cos_52s, x); + } +}//namespace detail + + // wrapAngle + template + GLM_FUNC_QUALIFIER T wrapAngle(T angle) + { + return abs(mod(angle, two_pi())); + } + + template + GLM_FUNC_QUALIFIER vec wrapAngle(vec const& x) + { + return detail::functor1::call(wrapAngle, x); + } + + // cos + template + GLM_FUNC_QUALIFIER T fastCos(T x) + { + T const angle(wrapAngle(x)); + + if(angle < half_pi()) + return detail::cos_52s(angle); + if(angle < pi()) + return -detail::cos_52s(pi() - angle); + if(angle < (T(3) * half_pi())) + return -detail::cos_52s(angle - pi()); + + return detail::cos_52s(two_pi() - angle); + } + + template + GLM_FUNC_QUALIFIER vec fastCos(vec const& x) + { + return detail::functor1::call(fastCos, x); + } + + // sin + template + GLM_FUNC_QUALIFIER T fastSin(T x) + { + return fastCos(half_pi() - x); + } + + template + GLM_FUNC_QUALIFIER vec fastSin(vec const& x) + { + return detail::functor1::call(fastSin, x); + } + + // tan + template + GLM_FUNC_QUALIFIER T fastTan(T x) + { + return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539)); + } + + template + GLM_FUNC_QUALIFIER vec fastTan(vec const& x) + { + return detail::functor1::call(fastTan, x); + } + + // asin + template + GLM_FUNC_QUALIFIER T fastAsin(T x) + { + return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159)); + } + + template + GLM_FUNC_QUALIFIER vec fastAsin(vec const& x) + { + return detail::functor1::call(fastAsin, x); + } + + // acos + template + GLM_FUNC_QUALIFIER T fastAcos(T x) + { + return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2) + } + + template + GLM_FUNC_QUALIFIER vec fastAcos(vec const& x) + { + return detail::functor1::call(fastAcos, x); + } + + // atan + template + GLM_FUNC_QUALIFIER T fastAtan(T y, T x) + { + T sgn = sign(y) * sign(x); + return abs(fastAtan(y / x)) * sgn; + } + + template + GLM_FUNC_QUALIFIER vec fastAtan(vec const& y, vec const& x) + { + return detail::functor2::call(fastAtan, y, x); + } + + template + GLM_FUNC_QUALIFIER T fastAtan(T x) + { + return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909)); + } + + template + GLM_FUNC_QUALIFIER vec fastAtan(vec const& x) + { + return detail::functor1::call(fastAtan, x); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/float_notmalize.inl b/src/other/manifold/glm/glm/gtx/float_notmalize.inl new file mode 100644 index 00000000000..8cdbc5aaa9c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/float_notmalize.inl @@ -0,0 +1,13 @@ +/// @ref gtx_float_normalize + +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec floatNormalize(vec const& v) + { + return vec(v) / static_cast(std::numeric_limits::max()); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/functions.hpp b/src/other/manifold/glm/glm/gtx/functions.hpp new file mode 100644 index 00000000000..9f4166c4c1c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/functions.hpp @@ -0,0 +1,56 @@ +/// @ref gtx_functions +/// @file glm/gtx/functions.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_functions GLM_GTX_functions +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// List of useful common functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/type_vec2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_functions is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_functions extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_functions + /// @{ + + /// 1D gauss function + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL T gauss( + T x, + T ExpectedValue, + T StandardDeviation); + + /// 2D gauss function + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL T gauss( + vec<2, T, Q> const& Coord, + vec<2, T, Q> const& ExpectedValue, + vec<2, T, Q> const& StandardDeviation); + + /// @} +}//namespace glm + +#include "functions.inl" + diff --git a/src/other/manifold/glm/glm/gtx/functions.inl b/src/other/manifold/glm/glm/gtx/functions.inl new file mode 100644 index 00000000000..29cbb20b80f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/functions.inl @@ -0,0 +1,30 @@ +/// @ref gtx_functions + +#include "../exponential.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T gauss + ( + T x, + T ExpectedValue, + T StandardDeviation + ) + { + return exp(-((x - ExpectedValue) * (x - ExpectedValue)) / (static_cast(2) * StandardDeviation * StandardDeviation)) / (StandardDeviation * sqrt(static_cast(6.28318530717958647692528676655900576))); + } + + template + GLM_FUNC_QUALIFIER T gauss + ( + vec<2, T, Q> const& Coord, + vec<2, T, Q> const& ExpectedValue, + vec<2, T, Q> const& StandardDeviation + ) + { + vec<2, T, Q> const Squared = ((Coord - ExpectedValue) * (Coord - ExpectedValue)) / (static_cast(2) * StandardDeviation * StandardDeviation); + return exp(-(Squared.x + Squared.y)); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtx/gradient_paint.hpp b/src/other/manifold/glm/glm/gtx/gradient_paint.hpp new file mode 100644 index 00000000000..6f85bf482d9 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/gradient_paint.hpp @@ -0,0 +1,53 @@ +/// @ref gtx_gradient_paint +/// @file glm/gtx/gradient_paint.hpp +/// +/// @see core (dependence) +/// @see gtx_optimum_pow (dependence) +/// +/// @defgroup gtx_gradient_paint GLM_GTX_gradient_paint +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions that return the color of procedural gradient for specific coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/optimum_pow.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_gradient_paint is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_gradient_paint extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_gradient_paint + /// @{ + + /// Return a color from a radial gradient. + /// @see - gtx_gradient_paint + template + GLM_FUNC_DECL T radialGradient( + vec<2, T, Q> const& Center, + T const& Radius, + vec<2, T, Q> const& Focal, + vec<2, T, Q> const& Position); + + /// Return a color from a linear gradient. + /// @see - gtx_gradient_paint + template + GLM_FUNC_DECL T linearGradient( + vec<2, T, Q> const& Point0, + vec<2, T, Q> const& Point1, + vec<2, T, Q> const& Position); + + /// @} +}// namespace glm + +#include "gradient_paint.inl" diff --git a/src/other/manifold/glm/glm/gtx/gradient_paint.inl b/src/other/manifold/glm/glm/gtx/gradient_paint.inl new file mode 100644 index 00000000000..4c495e62cbf --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/gradient_paint.inl @@ -0,0 +1,36 @@ +/// @ref gtx_gradient_paint + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T radialGradient + ( + vec<2, T, Q> const& Center, + T const& Radius, + vec<2, T, Q> const& Focal, + vec<2, T, Q> const& Position + ) + { + vec<2, T, Q> F = Focal - Center; + vec<2, T, Q> D = Position - Focal; + T Radius2 = pow2(Radius); + T Fx2 = pow2(F.x); + T Fy2 = pow2(F.y); + + T Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x)); + T Denominator = Radius2 - (Fx2 + Fy2); + return Numerator / Denominator; + } + + template + GLM_FUNC_QUALIFIER T linearGradient + ( + vec<2, T, Q> const& Point0, + vec<2, T, Q> const& Point1, + vec<2, T, Q> const& Position + ) + { + vec<2, T, Q> Dist = Point1 - Point0; + return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/handed_coordinate_space.hpp b/src/other/manifold/glm/glm/gtx/handed_coordinate_space.hpp new file mode 100644 index 00000000000..3c8596892ce --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/handed_coordinate_space.hpp @@ -0,0 +1,50 @@ +/// @ref gtx_handed_coordinate_space +/// @file glm/gtx/handed_coordinate_space.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_handed_coordinate_space GLM_GTX_handed_coordinate_space +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// To know if a set of three basis vectors defines a right or left-handed coordinate system. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_handed_coordinate_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_handed_coordinate_space extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_handed_coordinate_space + /// @{ + + //! Return if a trihedron right handed or not. + //! From GLM_GTX_handed_coordinate_space extension. + template + GLM_FUNC_DECL bool rightHanded( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal); + + //! Return if a trihedron left handed or not. + //! From GLM_GTX_handed_coordinate_space extension. + template + GLM_FUNC_DECL bool leftHanded( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal); + + /// @} +}// namespace glm + +#include "handed_coordinate_space.inl" diff --git a/src/other/manifold/glm/glm/gtx/handed_coordinate_space.inl b/src/other/manifold/glm/glm/gtx/handed_coordinate_space.inl new file mode 100644 index 00000000000..e43c17bd312 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/handed_coordinate_space.inl @@ -0,0 +1,26 @@ +/// @ref gtx_handed_coordinate_space + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool rightHanded + ( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal + ) + { + return dot(cross(normal, tangent), binormal) > T(0); + } + + template + GLM_FUNC_QUALIFIER bool leftHanded + ( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal + ) + { + return dot(cross(normal, tangent), binormal) < T(0); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/hash.hpp b/src/other/manifold/glm/glm/gtx/hash.hpp new file mode 100644 index 00000000000..05dae9f4b07 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/hash.hpp @@ -0,0 +1,142 @@ +/// @ref gtx_hash +/// @file glm/gtx/hash.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_hash GLM_GTX_hash +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add std::hash support for glm types + +#pragma once + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_hash is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_hash extension included") +# endif +#endif + +#include + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../gtc/vec1.hpp" + +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" + +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" + +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" + +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" + +#if !GLM_HAS_CXX11_STL +# error "GLM_GTX_hash requires C++11 standard library support" +#endif + +namespace std +{ + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<1, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<2, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<3, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<4, T, Q> const& v) const; + }; + + template + struct hash> + { + GLM_FUNC_DECL size_t operator()(glm::qua const& q) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::tdualquat const& q) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 4, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 4, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 4, T,Q> const& m) const; + }; +} // namespace std + +#include "hash.inl" diff --git a/src/other/manifold/glm/glm/gtx/hash.inl b/src/other/manifold/glm/glm/gtx/hash.inl new file mode 100644 index 00000000000..ff71ca9f7ea --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/hash.inl @@ -0,0 +1,184 @@ +/// @ref gtx_hash +/// +/// @see core (dependence) +/// +/// @defgroup gtx_hash GLM_GTX_hash +/// @ingroup gtx +/// +/// @brief Add std::hash support for glm types +/// +/// need to be included to use the features of this extension. + +namespace glm { +namespace detail +{ + GLM_INLINE void hash_combine(size_t &seed, size_t hash) + { + hash += 0x9e3779b9 + (seed << 6) + (seed >> 2); + seed ^= hash; + } +}} + +namespace std +{ + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<1, T, Q> const& v) const + { + hash hasher; + return hasher(v.x); + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<2, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<3, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + glm::detail::hash_combine(seed, hasher(v.z)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<4, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + glm::detail::hash_combine(seed, hasher(v.z)); + glm::detail::hash_combine(seed, hasher(v.w)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::qua const& q) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(q.x)); + glm::detail::hash_combine(seed, hasher(q.y)); + glm::detail::hash_combine(seed, hasher(q.z)); + glm::detail::hash_combine(seed, hasher(q.w)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::tdualquat const& q) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(q.real)); + glm::detail::hash_combine(seed, hasher(q.dual)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 2, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 3, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 2, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 3, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 2, T,Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 3, T,Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } +} diff --git a/src/other/manifold/glm/glm/gtx/integer.hpp b/src/other/manifold/glm/glm/gtx/integer.hpp new file mode 100644 index 00000000000..d0b4c61a3fd --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/integer.hpp @@ -0,0 +1,76 @@ +/// @ref gtx_integer +/// @file glm/gtx/integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_integer GLM_GTX_integer +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add support for integer for core functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/integer.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_integer is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_integer extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_integer + /// @{ + + //! Returns x raised to the y power. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int pow(int x, uint y); + + //! Returns the positive square root of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int sqrt(int x); + + //! Returns the floor log2 of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL unsigned int floor_log2(unsigned int x); + + //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int mod(int x, int y); + + //! Return the factorial value of a number (!12 max, integer only) + //! From GLM_GTX_integer extension. + template + GLM_FUNC_DECL genType factorial(genType const& x); + + //! 32bit signed integer. + //! From GLM_GTX_integer extension. + typedef signed int sint; + + //! Returns x raised to the y power. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint pow(uint x, uint y); + + //! Returns the positive square root of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint sqrt(uint x); + + //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint mod(uint x, uint y); + + //! Returns the number of leading zeros. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint nlz(uint x); + + /// @} +}//namespace glm + +#include "integer.inl" diff --git a/src/other/manifold/glm/glm/gtx/integer.inl b/src/other/manifold/glm/glm/gtx/integer.inl new file mode 100644 index 00000000000..956366b250f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/integer.inl @@ -0,0 +1,185 @@ +/// @ref gtx_integer + +namespace glm +{ + // pow + GLM_FUNC_QUALIFIER int pow(int x, uint y) + { + if(y == 0) + return x >= 0 ? 1 : -1; + + int result = x; + for(uint i = 1; i < y; ++i) + result *= x; + return result; + } + + // sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387 + GLM_FUNC_QUALIFIER int sqrt(int x) + { + if(x <= 1) return x; + + int NextTrial = x >> 1; + int CurrentAnswer; + + do + { + CurrentAnswer = NextTrial; + NextTrial = (NextTrial + x / NextTrial) >> 1; + } while(NextTrial < CurrentAnswer); + + return CurrentAnswer; + } + +// Henry Gordon Dietz: http://aggregate.org/MAGIC/ +namespace detail +{ + GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x) + { + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way + */ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return(x & 0x0000003f); + } +}//namespace detail + + // Henry Gordon Dietz: http://aggregate.org/MAGIC/ +/* + GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + + return _detail::ones32(x) >> 1; + } +*/ + // mod + GLM_FUNC_QUALIFIER int mod(int x, int y) + { + return ((x % y) + y) % y; + } + + // factorial (!12 max, integer only) + template + GLM_FUNC_QUALIFIER genType factorial(genType const& x) + { + genType Temp = x; + genType Result; + for(Result = 1; Temp > 1; --Temp) + Result *= Temp; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> factorial( + vec<2, T, Q> const& x) + { + return vec<2, T, Q>( + factorial(x.x), + factorial(x.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> factorial( + vec<3, T, Q> const& x) + { + return vec<3, T, Q>( + factorial(x.x), + factorial(x.y), + factorial(x.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> factorial( + vec<4, T, Q> const& x) + { + return vec<4, T, Q>( + factorial(x.x), + factorial(x.y), + factorial(x.z), + factorial(x.w)); + } + + GLM_FUNC_QUALIFIER uint pow(uint x, uint y) + { + if (y == 0) + return 1u; + + uint result = x; + for(uint i = 1; i < y; ++i) + result *= x; + return result; + } + + GLM_FUNC_QUALIFIER uint sqrt(uint x) + { + if(x <= 1) return x; + + uint NextTrial = x >> 1; + uint CurrentAnswer; + + do + { + CurrentAnswer = NextTrial; + NextTrial = (NextTrial + x / NextTrial) >> 1; + } while(NextTrial < CurrentAnswer); + + return CurrentAnswer; + } + + GLM_FUNC_QUALIFIER uint mod(uint x, uint y) + { + return x - y * (x / y); + } + +#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC)) + + GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) + { + return 31u - findMSB(x); + } + +#else + + // Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt + GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) + { + int y, m, n; + + y = -int(x >> 16); // If left half of x is 0, + m = (y >> 16) & 16; // set n = 16. If left half + n = 16 - m; // is nonzero, set n = 0 and + x = x >> m; // shift x right 16. + // Now x is of the form 0000xxxx. + y = x - 0x100; // If positions 8-15 are 0, + m = (y >> 16) & 8; // add 8 to n and shift x left 8. + n = n + m; + x = x << m; + + y = x - 0x1000; // If positions 12-15 are 0, + m = (y >> 16) & 4; // add 4 to n and shift x left 4. + n = n + m; + x = x << m; + + y = x - 0x4000; // If positions 14-15 are 0, + m = (y >> 16) & 2; // add 2 to n and shift x left 2. + n = n + m; + x = x << m; + + y = x >> 14; // Set y = 0, 1, 2, or 3. + m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp. + return unsigned(n + 2 - m); + } + +#endif//(GLM_COMPILER) + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/intersect.hpp b/src/other/manifold/glm/glm/gtx/intersect.hpp new file mode 100644 index 00000000000..3c78f2b8e22 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/intersect.hpp @@ -0,0 +1,92 @@ +/// @ref gtx_intersect +/// @file glm/gtx/intersect.hpp +/// +/// @see core (dependence) +/// @see gtx_closest_point (dependence) +/// +/// @defgroup gtx_intersect GLM_GTX_intersect +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add intersection functions + +#pragma once + +// Dependency: +#include +#include +#include "../glm.hpp" +#include "../geometric.hpp" +#include "../gtx/closest_point.hpp" +#include "../gtx/vector_query.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_closest_point extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_intersect + /// @{ + + //! Compute the intersection of a ray and a plane. + //! Ray direction and plane normal must be unit length. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRayPlane( + genType const& orig, genType const& dir, + genType const& planeOrig, genType const& planeNormal, + typename genType::value_type & intersectionDistance); + + //! Compute the intersection of a ray and a triangle. + /// Based om Tomas Möller implementation http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/raytri/ + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRayTriangle( + vec<3, T, Q> const& orig, vec<3, T, Q> const& dir, + vec<3, T, Q> const& v0, vec<3, T, Q> const& v1, vec<3, T, Q> const& v2, + vec<2, T, Q>& baryPosition, T& distance); + + //! Compute the intersection of a line and a triangle. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectLineTriangle( + genType const& orig, genType const& dir, + genType const& vert0, genType const& vert1, genType const& vert2, + genType & position); + + //! Compute the intersection distance of a ray and a sphere. + //! The ray direction vector is unit length. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRaySphere( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, typename genType::value_type const sphereRadiusSquered, + typename genType::value_type & intersectionDistance); + + //! Compute the intersection of a ray and a sphere. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRaySphere( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal); + + //! Compute the intersection of a line and a sphere. + //! From GLM_GTX_intersect extension + template + GLM_FUNC_DECL bool intersectLineSphere( + genType const& point0, genType const& point1, + genType const& sphereCenter, typename genType::value_type sphereRadius, + genType & intersectionPosition1, genType & intersectionNormal1, + genType & intersectionPosition2 = genType(), genType & intersectionNormal2 = genType()); + + /// @} +}//namespace glm + +#include "intersect.inl" diff --git a/src/other/manifold/glm/glm/gtx/intersect.inl b/src/other/manifold/glm/glm/gtx/intersect.inl new file mode 100644 index 00000000000..54ecb4d909c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/intersect.inl @@ -0,0 +1,200 @@ +/// @ref gtx_intersect + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool intersectRayPlane + ( + genType const& orig, genType const& dir, + genType const& planeOrig, genType const& planeNormal, + typename genType::value_type & intersectionDistance + ) + { + typename genType::value_type d = glm::dot(dir, planeNormal); + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + + if(glm::abs(d) > Epsilon) // if dir and planeNormal are not perpendicular + { + typename genType::value_type const tmp_intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d; + if (tmp_intersectionDistance > static_cast(0)) { // allow only intersections + intersectionDistance = tmp_intersectionDistance; + return true; + } + } + + return false; + } + + template + GLM_FUNC_QUALIFIER bool intersectRayTriangle + ( + vec<3, T, Q> const& orig, vec<3, T, Q> const& dir, + vec<3, T, Q> const& vert0, vec<3, T, Q> const& vert1, vec<3, T, Q> const& vert2, + vec<2, T, Q>& baryPosition, T& distance + ) + { + // find vectors for two edges sharing vert0 + vec<3, T, Q> const edge1 = vert1 - vert0; + vec<3, T, Q> const edge2 = vert2 - vert0; + + // begin calculating determinant - also used to calculate U parameter + vec<3, T, Q> const p = glm::cross(dir, edge2); + + // if determinant is near zero, ray lies in plane of triangle + T const det = glm::dot(edge1, p); + + vec<3, T, Q> Perpendicular(0); + + if(det > std::numeric_limits::epsilon()) + { + // calculate distance from vert0 to ray origin + vec<3, T, Q> const dist = orig - vert0; + + // calculate U parameter and test bounds + baryPosition.x = glm::dot(dist, p); + if(baryPosition.x < static_cast(0) || baryPosition.x > det) + return false; + + // prepare to test V parameter + Perpendicular = glm::cross(dist, edge1); + + // calculate V parameter and test bounds + baryPosition.y = glm::dot(dir, Perpendicular); + if((baryPosition.y < static_cast(0)) || ((baryPosition.x + baryPosition.y) > det)) + return false; + } + else if(det < -std::numeric_limits::epsilon()) + { + // calculate distance from vert0 to ray origin + vec<3, T, Q> const dist = orig - vert0; + + // calculate U parameter and test bounds + baryPosition.x = glm::dot(dist, p); + if((baryPosition.x > static_cast(0)) || (baryPosition.x < det)) + return false; + + // prepare to test V parameter + Perpendicular = glm::cross(dist, edge1); + + // calculate V parameter and test bounds + baryPosition.y = glm::dot(dir, Perpendicular); + if((baryPosition.y > static_cast(0)) || (baryPosition.x + baryPosition.y < det)) + return false; + } + else + return false; // ray is parallel to the plane of the triangle + + T inv_det = static_cast(1) / det; + + // calculate distance, ray intersects triangle + distance = glm::dot(edge2, Perpendicular) * inv_det; + baryPosition *= inv_det; + + return true; + } + + template + GLM_FUNC_QUALIFIER bool intersectLineTriangle + ( + genType const& orig, genType const& dir, + genType const& vert0, genType const& vert1, genType const& vert2, + genType & position + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + + genType edge1 = vert1 - vert0; + genType edge2 = vert2 - vert0; + + genType Perpendicular = cross(dir, edge2); + + float det = dot(edge1, Perpendicular); + + if (det > -Epsilon && det < Epsilon) + return false; + typename genType::value_type inv_det = typename genType::value_type(1) / det; + + genType Tengant = orig - vert0; + + position.y = dot(Tengant, Perpendicular) * inv_det; + if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1)) + return false; + + genType Cotengant = cross(Tengant, edge1); + + position.z = dot(dir, Cotengant) * inv_det; + if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1)) + return false; + + position.x = dot(edge2, Cotengant) * inv_det; + + return true; + } + + template + GLM_FUNC_QUALIFIER bool intersectRaySphere + ( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadiusSquered, + typename genType::value_type & intersectionDistance + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + genType diff = sphereCenter - rayStarting; + typename genType::value_type t0 = dot(diff, rayNormalizedDirection); + typename genType::value_type dSquared = dot(diff, diff) - t0 * t0; + if( dSquared > sphereRadiusSquered ) + { + return false; + } + typename genType::value_type t1 = sqrt( sphereRadiusSquered - dSquared ); + intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1; + return intersectionDistance > Epsilon; + } + + template + GLM_FUNC_QUALIFIER bool intersectRaySphere + ( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal + ) + { + typename genType::value_type distance; + if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) ) + { + intersectionPosition = rayStarting + rayNormalizedDirection * distance; + intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius; + return true; + } + return false; + } + + template + GLM_FUNC_QUALIFIER bool intersectLineSphere + ( + genType const& point0, genType const& point1, + genType const& sphereCenter, typename genType::value_type sphereRadius, + genType & intersectionPoint1, genType & intersectionNormal1, + genType & intersectionPoint2, genType & intersectionNormal2 + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + genType dir = normalize(point1 - point0); + genType diff = sphereCenter - point0; + typename genType::value_type t0 = dot(diff, dir); + typename genType::value_type dSquared = dot(diff, diff) - t0 * t0; + if( dSquared > sphereRadius * sphereRadius ) + { + return false; + } + typename genType::value_type t1 = sqrt( sphereRadius * sphereRadius - dSquared ); + if( t0 < t1 + Epsilon ) + t1 = -t1; + intersectionPoint1 = point0 + dir * (t0 - t1); + intersectionNormal1 = (intersectionPoint1 - sphereCenter) / sphereRadius; + intersectionPoint2 = point0 + dir * (t0 + t1); + intersectionNormal2 = (intersectionPoint2 - sphereCenter) / sphereRadius; + return true; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/io.hpp b/src/other/manifold/glm/glm/gtx/io.hpp new file mode 100644 index 00000000000..8d974f00456 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/io.hpp @@ -0,0 +1,201 @@ +/// @ref gtx_io +/// @file glm/gtx/io.hpp +/// @author Jan P Springer (regnirpsj@gmail.com) +/// +/// @see core (dependence) +/// @see gtc_matrix_access (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_io GLM_GTX_io +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// std::[w]ostream support for glm types +/// +/// std::[w]ostream support for glm types + qualifier/width/etc. manipulators +/// based on howard hinnant's std::chrono io proposal +/// [http://home.roadrunner.com/~hinnant/bloomington/chrono_io.html] + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_io is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_io extension included") +# endif +#endif + +#include // std::basic_ostream<> (fwd) +#include // std::locale, std::locale::facet, std::locale::id +#include // std::pair<> + +namespace glm +{ + /// @addtogroup gtx_io + /// @{ + + namespace io + { + enum order_type { column_major, row_major}; + + template + class format_punct : public std::locale::facet + { + typedef CTy char_type; + + public: + + static std::locale::id id; + + bool formatted; + unsigned precision; + unsigned width; + char_type separator; + char_type delim_left; + char_type delim_right; + char_type space; + char_type newline; + order_type order; + + GLM_FUNC_DECL explicit format_punct(size_t a = 0); + GLM_FUNC_DECL explicit format_punct(format_punct const&); + }; + + template > + class basic_state_saver { + + public: + + GLM_FUNC_DECL explicit basic_state_saver(std::basic_ios&); + GLM_FUNC_DECL ~basic_state_saver(); + + private: + + typedef ::std::basic_ios state_type; + typedef typename state_type::char_type char_type; + typedef ::std::ios_base::fmtflags flags_type; + typedef ::std::streamsize streamsize_type; + typedef ::std::locale const locale_type; + + state_type& state_; + flags_type flags_; + streamsize_type precision_; + streamsize_type width_; + char_type fill_; + locale_type locale_; + + GLM_FUNC_DECL basic_state_saver& operator=(basic_state_saver const&); + }; + + typedef basic_state_saver state_saver; + typedef basic_state_saver wstate_saver; + + template > + class basic_format_saver + { + public: + + GLM_FUNC_DECL explicit basic_format_saver(std::basic_ios&); + GLM_FUNC_DECL ~basic_format_saver(); + + private: + + basic_state_saver const bss_; + + GLM_FUNC_DECL basic_format_saver& operator=(basic_format_saver const&); + }; + + typedef basic_format_saver format_saver; + typedef basic_format_saver wformat_saver; + + struct precision + { + unsigned value; + + GLM_FUNC_DECL explicit precision(unsigned); + }; + + struct width + { + unsigned value; + + GLM_FUNC_DECL explicit width(unsigned); + }; + + template + struct delimeter + { + CTy value[3]; + + GLM_FUNC_DECL explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); + }; + + struct order + { + order_type value; + + GLM_FUNC_DECL explicit order(order_type); + }; + + // functions, inlined (inline) + + template + FTy const& get_facet(std::basic_ios&); + template + std::basic_ios& formatted(std::basic_ios&); + template + std::basic_ios& unformattet(std::basic_ios&); + + template + std::basic_ostream& operator<<(std::basic_ostream&, precision const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, width const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, delimeter const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, order const&); + }//namespace io + + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, qua const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<1, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 4, T, Q> const&); + + template + GLM_FUNC_DECL std::basic_ostream & operator<<(std::basic_ostream &, + std::pair const, mat<4, 4, T, Q> const> const&); + + /// @} +}//namespace glm + +#include "io.inl" diff --git a/src/other/manifold/glm/glm/gtx/io.inl b/src/other/manifold/glm/glm/gtx/io.inl new file mode 100644 index 00000000000..a3a1bb6c26b --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/io.inl @@ -0,0 +1,440 @@ +/// @ref gtx_io +/// @author Jan P Springer (regnirpsj@gmail.com) + +#include // std::fixed, std::setfill<>, std::setprecision, std::right, std::setw +#include // std::basic_ostream<> +#include "../gtc/matrix_access.hpp" // glm::col, glm::row +#include "../gtx/type_trait.hpp" // glm::type<> + +namespace glm{ +namespace io +{ + template + GLM_FUNC_QUALIFIER format_punct::format_punct(size_t a) + : std::locale::facet(a) + , formatted(true) + , precision(3) + , width(1 + 4 + 1 + precision) + , separator(',') + , delim_left('[') + , delim_right(']') + , space(' ') + , newline('\n') + , order(column_major) + {} + + template + GLM_FUNC_QUALIFIER format_punct::format_punct(format_punct const& a) + : std::locale::facet(0) + , formatted(a.formatted) + , precision(a.precision) + , width(a.width) + , separator(a.separator) + , delim_left(a.delim_left) + , delim_right(a.delim_right) + , space(a.space) + , newline(a.newline) + , order(a.order) + {} + + template std::locale::id format_punct::id; + + template + GLM_FUNC_QUALIFIER basic_state_saver::basic_state_saver(std::basic_ios& a) + : state_(a) + , flags_(a.flags()) + , precision_(a.precision()) + , width_(a.width()) + , fill_(a.fill()) + , locale_(a.getloc()) + {} + + template + GLM_FUNC_QUALIFIER basic_state_saver::~basic_state_saver() + { + state_.imbue(locale_); + state_.fill(fill_); + state_.width(width_); + state_.precision(precision_); + state_.flags(flags_); + } + + template + GLM_FUNC_QUALIFIER basic_format_saver::basic_format_saver(std::basic_ios& a) + : bss_(a) + { + a.imbue(std::locale(a.getloc(), new format_punct(get_facet >(a)))); + } + + template + GLM_FUNC_QUALIFIER + basic_format_saver::~basic_format_saver() + {} + + GLM_FUNC_QUALIFIER precision::precision(unsigned a) + : value(a) + {} + + GLM_FUNC_QUALIFIER width::width(unsigned a) + : value(a) + {} + + template + GLM_FUNC_QUALIFIER delimeter::delimeter(CTy a, CTy b, CTy c) + : value() + { + value[0] = a; + value[1] = b; + value[2] = c; + } + + GLM_FUNC_QUALIFIER order::order(order_type a) + : value(a) + {} + + template + GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios& ios) + { + if(!std::has_facet(ios.getloc())) + ios.imbue(std::locale(ios.getloc(), new FTy)); + + return std::use_facet(ios.getloc()); + } + + template + GLM_FUNC_QUALIFIER std::basic_ios& formatted(std::basic_ios& ios) + { + const_cast&>(get_facet >(ios)).formatted = true; + return ios; + } + + template + GLM_FUNC_QUALIFIER std::basic_ios& unformatted(std::basic_ios& ios) + { + const_cast&>(get_facet >(ios)).formatted = false; + return ios; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, precision const& a) + { + const_cast&>(get_facet >(os)).precision = a.value; + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, width const& a) + { + const_cast&>(get_facet >(os)).width = a.value; + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, delimeter const& a) + { + format_punct & fmt(const_cast&>(get_facet >(os))); + + fmt.delim_left = a.value[0]; + fmt.delim_right = a.value[1]; + fmt.separator = a.value[2]; + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, order const& a) + { + const_cast&>(get_facet >(os)).order = a.value; + return os; + } +} // namespace io + +namespace detail +{ + template + GLM_FUNC_QUALIFIER std::basic_ostream& + print_vector_on(std::basic_ostream& os, V const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + + length_t const& components(type::components); + + if(fmt.formatted) + { + io::basic_state_saver const bss(os); + + os << std::fixed << std::right << std::setprecision(fmt.precision) << std::setfill(fmt.space) << fmt.delim_left; + + for(length_t i(0); i < components; ++i) + { + os << std::setw(fmt.width) << a[i]; + if(components-1 != i) + os << fmt.separator; + } + + os << fmt.delim_right; + } + else + { + for(length_t i(0); i < components; ++i) + { + os << a[i]; + + if(components-1 != i) + os << fmt.space; + } + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, qua const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<1, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<2, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<3, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<4, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + +namespace detail +{ + template class M, length_t C, length_t R, typename T, qualifier Q> + GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_on(std::basic_ostream& os, M const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + + length_t const& cols(type >::cols); + length_t const& rows(type >::rows); + + if(fmt.formatted) + { + os << fmt.newline << fmt.delim_left; + + switch(fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < rows; ++i) + { + if (0 != i) + os << fmt.space; + + os << row(a, i); + + if(rows-1 != i) + os << fmt.newline; + } + } + break; + + case io::row_major: + { + for(length_t i(0); i < cols; ++i) + { + if(0 != i) + os << fmt.space; + + os << column(a, i); + + if(cols-1 != i) + os << fmt.newline; + } + } + break; + } + + os << fmt.delim_right; + } + else + { + switch (fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < cols; ++i) + { + os << column(a, i); + + if(cols - 1 != i) + os << fmt.space; + } + } + break; + + case io::row_major: + { + for (length_t i(0); i < rows; ++i) + { + os << row(a, i); + + if (rows-1 != i) + os << fmt.space; + } + } + break; + } + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<3, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<3, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<3, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + +namespace detail +{ + template class M, length_t C, length_t R, typename T, qualifier Q> + GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_pair_on(std::basic_ostream& os, std::pair const, M const> const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + M const& ml(a.first); + M const& mr(a.second); + length_t const& cols(type >::cols); + length_t const& rows(type >::rows); + + if(fmt.formatted) + { + os << fmt.newline << fmt.delim_left; + + switch(fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < rows; ++i) + { + if(0 != i) + os << fmt.space; + + os << row(ml, i) << ((rows-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << row(mr, i); + + if(rows-1 != i) + os << fmt.newline; + } + } + break; + case io::row_major: + { + for(length_t i(0); i < cols; ++i) + { + if(0 != i) + os << fmt.space; + + os << column(ml, i) << ((cols-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << column(mr, i); + + if(cols-1 != i) + os << fmt.newline; + } + } + break; + } + + os << fmt.delim_right; + } + else + { + os << ml << fmt.space << mr; + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<( + std::basic_ostream & os, + std::pair const, + mat<4, 4, T, Q> const> const& a) + { + return detail::print_matrix_pair_on(os, a); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/log_base.hpp b/src/other/manifold/glm/glm/gtx/log_base.hpp new file mode 100644 index 00000000000..ba28c9d7bff --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/log_base.hpp @@ -0,0 +1,48 @@ +/// @ref gtx_log_base +/// @file glm/gtx/log_base.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_log_base GLM_GTX_log_base +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Logarithm for any base. base can be a vector or a scalar. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_log_base is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_log_base extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_log_base + /// @{ + + /// Logarithm for any base. + /// From GLM_GTX_log_base. + template + GLM_FUNC_DECL genType log( + genType const& x, + genType const& base); + + /// Logarithm for any base. + /// From GLM_GTX_log_base. + template + GLM_FUNC_DECL vec sign( + vec const& x, + vec const& base); + + /// @} +}//namespace glm + +#include "log_base.inl" diff --git a/src/other/manifold/glm/glm/gtx/log_base.inl b/src/other/manifold/glm/glm/gtx/log_base.inl new file mode 100644 index 00000000000..4bbb8e895ab --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/log_base.inl @@ -0,0 +1,16 @@ +/// @ref gtx_log_base + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType log(genType const& x, genType const& base) + { + return glm::log(x) / glm::log(base); + } + + template + GLM_FUNC_QUALIFIER vec log(vec const& x, vec const& base) + { + return glm::log(x) / glm::log(base); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_cross_product.hpp b/src/other/manifold/glm/glm/gtx/matrix_cross_product.hpp new file mode 100644 index 00000000000..1e585f9a4ff --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_cross_product.hpp @@ -0,0 +1,47 @@ +/// @ref gtx_matrix_cross_product +/// @file glm/gtx/matrix_cross_product.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_matrix_cross_product GLM_GTX_matrix_cross_product +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build cross product matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_cross_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_cross_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_cross_product + /// @{ + + //! Build a cross product matrix. + //! From GLM_GTX_matrix_cross_product extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> matrixCross3( + vec<3, T, Q> const& x); + + //! Build a cross product matrix. + //! From GLM_GTX_matrix_cross_product extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> matrixCross4( + vec<3, T, Q> const& x); + + /// @} +}//namespace glm + +#include "matrix_cross_product.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_cross_product.inl b/src/other/manifold/glm/glm/gtx/matrix_cross_product.inl new file mode 100644 index 00000000000..3a153977cf5 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_cross_product.inl @@ -0,0 +1,37 @@ +/// @ref gtx_matrix_cross_product + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> matrixCross3 + ( + vec<3, T, Q> const& x + ) + { + mat<3, 3, T, Q> Result(T(0)); + Result[0][1] = x.z; + Result[1][0] = -x.z; + Result[0][2] = -x.y; + Result[2][0] = x.y; + Result[1][2] = x.x; + Result[2][1] = -x.x; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> matrixCross4 + ( + vec<3, T, Q> const& x + ) + { + mat<4, 4, T, Q> Result(T(0)); + Result[0][1] = x.z; + Result[1][0] = -x.z; + Result[0][2] = -x.y; + Result[2][0] = x.y; + Result[1][2] = x.x; + Result[2][1] = -x.x; + return Result; + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_decompose.hpp b/src/other/manifold/glm/glm/gtx/matrix_decompose.hpp new file mode 100644 index 00000000000..acd7a7f0681 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_decompose.hpp @@ -0,0 +1,46 @@ +/// @ref gtx_matrix_decompose +/// @file glm/gtx/matrix_decompose.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_decompose GLM_GTX_matrix_decompose +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Decomposes a model matrix to translations, rotation and scale components + +#pragma once + +// Dependencies +#include "../mat4x4.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../geometric.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtc/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_decompose is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_decompose extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_decompose + /// @{ + + /// Decomposes a model matrix to translations, rotation and scale components + /// @see gtx_matrix_decompose + template + GLM_FUNC_DECL bool decompose( + mat<4, 4, T, Q> const& modelMatrix, + vec<3, T, Q> & scale, qua & orientation, vec<3, T, Q> & translation, vec<3, T, Q> & skew, vec<4, T, Q> & perspective); + + /// @} +}//namespace glm + +#include "matrix_decompose.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_decompose.inl b/src/other/manifold/glm/glm/gtx/matrix_decompose.inl new file mode 100644 index 00000000000..694f5eca74a --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_decompose.inl @@ -0,0 +1,186 @@ +/// @ref gtx_matrix_decompose + +#include "../gtc/constants.hpp" +#include "../gtc/epsilon.hpp" + +namespace glm{ +namespace detail +{ + /// Make a linear combination of two vectors and return the result. + // result = (a * ascl) + (b * bscl) + template + GLM_FUNC_QUALIFIER vec<3, T, Q> combine( + vec<3, T, Q> const& a, + vec<3, T, Q> const& b, + T ascl, T bscl) + { + return (a * ascl) + (b * bscl); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> scale(vec<3, T, Q> const& v, T desiredLength) + { + return v * desiredLength / length(v); + } +}//namespace detail + + // Matrix decompose + // http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp + // Decomposes the mode matrix to translations,rotation scale components + + template + GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, qua & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective) + { + mat<4, 4, T, Q> LocalMatrix(ModelMatrix); + + // Normalize the matrix. + if(epsilonEqual(LocalMatrix[3][3], static_cast(0), epsilon())) + return false; + + for(length_t i = 0; i < 4; ++i) + for(length_t j = 0; j < 4; ++j) + LocalMatrix[i][j] /= LocalMatrix[3][3]; + + // perspectiveMatrix is used to solve for perspective, but it also provides + // an easy way to test for singularity of the upper 3x3 component. + mat<4, 4, T, Q> PerspectiveMatrix(LocalMatrix); + + for(length_t i = 0; i < 3; i++) + PerspectiveMatrix[i][3] = static_cast(0); + PerspectiveMatrix[3][3] = static_cast(1); + + /// TODO: Fixme! + if(epsilonEqual(determinant(PerspectiveMatrix), static_cast(0), epsilon())) + return false; + + // First, isolate perspective. This is the messiest. + if( + epsilonNotEqual(LocalMatrix[0][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[1][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[2][3], static_cast(0), epsilon())) + { + // rightHandSide is the right hand side of the equation. + vec<4, T, Q> RightHandSide; + RightHandSide[0] = LocalMatrix[0][3]; + RightHandSide[1] = LocalMatrix[1][3]; + RightHandSide[2] = LocalMatrix[2][3]; + RightHandSide[3] = LocalMatrix[3][3]; + + // Solve the equation by inverting PerspectiveMatrix and multiplying + // rightHandSide by the inverse. (This is the easiest way, not + // necessarily the best.) + mat<4, 4, T, Q> InversePerspectiveMatrix = glm::inverse(PerspectiveMatrix);// inverse(PerspectiveMatrix, inversePerspectiveMatrix); + mat<4, 4, T, Q> TransposedInversePerspectiveMatrix = glm::transpose(InversePerspectiveMatrix);// transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix); + + Perspective = TransposedInversePerspectiveMatrix * RightHandSide; + // v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint); + + // Clear the perspective partition + LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast(0); + LocalMatrix[3][3] = static_cast(1); + } + else + { + // No perspective. + Perspective = vec<4, T, Q>(0, 0, 0, 1); + } + + // Next take care of translation (easy). + Translation = vec<3, T, Q>(LocalMatrix[3]); + LocalMatrix[3] = vec<4, T, Q>(0, 0, 0, LocalMatrix[3].w); + + vec<3, T, Q> Row[3], Pdum3; + + // Now get scale and shear. + for(length_t i = 0; i < 3; ++i) + for(length_t j = 0; j < 3; ++j) + Row[i][j] = LocalMatrix[i][j]; + + // Compute X scale factor and normalize first row. + Scale.x = length(Row[0]);// v3Length(Row[0]); + + Row[0] = detail::scale(Row[0], static_cast(1)); + + // Compute XY shear factor and make 2nd row orthogonal to 1st. + Skew.z = dot(Row[0], Row[1]); + Row[1] = detail::combine(Row[1], Row[0], static_cast(1), -Skew.z); + + // Now, compute Y scale and normalize 2nd row. + Scale.y = length(Row[1]); + Row[1] = detail::scale(Row[1], static_cast(1)); + Skew.z /= Scale.y; + + // Compute XZ and YZ shears, orthogonalize 3rd row. + Skew.y = glm::dot(Row[0], Row[2]); + Row[2] = detail::combine(Row[2], Row[0], static_cast(1), -Skew.y); + Skew.x = glm::dot(Row[1], Row[2]); + Row[2] = detail::combine(Row[2], Row[1], static_cast(1), -Skew.x); + + // Next, get Z scale and normalize 3rd row. + Scale.z = length(Row[2]); + Row[2] = detail::scale(Row[2], static_cast(1)); + Skew.y /= Scale.z; + Skew.x /= Scale.z; + + // At this point, the matrix (in rows[]) is orthonormal. + // Check for a coordinate system flip. If the determinant + // is -1, then negate the matrix and the scaling factors. + Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3); + if(dot(Row[0], Pdum3) < 0) + { + for(length_t i = 0; i < 3; i++) + { + Scale[i] *= static_cast(-1); + Row[i] *= static_cast(-1); + } + } + + // Now, get the rotations out, as described in the gem. + + // FIXME - Add the ability to return either quaternions (which are + // easier to recompose with) or Euler angles (rx, ry, rz), which + // are easier for authors to deal with. The latter will only be useful + // when we fix https://bugs.webkit.org/show_bug.cgi?id=23799, so I + // will leave the Euler angle code here for now. + + // ret.rotateY = asin(-Row[0][2]); + // if (cos(ret.rotateY) != 0) { + // ret.rotateX = atan2(Row[1][2], Row[2][2]); + // ret.rotateZ = atan2(Row[0][1], Row[0][0]); + // } else { + // ret.rotateX = atan2(-Row[2][0], Row[1][1]); + // ret.rotateZ = 0; + // } + + int i, j, k = 0; + T root, trace = Row[0].x + Row[1].y + Row[2].z; + if(trace > static_cast(0)) + { + root = sqrt(trace + static_cast(1.0)); + Orientation.w = static_cast(0.5) * root; + root = static_cast(0.5) / root; + Orientation.x = root * (Row[1].z - Row[2].y); + Orientation.y = root * (Row[2].x - Row[0].z); + Orientation.z = root * (Row[0].y - Row[1].x); + } // End if > 0 + else + { + static int Next[3] = {1, 2, 0}; + i = 0; + if(Row[1].y > Row[0].x) i = 1; + if(Row[2].z > Row[i][i]) i = 2; + j = Next[i]; + k = Next[j]; + + root = sqrt(Row[i][i] - Row[j][j] - Row[k][k] + static_cast(1.0)); + + Orientation[i] = static_cast(0.5) * root; + root = static_cast(0.5) / root; + Orientation[j] = root * (Row[i][j] + Row[j][i]); + Orientation[k] = root * (Row[i][k] + Row[k][i]); + Orientation.w = root * (Row[j][k] - Row[k][j]); + } // End if <= 0 + + return true; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_factorisation.hpp b/src/other/manifold/glm/glm/gtx/matrix_factorisation.hpp new file mode 100644 index 00000000000..5a975d60b6c --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_factorisation.hpp @@ -0,0 +1,69 @@ +/// @ref gtx_matrix_factorisation +/// @file glm/gtx/matrix_factorisation.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_factorisation GLM_GTX_matrix_factorisation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions to factor matrices in various forms + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_factorisation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_factorisation extension included") +# endif +#endif + +/* +Suggestions: + - Move helper functions flipud and fliplr to another file: They may be helpful in more general circumstances. + - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc... +*/ + +namespace glm +{ + /// @addtogroup gtx_matrix_factorisation + /// @{ + + /// Flips the matrix rows up and down. + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL mat flipud(mat const& in); + + /// Flips the matrix columns right and left. + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL mat fliplr(mat const& in); + + /// Performs QR factorisation of a matrix. + /// Returns 2 matrices, q and r, such that the columns of q are orthonormal and span the same subspace than those of the input matrix, r is an upper triangular matrix, and q*r=in. + /// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m). + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL void qr_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& q, mat& r); + + /// Performs RQ factorisation of a matrix. + /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in. + /// Note that in the context of RQ factorisation, the diagonal is seen as starting in the lower-right corner of the matrix, instead of the usual upper-left. + /// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m). + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL void rq_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& r, mat& q); + + /// @} +} + +#include "matrix_factorisation.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_factorisation.inl b/src/other/manifold/glm/glm/gtx/matrix_factorisation.inl new file mode 100644 index 00000000000..c479b8ad990 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_factorisation.inl @@ -0,0 +1,84 @@ +/// @ref gtx_matrix_factorisation + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat flipud(mat const& in) + { + mat tin = transpose(in); + tin = fliplr(tin); + mat out = transpose(tin); + + return out; + } + + template + GLM_FUNC_QUALIFIER mat fliplr(mat const& in) + { + mat out; + for (length_t i = 0; i < C; i++) + { + out[i] = in[(C - i) - 1]; + } + + return out; + } + + template + GLM_FUNC_QUALIFIER void qr_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& q, mat& r) + { + // Uses modified Gram-Schmidt method + // Source: https://en.wikipedia.org/wiki/GramSchmidt_process + // And https://en.wikipedia.org/wiki/QR_decomposition + + //For all the linearly independs columns of the input... + // (there can be no more linearly independents columns than there are rows.) + for (length_t i = 0; i < (C < R ? C : R); i++) + { + //Copy in Q the input's i-th column. + q[i] = in[i]; + + //j = [0,i[ + // Make that column orthogonal to all the previous ones by substracting to it the non-orthogonal projection of all the previous columns. + // Also: Fill the zero elements of R + for (length_t j = 0; j < i; j++) + { + q[i] -= dot(q[i], q[j])*q[j]; + r[j][i] = 0; + } + + //Now, Q i-th column is orthogonal to all the previous columns. Normalize it. + q[i] = normalize(q[i]); + + //j = [i,C[ + //Finally, compute the corresponding coefficients of R by computing the projection of the resulting column on the other columns of the input. + for (length_t j = i; j < C; j++) + { + r[j][i] = dot(in[j], q[i]); + } + } + } + + template + GLM_FUNC_QUALIFIER void rq_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& r, mat& q) + { + // From https://en.wikipedia.org/wiki/QR_decomposition: + // The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices. + // QR decomposition is GramSchmidt orthogonalization of columns of A, started from the first column. + // RQ decomposition is GramSchmidt orthogonalization of rows of A, started from the last row. + + mat tin = transpose(in); + tin = fliplr(tin); + + mat tr; + mat<(C < R ? C : R), C, T, Q> tq; + qr_decompose(tin, tq, tr); + + tr = fliplr(tr); + r = transpose(tr); + r = fliplr(r); + + tq = fliplr(tq); + q = transpose(tq); + } +} //namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_interpolation.hpp b/src/other/manifold/glm/glm/gtx/matrix_interpolation.hpp new file mode 100644 index 00000000000..7d5ad4cd9ad --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_interpolation.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_matrix_interpolation +/// @file glm/gtx/matrix_interpolation.hpp +/// @author Ghenadii Ursachi (the.asteroth@gmail.com) +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_interpolation GLM_GTX_matrix_interpolation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Allows to directly interpolate two matrices. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_interpolation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_interpolation extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_interpolation + /// @{ + + /// Get the axis and angle of the rotation from a matrix. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL void axisAngle( + mat<4, 4, T, Q> const& Mat, vec<3, T, Q> & Axis, T & Angle); + + /// Build a matrix from axis and angle. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> axisAngleMatrix( + vec<3, T, Q> const& Axis, T const Angle); + + /// Extracts the rotation part of a matrix. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> extractMatrixRotation( + mat<4, 4, T, Q> const& Mat); + + /// Build a interpolation of 4 * 4 matrixes. + /// From GLM_GTX_matrix_interpolation extension. + /// Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results. + template + GLM_FUNC_DECL mat<4, 4, T, Q> interpolate( + mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const Delta); + + /// @} +}//namespace glm + +#include "matrix_interpolation.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_interpolation.inl b/src/other/manifold/glm/glm/gtx/matrix_interpolation.inl new file mode 100644 index 00000000000..de40b7d745e --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_interpolation.inl @@ -0,0 +1,129 @@ +/// @ref gtx_matrix_interpolation + +#include "../gtc/constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q> & axis, T& angle) + { + T epsilon = static_cast(0.01); + T epsilon2 = static_cast(0.1); + + if((abs(m[1][0] - m[0][1]) < epsilon) && (abs(m[2][0] - m[0][2]) < epsilon) && (abs(m[2][1] - m[1][2]) < epsilon)) + { + if ((abs(m[1][0] + m[0][1]) < epsilon2) && (abs(m[2][0] + m[0][2]) < epsilon2) && (abs(m[2][1] + m[1][2]) < epsilon2) && (abs(m[0][0] + m[1][1] + m[2][2] - static_cast(3.0)) < epsilon2)) + { + angle = static_cast(0.0); + axis.x = static_cast(1.0); + axis.y = static_cast(0.0); + axis.z = static_cast(0.0); + return; + } + angle = static_cast(3.1415926535897932384626433832795); + T xx = (m[0][0] + static_cast(1.0)) * static_cast(0.5); + T yy = (m[1][1] + static_cast(1.0)) * static_cast(0.5); + T zz = (m[2][2] + static_cast(1.0)) * static_cast(0.5); + T xy = (m[1][0] + m[0][1]) * static_cast(0.25); + T xz = (m[2][0] + m[0][2]) * static_cast(0.25); + T yz = (m[2][1] + m[1][2]) * static_cast(0.25); + if((xx > yy) && (xx > zz)) + { + if(xx < epsilon) + { + axis.x = static_cast(0.0); + axis.y = static_cast(0.7071); + axis.z = static_cast(0.7071); + } + else + { + axis.x = sqrt(xx); + axis.y = xy / axis.x; + axis.z = xz / axis.x; + } + } + else if (yy > zz) + { + if(yy < epsilon) + { + axis.x = static_cast(0.7071); + axis.y = static_cast(0.0); + axis.z = static_cast(0.7071); + } + else + { + axis.y = sqrt(yy); + axis.x = xy / axis.y; + axis.z = yz / axis.y; + } + } + else + { + if (zz < epsilon) + { + axis.x = static_cast(0.7071); + axis.y = static_cast(0.7071); + axis.z = static_cast(0.0); + } + else + { + axis.z = sqrt(zz); + axis.x = xz / axis.z; + axis.y = yz / axis.z; + } + } + return; + } + T s = sqrt((m[2][1] - m[1][2]) * (m[2][1] - m[1][2]) + (m[2][0] - m[0][2]) * (m[2][0] - m[0][2]) + (m[1][0] - m[0][1]) * (m[1][0] - m[0][1])); + if (glm::abs(s) < T(0.001)) + s = static_cast(1); + T const angleCos = (m[0][0] + m[1][1] + m[2][2] - static_cast(1)) * static_cast(0.5); + if(angleCos - static_cast(1) < epsilon) + angle = pi() * static_cast(0.25); + else + angle = acos(angleCos); + axis.x = (m[1][2] - m[2][1]) / s; + axis.y = (m[2][0] - m[0][2]) / s; + axis.z = (m[0][1] - m[1][0]) / s; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> axisAngleMatrix(vec<3, T, Q> const& axis, T const angle) + { + T c = cos(angle); + T s = sin(angle); + T t = static_cast(1) - c; + vec<3, T, Q> n = normalize(axis); + + return mat<4, 4, T, Q>( + t * n.x * n.x + c, t * n.x * n.y + n.z * s, t * n.x * n.z - n.y * s, static_cast(0.0), + t * n.x * n.y - n.z * s, t * n.y * n.y + c, t * n.y * n.z + n.x * s, static_cast(0.0), + t * n.x * n.z + n.y * s, t * n.y * n.z - n.x * s, t * n.z * n.z + c, static_cast(0.0), + static_cast(0.0), static_cast(0.0), static_cast(0.0), static_cast(1.0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> extractMatrixRotation(mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0][0], m[0][1], m[0][2], static_cast(0.0), + m[1][0], m[1][1], m[1][2], static_cast(0.0), + m[2][0], m[2][1], m[2][2], static_cast(0.0), + static_cast(0.0), static_cast(0.0), static_cast(0.0), static_cast(1.0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> interpolate(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const delta) + { + mat<4, 4, T, Q> m1rot = extractMatrixRotation(m1); + mat<4, 4, T, Q> dltRotation = m2 * transpose(m1rot); + vec<3, T, Q> dltAxis; + T dltAngle; + axisAngle(dltRotation, dltAxis, dltAngle); + mat<4, 4, T, Q> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot; + out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]); + out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]); + out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]); + return out; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_major_storage.hpp b/src/other/manifold/glm/glm/gtx/matrix_major_storage.hpp new file mode 100644 index 00000000000..8c6bc22d14e --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_major_storage.hpp @@ -0,0 +1,119 @@ +/// @ref gtx_matrix_major_storage +/// @file glm/gtx/matrix_major_storage.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_matrix_major_storage GLM_GTX_matrix_major_storage +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build matrices with specific matrix order, row or column + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_major_storage is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_major_storage extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_major_storage + /// @{ + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2( + mat<2, 2, T, Q> const& m); + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3( + mat<3, 3, T, Q> const& m); + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4( + vec<4, T, Q> const& v1, + vec<4, T, Q> const& v2, + vec<4, T, Q> const& v3, + vec<4, T, Q> const& v4); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4( + mat<4, 4, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2( + mat<2, 2, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3( + mat<3, 3, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4( + vec<4, T, Q> const& v1, + vec<4, T, Q> const& v2, + vec<4, T, Q> const& v3, + vec<4, T, Q> const& v4); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4( + mat<4, 4, T, Q> const& m); + + /// @} +}//namespace glm + +#include "matrix_major_storage.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_major_storage.inl b/src/other/manifold/glm/glm/gtx/matrix_major_storage.inl new file mode 100644 index 00000000000..279dd3433d0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_major_storage.inl @@ -0,0 +1,166 @@ +/// @ref gtx_matrix_major_storage + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2 + ( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2 + ) + { + mat<2, 2, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2( + const mat<2, 2, T, Q>& m) + { + mat<2, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3( + const vec<3, T, Q>& v1, + const vec<3, T, Q>& v2, + const vec<3, T, Q>& v3) + { + mat<3, 3, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[2][0] = v1.z; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + Result[2][1] = v2.z; + Result[0][2] = v3.x; + Result[1][2] = v3.y; + Result[2][2] = v3.z; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3( + const mat<3, 3, T, Q>& m) + { + mat<3, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4( + const vec<4, T, Q>& v1, + const vec<4, T, Q>& v2, + const vec<4, T, Q>& v3, + const vec<4, T, Q>& v4) + { + mat<4, 4, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[2][0] = v1.z; + Result[3][0] = v1.w; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + Result[2][1] = v2.z; + Result[3][1] = v2.w; + Result[0][2] = v3.x; + Result[1][2] = v3.y; + Result[2][2] = v3.z; + Result[3][2] = v3.w; + Result[0][3] = v4.x; + Result[1][3] = v4.y; + Result[2][3] = v4.z; + Result[3][3] = v4.w; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4( + const mat<4, 4, T, Q>& m) + { + mat<4, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + Result[3][3] = m[3][3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2( + const vec<2, T, Q>& v1, + const vec<2, T, Q>& v2) + { + return mat<2, 2, T, Q>(v1, v2); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2( + const mat<2, 2, T, Q>& m) + { + return mat<2, 2, T, Q>(m); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3( + const vec<3, T, Q>& v1, + const vec<3, T, Q>& v2, + const vec<3, T, Q>& v3) + { + return mat<3, 3, T, Q>(v1, v2, v3); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3( + const mat<3, 3, T, Q>& m) + { + return mat<3, 3, T, Q>(m); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4( + const vec<4, T, Q>& v1, + const vec<4, T, Q>& v2, + const vec<4, T, Q>& v3, + const vec<4, T, Q>& v4) + { + return mat<4, 4, T, Q>(v1, v2, v3, v4); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4( + const mat<4, 4, T, Q>& m) + { + return mat<4, 4, T, Q>(m); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_operation.hpp b/src/other/manifold/glm/glm/gtx/matrix_operation.hpp new file mode 100644 index 00000000000..de6ff1f86f4 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_operation.hpp @@ -0,0 +1,103 @@ +/// @ref gtx_matrix_operation +/// @file glm/gtx/matrix_operation.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_operation GLM_GTX_matrix_operation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build diagonal matrices from vectors. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_operation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_operation extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_operation + /// @{ + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> diagonal2x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 3, T, Q> diagonal2x3( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 4, T, Q> diagonal2x4( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 2, T, Q> diagonal3x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> diagonal3x3( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 4, T, Q> diagonal3x4( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 2, T, Q> diagonal4x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 3, T, Q> diagonal4x3( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> diagonal4x4( + vec<4, T, Q> const& v); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m); + + /// @} +}//namespace glm + +#include "matrix_operation.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_operation.inl b/src/other/manifold/glm/glm/gtx/matrix_operation.inl new file mode 100644 index 00000000000..9de83f82367 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_operation.inl @@ -0,0 +1,176 @@ +/// @ref gtx_matrix_operation + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> diagonal2x2 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> diagonal2x3 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> diagonal2x4 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> diagonal3x2 + ( + vec<2, T, Q> const& v + ) + { + mat<3, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> diagonal3x3 + ( + vec<3, T, Q> const& v + ) + { + mat<3, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> diagonal3x4 + ( + vec<3, T, Q> const& v + ) + { + mat<3, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> diagonal4x4 + ( + vec<4, T, Q> const& v + ) + { + mat<4, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + Result[3][3] = v[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> diagonal4x3 + ( + vec<3, T, Q> const& v + ) + { + mat<4, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> diagonal4x2 + ( + vec<2, T, Q> const& v + ) + { + mat<4, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + +m[1][1], -m[1][0], + -m[0][1], +m[0][0]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m) + { + T const m00 = determinant(mat<2, 2, T, Q>(m[1][1], m[2][1], m[1][2], m[2][2])); + T const m01 = determinant(mat<2, 2, T, Q>(m[0][1], m[2][1], m[0][2], m[2][2])); + T const m02 = determinant(mat<2, 2, T, Q>(m[0][1], m[1][1], m[0][2], m[1][2])); + + T const m10 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][2], m[2][2])); + T const m11 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][2], m[2][2])); + T const m12 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][2], m[1][2])); + + T const m20 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][1], m[2][1])); + T const m21 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][1], m[2][1])); + T const m22 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][1], m[1][1])); + + return mat<3, 3, T, Q>( + +m00, -m01, +m02, + -m10, +m11, -m12, + +m20, -m21, +m22); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m) + { + T const m00 = determinant(mat<3, 3, T, Q>(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3])); + T const m01 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3])); + T const m02 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][1], m[3][3])); + T const m03 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2])); + + T const m10 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3])); + T const m11 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3])); + T const m12 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3])); + T const m13 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2])); + + T const m20 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3])); + T const m21 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3])); + T const m22 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3])); + T const m23 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2])); + + T const m30 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3])); + T const m31 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3])); + T const m32 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3])); + T const m33 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2])); + + return mat<4, 4, T, Q>( + +m00, -m01, +m02, -m03, + -m10, +m11, -m12, +m13, + +m20, -m21, +m22, -m23, + -m30, +m31, -m32, +m33); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_query.hpp b/src/other/manifold/glm/glm/gtx/matrix_query.hpp new file mode 100644 index 00000000000..8011b2b1d46 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_query.hpp @@ -0,0 +1,77 @@ +/// @ref gtx_matrix_query +/// @file glm/gtx/matrix_query.hpp +/// +/// @see core (dependence) +/// @see gtx_vector_query (dependence) +/// +/// @defgroup gtx_matrix_query GLM_GTX_matrix_query +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Query to evaluate matrix properties + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/vector_query.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_query is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_query extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_query + /// @{ + + /// Return whether a matrix a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is an identity matrix. + /// From GLM_GTX_matrix_query extension. + template class matType> + GLM_FUNC_DECL bool isIdentity(matType const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is an orthonormalized matrix. + /// From GLM_GTX_matrix_query extension. + template class matType> + GLM_FUNC_DECL bool isOrthogonal(matType const& m, T const& epsilon); + + /// @} +}//namespace glm + +#include "matrix_query.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_query.inl b/src/other/manifold/glm/glm/gtx/matrix_query.inl new file mode 100644 index 00000000000..77bd23108e3 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_query.inl @@ -0,0 +1,113 @@ +/// @ref gtx_matrix_query + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isIdentity(mat const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m[0].length() ; ++i) + { + for(length_t j = 0; result && j < i ; ++j) + result = abs(m[i][j]) <= epsilon; + if(result) + result = abs(m[i][i] - 1) <= epsilon; + for(length_t j = i + 1; result && j < m.length(); ++j) + result = abs(m[i][j]) <= epsilon; + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<2, 2, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<3, 3, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<4, 4, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isOrthogonal(mat const& m, T const& epsilon) + { + bool result = true; + for(length_t i(0); result && i < m.length() - 1; ++i) + for(length_t j(i + 1); result && j < m.length(); ++j) + result = areOrthogonal(m[i], m[j], epsilon); + + if(result) + { + mat tmp = transpose(m); + for(length_t i(0); result && i < m.length() - 1 ; ++i) + for(length_t j(i + 1); result && j < m.length(); ++j) + result = areOrthogonal(tmp[i], tmp[j], epsilon); + } + return result; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/matrix_transform_2d.hpp b/src/other/manifold/glm/glm/gtx/matrix_transform_2d.hpp new file mode 100644 index 00000000000..5f9c5402185 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_transform_2d.hpp @@ -0,0 +1,81 @@ +/// @ref gtx_matrix_transform_2d +/// @file glm/gtx/matrix_transform_2d.hpp +/// @author Miguel Ángel Pérez Martínez +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_transform_2d GLM_GTX_matrix_transform_2d +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines functions that generate common 2d transformation matrices. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../vec2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_transform_2d is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_transform_2d extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_transform_2d + /// @{ + + /// Builds a translation 3 * 3 matrix created from a vector of 2 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a translation vector. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v); + + /// Builds a rotation 3 * 3 matrix created from an angle. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param angle Rotation angle expressed in radians. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate( + mat<3, 3, T, Q> const& m, + T angle); + + /// Builds a scale 3 * 3 matrix created from a vector of 2 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a scale vector. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v); + + /// Builds an horizontal (parallel to the x axis) shear 3 * 3 matrix. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param y Shear factor. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX( + mat<3, 3, T, Q> const& m, + T y); + + /// Builds a vertical (parallel to the y axis) shear 3 * 3 matrix. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param x Shear factor. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY( + mat<3, 3, T, Q> const& m, + T x); + + /// @} +}//namespace glm + +#include "matrix_transform_2d.inl" diff --git a/src/other/manifold/glm/glm/gtx/matrix_transform_2d.inl b/src/other/manifold/glm/glm/gtx/matrix_transform_2d.inl new file mode 100644 index 00000000000..a68d24dc982 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/matrix_transform_2d.inl @@ -0,0 +1,68 @@ +/// @ref gtx_matrix_transform_2d +/// @author Miguel Ángel Pérez Martínez + +#include "../trigonometric.hpp" + +namespace glm +{ + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v) + { + mat<3, 3, T, Q> Result(m); + Result[2] = m[0] * v[0] + m[1] * v[1] + m[2]; + return Result; + } + + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate( + mat<3, 3, T, Q> const& m, + T angle) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + mat<3, 3, T, Q> Result; + Result[0] = m[0] * c + m[1] * s; + Result[1] = m[0] * -s + m[1] * c; + Result[2] = m[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v) + { + mat<3, 3, T, Q> Result; + Result[0] = m[0] * v[0]; + Result[1] = m[1] * v[1]; + Result[2] = m[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX( + mat<3, 3, T, Q> const& m, + T y) + { + mat<3, 3, T, Q> Result(1); + Result[0][1] = y; + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY( + mat<3, 3, T, Q> const& m, + T x) + { + mat<3, 3, T, Q> Result(1); + Result[1][0] = x; + return m * Result; + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/mixed_product.hpp b/src/other/manifold/glm/glm/gtx/mixed_product.hpp new file mode 100644 index 00000000000..b242e357e57 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/mixed_product.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_mixed_product +/// @file glm/gtx/mixed_product.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_mixed_product GLM_GTX_mixed_producte +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Mixed product of 3 vectors. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_mixed_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_mixed_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_mixed_product + /// @{ + + /// @brief Mixed product of 3 vectors (from GLM_GTX_mixed_product extension) + template + GLM_FUNC_DECL T mixedProduct( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + /// @} +}// namespace glm + +#include "mixed_product.inl" diff --git a/src/other/manifold/glm/glm/gtx/mixed_product.inl b/src/other/manifold/glm/glm/gtx/mixed_product.inl new file mode 100644 index 00000000000..e5cdbdb49a2 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/mixed_product.inl @@ -0,0 +1,15 @@ +/// @ref gtx_mixed_product + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T mixedProduct + ( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3 + ) + { + return dot(cross(v1, v2), v3); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/norm.hpp b/src/other/manifold/glm/glm/gtx/norm.hpp new file mode 100644 index 00000000000..dfaebb7a8be --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/norm.hpp @@ -0,0 +1,88 @@ +/// @ref gtx_norm +/// @file glm/gtx/norm.hpp +/// +/// @see core (dependence) +/// @see gtx_quaternion (dependence) +/// @see gtx_component_wise (dependence) +/// +/// @defgroup gtx_norm GLM_GTX_norm +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Various ways to compute vector norms. + +#pragma once + +// Dependency: +#include "../geometric.hpp" +#include "../gtx/quaternion.hpp" +#include "../gtx/component_wise.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_norm is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_norm extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_norm + /// @{ + + /// Returns the squared length of x. + /// From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T length2(vec const& x); + + /// Returns the squared distance between p0 and p1, i.e., length2(p0 - p1). + /// From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T distance2(vec const& p0, vec const& p1); + + //! Returns the L1 norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the L1 norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& v); + + //! Returns the L2 norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the L2 norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x); + + //! Returns the L norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth); + + //! Returns the L norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, unsigned int Depth); + + //! Returns the LMax norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the LMax norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x); + + /// @} +}//namespace glm + +#include "norm.inl" diff --git a/src/other/manifold/glm/glm/gtx/norm.inl b/src/other/manifold/glm/glm/gtx/norm.inl new file mode 100644 index 00000000000..6db561b37e0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/norm.inl @@ -0,0 +1,95 @@ +/// @ref gtx_norm + +#include "../detail/qualifier.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_length2 + { + GLM_FUNC_QUALIFIER static T call(vec const& v) + { + return dot(v, v); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER genType length2(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length2' accepts only floating-point inputs"); + return x * x; + } + + template + GLM_FUNC_QUALIFIER T length2(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length2' accepts only floating-point inputs"); + return detail::compute_length2::value>::call(v); + } + + template + GLM_FUNC_QUALIFIER T distance2(T p0, T p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance2' accepts only floating-point inputs"); + return length2(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T distance2(vec const& p0, vec const& p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance2' accepts only floating-point inputs"); + return length2(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z); + } + + template + GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& v) + { + return abs(v.x) + abs(v.y) + abs(v.z); + } + + template + GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b + ) + { + return length(b - a); + } + + template + GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& v) + { + return length(v); + } + + template + GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth) + { + return pow(pow(abs(y.x - x.x), T(Depth)) + pow(abs(y.y - x.y), T(Depth)) + pow(abs(y.z - x.z), T(Depth)), T(1) / T(Depth)); + } + + template + GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& v, unsigned int Depth) + { + return pow(pow(abs(v.x), T(Depth)) + pow(abs(v.y), T(Depth)) + pow(abs(v.z), T(Depth)), T(1) / T(Depth)); + } + + template + GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return compMax(abs(b - a)); + } + + template + GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& v) + { + return compMax(abs(v)); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/normal.hpp b/src/other/manifold/glm/glm/gtx/normal.hpp new file mode 100644 index 00000000000..068682f75f2 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/normal.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_normal +/// @file glm/gtx/normal.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_normal GLM_GTX_normal +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Compute the normal of a triangle. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_normal is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_normal extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_normal + /// @{ + + /// Computes triangle normal from triangle points. + /// + /// @see gtx_normal + template + GLM_FUNC_DECL vec<3, T, Q> triangleNormal(vec<3, T, Q> const& p1, vec<3, T, Q> const& p2, vec<3, T, Q> const& p3); + + /// @} +}//namespace glm + +#include "normal.inl" diff --git a/src/other/manifold/glm/glm/gtx/normal.inl b/src/other/manifold/glm/glm/gtx/normal.inl new file mode 100644 index 00000000000..74f9fc99458 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/normal.inl @@ -0,0 +1,15 @@ +/// @ref gtx_normal + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> triangleNormal + ( + vec<3, T, Q> const& p1, + vec<3, T, Q> const& p2, + vec<3, T, Q> const& p3 + ) + { + return normalize(cross(p1 - p2, p1 - p3)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/normalize_dot.hpp b/src/other/manifold/glm/glm/gtx/normalize_dot.hpp new file mode 100644 index 00000000000..51958023f01 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/normalize_dot.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_normalize_dot +/// @file glm/gtx/normalize_dot.hpp +/// +/// @see core (dependence) +/// @see gtx_fast_square_root (dependence) +/// +/// @defgroup gtx_normalize_dot GLM_GTX_normalize_dot +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Dot product of vectors that need to be normalize with a single square root. + +#pragma once + +// Dependency: +#include "../gtx/fast_square_root.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_normalize_dot is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_normalize_dot extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_normalize_dot + /// @{ + + /// Normalize parameters and returns the dot product of x and y. + /// It's faster that dot(normalize(x), normalize(y)). + /// + /// @see gtx_normalize_dot extension. + template + GLM_FUNC_DECL T normalizeDot(vec const& x, vec const& y); + + /// Normalize parameters and returns the dot product of x and y. + /// Faster that dot(fastNormalize(x), fastNormalize(y)). + /// + /// @see gtx_normalize_dot extension. + template + GLM_FUNC_DECL T fastNormalizeDot(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "normalize_dot.inl" diff --git a/src/other/manifold/glm/glm/gtx/normalize_dot.inl b/src/other/manifold/glm/glm/gtx/normalize_dot.inl new file mode 100644 index 00000000000..7bcd9a534a8 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/normalize_dot.inl @@ -0,0 +1,16 @@ +/// @ref gtx_normalize_dot + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T normalizeDot(vec const& x, vec const& y) + { + return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); + } + + template + GLM_FUNC_QUALIFIER T fastNormalizeDot(vec const& x, vec const& y) + { + return glm::dot(x, y) * glm::fastInverseSqrt(glm::dot(x, x) * glm::dot(y, y)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/number_precision.hpp b/src/other/manifold/glm/glm/gtx/number_precision.hpp new file mode 100644 index 00000000000..3a606bda040 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/number_precision.hpp @@ -0,0 +1,61 @@ +/// @ref gtx_number_precision +/// @file glm/gtx/number_precision.hpp +/// +/// @see core (dependence) +/// @see gtc_type_precision (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_number_precision GLM_GTX_number_precision +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defined size types. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/type_precision.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_number_precision is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_number_precision extension included") +# endif +#endif + +namespace glm{ +namespace gtx +{ + ///////////////////////////// + // Unsigned int vector types + + /// @addtogroup gtx_number_precision + /// @{ + + typedef u8 u8vec1; //!< \brief 8bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u16 u16vec1; //!< \brief 16bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u32 u32vec1; //!< \brief 32bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u64 u64vec1; //!< \brief 64bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + + ////////////////////// + // Float vector types + + typedef f32 f32vec1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64vec1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + + ////////////////////// + // Float matrix types + + typedef f32 f32mat1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f32 f32mat1x1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64mat1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64mat1x1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + + /// @} +}//namespace gtx +}//namespace glm + +#include "number_precision.inl" diff --git a/src/other/manifold/glm/glm/gtx/number_precision.inl b/src/other/manifold/glm/glm/gtx/number_precision.inl new file mode 100644 index 00000000000..b39d71c3b49 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/number_precision.inl @@ -0,0 +1,6 @@ +/// @ref gtx_number_precision + +namespace glm +{ + +} diff --git a/src/other/manifold/glm/glm/gtx/optimum_pow.hpp b/src/other/manifold/glm/glm/gtx/optimum_pow.hpp new file mode 100644 index 00000000000..9284a474d49 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/optimum_pow.hpp @@ -0,0 +1,54 @@ +/// @ref gtx_optimum_pow +/// @file glm/gtx/optimum_pow.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_optimum_pow GLM_GTX_optimum_pow +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Integer exponentiation of power functions. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_optimum_pow is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_optimum_pow extension included") +# endif +#endif + +namespace glm{ +namespace gtx +{ + /// @addtogroup gtx_optimum_pow + /// @{ + + /// Returns x raised to the power of 2. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow2(genType const& x); + + /// Returns x raised to the power of 3. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow3(genType const& x); + + /// Returns x raised to the power of 4. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow4(genType const& x); + + /// @} +}//namespace gtx +}//namespace glm + +#include "optimum_pow.inl" diff --git a/src/other/manifold/glm/glm/gtx/optimum_pow.inl b/src/other/manifold/glm/glm/gtx/optimum_pow.inl new file mode 100644 index 00000000000..a26c19c18bf --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/optimum_pow.inl @@ -0,0 +1,22 @@ +/// @ref gtx_optimum_pow + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType pow2(genType const& x) + { + return x * x; + } + + template + GLM_FUNC_QUALIFIER genType pow3(genType const& x) + { + return x * x * x; + } + + template + GLM_FUNC_QUALIFIER genType pow4(genType const& x) + { + return (x * x) * (x * x); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/orthonormalize.hpp b/src/other/manifold/glm/glm/gtx/orthonormalize.hpp new file mode 100644 index 00000000000..3e004fb06f9 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/orthonormalize.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_orthonormalize +/// @file glm/gtx/orthonormalize.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_orthonormalize GLM_GTX_orthonormalize +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Orthonormalize matrices. + +#pragma once + +// Dependency: +#include "../vec3.hpp" +#include "../mat3x3.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_orthonormalize is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_orthonormalize extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_orthonormalize + /// @{ + + /// Returns the orthonormalized matrix of m. + /// + /// @see gtx_orthonormalize + template + GLM_FUNC_DECL mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m); + + /// Orthonormalizes x according y. + /// + /// @see gtx_orthonormalize + template + GLM_FUNC_DECL vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + /// @} +}//namespace glm + +#include "orthonormalize.inl" diff --git a/src/other/manifold/glm/glm/gtx/orthonormalize.inl b/src/other/manifold/glm/glm/gtx/orthonormalize.inl new file mode 100644 index 00000000000..cb553ba6215 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/orthonormalize.inl @@ -0,0 +1,29 @@ +/// @ref gtx_orthonormalize + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m) + { + mat<3, 3, T, Q> r = m; + + r[0] = normalize(r[0]); + + T d0 = dot(r[0], r[1]); + r[1] -= r[0] * d0; + r[1] = normalize(r[1]); + + T d1 = dot(r[1], r[2]); + d0 = dot(r[0], r[2]); + r[2] -= r[0] * d0 + r[1] * d1; + r[2] = normalize(r[2]); + + return r; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + return normalize(x - y * dot(y, x)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/perpendicular.hpp b/src/other/manifold/glm/glm/gtx/perpendicular.hpp new file mode 100644 index 00000000000..72b77b6e238 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/perpendicular.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_perpendicular +/// @file glm/gtx/perpendicular.hpp +/// +/// @see core (dependence) +/// @see gtx_projection (dependence) +/// +/// @defgroup gtx_perpendicular GLM_GTX_perpendicular +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Perpendicular of a vector from other one + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/projection.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_perpendicular is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_perpendicular extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_perpendicular + /// @{ + + //! Projects x a perpendicular axis of Normal. + //! From GLM_GTX_perpendicular extension. + template + GLM_FUNC_DECL genType perp(genType const& x, genType const& Normal); + + /// @} +}//namespace glm + +#include "perpendicular.inl" diff --git a/src/other/manifold/glm/glm/gtx/perpendicular.inl b/src/other/manifold/glm/glm/gtx/perpendicular.inl new file mode 100644 index 00000000000..1e72f334230 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/perpendicular.inl @@ -0,0 +1,10 @@ +/// @ref gtx_perpendicular + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType perp(genType const& x, genType const& Normal) + { + return x - proj(x, Normal); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/polar_coordinates.hpp b/src/other/manifold/glm/glm/gtx/polar_coordinates.hpp new file mode 100644 index 00000000000..76beb82bd57 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/polar_coordinates.hpp @@ -0,0 +1,48 @@ +/// @ref gtx_polar_coordinates +/// @file glm/gtx/polar_coordinates.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_polar_coordinates GLM_GTX_polar_coordinates +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Conversion from Euclidean space to polar space and revert. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_polar_coordinates is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_polar_coordinates extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_polar_coordinates + /// @{ + + /// Convert Euclidean to Polar coordinates, x is the latitude, y the longitude and z the xz distance. + /// + /// @see gtx_polar_coordinates + template + GLM_FUNC_DECL vec<3, T, Q> polar( + vec<3, T, Q> const& euclidean); + + /// Convert Polar to Euclidean coordinates. + /// + /// @see gtx_polar_coordinates + template + GLM_FUNC_DECL vec<3, T, Q> euclidean( + vec<2, T, Q> const& polar); + + /// @} +}//namespace glm + +#include "polar_coordinates.inl" diff --git a/src/other/manifold/glm/glm/gtx/polar_coordinates.inl b/src/other/manifold/glm/glm/gtx/polar_coordinates.inl new file mode 100644 index 00000000000..371c8dddebd --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/polar_coordinates.inl @@ -0,0 +1,36 @@ +/// @ref gtx_polar_coordinates + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> polar + ( + vec<3, T, Q> const& euclidean + ) + { + T const Length(length(euclidean)); + vec<3, T, Q> const tmp(euclidean / Length); + T const xz_dist(sqrt(tmp.x * tmp.x + tmp.z * tmp.z)); + + return vec<3, T, Q>( + asin(tmp.y), // latitude + atan(tmp.x, tmp.z), // longitude + xz_dist); // xz distance + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> euclidean + ( + vec<2, T, Q> const& polar + ) + { + T const latitude(polar.x); + T const longitude(polar.y); + + return vec<3, T, Q>( + cos(latitude) * sin(longitude), + sin(latitude), + cos(latitude) * cos(longitude)); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/projection.hpp b/src/other/manifold/glm/glm/gtx/projection.hpp new file mode 100644 index 00000000000..678f3ad5a58 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/projection.hpp @@ -0,0 +1,43 @@ +/// @ref gtx_projection +/// @file glm/gtx/projection.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_projection GLM_GTX_projection +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Projection of a vector to other one + +#pragma once + +// Dependency: +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_projection is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_projection extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_projection + /// @{ + + /// Projects x on Normal. + /// + /// @param[in] x A vector to project + /// @param[in] Normal A normal that doesn't need to be of unit length. + /// + /// @see gtx_projection + template + GLM_FUNC_DECL genType proj(genType const& x, genType const& Normal); + + /// @} +}//namespace glm + +#include "projection.inl" diff --git a/src/other/manifold/glm/glm/gtx/projection.inl b/src/other/manifold/glm/glm/gtx/projection.inl new file mode 100644 index 00000000000..f23f884fb93 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/projection.inl @@ -0,0 +1,10 @@ +/// @ref gtx_projection + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType proj(genType const& x, genType const& Normal) + { + return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/quaternion.hpp b/src/other/manifold/glm/glm/gtx/quaternion.hpp new file mode 100644 index 00000000000..5c2b5ad0b57 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/quaternion.hpp @@ -0,0 +1,174 @@ +/// @ref gtx_quaternion +/// @file glm/gtx/quaternion.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_quaternion GLM_GTX_quaternion +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extented quaternion types and functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/quaternion.hpp" +#include "../ext/quaternion_exponential.hpp" +#include "../gtx/norm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_quaternion extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_quaternion + /// @{ + + /// Create an identity quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL GLM_CONSTEXPR qua quat_identity(); + + /// Compute a cross product between a quaternion and a vector. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> cross( + qua const& q, + vec<3, T, Q> const& v); + + //! Compute a cross product between a vector and a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> cross( + vec<3, T, Q> const& v, + qua const& q); + + //! Compute a point on a path according squad equation. + //! q1 and q2 are control points; s1 and s2 are intermediate control points. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua squad( + qua const& q1, + qua const& q2, + qua const& s1, + qua const& s2, + T const& h); + + //! Returns an intermediate control point for squad interpolation. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua intermediate( + qua const& prev, + qua const& curr, + qua const& next); + + //! Returns quarternion square root. + /// + /// @see gtx_quaternion + //template + //qua sqrt( + // qua const& q); + + //! Rotates a 3 components vector by a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> rotate( + qua const& q, + vec<3, T, Q> const& v); + + /// Rotates a 4 components vector by a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<4, T, Q> rotate( + qua const& q, + vec<4, T, Q> const& v); + + /// Extract the real component of a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL T extractRealComponent( + qua const& q); + + /// Converts a quaternion to a 3 * 3 matrix. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL mat<3, 3, T, Q> toMat3( + qua const& x){return mat3_cast(x);} + + /// Converts a quaternion to a 4 * 4 matrix. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL mat<4, 4, T, Q> toMat4( + qua const& x){return mat4_cast(x);} + + /// Converts a 3 * 3 matrix to a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua toQuat( + mat<3, 3, T, Q> const& x){return quat_cast(x);} + + /// Converts a 4 * 4 matrix to a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua toQuat( + mat<4, 4, T, Q> const& x){return quat_cast(x);} + + /// Quaternion interpolation using the rotation short path. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua shortMix( + qua const& x, + qua const& y, + T const& a); + + /// Quaternion normalized linear interpolation. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua fastMix( + qua const& x, + qua const& y, + T const& a); + + /// Compute the rotation between two vectors. + /// @param orig vector, needs to be normalized + /// @param dest vector, needs to be normalized + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua rotation( + vec<3, T, Q> const& orig, + vec<3, T, Q> const& dest); + + /// Returns the squared length of x. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL GLM_CONSTEXPR T length2(qua const& q); + + /// @} +}//namespace glm + +#include "quaternion.inl" diff --git a/src/other/manifold/glm/glm/gtx/quaternion.inl b/src/other/manifold/glm/glm/gtx/quaternion.inl new file mode 100644 index 00000000000..d125bccc9a7 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/quaternion.inl @@ -0,0 +1,159 @@ +/// @ref gtx_quaternion + +#include +#include "../gtc/constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua quat_identity() + { + return qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& v, qua const& q) + { + return inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> cross(qua const& q, vec<3, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER qua squad + ( + qua const& q1, + qua const& q2, + qua const& s1, + qua const& s2, + T const& h) + { + return mix(mix(q1, q2, h), mix(s1, s2, h), static_cast(2) * (static_cast(1) - h) * h); + } + + template + GLM_FUNC_QUALIFIER qua intermediate + ( + qua const& prev, + qua const& curr, + qua const& next + ) + { + qua invQuat = inverse(curr); + return exp((log(next * invQuat) + log(prev * invQuat)) / static_cast(-4)) * curr; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotate(qua const& q, vec<3, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotate(qua const& q, vec<4, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER T extractRealComponent(qua const& q) + { + T w = static_cast(1) - q.x * q.x - q.y * q.y - q.z * q.z; + if(w < T(0)) + return T(0); + else + return -sqrt(w); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T length2(qua const& q) + { + return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; + } + + template + GLM_FUNC_QUALIFIER qua shortMix(qua const& x, qua const& y, T const& a) + { + if(a <= static_cast(0)) return x; + if(a >= static_cast(1)) return y; + + T fCos = dot(x, y); + qua y2(y); //BUG!!! qua y2; + if(fCos < static_cast(0)) + { + y2 = -y; + fCos = -fCos; + } + + //if(fCos > 1.0f) // problem + T k0, k1; + if(fCos > (static_cast(1) - epsilon())) + { + k0 = static_cast(1) - a; + k1 = static_cast(0) + a; //BUG!!! 1.0f + a; + } + else + { + T fSin = sqrt(T(1) - fCos * fCos); + T fAngle = atan(fSin, fCos); + T fOneOverSin = static_cast(1) / fSin; + k0 = sin((static_cast(1) - a) * fAngle) * fOneOverSin; + k1 = sin((static_cast(0) + a) * fAngle) * fOneOverSin; + } + + return qua( + k0 * x.w + k1 * y2.w, + k0 * x.x + k1 * y2.x, + k0 * x.y + k1 * y2.y, + k0 * x.z + k1 * y2.z); + } + + template + GLM_FUNC_QUALIFIER qua fastMix(qua const& x, qua const& y, T const& a) + { + return glm::normalize(x * (static_cast(1) - a) + (y * a)); + } + + template + GLM_FUNC_QUALIFIER qua rotation(vec<3, T, Q> const& orig, vec<3, T, Q> const& dest) + { + T cosTheta = dot(orig, dest); + vec<3, T, Q> rotationAxis; + + if(cosTheta >= static_cast(1) - epsilon()) { + // orig and dest point in the same direction + return quat_identity(); + } + + if(cosTheta < static_cast(-1) + epsilon()) + { + // special case when vectors in opposite directions : + // there is no "ideal" rotation axis + // So guess one; any will do as long as it's perpendicular to start + // This implementation favors a rotation around the Up axis (Y), + // since it's often what you want to do. + rotationAxis = cross(vec<3, T, Q>(0, 0, 1), orig); + if(length2(rotationAxis) < epsilon()) // bad luck, they were parallel, try again! + rotationAxis = cross(vec<3, T, Q>(1, 0, 0), orig); + + rotationAxis = normalize(rotationAxis); + return angleAxis(pi(), rotationAxis); + } + + // Implementation from Stan Melax's Game Programming Gems 1 article + rotationAxis = cross(orig, dest); + + T s = sqrt((T(1) + cosTheta) * static_cast(2)); + T invs = static_cast(1) / s; + + return qua( + s * static_cast(0.5f), + rotationAxis.x * invs, + rotationAxis.y * invs, + rotationAxis.z * invs); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/range.hpp b/src/other/manifold/glm/glm/gtx/range.hpp new file mode 100644 index 00000000000..93bcb9a65a0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/range.hpp @@ -0,0 +1,98 @@ +/// @ref gtx_range +/// @file glm/gtx/range.hpp +/// @author Joshua Moerman +/// +/// @defgroup gtx_range GLM_GTX_range +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines begin and end for vectors and matrices. Useful for range-based for loop. +/// The range is defined over the elements, not over columns or rows (e.g. mat4 has 16 elements). + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_range is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_range extension included") +# endif +#endif + +#include "../gtc/type_ptr.hpp" +#include "../gtc/vec1.hpp" + +namespace glm +{ + /// @addtogroup gtx_range + /// @{ + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable : 4100) // unreferenced formal parameter +# endif + + template + inline length_t components(vec<1, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<2, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<3, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<4, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(genType const& m) + { + return m.length() * m[0].length(); + } + + template + inline typename genType::value_type const * begin(genType const& v) + { + return value_ptr(v); + } + + template + inline typename genType::value_type const * end(genType const& v) + { + return begin(v) + components(v); + } + + template + inline typename genType::value_type * begin(genType& v) + { + return value_ptr(v); + } + + template + inline typename genType::value_type * end(genType& v) + { + return begin(v) + components(v); + } + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif + + /// @} +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/raw_data.hpp b/src/other/manifold/glm/glm/gtx/raw_data.hpp new file mode 100644 index 00000000000..86cbe77d9ae --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/raw_data.hpp @@ -0,0 +1,51 @@ +/// @ref gtx_raw_data +/// @file glm/gtx/raw_data.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_raw_data GLM_GTX_raw_data +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Projection of a vector to other one + +#pragma once + +// Dependencies +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_raw_data is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_raw_data extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_raw_data + /// @{ + + //! Type for byte numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint8 byte; + + //! Type for word numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint16 word; + + //! Type for dword numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint32 dword; + + //! Type for qword numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint64 qword; + + /// @} +}// namespace glm + +#include "raw_data.inl" diff --git a/src/other/manifold/glm/glm/gtx/raw_data.inl b/src/other/manifold/glm/glm/gtx/raw_data.inl new file mode 100644 index 00000000000..c740317d334 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/raw_data.inl @@ -0,0 +1,2 @@ +/// @ref gtx_raw_data + diff --git a/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.hpp b/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.hpp new file mode 100644 index 00000000000..2103ca08f15 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.hpp @@ -0,0 +1,68 @@ +/// @ref gtx_rotate_normalized_axis +/// @file glm/gtx/rotate_normalized_axis.hpp +/// +/// @see core (dependence) +/// @see gtc_matrix_transform +/// @see gtc_quaternion +/// +/// @defgroup gtx_rotate_normalized_axis GLM_GTX_rotate_normalized_axis +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Quaternions and matrices rotations around normalized axis. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/epsilon.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_rotate_normalized_axis is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_rotate_normalized_axis extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_rotate_normalized_axis + /// @{ + + /// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle. + /// + /// @param m Input matrix multiplied by this rotation matrix. + /// @param angle Rotation angle expressed in radians. + /// @param axis Rotation axis, must be normalized. + /// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double. + /// + /// @see gtx_rotate_normalized_axis + /// @see - rotate(T angle, T x, T y, T z) + /// @see - rotate(mat<4, 4, T, Q> const& m, T angle, T x, T y, T z) + /// @see - rotate(T angle, vec<3, T, Q> const& v) + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotateNormalizedAxis( + mat<4, 4, T, Q> const& m, + T const& angle, + vec<3, T, Q> const& axis); + + /// Rotates a quaternion from a vector of 3 components normalized axis and an angle. + /// + /// @param q Source orientation + /// @param angle Angle expressed in radians. + /// @param axis Normalized axis of the rotation, must be normalized. + /// + /// @see gtx_rotate_normalized_axis + template + GLM_FUNC_DECL qua rotateNormalizedAxis( + qua const& q, + T const& angle, + vec<3, T, Q> const& axis); + + /// @} +}//namespace glm + +#include "rotate_normalized_axis.inl" diff --git a/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.inl b/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.inl new file mode 100644 index 00000000000..b2e9278c0ae --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/rotate_normalized_axis.inl @@ -0,0 +1,58 @@ +/// @ref gtx_rotate_normalized_axis + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotateNormalizedAxis + ( + mat<4, 4, T, Q> const& m, + T const& angle, + vec<3, T, Q> const& v + ) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + vec<3, T, Q> const axis(v); + + vec<3, T, Q> const temp((static_cast(1) - c) * axis); + + mat<4, 4, T, Q> Rotate; + Rotate[0][0] = c + temp[0] * axis[0]; + Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + + Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + Rotate[1][1] = c + temp[1] * axis[1]; + Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + + Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + Rotate[2][2] = c + temp[2] * axis[2]; + + mat<4, 4, T, Q> Result; + Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER qua rotateNormalizedAxis + ( + qua const& q, + T const& angle, + vec<3, T, Q> const& v + ) + { + vec<3, T, Q> const Tmp(v); + + T const AngleRad(angle); + T const Sin = sin(AngleRad * T(0.5)); + + return q * qua(cos(AngleRad * static_cast(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin); + //return gtc::quaternion::cross(q, tquat(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/rotate_vector.hpp b/src/other/manifold/glm/glm/gtx/rotate_vector.hpp new file mode 100644 index 00000000000..dcd5b95a6e5 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/rotate_vector.hpp @@ -0,0 +1,123 @@ +/// @ref gtx_rotate_vector +/// @file glm/gtx/rotate_vector.hpp +/// +/// @see core (dependence) +/// @see gtx_transform (dependence) +/// +/// @defgroup gtx_rotate_vector GLM_GTX_rotate_vector +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Function to directly rotate a vector + +#pragma once + +// Dependency: +#include "../gtx/transform.hpp" +#include "../gtc/epsilon.hpp" +#include "../ext/vector_relational.hpp" +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_rotate_vector is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_rotate_vector extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_rotate_vector + /// @{ + + /// Returns Spherical interpolation between two vectors + /// + /// @param x A first vector + /// @param y A second vector + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @see gtx_rotate_vector + template + GLM_FUNC_DECL vec<3, T, Q> slerp( + vec<3, T, Q> const& x, + vec<3, T, Q> const& y, + T const& a); + + //! Rotate a two dimensional vector. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<2, T, Q> rotate( + vec<2, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around an axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotate( + vec<3, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal); + + //! Rotate a four dimensional vector around an axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotate( + vec<4, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal); + + //! Rotate a three dimensional vector around the X axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateX( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around the Y axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateY( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around the Z axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateZ( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the X axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateX( + vec<4, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the Y axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateY( + vec<4, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the Z axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateZ( + vec<4, T, Q> const& v, + T const& angle); + + //! Build a rotation matrix from a normal and a up vector. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> orientation( + vec<3, T, Q> const& Normal, + vec<3, T, Q> const& Up); + + /// @} +}//namespace glm + +#include "rotate_vector.inl" diff --git a/src/other/manifold/glm/glm/gtx/rotate_vector.inl b/src/other/manifold/glm/glm/gtx/rotate_vector.inl new file mode 100644 index 00000000000..f8136e765e0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/rotate_vector.inl @@ -0,0 +1,187 @@ +/// @ref gtx_rotate_vector + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> slerp + ( + vec<3, T, Q> const& x, + vec<3, T, Q> const& y, + T const& a + ) + { + // get cosine of angle between vectors (-1 -> 1) + T CosAlpha = dot(x, y); + // get angle (0 -> pi) + T Alpha = acos(CosAlpha); + // get sine of angle between vectors (0 -> 1) + T SinAlpha = sin(Alpha); + // this breaks down when SinAlpha = 0, i.e. Alpha = 0 or pi + T t1 = sin((static_cast(1) - a) * Alpha) / SinAlpha; + T t2 = sin(a * Alpha) / SinAlpha; + + // interpolate src vectors + return x * t1 + y * t2; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> rotate + ( + vec<2, T, Q> const& v, + T const& angle + ) + { + vec<2, T, Q> Result; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotate + ( + vec<3, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal + ) + { + return mat<3, 3, T, Q>(glm::rotate(angle, normal)) * v; + } + /* + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateGTX( + const vec<3, T, Q>& x, + T angle, + const vec<3, T, Q>& normal) + { + const T Cos = cos(radians(angle)); + const T Sin = sin(radians(angle)); + return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin; + } + */ + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotate + ( + vec<4, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal + ) + { + return rotate(angle, normal) * v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateX + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result(v); + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.y = v.y * Cos - v.z * Sin; + Result.z = v.y * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateY + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos + v.z * Sin; + Result.z = -v.x * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateZ + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateX + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.y = v.y * Cos - v.z * Sin; + Result.z = v.y * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateY + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos + v.z * Sin; + Result.z = -v.x * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateZ + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientation + ( + vec<3, T, Q> const& Normal, + vec<3, T, Q> const& Up + ) + { + if(all(equal(Normal, Up, epsilon()))) + return mat<4, 4, T, Q>(static_cast(1)); + + vec<3, T, Q> RotationAxis = cross(Up, Normal); + T Angle = acos(dot(Normal, Up)); + + return rotate(Angle, RotationAxis); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/scalar_multiplication.hpp b/src/other/manifold/glm/glm/gtx/scalar_multiplication.hpp new file mode 100644 index 00000000000..496ba193f19 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/scalar_multiplication.hpp @@ -0,0 +1,75 @@ +/// @ref gtx +/// @file glm/gtx/scalar_multiplication.hpp +/// @author Joshua Moerman +/// +/// Include to use the features of this extension. +/// +/// Enables scalar multiplication for all types +/// +/// Since GLSL is very strict about types, the following (often used) combinations do not work: +/// double * vec4 +/// int * vec4 +/// vec4 / int +/// So we'll fix that! Of course "float * vec4" should remain the same (hence the enable_if magic) + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_scalar_multiplication is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_scalar_multiplication extension included") +# endif +#endif + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../mat2x2.hpp" +#include + +namespace glm +{ + template + using return_type_scalar_multiplication = typename std::enable_if< + !std::is_same::value // T may not be a float + && std::is_arithmetic::value, Vec // But it may be an int or double (no vec3 or mat3, ...) + >::type; + +#define GLM_IMPLEMENT_SCAL_MULT(Vec) \ + template \ + return_type_scalar_multiplication \ + operator*(T const& s, Vec rh){ \ + return rh *= static_cast(s); \ + } \ + \ + template \ + return_type_scalar_multiplication \ + operator*(Vec lh, T const& s){ \ + return lh *= static_cast(s); \ + } \ + \ + template \ + return_type_scalar_multiplication \ + operator/(Vec lh, T const& s){ \ + return lh *= 1.0f / static_cast(s); \ + } + +GLM_IMPLEMENT_SCAL_MULT(vec2) +GLM_IMPLEMENT_SCAL_MULT(vec3) +GLM_IMPLEMENT_SCAL_MULT(vec4) + +GLM_IMPLEMENT_SCAL_MULT(mat2) +GLM_IMPLEMENT_SCAL_MULT(mat2x3) +GLM_IMPLEMENT_SCAL_MULT(mat2x4) +GLM_IMPLEMENT_SCAL_MULT(mat3x2) +GLM_IMPLEMENT_SCAL_MULT(mat3) +GLM_IMPLEMENT_SCAL_MULT(mat3x4) +GLM_IMPLEMENT_SCAL_MULT(mat4x2) +GLM_IMPLEMENT_SCAL_MULT(mat4x3) +GLM_IMPLEMENT_SCAL_MULT(mat4) + +#undef GLM_IMPLEMENT_SCAL_MULT +} // namespace glm diff --git a/src/other/manifold/glm/glm/gtx/scalar_relational.hpp b/src/other/manifold/glm/glm/gtx/scalar_relational.hpp new file mode 100644 index 00000000000..8be9c57b8b3 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/scalar_relational.hpp @@ -0,0 +1,36 @@ +/// @ref gtx_scalar_relational +/// @file glm/gtx/scalar_relational.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_scalar_relational GLM_GTX_scalar_relational +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extend a position from a source to a position at a defined length. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extend is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extend extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_scalar_relational + /// @{ + + + + /// @} +}//namespace glm + +#include "scalar_relational.inl" diff --git a/src/other/manifold/glm/glm/gtx/scalar_relational.inl b/src/other/manifold/glm/glm/gtx/scalar_relational.inl new file mode 100644 index 00000000000..c2a121cff97 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/scalar_relational.inl @@ -0,0 +1,88 @@ +/// @ref gtx_scalar_relational + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool lessThan + ( + T const& x, + T const& y + ) + { + return x < y; + } + + template + GLM_FUNC_QUALIFIER bool lessThanEqual + ( + T const& x, + T const& y + ) + { + return x <= y; + } + + template + GLM_FUNC_QUALIFIER bool greaterThan + ( + T const& x, + T const& y + ) + { + return x > y; + } + + template + GLM_FUNC_QUALIFIER bool greaterThanEqual + ( + T const& x, + T const& y + ) + { + return x >= y; + } + + template + GLM_FUNC_QUALIFIER bool equal + ( + T const& x, + T const& y + ) + { + return detail::compute_equal::is_iec559>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER bool notEqual + ( + T const& x, + T const& y + ) + { + return !detail::compute_equal::is_iec559>::call(x, y); + } + + GLM_FUNC_QUALIFIER bool any + ( + bool const& x + ) + { + return x; + } + + GLM_FUNC_QUALIFIER bool all + ( + bool const& x + ) + { + return x; + } + + GLM_FUNC_QUALIFIER bool not_ + ( + bool const& x + ) + { + return !x; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/spline.hpp b/src/other/manifold/glm/glm/gtx/spline.hpp new file mode 100644 index 00000000000..731c979e358 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/spline.hpp @@ -0,0 +1,65 @@ +/// @ref gtx_spline +/// @file glm/gtx/spline.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_spline GLM_GTX_spline +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Spline functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/optimum_pow.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_spline is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_spline extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_spline + /// @{ + + /// Return a point from a catmull rom curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType catmullRom( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s); + + /// Return a point from a hermite curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType hermite( + genType const& v1, + genType const& t1, + genType const& v2, + genType const& t2, + typename genType::value_type const& s); + + /// Return a point from a cubic curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType cubic( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s); + + /// @} +}//namespace glm + +#include "spline.inl" diff --git a/src/other/manifold/glm/glm/gtx/spline.inl b/src/other/manifold/glm/glm/gtx/spline.inl new file mode 100644 index 00000000000..c3fd0565629 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/spline.inl @@ -0,0 +1,60 @@ +/// @ref gtx_spline + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType catmullRom + ( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s + ) + { + typename genType::value_type s2 = pow2(s); + typename genType::value_type s3 = pow3(s); + + typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s; + typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2); + typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s; + typename genType::value_type f4 = s3 - s2; + + return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2); + + } + + template + GLM_FUNC_QUALIFIER genType hermite + ( + genType const& v1, + genType const& t1, + genType const& v2, + genType const& t2, + typename genType::value_type const& s + ) + { + typename genType::value_type s2 = pow2(s); + typename genType::value_type s3 = pow3(s); + + typename genType::value_type f1 = typename genType::value_type(2) * s3 - typename genType::value_type(3) * s2 + typename genType::value_type(1); + typename genType::value_type f2 = typename genType::value_type(-2) * s3 + typename genType::value_type(3) * s2; + typename genType::value_type f3 = s3 - typename genType::value_type(2) * s2 + s; + typename genType::value_type f4 = s3 - s2; + + return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2; + } + + template + GLM_FUNC_QUALIFIER genType cubic + ( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s + ) + { + return ((v1 * s + v2) * s + v3) * s + v4; + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/std_based_type.hpp b/src/other/manifold/glm/glm/gtx/std_based_type.hpp new file mode 100644 index 00000000000..cd3be8cb789 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/std_based_type.hpp @@ -0,0 +1,68 @@ +/// @ref gtx_std_based_type +/// @file glm/gtx/std_based_type.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_std_based_type GLM_GTX_std_based_type +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Adds vector types based on STL value types. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_std_based_type is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_std_based_type extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_std_based_type + /// @{ + + /// Vector type based of one std::size_t component. + /// @see GLM_GTX_std_based_type + typedef vec<1, std::size_t, defaultp> size1; + + /// Vector type based of two std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<2, std::size_t, defaultp> size2; + + /// Vector type based of three std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<3, std::size_t, defaultp> size3; + + /// Vector type based of four std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<4, std::size_t, defaultp> size4; + + /// Vector type based of one std::size_t component. + /// @see GLM_GTX_std_based_type + typedef vec<1, std::size_t, defaultp> size1_t; + + /// Vector type based of two std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<2, std::size_t, defaultp> size2_t; + + /// Vector type based of three std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<3, std::size_t, defaultp> size3_t; + + /// Vector type based of four std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<4, std::size_t, defaultp> size4_t; + + /// @} +}//namespace glm + +#include "std_based_type.inl" diff --git a/src/other/manifold/glm/glm/gtx/std_based_type.inl b/src/other/manifold/glm/glm/gtx/std_based_type.inl new file mode 100644 index 00000000000..9c34bdb6e0f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/std_based_type.inl @@ -0,0 +1,6 @@ +/// @ref gtx_std_based_type + +namespace glm +{ + +} diff --git a/src/other/manifold/glm/glm/gtx/string_cast.hpp b/src/other/manifold/glm/glm/gtx/string_cast.hpp new file mode 100644 index 00000000000..27846bf89f0 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/string_cast.hpp @@ -0,0 +1,52 @@ +/// @ref gtx_string_cast +/// @file glm/gtx/string_cast.hpp +/// +/// @see core (dependence) +/// @see gtx_integer (dependence) +/// @see gtx_quaternion (dependence) +/// +/// @defgroup gtx_string_cast GLM_GTX_string_cast +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Setup strings for GLM type values +/// +/// This extension is not supported with CUDA + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/type_precision.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" +#include +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_string_cast is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_string_cast extension included") +# endif +#endif + +#if(GLM_COMPILER & GLM_COMPILER_CUDA) +# error "GLM_GTX_string_cast is not supported on CUDA compiler" +#endif + +namespace glm +{ + /// @addtogroup gtx_string_cast + /// @{ + + /// Create a string from a GLM vector or matrix typed variable. + /// @see gtx_string_cast extension. + template + GLM_FUNC_DECL std::string to_string(genType const& x); + + /// @} +}//namespace glm + +#include "string_cast.inl" diff --git a/src/other/manifold/glm/glm/gtx/string_cast.inl b/src/other/manifold/glm/glm/gtx/string_cast.inl new file mode 100644 index 00000000000..f67751d41c2 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/string_cast.inl @@ -0,0 +1,492 @@ +/// @ref gtx_string_cast + +#include +#include + +namespace glm{ +namespace detail +{ + template + struct cast + { + typedef T value_type; + }; + + template <> + struct cast + { + typedef double value_type; + }; + + GLM_FUNC_QUALIFIER std::string format(const char* msg, ...) + { + std::size_t const STRING_BUFFER(4096); + char text[STRING_BUFFER]; + va_list list; + + if(msg == GLM_NULLPTR) + return std::string(); + + va_start(list, msg); +# if (GLM_COMPILER & GLM_COMPILER_VC) + vsprintf_s(text, STRING_BUFFER, msg, list); +# else// + std::vsprintf(text, msg, list); +# endif// + va_end(list); + + return std::string(text); + } + + static const char* LabelTrue = "true"; + static const char* LabelFalse = "false"; + + template + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%d";} + }; + + template + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%f";} + }; + +# if GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC + template<> + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%lld";} + }; + + template<> + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%lld";} + }; +# endif//GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC + + template + struct prefix{}; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "d";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "b";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u8";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i8";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u16";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i16";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u64";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i64";} + }; + + template + struct compute_to_string + {}; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<1, bool, Q> const& x) + { + return detail::format("bvec1(%s)", + x[0] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<2, bool, Q> const& x) + { + return detail::format("bvec2(%s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<3, bool, Q> const& x) + { + return detail::format("bvec3(%s, %s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse, + x[2] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<4, bool, Q> const& x) + { + return detail::format("bvec4(%s, %s, %s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse, + x[2] ? detail::LabelTrue : detail::LabelFalse, + x[3] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<1, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec1(%s)", + PrefixStr, + LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec2(%s, %s)", + PrefixStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec3(%s, %s, %s)", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1]), + static_cast::value_type>(x[2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec4(%s, %s, %s, %s)", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1]), + static_cast::value_type>(x[2]), + static_cast::value_type>(x[3])); + } + }; + + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x2((%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x3((%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x4((%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x2((%s, %s), (%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), static_cast::value_type>(x[2][3])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x2((%s, %s), (%s, %s), (%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1]), static_cast::value_type>(x[3][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), static_cast::value_type>(x[2][3]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1]), static_cast::value_type>(x[3][2]), static_cast::value_type>(x[3][3])); + } + }; + + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(qua const& q) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%squat(%s, {%s, %s, %s})", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(q.w), + static_cast::value_type>(q.x), + static_cast::value_type>(q.y), + static_cast::value_type>(q.z)); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(tdualquat const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%sdualquat((%s, {%s, %s, %s}), (%s, {%s, %s, %s}))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x.real.w), + static_cast::value_type>(x.real.x), + static_cast::value_type>(x.real.y), + static_cast::value_type>(x.real.z), + static_cast::value_type>(x.dual.w), + static_cast::value_type>(x.dual.x), + static_cast::value_type>(x.dual.y), + static_cast::value_type>(x.dual.z)); + } + }; + +}//namespace detail + +template +GLM_FUNC_QUALIFIER std::string to_string(matType const& x) +{ + return detail::compute_to_string::call(x); +} + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/texture.hpp b/src/other/manifold/glm/glm/gtx/texture.hpp new file mode 100644 index 00000000000..20585e68ce1 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/texture.hpp @@ -0,0 +1,46 @@ +/// @ref gtx_texture +/// @file glm/gtx/texture.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_texture GLM_GTX_texture +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Wrapping mode of texture coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/integer.hpp" +#include "../gtx/component_wise.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_texture is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_texture extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_texture + /// @{ + + /// Compute the number of mipmaps levels necessary to create a mipmap complete texture + /// + /// @param Extent Extent of the texture base level mipmap + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + template + T levels(vec const& Extent); + + /// @} +}// namespace glm + +#include "texture.inl" + diff --git a/src/other/manifold/glm/glm/gtx/texture.inl b/src/other/manifold/glm/glm/gtx/texture.inl new file mode 100644 index 00000000000..593c826141b --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/texture.inl @@ -0,0 +1,17 @@ +/// @ref gtx_texture + +namespace glm +{ + template + inline T levels(vec const& Extent) + { + return glm::log2(compMax(Extent)) + static_cast(1); + } + + template + inline T levels(T Extent) + { + return vec<1, T, defaultp>(Extent).x; + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtx/transform.hpp b/src/other/manifold/glm/glm/gtx/transform.hpp new file mode 100644 index 00000000000..0279fc8bd32 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/transform.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_transform +/// @file glm/gtx/transform.hpp +/// +/// @see core (dependence) +/// @see gtc_matrix_transform (dependence) +/// @see gtx_transform +/// @see gtx_transform2 +/// +/// @defgroup gtx_transform GLM_GTX_transform +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add transformation matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_transform is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_transform extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_transform + /// @{ + + /// Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> translate( + vec<3, T, Q> const& v); + + /// Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotate( + T angle, + vec<3, T, Q> const& v); + + /// Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> scale( + vec<3, T, Q> const& v); + + /// @} +}// namespace glm + +#include "transform.inl" diff --git a/src/other/manifold/glm/glm/gtx/transform.inl b/src/other/manifold/glm/glm/gtx/transform.inl new file mode 100644 index 00000000000..48ee6801b65 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/transform.inl @@ -0,0 +1,23 @@ +/// @ref gtx_transform + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(vec<3, T, Q> const& v) + { + return translate(mat<4, 4, T, Q>(static_cast(1)), v); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(T angle, vec<3, T, Q> const& v) + { + return rotate(mat<4, 4, T, Q>(static_cast(1)), angle, v); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(vec<3, T, Q> const& v) + { + return scale(mat<4, 4, T, Q>(static_cast(1)), v); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/transform2.hpp b/src/other/manifold/glm/glm/gtx/transform2.hpp new file mode 100644 index 00000000000..0d8ba9d90bc --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/transform2.hpp @@ -0,0 +1,89 @@ +/// @ref gtx_transform2 +/// @file glm/gtx/transform2.hpp +/// +/// @see core (dependence) +/// @see gtx_transform (dependence) +/// +/// @defgroup gtx_transform2 GLM_GTX_transform2 +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add extra transformation matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_transform2 is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_transform2 extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_transform2 + /// @{ + + //! Transforms a matrix with a shearing on X axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> shearX2D(mat<3, 3, T, Q> const& m, T y); + + //! Transforms a matrix with a shearing on Y axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> shearY2D(mat<3, 3, T, Q> const& m, T x); + + //! Transforms a matrix with a shearing on X axis + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearX3D(mat<4, 4, T, Q> const& m, T y, T z); + + //! Transforms a matrix with a shearing on Y axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearY3D(mat<4, 4, T, Q> const& m, T x, T z); + + //! Transforms a matrix with a shearing on Z axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearZ3D(mat<4, 4, T, Q> const& m, T x, T y); + + //template GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear(const mat<4, 4, T, Q> & m, shearPlane, planePoint, angle) + // Identity + tan(angle) * cross(Normal, OnPlaneVector) 0 + // - dot(PointOnPlane, normal) * OnPlaneVector 1 + + // Reflect functions seem to don't work + //template mat<3, 3, T, Q> reflect2D(const mat<3, 3, T, Q> & m, const vec<3, T, Q>& normal){return reflect2DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension) + //template mat<4, 4, T, Q> reflect3D(const mat<4, 4, T, Q> & m, const vec<3, T, Q>& normal){return reflect3DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension) + + //! Build planar projection matrix along normal axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> proj2D(mat<3, 3, T, Q> const& m, vec<3, T, Q> const& normal); + + //! Build planar projection matrix along normal axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> proj3D(mat<4, 4, T, Q> const & m, vec<3, T, Q> const& normal); + + //! Build a scale bias matrix. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> scaleBias(T scale, T bias); + + //! Build a scale bias matrix. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> scaleBias(mat<4, 4, T, Q> const& m, T scale, T bias); + + /// @} +}// namespace glm + +#include "transform2.inl" diff --git a/src/other/manifold/glm/glm/gtx/transform2.inl b/src/other/manifold/glm/glm/gtx/transform2.inl new file mode 100644 index 00000000000..2b53198b330 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/transform2.inl @@ -0,0 +1,125 @@ +/// @ref gtx_transform2 + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX2D(mat<3, 3, T, Q> const& m, T s) + { + mat<3, 3, T, Q> r(1); + r[1][0] = s; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY2D(mat<3, 3, T, Q> const& m, T s) + { + mat<3, 3, T, Q> r(1); + r[0][1] = s; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearX3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[0][1] = s; + r[0][2] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearY3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[1][0] = s; + r[1][2] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearZ3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[2][0] = s; + r[2][1] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> reflect2D(mat<3, 3, T, Q> const& m, vec<3, T, Q> const& normal) + { + mat<3, 3, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - static_cast(2) * normal.x * normal.x; + r[0][1] = -static_cast(2) * normal.x * normal.y; + r[1][0] = -static_cast(2) * normal.x * normal.y; + r[1][1] = static_cast(1) - static_cast(2) * normal.y * normal.y; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> reflect3D(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& normal) + { + mat<4, 4, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - static_cast(2) * normal.x * normal.x; + r[0][1] = -static_cast(2) * normal.x * normal.y; + r[0][2] = -static_cast(2) * normal.x * normal.z; + + r[1][0] = -static_cast(2) * normal.x * normal.y; + r[1][1] = static_cast(1) - static_cast(2) * normal.y * normal.y; + r[1][2] = -static_cast(2) * normal.y * normal.z; + + r[2][0] = -static_cast(2) * normal.x * normal.z; + r[2][1] = -static_cast(2) * normal.y * normal.z; + r[2][2] = static_cast(1) - static_cast(2) * normal.z * normal.z; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> proj2D( + const mat<3, 3, T, Q>& m, + const vec<3, T, Q>& normal) + { + mat<3, 3, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - normal.x * normal.x; + r[0][1] = - normal.x * normal.y; + r[1][0] = - normal.x * normal.y; + r[1][1] = static_cast(1) - normal.y * normal.y; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> proj3D( + const mat<4, 4, T, Q>& m, + const vec<3, T, Q>& normal) + { + mat<4, 4, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - normal.x * normal.x; + r[0][1] = - normal.x * normal.y; + r[0][2] = - normal.x * normal.z; + r[1][0] = - normal.x * normal.y; + r[1][1] = static_cast(1) - normal.y * normal.y; + r[1][2] = - normal.y * normal.z; + r[2][0] = - normal.x * normal.z; + r[2][1] = - normal.y * normal.z; + r[2][2] = static_cast(1) - normal.z * normal.z; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scaleBias(T scale, T bias) + { + mat<4, 4, T, Q> result; + result[3] = vec<4, T, Q>(vec<3, T, Q>(bias), static_cast(1)); + result[0][0] = scale; + result[1][1] = scale; + result[2][2] = scale; + return result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scaleBias(mat<4, 4, T, Q> const& m, T scale, T bias) + { + return m * scaleBias(scale, bias); + } +}//namespace glm + diff --git a/src/other/manifold/glm/glm/gtx/type_aligned.hpp b/src/other/manifold/glm/glm/gtx/type_aligned.hpp new file mode 100644 index 00000000000..2ae522c1fc7 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/type_aligned.hpp @@ -0,0 +1,982 @@ +/// @ref gtx_type_aligned +/// @file glm/gtx/type_aligned.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_type_aligned GLM_GTX_type_aligned +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines aligned types. + +#pragma once + +// Dependency: +#include "../gtc/type_precision.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_type_aligned is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_type_aligned extension included") +# endif +#endif + +namespace glm +{ + /////////////////////////// + // Signed int vector types + + /// @addtogroup gtx_type_aligned + /// @{ + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int8, aligned_lowp_int8, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int16, aligned_lowp_int16, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int32, aligned_lowp_int32, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int64, aligned_lowp_int64, 8); + + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int8_t, aligned_lowp_int8_t, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int16_t, aligned_lowp_int16_t, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int32_t, aligned_lowp_int32_t, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int64_t, aligned_lowp_int64_t, 8); + + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i8, aligned_lowp_i8, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i16, aligned_lowp_i16, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i32, aligned_lowp_i32, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i64, aligned_lowp_i64, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int8, aligned_mediump_int8, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int16, aligned_mediump_int16, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int32, aligned_mediump_int32, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int64, aligned_mediump_int64, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int8_t, aligned_mediump_int8_t, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int16_t, aligned_mediump_int16_t, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int32_t, aligned_mediump_int32_t, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int64_t, aligned_mediump_int64_t, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i8, aligned_mediump_i8, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i16, aligned_mediump_i16, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i32, aligned_mediump_i32, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i64, aligned_mediump_i64, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int8, aligned_highp_int8, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int16, aligned_highp_int16, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int32, aligned_highp_int32, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int64, aligned_highp_int64, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int8_t, aligned_highp_int8_t, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int16_t, aligned_highp_int16_t, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int32_t, aligned_highp_int32_t, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int64_t, aligned_highp_int64_t, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i8, aligned_highp_i8, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i16, aligned_highp_i16, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i32, aligned_highp_i32, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i64, aligned_highp_i64, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int8, aligned_int8, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int16, aligned_int16, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int32, aligned_int32, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int64, aligned_int64, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int8_t, aligned_int8_t, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int16_t, aligned_int16_t, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int32_t, aligned_int32_t, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int64_t, aligned_int64_t, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8, aligned_i8, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16, aligned_i16, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32, aligned_i32, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64, aligned_i64, 8); + + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec1, aligned_ivec1, 4); + + /// Default qualifier 32 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec2, aligned_ivec2, 8); + + /// Default qualifier 32 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec3, aligned_ivec3, 16); + + /// Default qualifier 32 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec4, aligned_ivec4, 16); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec1, aligned_i8vec1, 1); + + /// Default qualifier 8 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec2, aligned_i8vec2, 2); + + /// Default qualifier 8 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec3, aligned_i8vec3, 4); + + /// Default qualifier 8 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec4, aligned_i8vec4, 4); + + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec1, aligned_i16vec1, 2); + + /// Default qualifier 16 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec2, aligned_i16vec2, 4); + + /// Default qualifier 16 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec3, aligned_i16vec3, 8); + + /// Default qualifier 16 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec4, aligned_i16vec4, 8); + + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec1, aligned_i32vec1, 4); + + /// Default qualifier 32 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec2, aligned_i32vec2, 8); + + /// Default qualifier 32 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec3, aligned_i32vec3, 16); + + /// Default qualifier 32 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec4, aligned_i32vec4, 16); + + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec1, aligned_i64vec1, 8); + + /// Default qualifier 64 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec2, aligned_i64vec2, 16); + + /// Default qualifier 64 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec3, aligned_i64vec3, 32); + + /// Default qualifier 64 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec4, aligned_i64vec4, 32); + + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint8, aligned_lowp_uint8, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint16, aligned_lowp_uint16, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint32, aligned_lowp_uint32, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint64, aligned_lowp_uint64, 8); + + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint8_t, aligned_lowp_uint8_t, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint16_t, aligned_lowp_uint16_t, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint32_t, aligned_lowp_uint32_t, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint64_t, aligned_lowp_uint64_t, 8); + + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u8, aligned_lowp_u8, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u16, aligned_lowp_u16, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u32, aligned_lowp_u32, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u64, aligned_lowp_u64, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint8, aligned_mediump_uint8, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint16, aligned_mediump_uint16, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint32, aligned_mediump_uint32, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint64, aligned_mediump_uint64, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint8_t, aligned_mediump_uint8_t, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint16_t, aligned_mediump_uint16_t, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint32_t, aligned_mediump_uint32_t, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint64_t, aligned_mediump_uint64_t, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u8, aligned_mediump_u8, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u16, aligned_mediump_u16, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u32, aligned_mediump_u32, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u64, aligned_mediump_u64, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint8, aligned_highp_uint8, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint16, aligned_highp_uint16, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint32, aligned_highp_uint32, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint64, aligned_highp_uint64, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint8_t, aligned_highp_uint8_t, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint16_t, aligned_highp_uint16_t, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint32_t, aligned_highp_uint32_t, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint64_t, aligned_highp_uint64_t, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u8, aligned_highp_u8, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u16, aligned_highp_u16, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u32, aligned_highp_u32, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u64, aligned_highp_u64, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint8, aligned_uint8, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint16, aligned_uint16, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint32, aligned_uint32, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint64, aligned_uint64, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint8_t, aligned_uint8_t, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint16_t, aligned_uint16_t, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint32_t, aligned_uint32_t, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint64_t, aligned_uint64_t, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8, aligned_u8, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16, aligned_u16, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32, aligned_u32, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64, aligned_u64, 8); + + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec1, aligned_uvec1, 4); + + /// Default qualifier 32 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec2, aligned_uvec2, 8); + + /// Default qualifier 32 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec3, aligned_uvec3, 16); + + /// Default qualifier 32 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec4, aligned_uvec4, 16); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec1, aligned_u8vec1, 1); + + /// Default qualifier 8 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec2, aligned_u8vec2, 2); + + /// Default qualifier 8 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec3, aligned_u8vec3, 4); + + /// Default qualifier 8 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec4, aligned_u8vec4, 4); + + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec1, aligned_u16vec1, 2); + + /// Default qualifier 16 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec2, aligned_u16vec2, 4); + + /// Default qualifier 16 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec3, aligned_u16vec3, 8); + + /// Default qualifier 16 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec4, aligned_u16vec4, 8); + + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec1, aligned_u32vec1, 4); + + /// Default qualifier 32 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec2, aligned_u32vec2, 8); + + /// Default qualifier 32 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec3, aligned_u32vec3, 16); + + /// Default qualifier 32 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec4, aligned_u32vec4, 16); + + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec1, aligned_u64vec1, 8); + + /// Default qualifier 64 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec2, aligned_u64vec2, 16); + + /// Default qualifier 64 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec3, aligned_u64vec3, 32); + + /// Default qualifier 64 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec4, aligned_u64vec4, 32); + + + ////////////////////// + // Float vector types + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32, aligned_float32, 4); + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32_t, aligned_float32_t, 4); + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32, aligned_f32, 4); + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64, aligned_float64, 8); + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64_t, aligned_float64_t, 8); + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64, aligned_f64, 8); + +# endif//GLM_FORCE_SINGLE_ONLY + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec1, aligned_vec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec2, aligned_vec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec3, aligned_vec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec4, aligned_vec4, 16); + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec1, aligned_fvec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec2, aligned_fvec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec3, aligned_fvec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec4, aligned_fvec4, 16); + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec1, aligned_f32vec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec2, aligned_f32vec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec3, aligned_f32vec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec4, aligned_f32vec4, 16); + + + /// Double-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec1, aligned_dvec1, 8); + + /// Double-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec2, aligned_dvec2, 16); + + /// Double-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec3, aligned_dvec3, 32); + + /// Double-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec4, aligned_dvec4, 32); + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec1, aligned_f64vec1, 8); + + /// Double-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec2, aligned_f64vec2, 16); + + /// Double-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec3, aligned_f64vec3, 32); + + /// Double-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec4, aligned_f64vec4, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + ////////////////////// + // Float matrix types + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1 mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat2, aligned_mat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat3, aligned_mat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat4, aligned_mat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat2x2, aligned_mat2x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat3x3, aligned_mat3x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat4x4, aligned_mat4x4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 fmat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x2, aligned_fmat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x3, aligned_fmat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x4, aligned_fmat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f32 fmat1x1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x2, aligned_fmat2x2, 16); + + /// Single-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x3, aligned_fmat2x3, 16); + + /// Single-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x4, aligned_fmat2x4, 16); + + /// Single-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x2, aligned_fmat3x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x3, aligned_fmat3x3, 16); + + /// Single-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x4, aligned_fmat3x4, 16); + + /// Single-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x2, aligned_fmat4x2, 16); + + /// Single-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x3, aligned_fmat4x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x4, aligned_fmat4x4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 f32mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x2, aligned_f32mat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x3, aligned_f32mat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x4, aligned_f32mat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f32 f32mat1x1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x2, aligned_f32mat2x2, 16); + + /// Single-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x3, aligned_f32mat2x3, 16); + + /// Single-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x4, aligned_f32mat2x4, 16); + + /// Single-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x2, aligned_f32mat3x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x3, aligned_f32mat3x3, 16); + + /// Single-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x4, aligned_f32mat3x4, 16); + + /// Single-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x2, aligned_f32mat4x2, 16); + + /// Single-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x3, aligned_f32mat4x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x4, aligned_f32mat4x4, 16); + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 f64mat1; + + /// Double-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x2, aligned_f64mat2, 32); + + /// Double-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x3, aligned_f64mat3, 32); + + /// Double-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x4, aligned_f64mat4, 32); + + + /// Double-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f64 f64mat1x1; + + /// Double-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x2, aligned_f64mat2x2, 32); + + /// Double-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x3, aligned_f64mat2x3, 32); + + /// Double-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x4, aligned_f64mat2x4, 32); + + /// Double-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x2, aligned_f64mat3x2, 32); + + /// Double-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x3, aligned_f64mat3x3, 32); + + /// Double-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x4, aligned_f64mat3x4, 32); + + /// Double-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x2, aligned_f64mat4x2, 32); + + /// Double-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x3, aligned_f64mat4x3, 32); + + /// Double-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x4, aligned_f64mat4x4, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + + ////////////////////////// + // Quaternion types + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(quat, aligned_quat, 16); + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(quat, aligned_fquat, 16); + + /// Double-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dquat, aligned_dquat, 32); + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32quat, aligned_f32quat, 16); + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64quat, aligned_f64quat, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + /// @} +}//namespace glm + +#include "type_aligned.inl" diff --git a/src/other/manifold/glm/glm/gtx/type_aligned.inl b/src/other/manifold/glm/glm/gtx/type_aligned.inl new file mode 100644 index 00000000000..54c1b818b64 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/type_aligned.inl @@ -0,0 +1,6 @@ +/// @ref gtc_type_aligned + +namespace glm +{ + +} diff --git a/src/other/manifold/glm/glm/gtx/type_trait.hpp b/src/other/manifold/glm/glm/gtx/type_trait.hpp new file mode 100644 index 00000000000..56685c8cb98 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/type_trait.hpp @@ -0,0 +1,85 @@ +/// @ref gtx_type_trait +/// @file glm/gtx/type_trait.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_type_trait GLM_GTX_type_trait +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines traits for each type. + +#pragma once + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_type_trait is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_type_trait extension included") +# endif +#endif + +// Dependency: +#include "../detail/qualifier.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" + +namespace glm +{ + /// @addtogroup gtx_type_trait + /// @{ + + template + struct type + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = false; + static length_t const components = 0; + static length_t const cols = 0; + static length_t const rows = 0; + }; + + template + struct type > + { + static bool const is_vec = true; + static bool const is_mat = false; + static bool const is_quat = false; + static length_t const components = L; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = true; + static bool const is_quat = false; + static length_t const components = C; + static length_t const cols = C; + static length_t const rows = R; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = true; + static length_t const components = 4; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = true; + static length_t const components = 8; + }; + + /// @} +}//namespace glm + +#include "type_trait.inl" diff --git a/src/other/manifold/glm/glm/gtx/type_trait.inl b/src/other/manifold/glm/glm/gtx/type_trait.inl new file mode 100644 index 00000000000..045de959cc2 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/type_trait.inl @@ -0,0 +1,61 @@ +/// @ref gtx_type_trait + +namespace glm +{ + template + bool const type::is_vec; + template + bool const type::is_mat; + template + bool const type::is_quat; + template + length_t const type::components; + template + length_t const type::cols; + template + length_t const type::rows; + + // vec + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + + // mat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + template + length_t const type >::cols; + template + length_t const type >::rows; + + // tquat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + + // tdualquat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/vec_swizzle.hpp b/src/other/manifold/glm/glm/gtx/vec_swizzle.hpp new file mode 100644 index 00000000000..1c49abcb6ad --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/vec_swizzle.hpp @@ -0,0 +1,2782 @@ +/// @ref gtx_vec_swizzle +/// @file glm/gtx/vec_swizzle.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_vec_swizzle GLM_GTX_vec_swizzle +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions to perform swizzle operation. + +#pragma once + +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vec_swizzle is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vec_swizzle extension included") +# endif +#endif + +namespace glm { + // xx + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<1, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + // xy + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + // xz + template + GLM_INLINE glm::vec<2, T, Q> xz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> xz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.z); + } + + // xw + template + GLM_INLINE glm::vec<2, T, Q> xw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.w); + } + + // yx + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + // yy + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + // yz + template + GLM_INLINE glm::vec<2, T, Q> yz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> yz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.z); + } + + // yw + template + GLM_INLINE glm::vec<2, T, Q> yw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.w); + } + + // zx + template + GLM_INLINE glm::vec<2, T, Q> zx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> zx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.x); + } + + // zy + template + GLM_INLINE glm::vec<2, T, Q> zy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> zy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.y); + } + + // zz + template + GLM_INLINE glm::vec<2, T, Q> zz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> zz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.z); + } + + // zw + template + GLM_INLINE glm::vec<2, T, Q> zw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.w); + } + + // wx + template + GLM_INLINE glm::vec<2, T, Q> wx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.x); + } + + // wy + template + GLM_INLINE glm::vec<2, T, Q> wy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.y); + } + + // wz + template + GLM_INLINE glm::vec<2, T, Q> wz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.z); + } + + // ww + template + GLM_INLINE glm::vec<2, T, Q> ww(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.w); + } + + // xxx + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<1, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + // xxy + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + // xxz + template + GLM_INLINE glm::vec<3, T, Q> xxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.z); + } + + // xxw + template + GLM_INLINE glm::vec<3, T, Q> xxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.w); + } + + // xyx + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + // xyy + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + // xyz + template + GLM_INLINE glm::vec<3, T, Q> xyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.z); + } + + // xyw + template + GLM_INLINE glm::vec<3, T, Q> xyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.w); + } + + // xzx + template + GLM_INLINE glm::vec<3, T, Q> xzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.x); + } + + // xzy + template + GLM_INLINE glm::vec<3, T, Q> xzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.y); + } + + // xzz + template + GLM_INLINE glm::vec<3, T, Q> xzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.z); + } + + // xzw + template + GLM_INLINE glm::vec<3, T, Q> xzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.w); + } + + // xwx + template + GLM_INLINE glm::vec<3, T, Q> xwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.x); + } + + // xwy + template + GLM_INLINE glm::vec<3, T, Q> xwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.y); + } + + // xwz + template + GLM_INLINE glm::vec<3, T, Q> xwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.z); + } + + // xww + template + GLM_INLINE glm::vec<3, T, Q> xww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.w); + } + + // yxx + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + // yxy + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + // yxz + template + GLM_INLINE glm::vec<3, T, Q> yxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.z); + } + + // yxw + template + GLM_INLINE glm::vec<3, T, Q> yxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.w); + } + + // yyx + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + // yyy + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + // yyz + template + GLM_INLINE glm::vec<3, T, Q> yyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.z); + } + + // yyw + template + GLM_INLINE glm::vec<3, T, Q> yyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.w); + } + + // yzx + template + GLM_INLINE glm::vec<3, T, Q> yzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.x); + } + + // yzy + template + GLM_INLINE glm::vec<3, T, Q> yzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.y); + } + + // yzz + template + GLM_INLINE glm::vec<3, T, Q> yzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.z); + } + + // yzw + template + GLM_INLINE glm::vec<3, T, Q> yzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.w); + } + + // ywx + template + GLM_INLINE glm::vec<3, T, Q> ywx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.x); + } + + // ywy + template + GLM_INLINE glm::vec<3, T, Q> ywy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.y); + } + + // ywz + template + GLM_INLINE glm::vec<3, T, Q> ywz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.z); + } + + // yww + template + GLM_INLINE glm::vec<3, T, Q> yww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.w); + } + + // zxx + template + GLM_INLINE glm::vec<3, T, Q> zxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.x); + } + + // zxy + template + GLM_INLINE glm::vec<3, T, Q> zxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.y); + } + + // zxz + template + GLM_INLINE glm::vec<3, T, Q> zxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.z); + } + + // zxw + template + GLM_INLINE glm::vec<3, T, Q> zxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.w); + } + + // zyx + template + GLM_INLINE glm::vec<3, T, Q> zyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.x); + } + + // zyy + template + GLM_INLINE glm::vec<3, T, Q> zyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.y); + } + + // zyz + template + GLM_INLINE glm::vec<3, T, Q> zyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.z); + } + + // zyw + template + GLM_INLINE glm::vec<3, T, Q> zyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.w); + } + + // zzx + template + GLM_INLINE glm::vec<3, T, Q> zzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.x); + } + + // zzy + template + GLM_INLINE glm::vec<3, T, Q> zzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.y); + } + + // zzz + template + GLM_INLINE glm::vec<3, T, Q> zzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.z); + } + + // zzw + template + GLM_INLINE glm::vec<3, T, Q> zzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.w); + } + + // zwx + template + GLM_INLINE glm::vec<3, T, Q> zwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.x); + } + + // zwy + template + GLM_INLINE glm::vec<3, T, Q> zwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.y); + } + + // zwz + template + GLM_INLINE glm::vec<3, T, Q> zwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.z); + } + + // zww + template + GLM_INLINE glm::vec<3, T, Q> zww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.w); + } + + // wxx + template + GLM_INLINE glm::vec<3, T, Q> wxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.x); + } + + // wxy + template + GLM_INLINE glm::vec<3, T, Q> wxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.y); + } + + // wxz + template + GLM_INLINE glm::vec<3, T, Q> wxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.z); + } + + // wxw + template + GLM_INLINE glm::vec<3, T, Q> wxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.w); + } + + // wyx + template + GLM_INLINE glm::vec<3, T, Q> wyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.x); + } + + // wyy + template + GLM_INLINE glm::vec<3, T, Q> wyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.y); + } + + // wyz + template + GLM_INLINE glm::vec<3, T, Q> wyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.z); + } + + // wyw + template + GLM_INLINE glm::vec<3, T, Q> wyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.w); + } + + // wzx + template + GLM_INLINE glm::vec<3, T, Q> wzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.x); + } + + // wzy + template + GLM_INLINE glm::vec<3, T, Q> wzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.y); + } + + // wzz + template + GLM_INLINE glm::vec<3, T, Q> wzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.z); + } + + // wzw + template + GLM_INLINE glm::vec<3, T, Q> wzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.w); + } + + // wwx + template + GLM_INLINE glm::vec<3, T, Q> wwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.x); + } + + // wwy + template + GLM_INLINE glm::vec<3, T, Q> wwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.y); + } + + // wwz + template + GLM_INLINE glm::vec<3, T, Q> wwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.z); + } + + // www + template + GLM_INLINE glm::vec<3, T, Q> www(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.w); + } + + // xxxx + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<1, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + // xxxy + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + // xxxz + template + GLM_INLINE glm::vec<4, T, Q> xxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.z); + } + + // xxxw + template + GLM_INLINE glm::vec<4, T, Q> xxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.w); + } + + // xxyx + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + // xxyy + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + // xxyz + template + GLM_INLINE glm::vec<4, T, Q> xxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.z); + } + + // xxyw + template + GLM_INLINE glm::vec<4, T, Q> xxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.w); + } + + // xxzx + template + GLM_INLINE glm::vec<4, T, Q> xxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.x); + } + + // xxzy + template + GLM_INLINE glm::vec<4, T, Q> xxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.y); + } + + // xxzz + template + GLM_INLINE glm::vec<4, T, Q> xxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.z); + } + + // xxzw + template + GLM_INLINE glm::vec<4, T, Q> xxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.w); + } + + // xxwx + template + GLM_INLINE glm::vec<4, T, Q> xxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.x); + } + + // xxwy + template + GLM_INLINE glm::vec<4, T, Q> xxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.y); + } + + // xxwz + template + GLM_INLINE glm::vec<4, T, Q> xxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.z); + } + + // xxww + template + GLM_INLINE glm::vec<4, T, Q> xxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.w); + } + + // xyxx + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + // xyxy + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + // xyxz + template + GLM_INLINE glm::vec<4, T, Q> xyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.z); + } + + // xyxw + template + GLM_INLINE glm::vec<4, T, Q> xyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.w); + } + + // xyyx + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + // xyyy + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + // xyyz + template + GLM_INLINE glm::vec<4, T, Q> xyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.z); + } + + // xyyw + template + GLM_INLINE glm::vec<4, T, Q> xyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.w); + } + + // xyzx + template + GLM_INLINE glm::vec<4, T, Q> xyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.x); + } + + // xyzy + template + GLM_INLINE glm::vec<4, T, Q> xyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y); + } + + // xyzz + template + GLM_INLINE glm::vec<4, T, Q> xyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } + + // xyzw + template + GLM_INLINE glm::vec<4, T, Q> xyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.w); + } + + // xywx + template + GLM_INLINE glm::vec<4, T, Q> xywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.x); + } + + // xywy + template + GLM_INLINE glm::vec<4, T, Q> xywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.y); + } + + // xywz + template + GLM_INLINE glm::vec<4, T, Q> xywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.z); + } + + // xyww + template + GLM_INLINE glm::vec<4, T, Q> xyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.w); + } + + // xzxx + template + GLM_INLINE glm::vec<4, T, Q> xzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.x); + } + + // xzxy + template + GLM_INLINE glm::vec<4, T, Q> xzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.y); + } + + // xzxz + template + GLM_INLINE glm::vec<4, T, Q> xzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.z); + } + + // xzxw + template + GLM_INLINE glm::vec<4, T, Q> xzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.w); + } + + // xzyx + template + GLM_INLINE glm::vec<4, T, Q> xzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.x); + } + + // xzyy + template + GLM_INLINE glm::vec<4, T, Q> xzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.y); + } + + // xzyz + template + GLM_INLINE glm::vec<4, T, Q> xzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.z); + } + + // xzyw + template + GLM_INLINE glm::vec<4, T, Q> xzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.w); + } + + // xzzx + template + GLM_INLINE glm::vec<4, T, Q> xzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.x); + } + + // xzzy + template + GLM_INLINE glm::vec<4, T, Q> xzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.y); + } + + // xzzz + template + GLM_INLINE glm::vec<4, T, Q> xzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.z); + } + + // xzzw + template + GLM_INLINE glm::vec<4, T, Q> xzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.w); + } + + // xzwx + template + GLM_INLINE glm::vec<4, T, Q> xzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.x); + } + + // xzwy + template + GLM_INLINE glm::vec<4, T, Q> xzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.y); + } + + // xzwz + template + GLM_INLINE glm::vec<4, T, Q> xzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.z); + } + + // xzww + template + GLM_INLINE glm::vec<4, T, Q> xzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.w); + } + + // xwxx + template + GLM_INLINE glm::vec<4, T, Q> xwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.x); + } + + // xwxy + template + GLM_INLINE glm::vec<4, T, Q> xwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.y); + } + + // xwxz + template + GLM_INLINE glm::vec<4, T, Q> xwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.z); + } + + // xwxw + template + GLM_INLINE glm::vec<4, T, Q> xwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.w); + } + + // xwyx + template + GLM_INLINE glm::vec<4, T, Q> xwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.x); + } + + // xwyy + template + GLM_INLINE glm::vec<4, T, Q> xwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.y); + } + + // xwyz + template + GLM_INLINE glm::vec<4, T, Q> xwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.z); + } + + // xwyw + template + GLM_INLINE glm::vec<4, T, Q> xwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.w); + } + + // xwzx + template + GLM_INLINE glm::vec<4, T, Q> xwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.x); + } + + // xwzy + template + GLM_INLINE glm::vec<4, T, Q> xwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.y); + } + + // xwzz + template + GLM_INLINE glm::vec<4, T, Q> xwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.z); + } + + // xwzw + template + GLM_INLINE glm::vec<4, T, Q> xwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.w); + } + + // xwwx + template + GLM_INLINE glm::vec<4, T, Q> xwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.x); + } + + // xwwy + template + GLM_INLINE glm::vec<4, T, Q> xwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.y); + } + + // xwwz + template + GLM_INLINE glm::vec<4, T, Q> xwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.z); + } + + // xwww + template + GLM_INLINE glm::vec<4, T, Q> xwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.w); + } + + // yxxx + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + // yxxy + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + // yxxz + template + GLM_INLINE glm::vec<4, T, Q> yxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.z); + } + + // yxxw + template + GLM_INLINE glm::vec<4, T, Q> yxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.w); + } + + // yxyx + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + // yxyy + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + // yxyz + template + GLM_INLINE glm::vec<4, T, Q> yxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.z); + } + + // yxyw + template + GLM_INLINE glm::vec<4, T, Q> yxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.w); + } + + // yxzx + template + GLM_INLINE glm::vec<4, T, Q> yxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.x); + } + + // yxzy + template + GLM_INLINE glm::vec<4, T, Q> yxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.y); + } + + // yxzz + template + GLM_INLINE glm::vec<4, T, Q> yxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.z); + } + + // yxzw + template + GLM_INLINE glm::vec<4, T, Q> yxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.w); + } + + // yxwx + template + GLM_INLINE glm::vec<4, T, Q> yxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.x); + } + + // yxwy + template + GLM_INLINE glm::vec<4, T, Q> yxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.y); + } + + // yxwz + template + GLM_INLINE glm::vec<4, T, Q> yxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.z); + } + + // yxww + template + GLM_INLINE glm::vec<4, T, Q> yxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.w); + } + + // yyxx + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + // yyxy + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + // yyxz + template + GLM_INLINE glm::vec<4, T, Q> yyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.z); + } + + // yyxw + template + GLM_INLINE glm::vec<4, T, Q> yyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.w); + } + + // yyyx + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + // yyyy + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + // yyyz + template + GLM_INLINE glm::vec<4, T, Q> yyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.z); + } + + // yyyw + template + GLM_INLINE glm::vec<4, T, Q> yyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.w); + } + + // yyzx + template + GLM_INLINE glm::vec<4, T, Q> yyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.x); + } + + // yyzy + template + GLM_INLINE glm::vec<4, T, Q> yyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.y); + } + + // yyzz + template + GLM_INLINE glm::vec<4, T, Q> yyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.z); + } + + // yyzw + template + GLM_INLINE glm::vec<4, T, Q> yyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.w); + } + + // yywx + template + GLM_INLINE glm::vec<4, T, Q> yywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.x); + } + + // yywy + template + GLM_INLINE glm::vec<4, T, Q> yywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.y); + } + + // yywz + template + GLM_INLINE glm::vec<4, T, Q> yywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.z); + } + + // yyww + template + GLM_INLINE glm::vec<4, T, Q> yyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.w); + } + + // yzxx + template + GLM_INLINE glm::vec<4, T, Q> yzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.x); + } + + // yzxy + template + GLM_INLINE glm::vec<4, T, Q> yzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.y); + } + + // yzxz + template + GLM_INLINE glm::vec<4, T, Q> yzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.z); + } + + // yzxw + template + GLM_INLINE glm::vec<4, T, Q> yzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.w); + } + + // yzyx + template + GLM_INLINE glm::vec<4, T, Q> yzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.x); + } + + // yzyy + template + GLM_INLINE glm::vec<4, T, Q> yzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.y); + } + + // yzyz + template + GLM_INLINE glm::vec<4, T, Q> yzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.z); + } + + // yzyw + template + GLM_INLINE glm::vec<4, T, Q> yzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.w); + } + + // yzzx + template + GLM_INLINE glm::vec<4, T, Q> yzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.x); + } + + // yzzy + template + GLM_INLINE glm::vec<4, T, Q> yzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.y); + } + + // yzzz + template + GLM_INLINE glm::vec<4, T, Q> yzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.z); + } + + // yzzw + template + GLM_INLINE glm::vec<4, T, Q> yzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.w); + } + + // yzwx + template + GLM_INLINE glm::vec<4, T, Q> yzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.x); + } + + // yzwy + template + GLM_INLINE glm::vec<4, T, Q> yzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.y); + } + + // yzwz + template + GLM_INLINE glm::vec<4, T, Q> yzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.z); + } + + // yzww + template + GLM_INLINE glm::vec<4, T, Q> yzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.w); + } + + // ywxx + template + GLM_INLINE glm::vec<4, T, Q> ywxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.x); + } + + // ywxy + template + GLM_INLINE glm::vec<4, T, Q> ywxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.y); + } + + // ywxz + template + GLM_INLINE glm::vec<4, T, Q> ywxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.z); + } + + // ywxw + template + GLM_INLINE glm::vec<4, T, Q> ywxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.w); + } + + // ywyx + template + GLM_INLINE glm::vec<4, T, Q> ywyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.x); + } + + // ywyy + template + GLM_INLINE glm::vec<4, T, Q> ywyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.y); + } + + // ywyz + template + GLM_INLINE glm::vec<4, T, Q> ywyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.z); + } + + // ywyw + template + GLM_INLINE glm::vec<4, T, Q> ywyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.w); + } + + // ywzx + template + GLM_INLINE glm::vec<4, T, Q> ywzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.x); + } + + // ywzy + template + GLM_INLINE glm::vec<4, T, Q> ywzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.y); + } + + // ywzz + template + GLM_INLINE glm::vec<4, T, Q> ywzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.z); + } + + // ywzw + template + GLM_INLINE glm::vec<4, T, Q> ywzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.w); + } + + // ywwx + template + GLM_INLINE glm::vec<4, T, Q> ywwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.x); + } + + // ywwy + template + GLM_INLINE glm::vec<4, T, Q> ywwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.y); + } + + // ywwz + template + GLM_INLINE glm::vec<4, T, Q> ywwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.z); + } + + // ywww + template + GLM_INLINE glm::vec<4, T, Q> ywww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.w); + } + + // zxxx + template + GLM_INLINE glm::vec<4, T, Q> zxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.x); + } + + // zxxy + template + GLM_INLINE glm::vec<4, T, Q> zxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.y); + } + + // zxxz + template + GLM_INLINE glm::vec<4, T, Q> zxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.z); + } + + // zxxw + template + GLM_INLINE glm::vec<4, T, Q> zxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.w); + } + + // zxyx + template + GLM_INLINE glm::vec<4, T, Q> zxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.x); + } + + // zxyy + template + GLM_INLINE glm::vec<4, T, Q> zxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.y); + } + + // zxyz + template + GLM_INLINE glm::vec<4, T, Q> zxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.z); + } + + // zxyw + template + GLM_INLINE glm::vec<4, T, Q> zxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.w); + } + + // zxzx + template + GLM_INLINE glm::vec<4, T, Q> zxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.x); + } + + // zxzy + template + GLM_INLINE glm::vec<4, T, Q> zxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.y); + } + + // zxzz + template + GLM_INLINE glm::vec<4, T, Q> zxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.z); + } + + // zxzw + template + GLM_INLINE glm::vec<4, T, Q> zxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.w); + } + + // zxwx + template + GLM_INLINE glm::vec<4, T, Q> zxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.x); + } + + // zxwy + template + GLM_INLINE glm::vec<4, T, Q> zxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.y); + } + + // zxwz + template + GLM_INLINE glm::vec<4, T, Q> zxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.z); + } + + // zxww + template + GLM_INLINE glm::vec<4, T, Q> zxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.w); + } + + // zyxx + template + GLM_INLINE glm::vec<4, T, Q> zyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.x); + } + + // zyxy + template + GLM_INLINE glm::vec<4, T, Q> zyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.y); + } + + // zyxz + template + GLM_INLINE glm::vec<4, T, Q> zyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.z); + } + + // zyxw + template + GLM_INLINE glm::vec<4, T, Q> zyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.w); + } + + // zyyx + template + GLM_INLINE glm::vec<4, T, Q> zyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.x); + } + + // zyyy + template + GLM_INLINE glm::vec<4, T, Q> zyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.y); + } + + // zyyz + template + GLM_INLINE glm::vec<4, T, Q> zyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.z); + } + + // zyyw + template + GLM_INLINE glm::vec<4, T, Q> zyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.w); + } + + // zyzx + template + GLM_INLINE glm::vec<4, T, Q> zyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.x); + } + + // zyzy + template + GLM_INLINE glm::vec<4, T, Q> zyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.y); + } + + // zyzz + template + GLM_INLINE glm::vec<4, T, Q> zyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.z); + } + + // zyzw + template + GLM_INLINE glm::vec<4, T, Q> zyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.w); + } + + // zywx + template + GLM_INLINE glm::vec<4, T, Q> zywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.x); + } + + // zywy + template + GLM_INLINE glm::vec<4, T, Q> zywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.y); + } + + // zywz + template + GLM_INLINE glm::vec<4, T, Q> zywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.z); + } + + // zyww + template + GLM_INLINE glm::vec<4, T, Q> zyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.w); + } + + // zzxx + template + GLM_INLINE glm::vec<4, T, Q> zzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.x); + } + + // zzxy + template + GLM_INLINE glm::vec<4, T, Q> zzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.y); + } + + // zzxz + template + GLM_INLINE glm::vec<4, T, Q> zzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.z); + } + + // zzxw + template + GLM_INLINE glm::vec<4, T, Q> zzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.w); + } + + // zzyx + template + GLM_INLINE glm::vec<4, T, Q> zzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.x); + } + + // zzyy + template + GLM_INLINE glm::vec<4, T, Q> zzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.y); + } + + // zzyz + template + GLM_INLINE glm::vec<4, T, Q> zzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.z); + } + + // zzyw + template + GLM_INLINE glm::vec<4, T, Q> zzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.w); + } + + // zzzx + template + GLM_INLINE glm::vec<4, T, Q> zzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.x); + } + + // zzzy + template + GLM_INLINE glm::vec<4, T, Q> zzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.y); + } + + // zzzz + template + GLM_INLINE glm::vec<4, T, Q> zzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.z); + } + + // zzzw + template + GLM_INLINE glm::vec<4, T, Q> zzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.w); + } + + // zzwx + template + GLM_INLINE glm::vec<4, T, Q> zzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.x); + } + + // zzwy + template + GLM_INLINE glm::vec<4, T, Q> zzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.y); + } + + // zzwz + template + GLM_INLINE glm::vec<4, T, Q> zzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.z); + } + + // zzww + template + GLM_INLINE glm::vec<4, T, Q> zzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.w); + } + + // zwxx + template + GLM_INLINE glm::vec<4, T, Q> zwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.x); + } + + // zwxy + template + GLM_INLINE glm::vec<4, T, Q> zwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.y); + } + + // zwxz + template + GLM_INLINE glm::vec<4, T, Q> zwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.z); + } + + // zwxw + template + GLM_INLINE glm::vec<4, T, Q> zwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.w); + } + + // zwyx + template + GLM_INLINE glm::vec<4, T, Q> zwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.x); + } + + // zwyy + template + GLM_INLINE glm::vec<4, T, Q> zwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.y); + } + + // zwyz + template + GLM_INLINE glm::vec<4, T, Q> zwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.z); + } + + // zwyw + template + GLM_INLINE glm::vec<4, T, Q> zwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.w); + } + + // zwzx + template + GLM_INLINE glm::vec<4, T, Q> zwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.x); + } + + // zwzy + template + GLM_INLINE glm::vec<4, T, Q> zwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.y); + } + + // zwzz + template + GLM_INLINE glm::vec<4, T, Q> zwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.z); + } + + // zwzw + template + GLM_INLINE glm::vec<4, T, Q> zwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.w); + } + + // zwwx + template + GLM_INLINE glm::vec<4, T, Q> zwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.x); + } + + // zwwy + template + GLM_INLINE glm::vec<4, T, Q> zwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.y); + } + + // zwwz + template + GLM_INLINE glm::vec<4, T, Q> zwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.z); + } + + // zwww + template + GLM_INLINE glm::vec<4, T, Q> zwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.w); + } + + // wxxx + template + GLM_INLINE glm::vec<4, T, Q> wxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.x); + } + + // wxxy + template + GLM_INLINE glm::vec<4, T, Q> wxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.y); + } + + // wxxz + template + GLM_INLINE glm::vec<4, T, Q> wxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.z); + } + + // wxxw + template + GLM_INLINE glm::vec<4, T, Q> wxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.w); + } + + // wxyx + template + GLM_INLINE glm::vec<4, T, Q> wxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.x); + } + + // wxyy + template + GLM_INLINE glm::vec<4, T, Q> wxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.y); + } + + // wxyz + template + GLM_INLINE glm::vec<4, T, Q> wxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.z); + } + + // wxyw + template + GLM_INLINE glm::vec<4, T, Q> wxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.w); + } + + // wxzx + template + GLM_INLINE glm::vec<4, T, Q> wxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.x); + } + + // wxzy + template + GLM_INLINE glm::vec<4, T, Q> wxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.y); + } + + // wxzz + template + GLM_INLINE glm::vec<4, T, Q> wxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.z); + } + + // wxzw + template + GLM_INLINE glm::vec<4, T, Q> wxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.w); + } + + // wxwx + template + GLM_INLINE glm::vec<4, T, Q> wxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.x); + } + + // wxwy + template + GLM_INLINE glm::vec<4, T, Q> wxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.y); + } + + // wxwz + template + GLM_INLINE glm::vec<4, T, Q> wxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.z); + } + + // wxww + template + GLM_INLINE glm::vec<4, T, Q> wxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.w); + } + + // wyxx + template + GLM_INLINE glm::vec<4, T, Q> wyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.x); + } + + // wyxy + template + GLM_INLINE glm::vec<4, T, Q> wyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.y); + } + + // wyxz + template + GLM_INLINE glm::vec<4, T, Q> wyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.z); + } + + // wyxw + template + GLM_INLINE glm::vec<4, T, Q> wyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.w); + } + + // wyyx + template + GLM_INLINE glm::vec<4, T, Q> wyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.x); + } + + // wyyy + template + GLM_INLINE glm::vec<4, T, Q> wyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.y); + } + + // wyyz + template + GLM_INLINE glm::vec<4, T, Q> wyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.z); + } + + // wyyw + template + GLM_INLINE glm::vec<4, T, Q> wyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.w); + } + + // wyzx + template + GLM_INLINE glm::vec<4, T, Q> wyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.x); + } + + // wyzy + template + GLM_INLINE glm::vec<4, T, Q> wyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.y); + } + + // wyzz + template + GLM_INLINE glm::vec<4, T, Q> wyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.z); + } + + // wyzw + template + GLM_INLINE glm::vec<4, T, Q> wyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.w); + } + + // wywx + template + GLM_INLINE glm::vec<4, T, Q> wywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.x); + } + + // wywy + template + GLM_INLINE glm::vec<4, T, Q> wywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.y); + } + + // wywz + template + GLM_INLINE glm::vec<4, T, Q> wywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.z); + } + + // wyww + template + GLM_INLINE glm::vec<4, T, Q> wyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.w); + } + + // wzxx + template + GLM_INLINE glm::vec<4, T, Q> wzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.x); + } + + // wzxy + template + GLM_INLINE glm::vec<4, T, Q> wzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.y); + } + + // wzxz + template + GLM_INLINE glm::vec<4, T, Q> wzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.z); + } + + // wzxw + template + GLM_INLINE glm::vec<4, T, Q> wzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.w); + } + + // wzyx + template + GLM_INLINE glm::vec<4, T, Q> wzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.x); + } + + // wzyy + template + GLM_INLINE glm::vec<4, T, Q> wzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.y); + } + + // wzyz + template + GLM_INLINE glm::vec<4, T, Q> wzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.z); + } + + // wzyw + template + GLM_INLINE glm::vec<4, T, Q> wzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.w); + } + + // wzzx + template + GLM_INLINE glm::vec<4, T, Q> wzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.x); + } + + // wzzy + template + GLM_INLINE glm::vec<4, T, Q> wzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.y); + } + + // wzzz + template + GLM_INLINE glm::vec<4, T, Q> wzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.z); + } + + // wzzw + template + GLM_INLINE glm::vec<4, T, Q> wzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.w); + } + + // wzwx + template + GLM_INLINE glm::vec<4, T, Q> wzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.x); + } + + // wzwy + template + GLM_INLINE glm::vec<4, T, Q> wzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.y); + } + + // wzwz + template + GLM_INLINE glm::vec<4, T, Q> wzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.z); + } + + // wzww + template + GLM_INLINE glm::vec<4, T, Q> wzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.w); + } + + // wwxx + template + GLM_INLINE glm::vec<4, T, Q> wwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.x); + } + + // wwxy + template + GLM_INLINE glm::vec<4, T, Q> wwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.y); + } + + // wwxz + template + GLM_INLINE glm::vec<4, T, Q> wwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.z); + } + + // wwxw + template + GLM_INLINE glm::vec<4, T, Q> wwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.w); + } + + // wwyx + template + GLM_INLINE glm::vec<4, T, Q> wwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.x); + } + + // wwyy + template + GLM_INLINE glm::vec<4, T, Q> wwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.y); + } + + // wwyz + template + GLM_INLINE glm::vec<4, T, Q> wwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.z); + } + + // wwyw + template + GLM_INLINE glm::vec<4, T, Q> wwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.w); + } + + // wwzx + template + GLM_INLINE glm::vec<4, T, Q> wwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.x); + } + + // wwzy + template + GLM_INLINE glm::vec<4, T, Q> wwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.y); + } + + // wwzz + template + GLM_INLINE glm::vec<4, T, Q> wwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.z); + } + + // wwzw + template + GLM_INLINE glm::vec<4, T, Q> wwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.w); + } + + // wwwx + template + GLM_INLINE glm::vec<4, T, Q> wwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.x); + } + + // wwwy + template + GLM_INLINE glm::vec<4, T, Q> wwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.y); + } + + // wwwz + template + GLM_INLINE glm::vec<4, T, Q> wwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.z); + } + + // wwww + template + GLM_INLINE glm::vec<4, T, Q> wwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.w); + } + +} diff --git a/src/other/manifold/glm/glm/gtx/vector_angle.hpp b/src/other/manifold/glm/glm/gtx/vector_angle.hpp new file mode 100644 index 00000000000..9ae437126b1 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/vector_angle.hpp @@ -0,0 +1,57 @@ +/// @ref gtx_vector_angle +/// @file glm/gtx/vector_angle.hpp +/// +/// @see core (dependence) +/// @see gtx_quaternion (dependence) +/// @see gtx_epsilon (dependence) +/// +/// @defgroup gtx_vector_angle GLM_GTX_vector_angle +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Compute angle between vectors + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/epsilon.hpp" +#include "../gtx/quaternion.hpp" +#include "../gtx/rotate_vector.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vector_angle is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vector_angle extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_vector_angle + /// @{ + + //! Returns the absolute angle between two vectors. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T angle(vec const& x, vec const& y); + + //! Returns the oriented angle between two 2d vectors. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T orientedAngle(vec<2, T, Q> const& x, vec<2, T, Q> const& y); + + //! Returns the oriented angle between two 3d vectors based from a reference axis. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T orientedAngle(vec<3, T, Q> const& x, vec<3, T, Q> const& y, vec<3, T, Q> const& ref); + + /// @} +}// namespace glm + +#include "vector_angle.inl" diff --git a/src/other/manifold/glm/glm/gtx/vector_angle.inl b/src/other/manifold/glm/glm/gtx/vector_angle.inl new file mode 100644 index 00000000000..a1f957a594f --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/vector_angle.inl @@ -0,0 +1,44 @@ +/// @ref gtx_vector_angle + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType angle + ( + genType const& x, + genType const& y + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'angle' only accept floating-point inputs"); + return acos(clamp(dot(x, y), genType(-1), genType(1))); + } + + template + GLM_FUNC_QUALIFIER T angle(vec const& x, vec const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'angle' only accept floating-point inputs"); + return acos(clamp(dot(x, y), T(-1), T(1))); + } + + //! \todo epsilon is hard coded to 0.01 + template + GLM_FUNC_QUALIFIER T orientedAngle(vec<2, T, Q> const& x, vec<2, T, Q> const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'orientedAngle' only accept floating-point inputs"); + T const Angle(acos(clamp(dot(x, y), T(-1), T(1)))); + + if(all(epsilonEqual(y, glm::rotate(x, Angle), T(0.0001)))) + return Angle; + else + return -Angle; + } + + template + GLM_FUNC_QUALIFIER T orientedAngle(vec<3, T, Q> const& x, vec<3, T, Q> const& y, vec<3, T, Q> const& ref) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'orientedAngle' only accept floating-point inputs"); + + T const Angle(acos(clamp(dot(x, y), T(-1), T(1)))); + return mix(Angle, -Angle, dot(ref, cross(x, y)) < T(0)); + } +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/vector_query.hpp b/src/other/manifold/glm/glm/gtx/vector_query.hpp new file mode 100644 index 00000000000..77c7b974be5 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/vector_query.hpp @@ -0,0 +1,66 @@ +/// @ref gtx_vector_query +/// @file glm/gtx/vector_query.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_vector_query GLM_GTX_vector_query +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Query informations of vector types + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vector_query is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vector_query extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_vector_query + /// @{ + + //! Check whether two vectors are collinears. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areCollinear(vec const& v0, vec const& v1, T const& epsilon); + + //! Check whether two vectors are orthogonals. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areOrthogonal(vec const& v0, vec const& v1, T const& epsilon); + + //! Check whether a vector is normalized. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool isNormalized(vec const& v, T const& epsilon); + + //! Check whether a vector is null. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool isNull(vec const& v, T const& epsilon); + + //! Check whether a each component of a vector is null. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL vec isCompNull(vec const& v, T const& epsilon); + + //! Check whether two vectors are orthonormal. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areOrthonormal(vec const& v0, vec const& v1, T const& epsilon); + + /// @} +}// namespace glm + +#include "vector_query.inl" diff --git a/src/other/manifold/glm/glm/gtx/vector_query.inl b/src/other/manifold/glm/glm/gtx/vector_query.inl new file mode 100644 index 00000000000..d1a5c9be46b --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/vector_query.inl @@ -0,0 +1,154 @@ +/// @ref gtx_vector_query + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_areCollinear{}; + + template + struct compute_areCollinear<2, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<2, T, Q> const& v0, vec<2, T, Q> const& v1, T const& epsilon) + { + return length(cross(vec<3, T, Q>(v0, static_cast(0)), vec<3, T, Q>(v1, static_cast(0)))) < epsilon; + } + }; + + template + struct compute_areCollinear<3, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<3, T, Q> const& v0, vec<3, T, Q> const& v1, T const& epsilon) + { + return length(cross(v0, v1)) < epsilon; + } + }; + + template + struct compute_areCollinear<4, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<4, T, Q> const& v0, vec<4, T, Q> const& v1, T const& epsilon) + { + return length(cross(vec<3, T, Q>(v0), vec<3, T, Q>(v1))) < epsilon; + } + }; + + template + struct compute_isCompNull{}; + + template + struct compute_isCompNull<2, T, Q> + { + GLM_FUNC_QUALIFIER static vec<2, bool, Q> call(vec<2, T, Q> const& v, T const& epsilon) + { + return vec<2, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon)); + } + }; + + template + struct compute_isCompNull<3, T, Q> + { + GLM_FUNC_QUALIFIER static vec<3, bool, Q> call(vec<3, T, Q> const& v, T const& epsilon) + { + return vec<3, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon), + (abs(v.z) < epsilon)); + } + }; + + template + struct compute_isCompNull<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, bool, Q> call(vec<4, T, Q> const& v, T const& epsilon) + { + return vec<4, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon), + (abs(v.z) < epsilon), + (abs(v.w) < epsilon)); + } + }; + +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool areCollinear(vec const& v0, vec const& v1, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'areCollinear' only accept floating-point inputs"); + + return detail::compute_areCollinear::call(v0, v1, epsilon); + } + + template + GLM_FUNC_QUALIFIER bool areOrthogonal(vec const& v0, vec const& v1, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'areOrthogonal' only accept floating-point inputs"); + + return abs(dot(v0, v1)) <= max( + static_cast(1), + length(v0)) * max(static_cast(1), length(v1)) * epsilon; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isNormalized' only accept floating-point inputs"); + + return abs(length(v) - static_cast(1)) <= static_cast(2) * epsilon; + } + + template + GLM_FUNC_QUALIFIER bool isNull(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isNull' only accept floating-point inputs"); + + return length(v) <= epsilon; + } + + template + GLM_FUNC_QUALIFIER vec isCompNull(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isCompNull' only accept floating-point inputs"); + + return detail::compute_isCompNull::call(v, epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<2, bool, Q> isCompNull(vec<2, T, Q> const& v, T const& epsilon) + { + return vec<2, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<3, bool, Q> isCompNull(vec<3, T, Q> const& v, T const& epsilon) + { + return vec<3, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon, + abs(v.z) < epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isCompNull(vec<4, T, Q> const& v, T const& epsilon) + { + return vec<4, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon, + abs(v.z) < epsilon, + abs(v.w) < epsilon); + } + + template + GLM_FUNC_QUALIFIER bool areOrthonormal(vec const& v0, vec const& v1, T const& epsilon) + { + return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon); + } + +}//namespace glm diff --git a/src/other/manifold/glm/glm/gtx/wrap.hpp b/src/other/manifold/glm/glm/gtx/wrap.hpp new file mode 100644 index 00000000000..ad4eb3fca74 --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/wrap.hpp @@ -0,0 +1,37 @@ +/// @ref gtx_wrap +/// @file glm/gtx/wrap.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_wrap GLM_GTX_wrap +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Wrapping mode of texture coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/scalar_common.hpp" +#include "../ext/vector_common.hpp" +#include "../gtc/vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_wrap is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_wrap extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_wrap + /// @{ + + /// @} +}// namespace glm + +#include "wrap.inl" diff --git a/src/other/manifold/glm/glm/gtx/wrap.inl b/src/other/manifold/glm/glm/gtx/wrap.inl new file mode 100644 index 00000000000..4be3b4c38ae --- /dev/null +++ b/src/other/manifold/glm/glm/gtx/wrap.inl @@ -0,0 +1,6 @@ +/// @ref gtx_wrap + +namespace glm +{ + +}//namespace glm diff --git a/src/other/manifold/glm/glm/integer.hpp b/src/other/manifold/glm/glm/integer.hpp new file mode 100644 index 00000000000..8817db3f0a2 --- /dev/null +++ b/src/other/manifold/glm/glm/integer.hpp @@ -0,0 +1,212 @@ +/// @ref core +/// @file glm/integer.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.8 Integer Functions +/// +/// @defgroup core_func_integer Integer functions +/// @ingroup core +/// +/// Provides GLSL functions on integer types +/// +/// These all operate component-wise. The description is per component. +/// The notation [a, b] means the set of bits from bit-number a through bit-number +/// b, inclusive. The lowest-order bit is bit 0. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/qualifier.hpp" +#include "common.hpp" +#include "vector_relational.hpp" + +namespace glm +{ + /// @addtogroup core_func_integer + /// @{ + + /// Adds 32-bit unsigned integer x and y, returning the sum + /// modulo pow(2, 32). The value carry is set to 0 if the sum was + /// less than pow(2, 32), or to 1 otherwise. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL uaddCarry man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec uaddCarry( + vec const& x, + vec const& y, + vec & carry); + + /// Subtracts the 32-bit unsigned integer y from x, returning + /// the difference if non-negative, or pow(2, 32) plus the difference + /// otherwise. The value borrow is set to 0 if x >= y, or to 1 otherwise. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL usubBorrow man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec usubBorrow( + vec const& x, + vec const& y, + vec & borrow); + + /// Multiplies 32-bit integers x and y, producing a 64-bit + /// result. The 32 least-significant bits are returned in lsb. + /// The 32 most-significant bits are returned in msb. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL umulExtended man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL void umulExtended( + vec const& x, + vec const& y, + vec & msb, + vec & lsb); + + /// Multiplies 32-bit integers x and y, producing a 64-bit + /// result. The 32 least-significant bits are returned in lsb. + /// The 32 most-significant bits are returned in msb. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL imulExtended man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL void imulExtended( + vec const& x, + vec const& y, + vec & msb, + vec & lsb); + + /// Extracts bits [offset, offset + bits - 1] from value, + /// returning them in the least significant bits of the result. + /// For unsigned data types, the most significant bits of the + /// result will be set to zero. For signed data types, the + /// most significant bits will be set to the value of bit offset + base - 1. + /// + /// If bits is zero, the result will be zero. The result will be + /// undefined if offset or bits is negative, or if the sum of + /// offset and bits is greater than the number of bits used + /// to store the operand. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL bitfieldExtract man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldExtract( + vec const& Value, + int Offset, + int Bits); + + /// Returns the insertion the bits least-significant bits of insert into base. + /// + /// The result will have bits [offset, offset + bits - 1] taken + /// from bits [0, bits - 1] of insert, and all other bits taken + /// directly from the corresponding bits of base. If bits is + /// zero, the result will simply be base. The result will be + /// undefined if offset or bits is negative, or if the sum of + /// offset and bits is greater than the number of bits used to + /// store the operand. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitfieldInsert man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldInsert( + vec const& Base, + vec const& Insert, + int Offset, + int Bits); + + /// Returns the reversal of the bits of value. + /// The bit numbered n of the result will be taken from bit (bits - 1) - n of value, + /// where bits is the total number of bits used to represent value. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitfieldReverse man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldReverse(vec const& v); + + /// Returns the number of bits set to 1 in the binary representation of value. + /// + /// @tparam genType Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitCount man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int bitCount(genType v); + + /// Returns the number of bits set to 1 in the binary representation of value. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitCount man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitCount(vec const& v); + + /// Returns the bit number of the least significant bit set to + /// 1 in the binary representation of value. + /// If value is zero, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see GLSL findLSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int findLSB(genIUType x); + + /// Returns the bit number of the least significant bit set to + /// 1 in the binary representation of value. + /// If value is zero, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL findLSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec findLSB(vec const& v); + + /// Returns the bit number of the most significant bit in the binary representation of value. + /// For positive integers, the result will be the bit number of the most significant bit set to 1. + /// For negative integers, the result will be the bit number of the most significant + /// bit set to 0. For a value of zero or negative one, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see GLSL findMSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int findMSB(genIUType x); + + /// Returns the bit number of the most significant bit in the binary representation of value. + /// For positive integers, the result will be the bit number of the most significant bit set to 1. + /// For negative integers, the result will be the bit number of the most significant + /// bit set to 0. For a value of zero or negative one, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL findMSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec findMSB(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_integer.inl" diff --git a/src/other/manifold/glm/glm/mat2x2.hpp b/src/other/manifold/glm/glm/mat2x2.hpp new file mode 100644 index 00000000000..96bec96b9a6 --- /dev/null +++ b/src/other/manifold/glm/glm/mat2x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x2.hpp + +#pragma once +#include "./ext/matrix_double2x2.hpp" +#include "./ext/matrix_double2x2_precision.hpp" +#include "./ext/matrix_float2x2.hpp" +#include "./ext/matrix_float2x2_precision.hpp" + diff --git a/src/other/manifold/glm/glm/mat2x3.hpp b/src/other/manifold/glm/glm/mat2x3.hpp new file mode 100644 index 00000000000..d68dc25eda9 --- /dev/null +++ b/src/other/manifold/glm/glm/mat2x3.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x3.hpp + +#pragma once +#include "./ext/matrix_double2x3.hpp" +#include "./ext/matrix_double2x3_precision.hpp" +#include "./ext/matrix_float2x3.hpp" +#include "./ext/matrix_float2x3_precision.hpp" + diff --git a/src/other/manifold/glm/glm/mat2x4.hpp b/src/other/manifold/glm/glm/mat2x4.hpp new file mode 100644 index 00000000000..b04b7387b1a --- /dev/null +++ b/src/other/manifold/glm/glm/mat2x4.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x4.hpp + +#pragma once +#include "./ext/matrix_double2x4.hpp" +#include "./ext/matrix_double2x4_precision.hpp" +#include "./ext/matrix_float2x4.hpp" +#include "./ext/matrix_float2x4_precision.hpp" + diff --git a/src/other/manifold/glm/glm/mat3x2.hpp b/src/other/manifold/glm/glm/mat3x2.hpp new file mode 100644 index 00000000000..c85315372dc --- /dev/null +++ b/src/other/manifold/glm/glm/mat3x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat3x2.hpp + +#pragma once +#include "./ext/matrix_double3x2.hpp" +#include "./ext/matrix_double3x2_precision.hpp" +#include "./ext/matrix_float3x2.hpp" +#include "./ext/matrix_float3x2_precision.hpp" + diff --git a/src/other/manifold/glm/glm/mat3x3.hpp b/src/other/manifold/glm/glm/mat3x3.hpp new file mode 100644 index 00000000000..fd4fa31cdee --- /dev/null +++ b/src/other/manifold/glm/glm/mat3x3.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat3x3.hpp + +#pragma once +#include "./ext/matrix_double3x3.hpp" +#include "./ext/matrix_double3x3_precision.hpp" +#include "./ext/matrix_float3x3.hpp" +#include "./ext/matrix_float3x3_precision.hpp" diff --git a/src/other/manifold/glm/glm/mat3x4.hpp b/src/other/manifold/glm/glm/mat3x4.hpp new file mode 100644 index 00000000000..6342bf5b992 --- /dev/null +++ b/src/other/manifold/glm/glm/mat3x4.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat3x4.hpp + +#pragma once +#include "./ext/matrix_double3x4.hpp" +#include "./ext/matrix_double3x4_precision.hpp" +#include "./ext/matrix_float3x4.hpp" +#include "./ext/matrix_float3x4_precision.hpp" diff --git a/src/other/manifold/glm/glm/mat4x2.hpp b/src/other/manifold/glm/glm/mat4x2.hpp new file mode 100644 index 00000000000..e013e46b9c2 --- /dev/null +++ b/src/other/manifold/glm/glm/mat4x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat4x2.hpp + +#pragma once +#include "./ext/matrix_double4x2.hpp" +#include "./ext/matrix_double4x2_precision.hpp" +#include "./ext/matrix_float4x2.hpp" +#include "./ext/matrix_float4x2_precision.hpp" + diff --git a/src/other/manifold/glm/glm/mat4x3.hpp b/src/other/manifold/glm/glm/mat4x3.hpp new file mode 100644 index 00000000000..205725abd25 --- /dev/null +++ b/src/other/manifold/glm/glm/mat4x3.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat4x3.hpp + +#pragma once +#include "./ext/matrix_double4x3.hpp" +#include "./ext/matrix_double4x3_precision.hpp" +#include "./ext/matrix_float4x3.hpp" +#include "./ext/matrix_float4x3_precision.hpp" diff --git a/src/other/manifold/glm/glm/mat4x4.hpp b/src/other/manifold/glm/glm/mat4x4.hpp new file mode 100644 index 00000000000..3515f7f370b --- /dev/null +++ b/src/other/manifold/glm/glm/mat4x4.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat4x4.hpp + +#pragma once +#include "./ext/matrix_double4x4.hpp" +#include "./ext/matrix_double4x4_precision.hpp" +#include "./ext/matrix_float4x4.hpp" +#include "./ext/matrix_float4x4_precision.hpp" + diff --git a/src/other/manifold/glm/glm/matrix.hpp b/src/other/manifold/glm/glm/matrix.hpp new file mode 100644 index 00000000000..6badf538504 --- /dev/null +++ b/src/other/manifold/glm/glm/matrix.hpp @@ -0,0 +1,161 @@ +/// @ref core +/// @file glm/matrix.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions +/// +/// @defgroup core_func_matrix Matrix functions +/// @ingroup core +/// +/// Provides GLSL matrix functions. +/// +/// Include to use these core features. + +#pragma once + +// Dependencies +#include "detail/qualifier.hpp" +#include "detail/setup.hpp" +#include "vec2.hpp" +#include "vec3.hpp" +#include "vec4.hpp" +#include "mat2x2.hpp" +#include "mat2x3.hpp" +#include "mat2x4.hpp" +#include "mat3x2.hpp" +#include "mat3x3.hpp" +#include "mat3x4.hpp" +#include "mat4x2.hpp" +#include "mat4x3.hpp" +#include "mat4x4.hpp" + +namespace glm { +namespace detail +{ + template + struct outerProduct_trait{}; + + template + struct outerProduct_trait<2, 2, T, Q> + { + typedef mat<2, 2, T, Q> type; + }; + + template + struct outerProduct_trait<2, 3, T, Q> + { + typedef mat<3, 2, T, Q> type; + }; + + template + struct outerProduct_trait<2, 4, T, Q> + { + typedef mat<4, 2, T, Q> type; + }; + + template + struct outerProduct_trait<3, 2, T, Q> + { + typedef mat<2, 3, T, Q> type; + }; + + template + struct outerProduct_trait<3, 3, T, Q> + { + typedef mat<3, 3, T, Q> type; + }; + + template + struct outerProduct_trait<3, 4, T, Q> + { + typedef mat<4, 3, T, Q> type; + }; + + template + struct outerProduct_trait<4, 2, T, Q> + { + typedef mat<2, 4, T, Q> type; + }; + + template + struct outerProduct_trait<4, 3, T, Q> + { + typedef mat<3, 4, T, Q> type; + }; + + template + struct outerProduct_trait<4, 4, T, Q> + { + typedef mat<4, 4, T, Q> type; + }; +}//namespace detail + + /// @addtogroup core_func_matrix + /// @{ + + /// Multiply matrix x by matrix y component-wise, i.e., + /// result[i][j] is the scalar product of x[i][j] and y[i][j]. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL matrixCompMult man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL mat matrixCompMult(mat const& x, mat const& y); + + /// Treats the first parameter c as a column vector + /// and the second parameter r as a row vector + /// and does a linear algebraic matrix multiply c * r. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL outerProduct man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename detail::outerProduct_trait::type outerProduct(vec const& c, vec const& r); + + /// Returns the transposed matrix of x + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL transpose man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename mat::transpose_type transpose(mat const& x); + + /// Return the determinant of a squared matrix. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL determinant man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL T determinant(mat const& m); + + /// Return the inverse of a squared matrix. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL inverse man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL mat inverse(mat const& m); + + /// @} +}//namespace glm + +#include "detail/func_matrix.inl" diff --git a/src/other/manifold/glm/glm/packing.hpp b/src/other/manifold/glm/glm/packing.hpp new file mode 100644 index 00000000000..ca83ac1dec9 --- /dev/null +++ b/src/other/manifold/glm/glm/packing.hpp @@ -0,0 +1,173 @@ +/// @ref core +/// @file glm/packing.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions +/// @see gtc_packing +/// +/// @defgroup core_func_packing Floating-Point Pack and Unpack Functions +/// @ingroup core +/// +/// Provides GLSL functions to pack and unpack half, single and double-precision floating point values into more compact integer types. +/// +/// These functions do not operate component-wise, rather as described in each case. +/// +/// Include to use these core features. + +#pragma once + +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float4.hpp" + +namespace glm +{ + /// @addtogroup core_func_packing + /// @{ + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packUnorm2x16(vec2 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x16: round(clamp(v, -1, +1) * 32767.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packSnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packSnorm2x16(vec2 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm4x8: round(clamp(c, 0, +1) * 255.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packUnorm4x8(vec4 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm4x8: round(clamp(c, -1, +1) * 127.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packSnorm4x8(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm2x16: f / 65535.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackUnorm2x16(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm2x16: clamp(f / 32767.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackSnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackSnorm2x16(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackUnorm4x8(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm4x8: clamp(f / 127.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackSnorm4x8(uint p); + + /// Returns a double-qualifier value obtained by packing the components of v into a 64-bit value. + /// If an IEEE 754 Inf or NaN is created, it will not signal, and the resulting floating point value is unspecified. + /// Otherwise, the bit- level representation of v is preserved. + /// The first vector component specifies the 32 least significant bits; + /// the second component specifies the 32 most significant bits. + /// + /// @see GLSL packDouble2x32 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL double packDouble2x32(uvec2 const& v); + + /// Returns a two-component unsigned integer vector representation of v. + /// The bit-level representation of v is preserved. + /// The first component of the vector contains the 32 least significant bits of the double; + /// the second component consists the 32 most significant bits. + /// + /// @see GLSL unpackDouble2x32 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uvec2 unpackDouble2x32(double v); + + /// Returns an unsigned integer obtained by converting the components of a two-component floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing these two 16- bit integers into a 32-bit unsigned integer. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the second component specifies the 16 most-significant bits. + /// + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packHalf2x16(vec2 const& v); + + /// Returns a two-component floating-point vector with components obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values, + /// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification, + /// and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the second component is obtained from the 16 most-significant bits of v. + /// + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackHalf2x16(uint v); + + /// @} +}//namespace glm + +#include "detail/func_packing.inl" diff --git a/src/other/manifold/glm/glm/simd/common.h b/src/other/manifold/glm/glm/simd/common.h new file mode 100644 index 00000000000..9b017cb4256 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/common.h @@ -0,0 +1,240 @@ +/// @ref simd +/// @file glm/simd/common.h + +#pragma once + +#include "platform.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_add(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_add_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_add(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_add_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_sub(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_sub_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_sub(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_sub_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_mul(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_mul_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_mul(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_mul_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_div(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_div_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_div(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_div_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_div_lowp(glm_f32vec4 a, glm_f32vec4 b) +{ + return glm_vec4_mul(a, _mm_rcp_ps(b)); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_swizzle_xyzw(glm_f32vec4 a) +{ +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + return _mm_permute_ps(a, _MM_SHUFFLE(3, 2, 1, 0)); +# else + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 1, 0)); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) +{ +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) + return _mm_fmadd_ss(a, b, c); +# else + return _mm_add_ss(_mm_mul_ss(a, b), c); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) +{ +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) + return _mm_fmadd_ps(a, b, c); +# else + return glm_vec4_add(glm_vec4_mul(a, b), c); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_abs(glm_f32vec4 x) +{ + return _mm_and_ps(x, _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF))); +} + +GLM_FUNC_QUALIFIER glm_ivec4 glm_ivec4_abs(glm_ivec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSSE3_BIT + return _mm_sign_epi32(x, x); +# else + glm_ivec4 const sgn0 = _mm_srai_epi32(x, 31); + glm_ivec4 const inv0 = _mm_xor_si128(x, sgn0); + glm_ivec4 const sub0 = _mm_sub_epi32(inv0, sgn0); + return sub0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_sign(glm_vec4 x) +{ + glm_vec4 const zro0 = _mm_setzero_ps(); + glm_vec4 const cmp0 = _mm_cmplt_ps(x, zro0); + glm_vec4 const cmp1 = _mm_cmpgt_ps(x, zro0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(-1.0f)); + glm_vec4 const and1 = _mm_and_ps(cmp1, _mm_set1_ps(1.0f)); + glm_vec4 const or0 = _mm_or_ps(and0, and1); + return or0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_round(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_round_ps(x, _MM_FROUND_TO_NEAREST_INT); +# else + glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000))); + glm_vec4 const and0 = _mm_and_ps(sgn0, x); + glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); + glm_vec4 const add0 = glm_vec4_add(x, or0); + glm_vec4 const sub0 = glm_vec4_sub(add0, or0); + return sub0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_floor(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_floor_ps(x); +# else + glm_vec4 const rnd0 = glm_vec4_round(x); + glm_vec4 const cmp0 = _mm_cmplt_ps(x, rnd0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + glm_vec4 const sub0 = glm_vec4_sub(rnd0, and0); + return sub0; +# endif +} + +/* trunc TODO +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_trunc(glm_vec4 x) +{ + return glm_vec4(); +} +*/ + +//roundEven +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_roundEven(glm_vec4 x) +{ + glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000))); + glm_vec4 const and0 = _mm_and_ps(sgn0, x); + glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); + glm_vec4 const add0 = glm_vec4_add(x, or0); + glm_vec4 const sub0 = glm_vec4_sub(add0, or0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_ceil(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_ceil_ps(x); +# else + glm_vec4 const rnd0 = glm_vec4_round(x); + glm_vec4 const cmp0 = _mm_cmpgt_ps(x, rnd0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + glm_vec4 const add0 = glm_vec4_add(rnd0, and0); + return add0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_fract(glm_vec4 x) +{ + glm_vec4 const flr0 = glm_vec4_floor(x); + glm_vec4 const sub0 = glm_vec4_sub(x, flr0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_mod(glm_vec4 x, glm_vec4 y) +{ + glm_vec4 const div0 = glm_vec4_div(x, y); + glm_vec4 const flr0 = glm_vec4_floor(div0); + glm_vec4 const mul0 = glm_vec4_mul(y, flr0); + glm_vec4 const sub0 = glm_vec4_sub(x, mul0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_clamp(glm_vec4 v, glm_vec4 minVal, glm_vec4 maxVal) +{ + glm_vec4 const min0 = _mm_min_ps(v, maxVal); + glm_vec4 const max0 = _mm_max_ps(min0, minVal); + return max0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_mix(glm_vec4 v1, glm_vec4 v2, glm_vec4 a) +{ + glm_vec4 const sub0 = glm_vec4_sub(_mm_set1_ps(1.0f), a); + glm_vec4 const mul0 = glm_vec4_mul(v1, sub0); + glm_vec4 const mad0 = glm_vec4_fma(v2, a, mul0); + return mad0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_step(glm_vec4 edge, glm_vec4 x) +{ + glm_vec4 const cmp = _mm_cmple_ps(x, edge); + return _mm_movemask_ps(cmp) == 0 ? _mm_set1_ps(1.0f) : _mm_setzero_ps(); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_smoothstep(glm_vec4 edge0, glm_vec4 edge1, glm_vec4 x) +{ + glm_vec4 const sub0 = glm_vec4_sub(x, edge0); + glm_vec4 const sub1 = glm_vec4_sub(edge1, edge0); + glm_vec4 const div0 = glm_vec4_sub(sub0, sub1); + glm_vec4 const clp0 = glm_vec4_clamp(div0, _mm_setzero_ps(), _mm_set1_ps(1.0f)); + glm_vec4 const mul0 = glm_vec4_mul(_mm_set1_ps(2.0f), clp0); + glm_vec4 const sub2 = glm_vec4_sub(_mm_set1_ps(3.0f), mul0); + glm_vec4 const mul1 = glm_vec4_mul(clp0, clp0); + glm_vec4 const mul2 = glm_vec4_mul(mul1, sub2); + return mul2; +} + +// Agner Fog method +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_nan(glm_vec4 x) +{ + glm_ivec4 const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + glm_ivec4 const t3 = _mm_set1_epi32(int(0xFF000000)); // exponent mask + glm_ivec4 const t4 = _mm_and_si128(t2, t3); // exponent + glm_ivec4 const t5 = _mm_andnot_si128(t3, t2); // fraction + glm_ivec4 const Equal = _mm_cmpeq_epi32(t3, t4); + glm_ivec4 const Nequal = _mm_cmpeq_epi32(t5, _mm_setzero_si128()); + glm_ivec4 const And = _mm_and_si128(Equal, Nequal); + return _mm_castsi128_ps(And); // exponent = all 1s and fraction != 0 +} + +// Agner Fog method +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_inf(glm_vec4 x) +{ + glm_ivec4 const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + return _mm_castsi128_ps(_mm_cmpeq_epi32(t2, _mm_set1_epi32(int(0xFF000000)))); // exponent is all 1s, fraction is 0 +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/exponential.h b/src/other/manifold/glm/glm/simd/exponential.h new file mode 100644 index 00000000000..bc351d0119b --- /dev/null +++ b/src/other/manifold/glm/glm/simd/exponential.h @@ -0,0 +1,20 @@ +/// @ref simd +/// @file glm/simd/experimental.h + +#pragma once + +#include "platform.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_sqrt_lowp(glm_f32vec4 x) +{ + return _mm_mul_ss(_mm_rsqrt_ss(x), x); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_sqrt_lowp(glm_f32vec4 x) +{ + return _mm_mul_ps(_mm_rsqrt_ps(x), x); +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/geometric.h b/src/other/manifold/glm/glm/simd/geometric.h new file mode 100644 index 00000000000..07d7cbcc425 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/geometric.h @@ -0,0 +1,124 @@ +/// @ref simd +/// @file glm/simd/geometric.h + +#pragma once + +#include "common.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_DECL glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2); +GLM_FUNC_DECL glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2); + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_length(glm_vec4 x) +{ + glm_vec4 const dot0 = glm_vec4_dot(x, x); + glm_vec4 const sqt0 = _mm_sqrt_ps(dot0); + return sqt0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_distance(glm_vec4 p0, glm_vec4 p1) +{ + glm_vec4 const sub0 = _mm_sub_ps(p0, p1); + glm_vec4 const len0 = glm_vec4_length(sub0); + return len0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2) +{ +# if GLM_ARCH & GLM_ARCH_AVX_BIT + return _mm_dp_ps(v1, v2, 0xff); +# elif GLM_ARCH & GLM_ARCH_SSE3_BIT + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const hadd0 = _mm_hadd_ps(mul0, mul0); + glm_vec4 const hadd1 = _mm_hadd_ps(hadd0, hadd0); + return hadd1; +# else + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1)); + glm_vec4 const add0 = _mm_add_ps(mul0, swp0); + glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3)); + glm_vec4 const add1 = _mm_add_ps(add0, swp1); + return add1; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2) +{ +# if GLM_ARCH & GLM_ARCH_AVX_BIT + return _mm_dp_ps(v1, v2, 0xff); +# elif GLM_ARCH & GLM_ARCH_SSE3_BIT + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const had0 = _mm_hadd_ps(mul0, mul0); + glm_vec4 const had1 = _mm_hadd_ps(had0, had0); + return had1; +# else + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const mov0 = _mm_movehl_ps(mul0, mul0); + glm_vec4 const add0 = _mm_add_ps(mov0, mul0); + glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, 1); + glm_vec4 const add1 = _mm_add_ss(add0, swp1); + return add1; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_cross(glm_vec4 v1, glm_vec4 v2) +{ + glm_vec4 const swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1)); + glm_vec4 const swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2)); + glm_vec4 const swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1)); + glm_vec4 const swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2)); + glm_vec4 const mul0 = _mm_mul_ps(swp0, swp3); + glm_vec4 const mul1 = _mm_mul_ps(swp1, swp2); + glm_vec4 const sub0 = _mm_sub_ps(mul0, mul1); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_normalize(glm_vec4 v) +{ + glm_vec4 const dot0 = glm_vec4_dot(v, v); + glm_vec4 const isr0 = _mm_rsqrt_ps(dot0); + glm_vec4 const mul0 = _mm_mul_ps(v, isr0); + return mul0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_faceforward(glm_vec4 N, glm_vec4 I, glm_vec4 Nref) +{ + glm_vec4 const dot0 = glm_vec4_dot(Nref, I); + glm_vec4 const sgn0 = glm_vec4_sign(dot0); + glm_vec4 const mul0 = _mm_mul_ps(sgn0, _mm_set1_ps(-1.0f)); + glm_vec4 const mul1 = _mm_mul_ps(N, mul0); + return mul1; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_reflect(glm_vec4 I, glm_vec4 N) +{ + glm_vec4 const dot0 = glm_vec4_dot(N, I); + glm_vec4 const mul0 = _mm_mul_ps(N, dot0); + glm_vec4 const mul1 = _mm_mul_ps(mul0, _mm_set1_ps(2.0f)); + glm_vec4 const sub0 = _mm_sub_ps(I, mul1); + return sub0; +} + +GLM_FUNC_QUALIFIER __m128 glm_vec4_refract(glm_vec4 I, glm_vec4 N, glm_vec4 eta) +{ + glm_vec4 const dot0 = glm_vec4_dot(N, I); + glm_vec4 const mul0 = _mm_mul_ps(eta, eta); + glm_vec4 const mul1 = _mm_mul_ps(dot0, dot0); + glm_vec4 const sub0 = _mm_sub_ps(_mm_set1_ps(1.0f), mul0); + glm_vec4 const sub1 = _mm_sub_ps(_mm_set1_ps(1.0f), mul1); + glm_vec4 const mul2 = _mm_mul_ps(sub0, sub1); + + if(_mm_movemask_ps(_mm_cmplt_ss(mul2, _mm_set1_ps(0.0f))) == 0) + return _mm_set1_ps(0.0f); + + glm_vec4 const sqt0 = _mm_sqrt_ps(mul2); + glm_vec4 const mad0 = glm_vec4_fma(eta, dot0, sqt0); + glm_vec4 const mul4 = _mm_mul_ps(mad0, N); + glm_vec4 const mul5 = _mm_mul_ps(eta, I); + glm_vec4 const sub2 = _mm_sub_ps(mul5, mul4); + + return sub2; +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/integer.h b/src/other/manifold/glm/glm/simd/integer.h new file mode 100644 index 00000000000..93814183fe0 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/integer.h @@ -0,0 +1,115 @@ +/// @ref simd +/// @file glm/simd/integer.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_uvec4 glm_i128_interleave(glm_uvec4 x) +{ + glm_uvec4 const Mask4 = _mm_set1_epi32(0x0000FFFF); + glm_uvec4 const Mask3 = _mm_set1_epi32(0x00FF00FF); + glm_uvec4 const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + glm_uvec4 const Mask1 = _mm_set1_epi32(0x33333333); + glm_uvec4 const Mask0 = _mm_set1_epi32(0x55555555); + + glm_uvec4 Reg1; + glm_uvec4 Reg2; + + // REG1 = x; + // REG2 = y; + //Reg1 = _mm_unpacklo_epi64(x, y); + Reg1 = x; + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + return Reg1; +} + +GLM_FUNC_QUALIFIER glm_uvec4 glm_i128_interleave2(glm_uvec4 x, glm_uvec4 y) +{ + glm_uvec4 const Mask4 = _mm_set1_epi32(0x0000FFFF); + glm_uvec4 const Mask3 = _mm_set1_epi32(0x00FF00FF); + glm_uvec4 const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + glm_uvec4 const Mask1 = _mm_set1_epi32(0x33333333); + glm_uvec4 const Mask0 = _mm_set1_epi32(0x55555555); + + glm_uvec4 Reg1; + glm_uvec4 Reg2; + + // REG1 = x; + // REG2 = y; + Reg1 = _mm_unpacklo_epi64(x, y); + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + return Reg1; +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/matrix.h b/src/other/manifold/glm/glm/simd/matrix.h new file mode 100644 index 00000000000..b6c42ea4c17 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/matrix.h @@ -0,0 +1,1028 @@ +/// @ref simd +/// @file glm/simd/matrix.h + +#pragma once + +#include "geometric.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER void glm_mat4_matrixCompMult(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_mul_ps(in1[0], in2[0]); + out[1] = _mm_mul_ps(in1[1], in2[1]); + out[2] = _mm_mul_ps(in1[2], in2[2]); + out[3] = _mm_mul_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER void glm_mat4_add(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_add_ps(in1[0], in2[0]); + out[1] = _mm_add_ps(in1[1], in2[1]); + out[2] = _mm_add_ps(in1[2], in2[2]); + out[3] = _mm_add_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER void glm_mat4_sub(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_sub_ps(in1[0], in2[0]); + out[1] = _mm_sub_ps(in1[1], in2[1]); + out[2] = _mm_sub_ps(in1[2], in2[2]); + out[3] = _mm_sub_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_mul_vec4(glm_vec4 const m[4], glm_vec4 v) +{ + __m128 v0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 v1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 v2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 v3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(m[0], v0); + __m128 m1 = _mm_mul_ps(m[1], v1); + __m128 m2 = _mm_mul_ps(m[2], v2); + __m128 m3 = _mm_mul_ps(m[3], v3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + return a2; +} + +GLM_FUNC_QUALIFIER __m128 glm_vec4_mul_mat4(glm_vec4 v, glm_vec4 const m[4]) +{ + __m128 i0 = m[0]; + __m128 i1 = m[1]; + __m128 i2 = m[2]; + __m128 i3 = m[3]; + + __m128 m0 = _mm_mul_ps(v, i0); + __m128 m1 = _mm_mul_ps(v, i1); + __m128 m2 = _mm_mul_ps(v, i2); + __m128 m3 = _mm_mul_ps(v, i3); + + __m128 u0 = _mm_unpacklo_ps(m0, m1); + __m128 u1 = _mm_unpackhi_ps(m0, m1); + __m128 a0 = _mm_add_ps(u0, u1); + + __m128 u2 = _mm_unpacklo_ps(m2, m3); + __m128 u3 = _mm_unpackhi_ps(m2, m3); + __m128 a1 = _mm_add_ps(u2, u3); + + __m128 f0 = _mm_movelh_ps(a0, a1); + __m128 f1 = _mm_movehl_ps(a1, a0); + __m128 f2 = _mm_add_ps(f0, f1); + + return f2; +} + +GLM_FUNC_QUALIFIER void glm_mat4_mul(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + { + __m128 e0 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[0] = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[1] = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[2] = a2; + } + + { + //(__m128&)_mm_shuffle_epi32(__m128i&)in2[0], _MM_SHUFFLE(3, 3, 3, 3)) + __m128 e0 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[3] = a2; + } +} + +GLM_FUNC_QUALIFIER void glm_mat4_transpose(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44); + __m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE); + __m128 tmp1 = _mm_shuffle_ps(in[2], in[3], 0x44); + __m128 tmp3 = _mm_shuffle_ps(in[2], in[3], 0xEE); + + out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88); + out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD); + out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88); + out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_highp(glm_vec4 const in[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + return Det0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_lowp(glm_vec4 const m[4]) +{ + // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128( + + //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + // First 2 columns + __m128 Swp2A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 1, 1, 2))); + __m128 Swp3A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(3, 2, 3, 3))); + __m128 MulA = _mm_mul_ps(Swp2A, Swp3A); + + // Second 2 columns + __m128 Swp2B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(3, 2, 3, 3))); + __m128 Swp3B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(0, 1, 1, 2))); + __m128 MulB = _mm_mul_ps(Swp2B, Swp3B); + + // Columns subtraction + __m128 SubE = _mm_sub_ps(MulA, MulB); + + // Last 2 rows + __m128 Swp2C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 0, 1, 2))); + __m128 Swp3C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(1, 2, 0, 0))); + __m128 MulC = _mm_mul_ps(Swp2C, Swp3C); + __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC); + + //vec<4, T, Q> DetCof( + // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + __m128 SubFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubE), _MM_SHUFFLE(2, 1, 0, 0))); + __m128 SwpFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(0, 0, 0, 1))); + __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA); + + __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1)); + __m128 SubFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpB), _MM_SHUFFLE(3, 1, 1, 0)));//SubF[0], SubE[3], SubE[3], SubE[1]; + __m128 SwpFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(1, 1, 2, 2))); + __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB); + + __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB); + + __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2)); + __m128 SubFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpC), _MM_SHUFFLE(3, 3, 2, 0))); + __m128 SwpFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(2, 3, 3, 3))); + __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC); + + __m128 AddRes = _mm_add_ps(SubRes, MulFacC); + __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f)); + + //return m[0][0] * DetCof[0] + // + m[0][1] * DetCof[1] + // + m[0][2] * DetCof[2] + // + m[0][3] * DetCof[3]; + + return glm_vec4_dot(m[0], DetCof); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant(glm_vec4 const m[4]) +{ + // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(add) + + //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + // First 2 columns + __m128 Swp2A = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 1, 1, 2)); + __m128 Swp3A = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(3, 2, 3, 3)); + __m128 MulA = _mm_mul_ps(Swp2A, Swp3A); + + // Second 2 columns + __m128 Swp2B = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(3, 2, 3, 3)); + __m128 Swp3B = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(0, 1, 1, 2)); + __m128 MulB = _mm_mul_ps(Swp2B, Swp3B); + + // Columns subtraction + __m128 SubE = _mm_sub_ps(MulA, MulB); + + // Last 2 rows + __m128 Swp2C = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 0, 1, 2)); + __m128 Swp3C = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(1, 2, 0, 0)); + __m128 MulC = _mm_mul_ps(Swp2C, Swp3C); + __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC); + + //vec<4, T, Q> DetCof( + // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + __m128 SubFacA = _mm_shuffle_ps(SubE, SubE, _MM_SHUFFLE(2, 1, 0, 0)); + __m128 SwpFacA = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(0, 0, 0, 1)); + __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA); + + __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1)); + __m128 SubFacB = _mm_shuffle_ps(SubTmpB, SubTmpB, _MM_SHUFFLE(3, 1, 1, 0));//SubF[0], SubE[3], SubE[3], SubE[1]; + __m128 SwpFacB = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(1, 1, 2, 2)); + __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB); + + __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB); + + __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2)); + __m128 SubFacC = _mm_shuffle_ps(SubTmpC, SubTmpC, _MM_SHUFFLE(3, 3, 2, 0)); + __m128 SwpFacC = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(2, 3, 3, 3)); + __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC); + + __m128 AddRes = _mm_add_ps(SubRes, MulFacC); + __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f)); + + //return m[0][0] * DetCof[0] + // + m[0][1] * DetCof[1] + // + m[0][2] * DetCof[2] + // + m[0][3] * DetCof[3]; + + return glm_vec4_dot(m[0], DetCof); +} + +GLM_FUNC_QUALIFIER void glm_mat4_inverse(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + __m128 Rcp0 = _mm_div_ps(_mm_set1_ps(1.0f), Det0); + //__m128 Rcp0 = _mm_rcp_ps(Det0); + + // Inverse /= Determinant; + out[0] = _mm_mul_ps(Inv0, Rcp0); + out[1] = _mm_mul_ps(Inv1, Rcp0); + out[2] = _mm_mul_ps(Inv2, Rcp0); + out[3] = _mm_mul_ps(Inv3, Rcp0); +} + +GLM_FUNC_QUALIFIER void glm_mat4_inverse_lowp(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + __m128 Rcp0 = _mm_rcp_ps(Det0); + //__m128 Rcp0 = _mm_div_ps(one, Det0); + // Inverse /= Determinant; + out[0] = _mm_mul_ps(Inv0, Rcp0); + out[1] = _mm_mul_ps(Inv1, Rcp0); + out[2] = _mm_mul_ps(Inv2, Rcp0); + out[3] = _mm_mul_ps(Inv3, Rcp0); +} +/* +GLM_FUNC_QUALIFIER void glm_mat4_rotate(__m128 const in[4], float Angle, float const v[3], __m128 out[4]) +{ + float a = glm::radians(Angle); + float c = cos(a); + float s = sin(a); + + glm::vec4 AxisA(v[0], v[1], v[2], float(0)); + __m128 AxisB = _mm_set_ps(AxisA.w, AxisA.z, AxisA.y, AxisA.x); + __m128 AxisC = detail::sse_nrm_ps(AxisB); + + __m128 Cos0 = _mm_set_ss(c); + __m128 CosA = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Sin0 = _mm_set_ss(s); + __m128 SinA = _mm_shuffle_ps(Sin0, Sin0, _MM_SHUFFLE(0, 0, 0, 0)); + + // vec<3, T, Q> temp = (valType(1) - c) * axis; + __m128 Temp0 = _mm_sub_ps(one, CosA); + __m128 Temp1 = _mm_mul_ps(Temp0, AxisC); + + //Rotate[0][0] = c + temp[0] * axis[0]; + //Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + //Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + __m128 Axis0 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 TmpA0 = _mm_mul_ps(Axis0, AxisC); + __m128 CosA0 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 1, 0)); + __m128 TmpA1 = _mm_add_ps(CosA0, TmpA0); + __m128 SinA0 = SinA;//_mm_set_ps(0.0f, s, -s, 0.0f); + __m128 TmpA2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 1, 2, 3)); + __m128 TmpA3 = _mm_mul_ps(SinA0, TmpA2); + __m128 TmpA4 = _mm_add_ps(TmpA1, TmpA3); + + //Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + //Rotate[1][1] = c + temp[1] * axis[1]; + //Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + __m128 Axis1 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 TmpB0 = _mm_mul_ps(Axis1, AxisC); + __m128 CosA1 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 0, 1)); + __m128 TmpB1 = _mm_add_ps(CosA1, TmpB0); + __m128 SinB0 = SinA;//_mm_set_ps(-s, 0.0f, s, 0.0f); + __m128 TmpB2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 0, 3, 2)); + __m128 TmpB3 = _mm_mul_ps(SinA0, TmpB2); + __m128 TmpB4 = _mm_add_ps(TmpB1, TmpB3); + + //Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + //Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + //Rotate[2][2] = c + temp[2] * axis[2]; + __m128 Axis2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 TmpC0 = _mm_mul_ps(Axis2, AxisC); + __m128 CosA2 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 0, 1, 1)); + __m128 TmpC1 = _mm_add_ps(CosA2, TmpC0); + __m128 SinC0 = SinA;//_mm_set_ps(s, -s, 0.0f, 0.0f); + __m128 TmpC2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 3, 0, 1)); + __m128 TmpC3 = _mm_mul_ps(SinA0, TmpC2); + __m128 TmpC4 = _mm_add_ps(TmpC1, TmpC3); + + __m128 Result[4]; + Result[0] = TmpA4; + Result[1] = TmpB4; + Result[2] = TmpC4; + Result[3] = _mm_set_ps(1, 0, 0, 0); + + //mat<4, 4, valType> Result; + //Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + //Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + //Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + //Result[3] = m[3]; + //return Result; + sse_mul_ps(in, Result, out); +} +*/ +GLM_FUNC_QUALIFIER void glm_mat4_outerProduct(__m128 const& c, __m128 const& r, __m128 out[4]) +{ + out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0))); + out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1))); + out[2] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(2, 2, 2, 2))); + out[3] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(3, 3, 3, 3))); +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/neon.h b/src/other/manifold/glm/glm/simd/neon.h new file mode 100644 index 00000000000..6c38b06c937 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/neon.h @@ -0,0 +1,155 @@ +/// @ref simd_neon +/// @file glm/simd/neon.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_NEON_BIT +#include + +namespace glm { + namespace neon { + static float32x4_t dupq_lane(float32x4_t vsrc, int lane) { + switch(lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + case 0: return vdupq_laneq_f32(vsrc, 0); + case 1: return vdupq_laneq_f32(vsrc, 1); + case 2: return vdupq_laneq_f32(vsrc, 2); + case 3: return vdupq_laneq_f32(vsrc, 3); +#else + case 0: return vdupq_n_f32(vgetq_lane_f32(vsrc, 0)); + case 1: return vdupq_n_f32(vgetq_lane_f32(vsrc, 1)); + case 2: return vdupq_n_f32(vgetq_lane_f32(vsrc, 2)); + case 3: return vdupq_n_f32(vgetq_lane_f32(vsrc, 3)); +#endif + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); + } + + static float32x2_t dup_lane(float32x4_t vsrc, int lane) { + switch(lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + case 0: return vdup_laneq_f32(vsrc, 0); + case 1: return vdup_laneq_f32(vsrc, 1); + case 2: return vdup_laneq_f32(vsrc, 2); + case 3: return vdup_laneq_f32(vsrc, 3); +#else + case 0: return vdup_n_f32(vgetq_lane_f32(vsrc, 0)); + case 1: return vdup_n_f32(vgetq_lane_f32(vsrc, 1)); + case 2: return vdup_n_f32(vgetq_lane_f32(vsrc, 2)); + case 3: return vdup_n_f32(vgetq_lane_f32(vsrc, 3)); +#endif + } + assert(!"Unreachable code executed!"); + return vdup_n_f32(0.0f); + } + + static float32x4_t copy_lane(float32x4_t vdst, int dlane, float32x4_t vsrc, int slane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + switch(dlane) { + case 0: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 0, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 0, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 0, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 0, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 1: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 1, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 1, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 1, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 1, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 2: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 2, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 2, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 2, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 2, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 3: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 3, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 3, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 3, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 3, vsrc, 3); + } + assert(!"Unreachable code executed!"); + } +#else + + float l; + switch(slane) { + case 0: l = vgetq_lane_f32(vsrc, 0); break; + case 1: l = vgetq_lane_f32(vsrc, 1); break; + case 2: l = vgetq_lane_f32(vsrc, 2); break; + case 3: l = vgetq_lane_f32(vsrc, 3); break; + default: + assert(!"Unreachable code executed!"); + } + switch(dlane) { + case 0: return vsetq_lane_f32(l, vdst, 0); + case 1: return vsetq_lane_f32(l, vdst, 1); + case 2: return vsetq_lane_f32(l, vdst, 2); + case 3: return vsetq_lane_f32(l, vdst, 3); + } +#endif + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); + } + + static float32x4_t mul_lane(float32x4_t v, float32x4_t vlane, int lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + switch(lane) { + case 0: return vmulq_laneq_f32(v, vlane, 0); break; + case 1: return vmulq_laneq_f32(v, vlane, 1); break; + case 2: return vmulq_laneq_f32(v, vlane, 2); break; + case 3: return vmulq_laneq_f32(v, vlane, 3); break; + default: + assert(!"Unreachable code executed!"); + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); +#else + return vmulq_f32(v, dupq_lane(vlane, lane)); +#endif + } + + static float32x4_t madd_lane(float32x4_t acc, float32x4_t v, float32x4_t vlane, int lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT +#ifdef GLM_CONFIG_FORCE_FMA +# define FMADD_LANE(acc, x, y, L) do { asm volatile ("fmla %0.4s, %1.4s, %2.4s" : "+w"(acc) : "w"(x), "w"(dup_lane(y, L))); } while(0) +#else +# define FMADD_LANE(acc, x, y, L) do { acc = vmlaq_laneq_f32(acc, x, y, L); } while(0) +#endif + + switch(lane) { + case 0: + FMADD_LANE(acc, v, vlane, 0); + return acc; + case 1: + FMADD_LANE(acc, v, vlane, 1); + return acc; + case 2: + FMADD_LANE(acc, v, vlane, 2); + return acc; + case 3: + FMADD_LANE(acc, v, vlane, 3); + return acc; + default: + assert(!"Unreachable code executed!"); + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); +# undef FMADD_LANE +#else + return vaddq_f32(acc, vmulq_f32(v, dupq_lane(vlane, lane))); +#endif + } + } //namespace neon +} // namespace glm +#endif // GLM_ARCH & GLM_ARCH_NEON_BIT diff --git a/src/other/manifold/glm/glm/simd/packing.h b/src/other/manifold/glm/glm/simd/packing.h new file mode 100644 index 00000000000..609163eb0d7 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/packing.h @@ -0,0 +1,8 @@ +/// @ref simd +/// @file glm/simd/packing.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/simd/platform.h b/src/other/manifold/glm/glm/simd/platform.h new file mode 100644 index 00000000000..ad25cc15a26 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/platform.h @@ -0,0 +1,398 @@ +#pragma once + +/////////////////////////////////////////////////////////////////////////////////// +// Platform + +#define GLM_PLATFORM_UNKNOWN 0x00000000 +#define GLM_PLATFORM_WINDOWS 0x00010000 +#define GLM_PLATFORM_LINUX 0x00020000 +#define GLM_PLATFORM_APPLE 0x00040000 +//#define GLM_PLATFORM_IOS 0x00080000 +#define GLM_PLATFORM_ANDROID 0x00100000 +#define GLM_PLATFORM_CHROME_NACL 0x00200000 +#define GLM_PLATFORM_UNIX 0x00400000 +#define GLM_PLATFORM_QNXNTO 0x00800000 +#define GLM_PLATFORM_WINCE 0x01000000 +#define GLM_PLATFORM_CYGWIN 0x02000000 + +#ifdef GLM_FORCE_PLATFORM_UNKNOWN +# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN +#elif defined(__CYGWIN__) +# define GLM_PLATFORM GLM_PLATFORM_CYGWIN +#elif defined(__QNXNTO__) +# define GLM_PLATFORM GLM_PLATFORM_QNXNTO +#elif defined(__APPLE__) +# define GLM_PLATFORM GLM_PLATFORM_APPLE +#elif defined(WINCE) +# define GLM_PLATFORM GLM_PLATFORM_WINCE +#elif defined(_WIN32) +# define GLM_PLATFORM GLM_PLATFORM_WINDOWS +#elif defined(__native_client__) +# define GLM_PLATFORM GLM_PLATFORM_CHROME_NACL +#elif defined(__ANDROID__) +# define GLM_PLATFORM GLM_PLATFORM_ANDROID +#elif defined(__linux) +# define GLM_PLATFORM GLM_PLATFORM_LINUX +#elif defined(__unix) +# define GLM_PLATFORM GLM_PLATFORM_UNIX +#else +# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN +#endif// + +/////////////////////////////////////////////////////////////////////////////////// +// Compiler + +#define GLM_COMPILER_UNKNOWN 0x00000000 + +// Intel +#define GLM_COMPILER_INTEL 0x00100000 +#define GLM_COMPILER_INTEL14 0x00100040 +#define GLM_COMPILER_INTEL15 0x00100050 +#define GLM_COMPILER_INTEL16 0x00100060 +#define GLM_COMPILER_INTEL17 0x00100070 + +// Visual C++ defines +#define GLM_COMPILER_VC 0x01000000 +#define GLM_COMPILER_VC12 0x01000001 +#define GLM_COMPILER_VC14 0x01000002 +#define GLM_COMPILER_VC15 0x01000003 +#define GLM_COMPILER_VC15_3 0x01000004 +#define GLM_COMPILER_VC15_5 0x01000005 +#define GLM_COMPILER_VC15_6 0x01000006 +#define GLM_COMPILER_VC15_7 0x01000007 +#define GLM_COMPILER_VC15_8 0x01000008 +#define GLM_COMPILER_VC15_9 0x01000009 +#define GLM_COMPILER_VC16 0x0100000A + +// GCC defines +#define GLM_COMPILER_GCC 0x02000000 +#define GLM_COMPILER_GCC46 0x020000D0 +#define GLM_COMPILER_GCC47 0x020000E0 +#define GLM_COMPILER_GCC48 0x020000F0 +#define GLM_COMPILER_GCC49 0x02000100 +#define GLM_COMPILER_GCC5 0x02000200 +#define GLM_COMPILER_GCC6 0x02000300 +#define GLM_COMPILER_GCC7 0x02000400 +#define GLM_COMPILER_GCC8 0x02000500 + +// CUDA +#define GLM_COMPILER_CUDA 0x10000000 +#define GLM_COMPILER_CUDA75 0x10000001 +#define GLM_COMPILER_CUDA80 0x10000002 +#define GLM_COMPILER_CUDA90 0x10000004 + +// SYCL +#define GLM_COMPILER_SYCL 0x00300000 + +// Clang +#define GLM_COMPILER_CLANG 0x20000000 +#define GLM_COMPILER_CLANG34 0x20000050 +#define GLM_COMPILER_CLANG35 0x20000060 +#define GLM_COMPILER_CLANG36 0x20000070 +#define GLM_COMPILER_CLANG37 0x20000080 +#define GLM_COMPILER_CLANG38 0x20000090 +#define GLM_COMPILER_CLANG39 0x200000A0 +#define GLM_COMPILER_CLANG40 0x200000B0 +#define GLM_COMPILER_CLANG41 0x200000C0 +#define GLM_COMPILER_CLANG42 0x200000D0 + +// Build model +#define GLM_MODEL_32 0x00000010 +#define GLM_MODEL_64 0x00000020 + +// Force generic C++ compiler +#ifdef GLM_FORCE_COMPILER_UNKNOWN +# define GLM_COMPILER GLM_COMPILER_UNKNOWN + +#elif defined(__INTEL_COMPILER) +# if __INTEL_COMPILER >= 1700 +# define GLM_COMPILER GLM_COMPILER_INTEL17 +# elif __INTEL_COMPILER >= 1600 +# define GLM_COMPILER GLM_COMPILER_INTEL16 +# elif __INTEL_COMPILER >= 1500 +# define GLM_COMPILER GLM_COMPILER_INTEL15 +# elif __INTEL_COMPILER >= 1400 +# define GLM_COMPILER GLM_COMPILER_INTEL14 +# elif __INTEL_COMPILER < 1400 +# error "GLM requires ICC 2013 SP1 or newer" +# endif + +// CUDA +#elif defined(__CUDACC__) +# if !defined(CUDA_VERSION) && !defined(GLM_FORCE_CUDA) +# include // make sure version is defined since nvcc does not define it itself! +# endif +# if CUDA_VERSION >= 8000 +# define GLM_COMPILER GLM_COMPILER_CUDA80 +# elif CUDA_VERSION >= 7500 +# define GLM_COMPILER GLM_COMPILER_CUDA75 +# elif CUDA_VERSION >= 7000 +# define GLM_COMPILER GLM_COMPILER_CUDA70 +# elif CUDA_VERSION < 7000 +# error "GLM requires CUDA 7.0 or higher" +# endif + +// SYCL +#elif defined(__SYCL_DEVICE_ONLY__) +# define GLM_COMPILER GLM_COMPILER_SYCL + +// Clang +#elif defined(__clang__) +# if defined(__apple_build_version__) +# if (__clang_major__ < 6) +# error "GLM requires Clang 3.4 / Apple Clang 6.0 or higher" +# elif __clang_major__ == 6 && __clang_minor__ == 0 +# define GLM_COMPILER GLM_COMPILER_CLANG35 +# elif __clang_major__ == 6 && __clang_minor__ >= 1 +# define GLM_COMPILER GLM_COMPILER_CLANG36 +# elif __clang_major__ >= 7 +# define GLM_COMPILER GLM_COMPILER_CLANG37 +# endif +# else +# if ((__clang_major__ == 3) && (__clang_minor__ < 4)) || (__clang_major__ < 3) +# error "GLM requires Clang 3.4 or higher" +# elif __clang_major__ == 3 && __clang_minor__ == 4 +# define GLM_COMPILER GLM_COMPILER_CLANG34 +# elif __clang_major__ == 3 && __clang_minor__ == 5 +# define GLM_COMPILER GLM_COMPILER_CLANG35 +# elif __clang_major__ == 3 && __clang_minor__ == 6 +# define GLM_COMPILER GLM_COMPILER_CLANG36 +# elif __clang_major__ == 3 && __clang_minor__ == 7 +# define GLM_COMPILER GLM_COMPILER_CLANG37 +# elif __clang_major__ == 3 && __clang_minor__ == 8 +# define GLM_COMPILER GLM_COMPILER_CLANG38 +# elif __clang_major__ == 3 && __clang_minor__ >= 9 +# define GLM_COMPILER GLM_COMPILER_CLANG39 +# elif __clang_major__ == 4 && __clang_minor__ == 0 +# define GLM_COMPILER GLM_COMPILER_CLANG40 +# elif __clang_major__ == 4 && __clang_minor__ == 1 +# define GLM_COMPILER GLM_COMPILER_CLANG41 +# elif __clang_major__ == 4 && __clang_minor__ >= 2 +# define GLM_COMPILER GLM_COMPILER_CLANG42 +# elif __clang_major__ >= 4 +# define GLM_COMPILER GLM_COMPILER_CLANG42 +# endif +# endif + +// Visual C++ +#elif defined(_MSC_VER) +# if _MSC_VER >= 1920 +# define GLM_COMPILER GLM_COMPILER_VC16 +# elif _MSC_VER >= 1916 +# define GLM_COMPILER GLM_COMPILER_VC15_9 +# elif _MSC_VER >= 1915 +# define GLM_COMPILER GLM_COMPILER_VC15_8 +# elif _MSC_VER >= 1914 +# define GLM_COMPILER GLM_COMPILER_VC15_7 +# elif _MSC_VER >= 1913 +# define GLM_COMPILER GLM_COMPILER_VC15_6 +# elif _MSC_VER >= 1912 +# define GLM_COMPILER GLM_COMPILER_VC15_5 +# elif _MSC_VER >= 1911 +# define GLM_COMPILER GLM_COMPILER_VC15_3 +# elif _MSC_VER >= 1910 +# define GLM_COMPILER GLM_COMPILER_VC15 +# elif _MSC_VER >= 1900 +# define GLM_COMPILER GLM_COMPILER_VC14 +# elif _MSC_VER >= 1800 +# define GLM_COMPILER GLM_COMPILER_VC12 +# elif _MSC_VER < 1800 +# error "GLM requires Visual C++ 12 - 2013 or higher" +# endif//_MSC_VER + +// G++ +#elif defined(__GNUC__) || defined(__MINGW32__) +# if __GNUC__ >= 8 +# define GLM_COMPILER GLM_COMPILER_GCC8 +# elif __GNUC__ >= 7 +# define GLM_COMPILER GLM_COMPILER_GCC7 +# elif __GNUC__ >= 6 +# define GLM_COMPILER GLM_COMPILER_GCC6 +# elif __GNUC__ >= 5 +# define GLM_COMPILER GLM_COMPILER_GCC5 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9 +# define GLM_COMPILER GLM_COMPILER_GCC49 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +# define GLM_COMPILER GLM_COMPILER_GCC48 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7 +# define GLM_COMPILER GLM_COMPILER_GCC47 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6 +# define GLM_COMPILER GLM_COMPILER_GCC46 +# elif ((__GNUC__ == 4) && (__GNUC_MINOR__ < 6)) || (__GNUC__ < 4) +# error "GLM requires GCC 4.6 or higher" +# endif + +#else +# define GLM_COMPILER GLM_COMPILER_UNKNOWN +#endif + +#ifndef GLM_COMPILER +# error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message." +#endif//GLM_COMPILER + +/////////////////////////////////////////////////////////////////////////////////// +// Instruction sets + +// User defines: GLM_FORCE_PURE GLM_FORCE_INTRINSICS GLM_FORCE_SSE2 GLM_FORCE_SSE3 GLM_FORCE_AVX GLM_FORCE_AVX2 GLM_FORCE_AVX2 + +#define GLM_ARCH_MIPS_BIT (0x10000000) +#define GLM_ARCH_PPC_BIT (0x20000000) +#define GLM_ARCH_ARM_BIT (0x40000000) +#define GLM_ARCH_ARMV8_BIT (0x01000000) +#define GLM_ARCH_X86_BIT (0x80000000) + +#define GLM_ARCH_SIMD_BIT (0x00001000) + +#define GLM_ARCH_NEON_BIT (0x00000001) +#define GLM_ARCH_SSE_BIT (0x00000002) +#define GLM_ARCH_SSE2_BIT (0x00000004) +#define GLM_ARCH_SSE3_BIT (0x00000008) +#define GLM_ARCH_SSSE3_BIT (0x00000010) +#define GLM_ARCH_SSE41_BIT (0x00000020) +#define GLM_ARCH_SSE42_BIT (0x00000040) +#define GLM_ARCH_AVX_BIT (0x00000080) +#define GLM_ARCH_AVX2_BIT (0x00000100) + +#define GLM_ARCH_UNKNOWN (0) +#define GLM_ARCH_X86 (GLM_ARCH_X86_BIT) +#define GLM_ARCH_SSE (GLM_ARCH_SSE_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_X86) +#define GLM_ARCH_SSE2 (GLM_ARCH_SSE2_BIT | GLM_ARCH_SSE) +#define GLM_ARCH_SSE3 (GLM_ARCH_SSE3_BIT | GLM_ARCH_SSE2) +#define GLM_ARCH_SSSE3 (GLM_ARCH_SSSE3_BIT | GLM_ARCH_SSE3) +#define GLM_ARCH_SSE41 (GLM_ARCH_SSE41_BIT | GLM_ARCH_SSSE3) +#define GLM_ARCH_SSE42 (GLM_ARCH_SSE42_BIT | GLM_ARCH_SSE41) +#define GLM_ARCH_AVX (GLM_ARCH_AVX_BIT | GLM_ARCH_SSE42) +#define GLM_ARCH_AVX2 (GLM_ARCH_AVX2_BIT | GLM_ARCH_AVX) +#define GLM_ARCH_ARM (GLM_ARCH_ARM_BIT) +#define GLM_ARCH_ARMV8 (GLM_ARCH_NEON_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_ARM | GLM_ARCH_ARMV8_BIT) +#define GLM_ARCH_NEON (GLM_ARCH_NEON_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_ARM) +#define GLM_ARCH_MIPS (GLM_ARCH_MIPS_BIT) +#define GLM_ARCH_PPC (GLM_ARCH_PPC_BIT) + +#if defined(GLM_FORCE_ARCH_UNKNOWN) || defined(GLM_FORCE_PURE) +# define GLM_ARCH GLM_ARCH_UNKNOWN +#elif defined(GLM_FORCE_NEON) +# if __ARM_ARCH >= 8 +# define GLM_ARCH (GLM_ARCH_ARMV8) +# else +# define GLM_ARCH (GLM_ARCH_NEON) +# endif +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_AVX2) +# define GLM_ARCH (GLM_ARCH_AVX2) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_AVX) +# define GLM_ARCH (GLM_ARCH_AVX) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE42) +# define GLM_ARCH (GLM_ARCH_SSE42) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE41) +# define GLM_ARCH (GLM_ARCH_SSE41) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSSE3) +# define GLM_ARCH (GLM_ARCH_SSSE3) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE3) +# define GLM_ARCH (GLM_ARCH_SSE3) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE2) +# define GLM_ARCH (GLM_ARCH_SSE2) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE) +# define GLM_ARCH (GLM_ARCH_SSE) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_INTRINSICS) && !defined(GLM_FORCE_XYZW_ONLY) +# if defined(__AVX2__) +# define GLM_ARCH (GLM_ARCH_AVX2) +# elif defined(__AVX__) +# define GLM_ARCH (GLM_ARCH_AVX) +# elif defined(__SSE4_2__) +# define GLM_ARCH (GLM_ARCH_SSE42) +# elif defined(__SSE4_1__) +# define GLM_ARCH (GLM_ARCH_SSE41) +# elif defined(__SSSE3__) +# define GLM_ARCH (GLM_ARCH_SSSE3) +# elif defined(__SSE3__) +# define GLM_ARCH (GLM_ARCH_SSE3) +# elif defined(__SSE2__) || defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86_FP) +# define GLM_ARCH (GLM_ARCH_SSE2) +# elif defined(__i386__) +# define GLM_ARCH (GLM_ARCH_X86) +# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) +# define GLM_ARCH (GLM_ARCH_ARMV8) +# elif defined(__ARM_NEON) +# define GLM_ARCH (GLM_ARCH_ARM | GLM_ARCH_NEON) +# elif defined(__arm__ ) || defined(_M_ARM) +# define GLM_ARCH (GLM_ARCH_ARM) +# elif defined(__mips__ ) +# define GLM_ARCH (GLM_ARCH_MIPS) +# elif defined(__powerpc__ ) || defined(_M_PPC) +# define GLM_ARCH (GLM_ARCH_PPC) +# else +# define GLM_ARCH (GLM_ARCH_UNKNOWN) +# endif +#else +# if defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86) || defined(__i386__) +# define GLM_ARCH (GLM_ARCH_X86) +# elif defined(__arm__) || defined(_M_ARM) +# define GLM_ARCH (GLM_ARCH_ARM) +# elif defined(__powerpc__) || defined(_M_PPC) +# define GLM_ARCH (GLM_ARCH_PPC) +# elif defined(__mips__) +# define GLM_ARCH (GLM_ARCH_MIPS) +# else +# define GLM_ARCH (GLM_ARCH_UNKNOWN) +# endif +#endif + +#if GLM_ARCH & GLM_ARCH_AVX2_BIT +# include +#elif GLM_ARCH & GLM_ARCH_AVX_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE42_BIT +# if GLM_COMPILER & GLM_COMPILER_CLANG +# include +# endif +# include +#elif GLM_ARCH & GLM_ARCH_SSE41_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSSE3_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE3_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE2_BIT +# include +#elif GLM_ARCH & GLM_ARCH_NEON_BIT +# include "neon.h" +#endif//GLM_ARCH + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + typedef __m128 glm_f32vec4; + typedef __m128i glm_i32vec4; + typedef __m128i glm_u32vec4; + typedef __m128d glm_f64vec2; + typedef __m128i glm_i64vec2; + typedef __m128i glm_u64vec2; + + typedef glm_f32vec4 glm_vec4; + typedef glm_i32vec4 glm_ivec4; + typedef glm_u32vec4 glm_uvec4; + typedef glm_f64vec2 glm_dvec2; +#endif + +#if GLM_ARCH & GLM_ARCH_AVX_BIT + typedef __m256d glm_f64vec4; + typedef glm_f64vec4 glm_dvec4; +#endif + +#if GLM_ARCH & GLM_ARCH_AVX2_BIT + typedef __m256i glm_i64vec4; + typedef __m256i glm_u64vec4; +#endif + +#if GLM_ARCH & GLM_ARCH_NEON_BIT + typedef float32x4_t glm_f32vec4; + typedef int32x4_t glm_i32vec4; + typedef uint32x4_t glm_u32vec4; +#endif diff --git a/src/other/manifold/glm/glm/simd/trigonometric.h b/src/other/manifold/glm/glm/simd/trigonometric.h new file mode 100644 index 00000000000..739b796e7e4 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/trigonometric.h @@ -0,0 +1,9 @@ +/// @ref simd +/// @file glm/simd/trigonometric.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/other/manifold/glm/glm/simd/vector_relational.h b/src/other/manifold/glm/glm/simd/vector_relational.h new file mode 100644 index 00000000000..f7385e97473 --- /dev/null +++ b/src/other/manifold/glm/glm/simd/vector_relational.h @@ -0,0 +1,8 @@ +/// @ref simd +/// @file glm/simd/vector_relational.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/other/manifold/glm/glm/trigonometric.hpp b/src/other/manifold/glm/glm/trigonometric.hpp new file mode 100644 index 00000000000..fcf07f899f8 --- /dev/null +++ b/src/other/manifold/glm/glm/trigonometric.hpp @@ -0,0 +1,210 @@ +/// @ref core +/// @file glm/trigonometric.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions +/// +/// @defgroup core_func_trigonometric Angle and Trigonometry Functions +/// @ingroup core +/// +/// Function parameters specified as angle are assumed to be in units of radians. +/// In no case will any of these functions result in a divide by zero error. If +/// the divisor of a ratio is 0, then results will be undefined. +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. +/// +/// @see ext_vector_trigonometric + +#pragma once + +#include "detail/setup.hpp" +#include "detail/qualifier.hpp" + +namespace glm +{ + /// @addtogroup core_func_trigonometric + /// @{ + + /// Converts degrees to radians and returns the result. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL radians man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec radians(vec const& degrees); + + /// Converts radians to degrees and returns the result. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL degrees man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec degrees(vec const& radians); + + /// The standard trigonometric sine function. + /// The values returned by this function will range from [-1, 1]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sin man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec sin(vec const& angle); + + /// The standard trigonometric cosine function. + /// The values returned by this function will range from [-1, 1]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL cos man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec cos(vec const& angle); + + /// The standard trigonometric tangent function. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL tan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec tan(vec const& angle); + + /// Arc sine. Returns an angle whose sine is x. + /// The range of values returned by this function is [-PI/2, PI/2]. + /// Results are undefined if |x| > 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL asin man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec asin(vec const& x); + + /// Arc cosine. Returns an angle whose sine is x. + /// The range of values returned by this function is [0, PI]. + /// Results are undefined if |x| > 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL acos man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec acos(vec const& x); + + /// Arc tangent. Returns an angle whose tangent is y/x. + /// The signs of x and y are used to determine what + /// quadrant the angle is in. The range of values returned + /// by this function is [-PI, PI]. Results are undefined + /// if x and y are both 0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atan(vec const& y, vec const& x); + + /// Arc tangent. Returns an angle whose tangent is y_over_x. + /// The range of values returned by this function is [-PI/2, PI/2]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atan(vec const& y_over_x); + + /// Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2 + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sinh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec sinh(vec const& angle); + + /// Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2 + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL cosh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec cosh(vec const& angle); + + /// Returns the hyperbolic tangent function, sinh(angle) / cosh(angle) + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL tanh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec tanh(vec const& angle); + + /// Arc hyperbolic sine; returns the inverse of sinh. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL asinh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec asinh(vec const& x); + + /// Arc hyperbolic cosine; returns the non-negative inverse + /// of cosh. Results are undefined if x < 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL acosh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec acosh(vec const& x); + + /// Arc hyperbolic tangent; returns the inverse of tanh. + /// Results are undefined if abs(x) >= 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atanh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atanh(vec const& x); + + /// @} +}//namespace glm + +#include "detail/func_trigonometric.inl" diff --git a/src/other/manifold/glm/glm/vec2.hpp b/src/other/manifold/glm/glm/vec2.hpp new file mode 100644 index 00000000000..cd4e0708e10 --- /dev/null +++ b/src/other/manifold/glm/glm/vec2.hpp @@ -0,0 +1,14 @@ +/// @ref core +/// @file glm/vec2.hpp + +#pragma once +#include "./ext/vector_bool2.hpp" +#include "./ext/vector_bool2_precision.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float2_precision.hpp" +#include "./ext/vector_double2.hpp" +#include "./ext/vector_double2_precision.hpp" +#include "./ext/vector_int2.hpp" +#include "./ext/vector_int2_sized.hpp" +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_uint2_sized.hpp" diff --git a/src/other/manifold/glm/glm/vec3.hpp b/src/other/manifold/glm/glm/vec3.hpp new file mode 100644 index 00000000000..f5a927dbe4c --- /dev/null +++ b/src/other/manifold/glm/glm/vec3.hpp @@ -0,0 +1,14 @@ +/// @ref core +/// @file glm/vec3.hpp + +#pragma once +#include "./ext/vector_bool3.hpp" +#include "./ext/vector_bool3_precision.hpp" +#include "./ext/vector_float3.hpp" +#include "./ext/vector_float3_precision.hpp" +#include "./ext/vector_double3.hpp" +#include "./ext/vector_double3_precision.hpp" +#include "./ext/vector_int3.hpp" +#include "./ext/vector_int3_sized.hpp" +#include "./ext/vector_uint3.hpp" +#include "./ext/vector_uint3_sized.hpp" diff --git a/src/other/manifold/glm/glm/vec4.hpp b/src/other/manifold/glm/glm/vec4.hpp new file mode 100644 index 00000000000..c6ea9f1ff4c --- /dev/null +++ b/src/other/manifold/glm/glm/vec4.hpp @@ -0,0 +1,15 @@ +/// @ref core +/// @file glm/vec4.hpp + +#pragma once +#include "./ext/vector_bool4.hpp" +#include "./ext/vector_bool4_precision.hpp" +#include "./ext/vector_float4.hpp" +#include "./ext/vector_float4_precision.hpp" +#include "./ext/vector_double4.hpp" +#include "./ext/vector_double4_precision.hpp" +#include "./ext/vector_int4.hpp" +#include "./ext/vector_int4_sized.hpp" +#include "./ext/vector_uint4.hpp" +#include "./ext/vector_uint4_sized.hpp" + diff --git a/src/other/manifold/glm/glm/vector_relational.hpp b/src/other/manifold/glm/glm/vector_relational.hpp new file mode 100644 index 00000000000..a0fe17eb707 --- /dev/null +++ b/src/other/manifold/glm/glm/vector_relational.hpp @@ -0,0 +1,121 @@ +/// @ref core +/// @file glm/vector_relational.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions +/// +/// @defgroup core_func_vector_relational Vector Relational Functions +/// @ingroup core +/// +/// Relational and equality operators (<, <=, >, >=, ==, !=) are defined to +/// operate on scalars and produce scalar Boolean results. For vector results, +/// use the following built-in functions. +/// +/// In all cases, the sizes of all the input and return vectors for any particular +/// call must match. +/// +/// Include to use these core features. +/// +/// @see ext_vector_relational + +#pragma once + +#include "detail/qualifier.hpp" +#include "detail/setup.hpp" + +namespace glm +{ + /// @addtogroup core_func_vector_relational + /// @{ + + /// Returns the component-wise comparison result of x < y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL lessThan man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x <= y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL lessThanEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x > y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL greaterThan man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x >= y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL greaterThanEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x == y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point, integer or bool scalar type. + /// + /// @see GLSL equal man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x != y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point, integer or bool scalar type. + /// + /// @see GLSL notEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y); + + /// Returns true if any component of x is true. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL any man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR bool any(vec const& v); + + /// Returns true if all components of x are true. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL all man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR bool all(vec const& v); + + /// Returns the component-wise logical complement of x. + /// /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL not man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec not_(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_vector_relational.inl" diff --git a/src/other/manifold/glm/readme.md b/src/other/manifold/glm/readme.md new file mode 100644 index 00000000000..611c2576658 --- /dev/null +++ b/src/other/manifold/glm/readme.md @@ -0,0 +1,1209 @@ +![glm](/doc/manual/logo-mini.png) + +[OpenGL Mathematics](http://glm.g-truc.net/) (*GLM*) is a header only C++ mathematics library for graphics software based on the [OpenGL Shading Language (GLSL) specifications](https://www.opengl.org/registry/doc/GLSLangSpec.4.50.diff.pdf). + +*GLM* provides classes and functions designed and implemented with the same naming conventions and functionality than *GLSL* so that anyone who knows *GLSL*, can use *GLM* as well in C++. + +This project isn't limited to *GLSL* features. An extension system, based on the *GLSL* extension conventions, provides extended capabilities: matrix transformations, quaternions, data packing, random numbers, noise, etc... + +This library works perfectly with *[OpenGL](https://www.opengl.org)* but it also ensures interoperability with other third party libraries and SDK. It is a good candidate for software rendering (raytracing / rasterisation), image processing, physic simulations and any development context that requires a simple and convenient mathematics library. + +*GLM* is written in C++98 but can take advantage of C++11 when supported by the compiler. It is a platform independent library with no dependence and it officially supports the following compilers: +- [Apple Clang 6.0](https://developer.apple.com/library/mac/documentation/CompilerTools/Conceptual/LLVMCompilerOverview/index.html) and higher +- [GCC](http://gcc.gnu.org/) 4.7 and higher +- [Intel C++ Composer](https://software.intel.com/en-us/intel-compilers) XE 2013 and higher +- [LLVM](http://llvm.org/) 3.4 and higher +- [Visual C++](http://www.visualstudio.com/) 2013 and higher +- [CUDA](https://developer.nvidia.com/about-cuda) 9.0 and higher (experimental) +- [SYCL](https://www.khronos.org/sycl/) (experimental: only [ComputeCpp](https://codeplay.com/products/computesuite/computecpp) implementation has been tested). +- Any C++11 compiler + +For more information about *GLM*, please have a look at the [manual](manual.md) and the [API reference documentation](http://glm.g-truc.net/0.9.8/api/index.html). +The source code and the documentation are licensed under either the [Happy Bunny License (Modified MIT) or the MIT License](manual.md#section0). + +Thanks for contributing to the project by [submitting issues](https://github.com/g-truc/glm/issues) for bug reports and feature requests. Any feedback is welcome at [glm@g-truc.net](mailto://glm@g-truc.net). + +```cpp +#include // glm::vec3 +#include // glm::vec4 +#include // glm::mat4 +#include // glm::translate, glm::rotate, glm::scale +#include // glm::perspective +#include // glm::pi + +glm::mat4 camera(float Translate, glm::vec2 const& Rotate) +{ + glm::mat4 Projection = glm::perspective(glm::pi() * 0.25f, 4.0f / 3.0f, 0.1f, 100.f); + glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate)); + View = glm::rotate(View, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f)); + View = glm::rotate(View, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f)); + glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); + return Projection * View * Model; +} +``` + +## [Lastest release](https://github.com/g-truc/glm/releases/latest) + +## Project Health + +| Service | System | Compiler | Status | +| ------- | ------ | -------- | ------ | +| [Travis CI](https://travis-ci.org/g-truc/glm)| MacOSX, Linux 64 bits | Clang 3.6, Clang 5.0, GCC 4.9, GCC 7.3 | [![Travis CI](https://travis-ci.org/g-truc/glm.svg?branch=master)](https://travis-ci.org/g-truc/glm) +| [AppVeyor](https://ci.appveyor.com/project/Groovounet/glm)| Windows 32 and 64 | Visual Studio 2013, Visual Studio 2015, Visual Studio 2017 | [![AppVeyor](https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva?svg=true)](https://ci.appveyor.com/project/Groovounet/glm) + +## Release notes + +### [GLM 0.9.9.8](https://github.com/g-truc/glm/releases/tag/0.9.9.8) - 2020-04-13 +#### Features: +- Added GLM_EXT_vector_intX* and GLM_EXT_vector_uintX* extensions +- Added GLM_EXT_matrix_intX* and GLM_EXT_matrix_uintX* extensions + +#### Improvements: +- Added clamp, repeat, mirrorClamp and mirrorRepeat function to GLM_EXT_scalar_commond and GLM_EXT_vector_commond extensions with tests + +#### Fixes: +- Fixed unnecessary warnings from matrix_projection.inl #995 +- Fixed quaternion slerp overload which interpolates with extra spins #996 +- Fixed for glm::length using arch64 #992 +- Fixed singularity check for quatLookAt #770 + +### [GLM 0.9.9.7](https://github.com/g-truc/glm/releases/tag/0.9.9.7) - 2020-01-05 +#### Improvements: +- Improved Neon support with more functions optimized #950 +- Added CMake GLM interface #963 +- Added fma implementation based on std::fma #969 +- Added missing quat constexpr #955 +- Added GLM_FORCE_QUAT_DATA_WXYZ to store quat data as w,x,y,z instead of x,y,z,w #983 + +#### Fixes: +- Fixed equal ULP variation when using negative sign #965 +- Fixed for intersection ray/plane and added related tests #953 +- Fixed ARM 64bit detection #949 +- Fixed GLM_EXT_matrix_clip_space warnings #980 +- Fixed Wimplicit-int-float-conversion warnings with clang 10+ #986 +- Fixed EXT_matrix_clip_space perspectiveFov + +### [GLM 0.9.9.6](https://github.com/g-truc/glm/releases/tag/0.9.9.6) - 2019-09-08 +#### Features: +- Added Neon support #945 +- Added SYCL support #914 +- Added EXT_scalar_integer extension with power of two and multiple scalar functions +- Added EXT_vector_integer extension with power of two and multiple vector functions + +#### Improvements: +- Added Visual C++ 2019 detection +- Added Visual C++ 2017 15.8 and 15.9 detection +- Added missing genType check for bitCount and bitfieldReverse #893 + +#### Fixes: +- Fixed for g++6 where -std=c++1z sets __cplusplus to 201500 instead of 201402 #921 +- Fixed hash hashes qua instead of tquat #919 +- Fixed .natvis as structs renamed #915 +- Fixed ldexp and frexp declaration #895 +- Fixed missing const to quaternion conversion operators #890 +- Fixed EXT_scalar_ulp and EXT_vector_ulp API coding style +- Fixed quaternion componant order: w, {x, y, z} #916 +- Fixed GLM_HAS_CXX11_STL broken on Clang with Linux #926 +- Fixed Clang or GCC build due to wrong GLM_HAS_IF_CONSTEXPR definition #907 +- Fixed CUDA 9 build #910 + +#### Deprecation: + - Removed CMake install and uninstall scripts + +### [GLM 0.9.9.5](https://github.com/g-truc/glm/releases/tag/0.9.9.5) - 2019-04-01 +#### Fixes: +- Fixed build errors when defining GLM_ENABLE_EXPERIMENTAL #884 #883 +- Fixed 'if constexpr' warning #887 +- Fixed missing declarations for frexp and ldexp #886 + +### [GLM 0.9.9.4](https://github.com/g-truc/glm/releases/tag/0.9.9.4) - 2019-03-19 +#### Features: +- Added mix implementation for matrices in EXT_matrix_common #842 +- Added BUILD_SHARED_LIBS and BUILD_STATIC_LIBS build options #871 + +#### Improvements: +- Added GLM_FORCE_INTRINSICS to enable SIMD instruction code path. By default, it's disabled allowing constexpr support by default. #865 +- Optimized inverseTransform #867 + +#### Fixes: +- Fixed in mat4x3 conversion #829 +- Fixed constexpr issue on GCC #832 #865 +- Fixed mix implementation to improve GLSL conformance #866 +- Fixed int8 being defined as unsigned char with some compiler #839 +- Fixed vec1 include #856 +- Ignore .vscode #848 + +### [GLM 0.9.9.3](https://github.com/g-truc/glm/releases/tag/0.9.9.3) - 2018-10-31 +#### Features: +- Added equal and notEqual overload with max ULPs parameters for scalar numbers #121 +- Added GLM_FORCE_SILENT_WARNINGS to silent GLM warnings when using language extensions but using W4 or Wpedantic warnings #814 #775 +- Added adjugate functions to GTX_matrix_operation #151 +- Added GLM_FORCE_ALIGNED_GENTYPES to enable aligned types and SIMD instruction are not enabled. This disable constexpr #816 + +#### Improvements: +- Added constant time ULP distance between float #121 +- Added GLM_FORCE_SILENT_WARNINGS to suppress GLM warnings #822 + +#### Fixes: +- Fixed simplex noise build with double #734 +- Fixed bitfieldInsert according to GLSL spec #818 +- Fixed refract for negative 'k' #808 + +### [GLM 0.9.9.2](https://github.com/g-truc/glm/releases/tag/0.9.9.2) - 2018-09-14 +#### Fixes: +- Fixed GLM_FORCE_CXX** section in the manual +- Fixed default initialization with vector and quaternion types using GLM_FORCE_CTOR_INIT #812 + +### [GLM 0.9.9.1](https://github.com/g-truc/glm/releases/tag/0.9.9.1) - 2018-09-03 +#### Features: +- Added bitfieldDeinterleave to GTC_bitfield +- Added missing equal and notEqual with epsilon for quaternion types to GTC_quaternion +- Added EXT_matrix_relational: equal and notEqual with epsilon for matrix types +- Added missing aligned matrix types to GTC_type_aligned +- Added C++17 detection +- Added Visual C++ language standard version detection +- Added PDF manual build from markdown + +#### Improvements: +- Added a section to the manual for contributing to GLM +- Refactor manual, lists all configuration defines +- Added missing vec1 based constructors +- Redesigned constexpr support which excludes both SIMD and constexpr #783 +- Added detection of Visual C++ 2017 toolsets +- Added identity functions #765 +- Splitted headers into EXT extensions to improve compilation time #670 +- Added separated performance tests +- Clarified refract valid range of the indices of refraction, between -1 and 1 inclusively #806 + +#### Fixes: +- Fixed SIMD detection on Clang and GCC +- Fixed build problems due to printf and std::clock_t #778 +- Fixed int mod +- Anonymous unions require C++ language extensions +- Fixed ortho #790 +- Fixed Visual C++ 2013 warnings in vector relational code #782 +- Fixed ICC build errors with constexpr #704 +- Fixed defaulted operator= and constructors #791 +- Fixed invalid conversion from int scalar with vec4 constructor when using SSE instruction +- Fixed infinite loop in random functions when using negative radius values using an assert #739 + +### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/tag/0.9.9.0) - 2018-05-22 +#### Features: +- Added RGBM encoding in GTC_packing #420 +- Added GTX_color_encoding extension +- Added GTX_vec_swizzle, faster compile time swizzling then swizzle operator #558 +- Added GTX_exterior_product with a vec2 cross implementation #621 +- Added GTX_matrix_factorisation to factor matrices in various forms #654 +- Added [GLM_ENABLE_EXPERIMENTAL](manual.md#section7_4) to enable experimental features. +- Added packing functions for integer vectors #639 +- Added conan packaging configuration #643 #641 +- Added quatLookAt to GTX_quaternion #659 +- Added fmin, fmax and fclamp to GTX_extended_min_max #372 +- Added EXT_vector_relational: extend equal and notEqual to take an epsilon argument +- Added EXT_vector_relational: openBounded and closeBounded +- Added EXT_vec1: *vec1 types +- Added GTX_texture: levels function +- Added spearate functions to use both nagative one and zero near clip plans #680 +- Added GLM_FORCE_SINGLE_ONLY to use GLM on platforms that don't support double #627 +- Added GTX_easing for interpolation functions #761 + +#### Improvements: +- No more default initialization of vector, matrix and quaternion types +- Added lowp variant of GTC_color_space convertLinearToSRGB #419 +- Replaced the manual by a markdown version #458 +- Improved API documentation #668 +- Optimized GTC_packing implementation +- Optimized GTC_noise functions +- Optimized GTC_color_space HSV to RGB conversions +- Optimised GTX_color_space_YCoCg YCoCgR conversions +- Optimized GTX_matrix_interpolation axisAngle function +- Added FAQ 12: Windows headers cause build errors... #557 +- Removed GCC shadow warnings #595 +- Added error for including of different versions of GLM #619 +- Added GLM_FORCE_IGNORE_VERSION to ignore error caused by including different version of GLM #619 +- Reduced warnings when using very strict compilation flags #646 +- length() member functions are constexpr #657 +- Added support of -Weverything with Clang #646 +- Improved exponential function test coverage +- Enabled warnings as error with Clang unit tests +- Conan package is an external repository: https://github.com/bincrafters/conan-glm +- Clarify quat_cast documentation, applying on pure rotation matrices #759 + +#### Fixes: +- Removed doxygen references to GTC_half_float which was removed in 0.9.4 +- Fixed glm::decompose #448 +- Fixed intersectRayTriangle #6 +- Fixed dual quaternion != operator #629 +- Fixed usused variable warning in GTX_spline #618 +- Fixed references to GLM_FORCE_RADIANS which was removed #642 +- Fixed glm::fastInverseSqrt to use fast inverse square #640 +- Fixed axisAngle NaN #638 +- Fixed integer pow from GTX_integer with null exponent #658 +- Fixed quat normalize build error #656 +- Fixed Visual C++ 2017.2 warning regarding __has_feature definision #655 +- Fixed documentation warnings +- Fixed GLM_HAS_OPENMP when OpenMP is not enabled +- Fixed Better follow GLSL min and max specification #372 +- Fixed quaternion constructor from two vectors special cases #469 +- Fixed glm::to_string on quaternions wrong components order #681 +- Fixed acsch #698 +- Fixed isnan on CUDA #727 + +#### Deprecation: +- Requires Visual Studio 2013, GCC 4.7, Clang 3.4, Cuda 7, ICC 2013 or a C++11 compiler +- Removed GLM_GTX_simd_vec4 extension +- Removed GLM_GTX_simd_mat4 extension +- Removed GLM_GTX_simd_quat extension +- Removed GLM_SWIZZLE, use GLM_FORCE_SWIZZLE instead +- Removed GLM_MESSAGES, use GLM_FORCE_MESSAGES instead +- Removed GLM_DEPTH_ZERO_TO_ONE, use GLM_FORCE_DEPTH_ZERO_TO_ONE instead +- Removed GLM_LEFT_HANDED, use GLM_FORCE_LEFT_HANDED instead +- Removed GLM_FORCE_NO_CTOR_INIT +- Removed glm::uninitialize + +--- +### [GLM 0.9.8.5](https://github.com/g-truc/glm/releases/tag/0.9.8.5) - 2017-08-16 +#### Features: +- Added Conan package support #647 + +#### Fixes: +- Fixed Clang version detection from source #608 +- Fixed packF3x9_E1x5 exponent packing #614 +- Fixed build error min and max specializations with integer #616 +- Fixed simd_mat4 build error #652 + +--- +### [GLM 0.9.8.4](https://github.com/g-truc/glm/releases/tag/0.9.8.4) - 2017-01-22 +#### Fixes: +- Fixed GTC_packing test failing on GCC x86 due to denorms #212 #577 +- Fixed POPCNT optimization build in Clang #512 +- Fixed intersectRayPlane returns true in parallel case #578 +- Fixed GCC 6.2 compiler warnings #580 +- Fixed GTX_matrix_decompose decompose #582 #448 +- Fixed GCC 4.5 and older build #566 +- Fixed Visual C++ internal error when declaring a global vec type with siwzzle expression enabled #594 +- Fixed GLM_FORCE_CXX11 with Clang and libstlc++ which wasn't using C++11 STL features. #604 + +--- +### [GLM 0.9.8.3](https://github.com/g-truc/glm/releases/tag/0.9.8.3) - 2016-11-12 +#### Improvements: +- Broader support of GLM_FORCE_UNRESTRICTED_GENTYPE #378 + +#### Fixes: +- Fixed Android build error with C++11 compiler but C++98 STL #284 #564 +- Fixed GTX_transform2 shear* functions #403 +- Fixed interaction between GLM_FORCE_UNRESTRICTED_GENTYPE and ortho function #568 +- Fixed bitCount with AVX on 32 bit builds #567 +- Fixed CMake find_package with version specification #572 #573 + +--- +### [GLM 0.9.8.2](https://github.com/g-truc/glm/releases/tag/0.9.8.2) - 2016-11-01 +#### Improvements: +- Added Visual C++ 15 detection +- Added Clang 4.0 detection +- Added warning messages when using GLM_FORCE_CXX** but the compiler + is known to not fully support the requested C++ version #555 +- Refactored GLM_COMPILER_VC values +- Made quat, vec, mat type component length() static #565 + +#### Fixes: +- Fixed Visual C++ constexpr build error #555, #556 + +--- +### [GLM 0.9.8.1](https://github.com/g-truc/glm/releases/tag/0.9.8.1) - 2016-09-25 +#### Improvements: +- Optimized quaternion log function #554 + +#### Fixes: +- Fixed GCC warning filtering, replaced -pedantic by -Wpedantic +- Fixed SIMD faceforward bug. #549 +- Fixed GCC 4.8 with C++11 compilation option #550 +- Fixed Visual Studio aligned type W4 warning #548 +- Fixed packing/unpacking function fixed for 5_6_5 and 5_5_5_1 #552 + +--- +### [GLM 0.9.8.0](https://github.com/g-truc/glm/releases/tag/0.9.8.0) - 2016-09-11 +#### Features: +- Added right and left handed projection and clip control support #447 #415 #119 +- Added compNormalize and compScale functions to GTX_component_wise +- Added packF3x9_E1x5 and unpackF3x9_E1x5 to GTC_packing for RGB9E5 #416 +- Added (un)packHalf to GTC_packing +- Added (un)packUnorm and (un)packSnorm to GTC_packing +- Added 16bit pack and unpack to GTC_packing +- Added 8bit pack and unpack to GTC_packing +- Added missing bvec* && and || operators +- Added iround and uround to GTC_integer, fast round on positive values +- Added raw SIMD API +- Added 'aligned' qualifiers +- Added GTC_type_aligned with aligned *vec* types +- Added GTC_functions extension +- Added quaternion version of isnan and isinf #521 +- Added lowestBitValue to GTX_bit #536 +- Added GLM_FORCE_UNRESTRICTED_GENTYPE allowing non basic genType #543 + +#### Improvements: +- Improved SIMD and swizzle operators interactions with GCC and Clang #474 +- Improved GTC_random linearRand documentation +- Improved GTC_reciprocal documentation +- Improved GLM_FORCE_EXPLICIT_CTOR coverage #481 +- Improved OpenMP support detection for Clang, GCC, ICC and VC +- Improved GTX_wrap for SIMD friendliness +- Added constexpr for *vec*, *mat*, *quat* and *dual_quat* types #493 +- Added NEON instruction set detection +- Added MIPS CPUs detection +- Added PowerPC CPUs detection +- Use Cuda built-in function for abs function implementation with Cuda compiler +- Factorized GLM_COMPILER_LLVM and GLM_COMPILER_APPLE_CLANG into GLM_COMPILER_CLANG +- No more warnings for use of long long +- Added more information to build messages + +#### Fixes: +- Fixed GTX_extended_min_max filename typo #386 +- Fixed intersectRayTriangle to not do any unintentional backface culling +- Fixed long long warnings when using C++98 on GCC and Clang #482 +- Fixed sign with signed integer function on non-x86 architecture +- Fixed strict aliasing warnings #473 +- Fixed missing vec1 overload to length2 and distance2 functions #431 +- Fixed GLM test '/fp:fast' and '/Za' command-line options are incompatible +- Fixed quaterion to mat3 cast function mat3_cast from GTC_quaternion #542 +- Fixed GTX_io for Cuda #547 #546 + +#### Deprecation: +- Removed GLM_FORCE_SIZE_FUNC define +- Deprecated GLM_GTX_simd_vec4 extension +- Deprecated GLM_GTX_simd_mat4 extension +- Deprecated GLM_GTX_simd_quat extension +- Deprecated GLM_SWIZZLE, use GLM_FORCE_SWIZZLE instead +- Deprecated GLM_MESSAGES, use GLM_FORCE_MESSAGES instead + +--- +### [GLM 0.9.7.6](https://github.com/g-truc/glm/releases/tag/0.9.7.6) - 2016-07-16 +#### Improvements: +- Added pkg-config file #509 +- Updated list of compiler versions detected +- Improved C++ 11 STL detection #523 + +#### Fixes: +- Fixed STL for C++11 detection on ICC #510 +- Fixed missing vec1 overload to length2 and distance2 functions #431 +- Fixed long long warnings when using C++98 on GCC and Clang #482 +- Fixed scalar reciprocal functions (GTC_reciprocal) #520 + +--- +### [GLM 0.9.7.5](https://github.com/g-truc/glm/releases/tag/0.9.7.5) - 2016-05-24 +#### Improvements: +- Added Visual C++ Clang toolset detection + +#### Fixes: +- Fixed uaddCarry warning #497 +- Fixed roundPowerOfTwo and floorPowerOfTwo #503 +- Fixed Visual C++ SIMD instruction set automatic detection in 64 bits +- Fixed to_string when used with GLM_FORCE_INLINE #506 +- Fixed GLM_FORCE_INLINE with binary vec4 operators +- Fixed GTX_extended_min_max filename typo #386 +- Fixed intersectRayTriangle to not do any unintentional backface culling + +--- +### [GLM 0.9.7.4](https://github.com/g-truc/glm/releases/tag/0.9.7.4) - 2016-03-19 +#### Fixes: +- Fixed asinh and atanh warning with C++98 STL #484 +- Fixed polar coordinates function latitude #485 +- Fixed outerProduct defintions and operator signatures for mat2x4 and vec4 #475 +- Fixed eulerAngles precision error, returns NaN #451 +- Fixed undefined reference errors #489 +- Fixed missing GLM_PLATFORM_CYGWIN declaration #495 +- Fixed various undefined reference errors #490 + +--- +### [GLM 0.9.7.3](https://github.com/g-truc/glm/releases/tag/0.9.7.3) - 2016-02-21 +#### Improvements: +- Added AVX512 detection + +#### Fixes: +- Fixed CMake policy warning +- Fixed GCC 6.0 detection #477 +- Fixed Clang build on Windows #479 +- Fixed 64 bits constants warnings on GCC #463 + +--- +### [GLM 0.9.7.2](https://github.com/g-truc/glm/releases/tag/0.9.7.2) - 2016-01-03 +#### Fixes: +- Fixed GTC_round floorMultiple/ceilMultiple #412 +- Fixed GTC_packing unpackUnorm3x10_1x2 #414 +- Fixed GTC_matrix_inverse affineInverse #192 +- Fixed ICC on Linux build errors #449 +- Fixed ldexp and frexp compilation errors +- Fixed "Declaration shadows a field" warning #468 +- Fixed 'GLM_COMPILER_VC2005 is not defined' warning #468 +- Fixed various 'X is not defined' warnings #468 +- Fixed missing unary + operator #435 +- Fixed Cygwin build errors when using C++11 #405 + +--- +### [GLM 0.9.7.1](https://github.com/g-truc/glm/releases/tag/0.9.7.1) - 2015-09-07 +#### Improvements: +- Improved constexpr for constant functions coverage #198 +- Added to_string for quat and dual_quat in GTX_string_cast #375 +- Improved overall execution time of unit tests #396 + +#### Fixes: +- Fixed strict alignment warnings #235 #370 +- Fixed link errors on compilers not supported default function #377 +- Fixed compilation warnings in vec4 +- Fixed non-identity quaternions for equal vectors #234 +- Fixed excessive GTX_fast_trigonometry execution time #396 +- Fixed Visual Studio 2015 'hides class member' warnings #394 +- Fixed builtin bitscan never being used #392 +- Removed unused func_noise.* files #398 + +--- +### [GLM 0.9.7.0](https://github.com/g-truc/glm/releases/tag/0.9.7.0) - 2015-08-02 +#### Features: +- Added GTC_color_space: convertLinearToSRGB and convertSRGBToLinear functions +- Added 'fmod' overload to GTX_common with tests #308 +- Left handed perspective and lookAt functions #314 +- Added functions eulerAngleXYZ and extractEulerAngleXYZ #311 +- Added to perform std::hash on GLM types #320 #367 +- Added for texcoord wrapping +- Added static components and precision members to all vector and quat types #350 +- Added .gitignore #349 +- Added support of defaulted functions to GLM types, to use them in unions #366 + +#### Improvements: +- Changed usage of __has_include to support Intel compiler #307 +- Specialized integer implementation of YCoCg-R #310 +- Don't show status message in 'FindGLM' if 'QUIET' option is set. #317 +- Added master branch continuous integration service on Linux 64 #332 +- Clarified manual regarding angle unit in GLM, added FAQ 11 #326 +- Updated list of compiler versions + +#### Fixes: +- Fixed default precision for quat and dual_quat type #312 +- Fixed (u)int64 MSB/LSB handling on BE archs #306 +- Fixed multi-line comment warning in g++. #315 +- Fixed specifier removal by 'std::make_pair<>' #333 +- Fixed perspective fovy argument documentation #327 +- Removed -m64 causing build issues on Linux 32 #331 +- Fixed isfinite with C++98 compilers #343 +- Fixed Intel compiler build error on Linux #354 +- Fixed use of libstdc++ with Clang #351 +- Fixed quaternion pow #346 +- Fixed decompose warnings #373 +- Fixed matrix conversions #371 + +#### Deprecation: +- Removed integer specification for 'mod' in GTC_integer #308 +- Removed GTX_multiple, replaced by GTC_round + +--- +### [GLM 0.9.6.3](https://github.com/g-truc/glm/releases/tag/0.9.6.3) - 2015-02-15 +- Fixed Android doesn't have C++ 11 STL #284 + +--- +### [GLM 0.9.6.2](https://github.com/g-truc/glm/releases/tag/0.9.6.2) - 2015-02-15 +#### Features: +- Added display of GLM version with other GLM_MESSAGES +- Added ARM instruction set detection + +#### Improvements: +- Removed assert for perspective with zFar < zNear #298 +- Added Visual Studio natvis support for vec1, quat and dualqual types +- Cleaned up C++11 feature detections +- Clarify GLM licensing + +#### Fixes: +- Fixed faceforward build #289 +- Fixed conflict with Xlib #define True 1 #293 +- Fixed decompose function VS2010 templating issues #294 +- Fixed mat4x3 = mat2x3 * mat4x2 operator #297 +- Fixed warnings in F2x11_1x10 packing function in GTC_packing #295 +- Fixed Visual Studio natvis support for vec4 #288 +- Fixed GTC_packing *pack*norm*x* build and added tests #292 +- Disabled GTX_scalar_multiplication for GCC, failing to build tests #242 +- Fixed Visual C++ 2015 constexpr errors: Disabled only partial support +- Fixed functions not inlined with Clang #302 +- Fixed memory corruption (undefined behaviour) #303 + +--- +### [GLM 0.9.6.1](https://github.com/g-truc/glm/releases/tag/0.9.6.1) - 2014-12-10 +#### Features: +- Added GLM_LANG_CXX14_FLAG and GLM_LANG_CXX1Z_FLAG language feature flags +- Added C++14 detection + +#### Improvements: +- Clean up GLM_MESSAGES compilation log to report only detected capabilities + +#### Fixes: +- Fixed scalar uaddCarry build error with Cuda #276 +- Fixed C++11 explicit conversion operators detection #282 +- Fixed missing explicit conversion when using integer log2 with *vec1 types +- Fixed 64 bits integer GTX_string_cast to_string on VC 32 bit compiler +- Fixed Android build issue, STL C++11 is not supported by the NDK #284 +- Fixed unsupported _BitScanForward64 and _BitScanReverse64 in VC10 +- Fixed Visual C++ 32 bit build #283 +- Fixed GLM_FORCE_SIZE_FUNC pragma message +- Fixed C++98 only build +- Fixed conflict between GTX_compatibility and GTC_quaternion #286 +- Fixed C++ language restriction using GLM_FORCE_CXX** + +--- +### [GLM 0.9.6.0](https://github.com/g-truc/glm/releases/tag/0.9.6.0) - 2014-11-30 +#### Features: +- Exposed template vector and matrix types in 'glm' namespace #239, #244 +- Added GTX_scalar_multiplication for C++ 11 compiler only #242 +- Added GTX_range for C++ 11 compiler only #240 +- Added closestPointOnLine function for tvec2 to GTX_closest_point #238 +- Added GTC_vec1 extension, *vec1 support to *vec* types +- Updated GTX_associated_min_max with vec1 support +- Added support of precision and integers to linearRand #230 +- Added Integer types support to GTX_string_cast #249 +- Added vec3 slerp #237 +- Added GTX_common with isdenomal #223 +- Added GLM_FORCE_SIZE_FUNC to replace .length() by .size() #245 +- Added GLM_FORCE_NO_CTOR_INIT +- Added 'uninitialize' to explicitly not initialize a GLM type +- Added GTC_bitfield extension, promoted GTX_bit +- Added GTC_integer extension, promoted GTX_bit and GTX_integer +- Added GTC_round extension, promoted GTX_bit +- Added GLM_FORCE_EXPLICIT_CTOR to require explicit type conversions #269 +- Added GTX_type_aligned for aligned vector, matrix and quaternion types + +#### Improvements: +- Rely on C++11 to implement isinf and isnan +- Removed GLM_FORCE_CUDA, Cuda is implicitly detected +- Separated Apple Clang and LLVM compiler detection +- Used pragma once +- Undetected C++ compiler automatically compile with GLM_FORCE_CXX98 and + GLM_FORCE_PURE +- Added not function (from GLSL specification) on VC12 +- Optimized bitfieldReverse and bitCount functions +- Optimized findLSB and findMSB functions. +- Optimized matrix-vector multiple performance with Cuda #257, #258 +- Reduced integer type redifinitions #233 +- Rewrited of GTX_fast_trigonometry #264 #265 +- Made types trivially copyable #263 +- Removed in GLM tests +- Used std features within GLM without redeclaring +- Optimized cot function #272 +- Optimized sign function #272 +- Added explicit cast from quat to mat3 and mat4 #275 + +#### Fixes: +- Fixed std::nextafter not supported with C++11 on Android #217 +- Fixed missing value_type for dual quaternion +- Fixed return type of dual quaternion length +- Fixed infinite loop in isfinite function with GCC #221 +- Fixed Visual Studio 14 compiler warnings +- Fixed implicit conversion from another tvec2 type to another tvec2 #241 +- Fixed lack of consistency of quat and dualquat constructors +- Fixed uaddCarray #253 +- Fixed float comparison warnings #270 + +#### Deprecation: +- Requires Visual Studio 2010, GCC 4.2, Apple Clang 4.0, LLVM 3.0, Cuda 4, ICC 2013 or a C++98 compiler +- Removed degrees for function parameters +- Removed GLM_FORCE_RADIANS, active by default +- Removed VC 2005 / 8 and 2008 / 9 support +- Removed GCC 3.4 to 4.3 support +- Removed LLVM GCC support +- Removed LLVM 2.6 to 3.1 support +- Removed CUDA 3.0 to 3.2 support + +--- +### [GLM 0.9.5.4 - 2014-06-21](https://github.com/g-truc/glm/releases/tag/0.9.5.4) +- Fixed non-utf8 character #196 +- Added FindGLM install for CMake #189 +- Fixed GTX_color_space - saturation #195 +- Fixed glm::isinf and glm::isnan for with Android NDK 9d #191 +- Fixed builtin GLM_ARCH_SSE4 #204 +- Optimized Quaternion vector rotation #205 +- Fixed missing doxygen @endcond tag #211 +- Fixed instruction set detection with Clang #158 +- Fixed orientate3 function #207 +- Fixed lerp when cosTheta is close to 1 in quaternion slerp #210 +- Added GTX_io for io with #144 +- Fixed fastDistance ambiguity #215 +- Fixed tweakedInfinitePerspective #208 and added user-defined epsilon to + tweakedInfinitePerspective +- Fixed std::copy and std::vector with GLM types #214 +- Fixed strict aliasing issues #212, #152 +- Fixed std::nextafter not supported with C++11 on Android #213 +- Fixed corner cases in exp and log functions for quaternions #199 + +--- +### GLM 0.9.5.3 - 2014-04-02 +- Added instruction set auto detection with Visual C++ using _M_IX86_FP - /arch + compiler argument +- Fixed GTX_raw_data code dependency +- Fixed GCC instruction set detection +- Added GLM_GTX_matrix_transform_2d extension (#178, #176) +- Fixed CUDA issues (#169, #168, #183, #182) +- Added support for all extensions but GTX_string_cast to CUDA +- Fixed strict aliasing warnings in GCC 4.8.1 / Android NDK 9c (#152) +- Fixed missing bitfieldInterleave definisions +- Fixed usubBorrow (#171) +- Fixed eulerAngle*** not consistent for right-handed coordinate system (#173) +- Added full tests for eulerAngle*** functions (#173) +- Added workaround for a CUDA compiler bug (#186, #185) + +--- +### GLM 0.9.5.2 - 2014-02-08 +- Fixed initializer list ambiguity (#159, #160) +- Fixed warnings with the Android NDK 9c +- Fixed non power of two matrix products +- Fixed mix function link error +- Fixed SSE code included in GLM tests on "pure" platforms +- Fixed undefined reference to fastInverseSqrt (#161) +- Fixed GLM_FORCE_RADIANS with build error (#165) +- Fix dot product clamp range for vector angle functions. (#163) +- Tentative fix for strict aliasing warning in GCC 4.8.1 / Android NDK 9c (#152) +- Fixed GLM_GTC_constants description brief (#162) + +--- +### GLM 0.9.5.1 - 2014-01-11 +- Fixed angle and orientedAngle that sometimes return NaN values (#145) +- Deprecated degrees for function parameters and display a message +- Added possible static_cast conversion of GLM types (#72) +- Fixed error 'inverse' is not a member of 'glm' from glm::unProject (#146) +- Fixed mismatch between some declarations and definitions +- Fixed inverse link error when using namespace glm; (#147) +- Optimized matrix inverse and division code (#149) +- Added intersectRayPlane function (#153) +- Fixed outerProduct return type (#155) + +--- +### GLM 0.9.5.0 - 2013-12-25 +- Added forward declarations (glm/fwd.hpp) for faster compilations +- Added per feature headers +- Minimized GLM internal dependencies +- Improved Intel Compiler detection +- Added bitfieldInterleave and _mm_bit_interleave_si128 functions +- Added GTX_scalar_relational +- Added GTX_dual_quaternion +- Added rotation function to GTX_quaternion (#22) +- Added precision variation of each type +- Added quaternion comparison functions +- Fixed GTX_multiple for negative value +- Removed GTX_ocl_type extension +- Fixed post increment and decrement operators +- Fixed perspective with zNear == 0 (#71) +- Removed l-value swizzle operators +- Cleaned up compiler detection code for unsupported compilers +- Replaced C cast by C++ casts +- Fixed .length() that should return a int and not a size_t +- Added GLM_FORCE_SIZE_T_LENGTH and glm::length_t +- Removed unnecessary conversions +- Optimized packing and unpacking functions +- Removed the normalization of the up argument of lookAt function (#114) +- Added low precision specializations of inversesqrt +- Fixed ldexp and frexp implementations +- Increased assert coverage +- Increased static_assert coverage +- Replaced GLM traits by STL traits when possible +- Allowed including individual core feature +- Increased unit tests completness +- Added creating of a quaternion from two vectors +- Added C++11 initializer lists +- Fixed umulExtended and imulExtended implementations for vector types (#76) +- Fixed CUDA coverage for GTC extensions +- Added GTX_io extension +- Improved GLM messages enabled when defining GLM_MESSAGES +- Hidden matrix _inverse function implementation detail into private section + +--- +### [GLM 0.9.4.6](https://github.com/g-truc/glm/releases/tag/0.9.4.6) - 2013-09-20 +- Fixed detection to select the last known compiler if newer version #106 +- Fixed is_int and is_uint code duplication with GCC and C++11 #107 +- Fixed test suite build while using Clang in C++11 mode +- Added c++1y mode support in CMake test suite +- Removed ms extension mode to CMake when no using Visual C++ +- Added pedantic mode to CMake test suite for Clang and GCC +- Added use of GCC frontend on Unix for ICC and Visual C++ fronted on Windows + for ICC +- Added compilation errors for unsupported compiler versions +- Fixed glm::orientation with GLM_FORCE_RADIANS defined #112 +- Fixed const ref issue on assignment operator taking a scalar parameter #116 +- Fixed glm::eulerAngleY implementation #117 + +--- +### GLM 0.9.4.5 - 2013-08-12 +- Fixed CUDA support +- Fixed inclusion of intrinsics in "pure" mode #92 +- Fixed language detection on GCC when the C++0x mode isn't enabled #95 +- Fixed issue #97: register is deprecated in C++11 +- Fixed issue #96: CUDA issues +- Added Windows CE detection #92 +- Added missing value_ptr for quaternions #99 + +--- +### GLM 0.9.4.4 - 2013-05-29 +- Fixed slerp when costheta is close to 1 #65 +- Fixed mat4x2 value_type constructor #70 +- Fixed glm.natvis for Visual C++ 12 #82 +- Added assert in inversesqrt to detect division by zero #61 +- Fixed missing swizzle operators #86 +- Fixed CUDA warnings #86 +- Fixed GLM natvis for VC11 #82 +- Fixed GLM_GTX_multiple with negative values #79 +- Fixed glm::perspective when zNear is zero #71 + +--- +### GLM 0.9.4.3 - 2013-03-20 +- Detected qualifier for Clang +- Fixed C++11 mode for GCC, couldn't be enabled without MS extensions +- Fixed squad, intermediate and exp quaternion functions +- Fixed GTX_polar_coordinates euclidean function, takes a vec2 instead of a vec3 +- Clarify the license applying on the manual +- Added a docx copy of the manual +- Fixed GLM_GTX_matrix_interpolation +- Fixed isnan and isinf on Android with Clang +- Autodetected C++ version using __cplusplus value +- Fixed mix for bool and bvec* third parameter + +--- +### GLM 0.9.4.2 - 2013-02-14 +- Fixed compAdd from GTX_component_wise +- Fixed SIMD support for Intel compiler on Windows +- Fixed isnan and isinf for CUDA compiler +- Fixed GLM_FORCE_RADIANS on glm::perspective +- Fixed GCC warnings +- Fixed packDouble2x32 on Xcode +- Fixed mix for vec4 SSE implementation +- Fixed 0x2013 dash character in comments that cause issue in Windows + Japanese mode +- Fixed documentation warnings +- Fixed CUDA warnings + +--- +### GLM 0.9.4.1 - 2012-12-22 +- Improved half support: -0.0 case and implicit conversions +- Fixed Intel Composer Compiler support on Linux +- Fixed interaction between quaternion and euler angles +- Fixed GTC_constants build +- Fixed GTX_multiple +- Fixed quat slerp using mix function when cosTheta close to 1 +- Improved fvec4SIMD and fmat4x4SIMD implementations +- Fixed assert messages +- Added slerp and lerp quaternion functions and tests + +--- +### GLM 0.9.4.0 - 2012-11-18 +- Added Intel Composer Compiler support +- Promoted GTC_espilon extension +- Promoted GTC_ulp extension +- Removed GLM website from the source repository +- Added GLM_FORCE_RADIANS so that all functions takes radians for arguments +- Fixed detection of Clang and LLVM GCC on MacOS X +- Added debugger visualizers for Visual C++ 2012 +- Requires Visual Studio 2005, GCC 4.2, Clang 2.6, Cuda 3, ICC 2013 or a C++98 compiler + +--- +### [GLM 0.9.3.4](https://github.com/g-truc/glm/releases/tag/0.9.3.4) - 2012-06-30 +- Added SSE4 and AVX2 detection. +- Removed VIRTREV_xstream and the incompatibility generated with GCC +- Fixed C++11 compiler option for GCC +- Removed MS language extension option for GCC (not fonctionnal) +- Fixed bitfieldExtract for vector types +- Fixed warnings +- Fixed SSE includes + +--- +### GLM 0.9.3.3 - 2012-05-10 +- Fixed isinf and isnan +- Improved compatibility with Intel compiler +- Added CMake test build options: SIMD, C++11, fast math and MS land ext +- Fixed SIMD mat4 test on GCC +- Fixed perspectiveFov implementation +- Fixed matrixCompMult for none-square matrices +- Fixed namespace issue on stream operators +- Fixed various warnings +- Added VC11 support + +--- +### GLM 0.9.3.2 - 2012-03-15 +- Fixed doxygen documentation +- Fixed Clang version detection +- Fixed simd mat4 /= operator + +--- +### GLM 0.9.3.1 - 2012-01-25 +- Fixed platform detection +- Fixed warnings +- Removed detail code from Doxygen doc + +--- +### GLM 0.9.3.0 - 2012-01-09 +- Added CPP Check project +- Fixed conflict with Windows headers +- Fixed isinf implementation +- Fixed Boost conflict +- Fixed warnings + +--- +### GLM 0.9.3.B - 2011-12-12 +- Added support for Chrone Native Client +- Added epsilon constant +- Removed value_size function from vector types +- Fixed roundEven on GCC +- Improved API documentation +- Fixed modf implementation +- Fixed step function accuracy +- Fixed outerProduct + +--- +### GLM 0.9.3.A - 2011-11-11 +- Improved doxygen documentation +- Added new swizzle operators for C++11 compilers +- Added new swizzle operators declared as functions +- Added GLSL 4.20 length for vector and matrix types +- Promoted GLM_GTC_noise extension: simplex, perlin, periodic noise functions +- Promoted GLM_GTC_random extension: linear, gaussian and various random number +generation distribution +- Added GLM_GTX_constants: provides useful constants +- Added extension versioning +- Removed many unused namespaces +- Fixed half based type contructors +- Added GLSL core noise functions + +--- +### [GLM 0.9.2.7](https://github.com/g-truc/glm/releases/tag/0.9.2.7) - 2011-10-24 +- Added more swizzling constructors +- Added missing none-squared matrix products + +--- +### [GLM 0.9.2.6](https://github.com/g-truc/glm/releases/tag/0.9.2.6) - 2011-10-01 +- Fixed half based type build on old GCC +- Fixed /W4 warnings on Visual C++ +- Fixed some missing l-value swizzle operators + +--- +### GLM 0.9.2.5 - 2011-09-20 +- Fixed floatBitToXint functions +- Fixed pack and unpack functions +- Fixed round functions + +--- +### GLM 0.9.2.4 - 2011-09-03 +- Fixed extensions bugs + +--- +### GLM 0.9.2.3 - 2011-06-08 +- Fixed build issues + +--- +### GLM 0.9.2.2 - 2011-06-02 +- Expend matrix constructors flexibility +- Improved quaternion implementation +- Fixed many warnings across platforms and compilers + +--- +### GLM 0.9.2.1 - 2011-05-24 +- Automatically detect CUDA support +- Improved compiler detection +- Fixed errors and warnings in VC with C++ extensions disabled +- Fixed and tested GLM_GTX_vector_angle +- Fixed and tested GLM_GTX_rotate_vector + +--- +### GLM 0.9.2.0 - 2011-05-09 +- Added CUDA support +- Added CTest test suite +- Added GLM_GTX_ulp extension +- Added GLM_GTX_noise extension +- Added GLM_GTX_matrix_interpolation extension +- Updated quaternion slerp interpolation + +--- +### [GLM 0.9.1.3](https://github.com/g-truc/glm/releases/tag/0.9.1.3) - 2011-05-07 +- Fixed bugs + +--- +### GLM 0.9.1.2 - 2011-04-15 +- Fixed bugs + +--- +### GLM 0.9.1.1 - 2011-03-17 +- Fixed bugs + +--- +### GLM 0.9.1.0 - 2011-03-03 +- Fixed bugs + +--- +### GLM 0.9.1.B - 2011-02-13 +- Updated API documentation +- Improved SIMD implementation +- Fixed Linux build + +--- +### [GLM 0.9.0.8](https://github.com/g-truc/glm/releases/tag/0.9.0.8) - 2011-02-13 +- Added quaternion product operator. +- Clarify that GLM is a header only library. + +--- +### GLM 0.9.1.A - 2011-01-31 +- Added SIMD support +- Added new swizzle functions +- Improved static assert error message with C++0x static_assert +- New setup system +- Reduced branching +- Fixed trunc implementation + +--- +### [GLM 0.9.0.7](https://github.com/g-truc/glm/releases/tag/0.9.0.7) - 2011-01-30 +- Added GLSL 4.10 packing functions +- Added == and != operators for every types. + +--- +### GLM 0.9.0.6 - 2010-12-21 +- Many matrices bugs fixed + +--- +### GLM 0.9.0.5 - 2010-11-01 +- Improved Clang support +- Fixed bugs + +--- +### GLM 0.9.0.4 - 2010-10-04 +- Added autoexp for GLM +- Fixed bugs + +--- +### GLM 0.9.0.3 - 2010-08-26 +- Fixed non-squared matrix operators + +--- +### GLM 0.9.0.2 - 2010-07-08 +- Added GLM_GTX_int_10_10_10_2 +- Fixed bugs + +--- +### GLM 0.9.0.1 - 2010-06-21 +- Fixed extensions errors + +--- +### GLM 0.9.0.0 - 2010-05-25 +- Objective-C support +- Fixed warnings +- Updated documentation + +--- +### GLM 0.9.B.2 - 2010-04-30 +- Git transition +- Removed experimental code from releases +- Fixed bugs + +--- +### GLM 0.9.B.1 - 2010-04-03 +- Based on GLSL 4.00 specification +- Added the new core functions +- Added some implicit conversion support + +--- +### GLM 0.9.A.2 - 2010-02-20 +- Improved some possible errors messages +- Improved declarations and definitions match + +--- +### GLM 0.9.A.1 - 2010-02-09 +- Removed deprecated features +- Internal redesign + +--- +### GLM 0.8.4.4 final - 2010-01-25 +- Fixed warnings + +--- +### GLM 0.8.4.3 final - 2009-11-16 +- Fixed Half float arithmetic +- Fixed setup defines + +--- +### GLM 0.8.4.2 final - 2009-10-19 +- Fixed Half float adds + +--- +### GLM 0.8.4.1 final - 2009-10-05 +- Updated documentation +- Fixed MacOS X build + +--- +### GLM 0.8.4.0 final - 2009-09-16 +- Added GCC 4.4 and VC2010 support +- Added matrix optimizations + +--- +### GLM 0.8.3.5 final - 2009-08-11 +- Fixed bugs + +--- +### GLM 0.8.3.4 final - 2009-08-10 +- Updated GLM according GLSL 1.5 spec +- Fixed bugs + +--- +### GLM 0.8.3.3 final - 2009-06-25 +- Fixed bugs + +--- +### GLM 0.8.3.2 final - 2009-06-04 +- Added GLM_GTC_quaternion +- Added GLM_GTC_type_precision + +--- +### GLM 0.8.3.1 final - 2009-05-21 +- Fixed old extension system. + +--- +### GLM 0.8.3.0 final - 2009-05-06 +- Added stable extensions. +- Added new extension system. + +--- +### GLM 0.8.2.3 final - 2009-04-01 +- Fixed bugs. + +--- +### GLM 0.8.2.2 final - 2009-02-24 +- Fixed bugs. + +--- +### GLM 0.8.2.1 final - 2009-02-13 +- Fixed bugs. + +--- +### GLM 0.8.2 final - 2009-01-21 +- Fixed bugs. + +--- +### GLM 0.8.1 final - 2008-10-30 +- Fixed bugs. + +--- +### GLM 0.8.0 final - 2008-10-23 +- New method to use extension. + +--- +### GLM 0.8.0 beta3 - 2008-10-10 +- Added CMake support for GLM tests. + +--- +### GLM 0.8.0 beta2 - 2008-10-04 +- Improved half scalars and vectors support. + +--- +### GLM 0.8.0 beta1 - 2008-09-26 +- Improved GLSL conformance +- Added GLSL 1.30 support +- Improved API documentation + +--- +### GLM 0.7.6 final - 2008-08-08 +- Improved C++ standard comformance +- Added Static assert for types checking + +--- +### GLM 0.7.5 final - 2008-07-05 +- Added build message system with Visual Studio +- Pedantic build with GCC + +--- +### GLM 0.7.4 final - 2008-06-01 +- Added external dependencies system. + +--- +### GLM 0.7.3 final - 2008-05-24 +- Fixed bugs +- Added new extension group + +--- +### GLM 0.7.2 final - 2008-04-27 +- Updated documentation +- Added preprocessor options + +--- +### GLM 0.7.1 final - 2008-03-24 +- Disabled half on GCC +- Fixed extensions + +--- +### GLM 0.7.0 final - 2008-03-22 +- Changed to MIT license +- Added new documentation + +--- +### GLM 0.6.4 - 2007-12-10 +- Fixed swizzle operators + +--- +### GLM 0.6.3 - 2007-11-05 +- Fixed type data accesses +- Fixed 3DSMax sdk conflict + +--- +### GLM 0.6.2 - 2007-10-08 +- Fixed extension + +--- +### GLM 0.6.1 - 2007-10-07 +- Fixed a namespace error +- Added extensions + +--- +### GLM 0.6.0 : 2007-09-16 +- Added new extension namespace mecanium +- Added Automatic compiler detection + +--- +### GLM 0.5.1 - 2007-02-19 +- Fixed swizzle operators + +--- +### GLM 0.5.0 - 2007-01-06 +- Upgrated to GLSL 1.2 +- Added swizzle operators +- Added setup settings + +--- +### GLM 0.4.1 - 2006-05-22 +- Added OpenGL examples + +--- +### GLM 0.4.0 - 2006-05-17 +- Added missing operators to vec* and mat* +- Added first GLSL 1.2 features +- Fixed windows.h before glm.h when windows.h required + +--- +### GLM 0.3.2 - 2006-04-21 +- Fixed texcoord components access. +- Fixed mat4 and imat4 division operators. + +--- +### GLM 0.3.1 - 2006-03-28 +- Added GCC 4.0 support under MacOS X. +- Added GCC 4.0 and 4.1 support under Linux. +- Added code optimisations. + +--- +### GLM 0.3 - 2006-02-19 +- Improved GLSL type conversion and construction compliance. +- Added experimental extensions. +- Added Doxygen Documentation. +- Added code optimisations. +- Fixed bugs. + +--- +### GLM 0.2 - 2005-05-05 +- Improve adaptative from GLSL. +- Add experimental extensions based on OpenGL extension process. +- Fixe bugs. + +--- +### GLM 0.1 - 2005-02-21 +- Add vec2, vec3, vec4 GLSL types +- Add ivec2, ivec3, ivec4 GLSL types +- Add bvec2, bvec3, bvec4 GLSL types +- Add mat2, mat3, mat4 GLSL types +- Add almost all functions + diff --git a/src/other/manifold/include/CMakeLists.txt b/src/other/manifold/include/CMakeLists.txt new file mode 100644 index 00000000000..cdb01783bc9 --- /dev/null +++ b/src/other/manifold/include/CMakeLists.txt @@ -0,0 +1,7 @@ +install(FILES + manifold/cross_section.h + manifold/manifold.h + manifold/public.h + manifold/sdf.h + DESTINATION ${INCLUDE_DIR}/manifold + ) diff --git a/src/other/manifold/include/ConvexHull.hpp b/src/other/manifold/include/ConvexHull.hpp new file mode 100644 index 00000000000..71b2ee1114f --- /dev/null +++ b/src/other/manifold/include/ConvexHull.hpp @@ -0,0 +1,182 @@ +#ifndef CONVEXHULL_HPP_ +#define CONVEXHULL_HPP_ + +#include "Structs/Vector3.hpp" +#include "Structs/Mesh.hpp" +#include "Structs/VertexDataSource.hpp" +#include +#include +#include +#include + +namespace quickhull { + + template + class ConvexHull { + std::unique_ptr>> m_optimizedVertexBuffer; + VertexDataSource m_vertices; + std::vector m_indices; + public: + ConvexHull() {} + + // Copy constructor + ConvexHull(const ConvexHull& o) { + m_indices = o.m_indices; + if (o.m_optimizedVertexBuffer) { + m_optimizedVertexBuffer.reset(new std::vector>(*o.m_optimizedVertexBuffer)); + m_vertices = VertexDataSource(*m_optimizedVertexBuffer); + } + else { + m_vertices = o.m_vertices; + } + } + + ConvexHull& operator=(const ConvexHull& o) { + if (&o == this) { + return *this; + } + m_indices = o.m_indices; + if (o.m_optimizedVertexBuffer) { + m_optimizedVertexBuffer.reset(new std::vector>(*o.m_optimizedVertexBuffer)); + m_vertices = VertexDataSource(*m_optimizedVertexBuffer); + } + else { + m_vertices = o.m_vertices; + } + return *this; + } + + ConvexHull(ConvexHull&& o) { + m_indices = std::move(o.m_indices); + if (o.m_optimizedVertexBuffer) { + m_optimizedVertexBuffer = std::move(o.m_optimizedVertexBuffer); + o.m_vertices = VertexDataSource(); + m_vertices = VertexDataSource(*m_optimizedVertexBuffer); + } + else { + m_vertices = o.m_vertices; + } + } + + ConvexHull& operator=(ConvexHull&& o) { + if (&o == this) { + return *this; + } + m_indices = std::move(o.m_indices); + if (o.m_optimizedVertexBuffer) { + m_optimizedVertexBuffer = std::move(o.m_optimizedVertexBuffer); + o.m_vertices = VertexDataSource(); + m_vertices = VertexDataSource(*m_optimizedVertexBuffer); + } + else { + m_vertices = o.m_vertices; + } + return *this; + } + + // Construct vertex and index buffers from half edge mesh and pointcloud + ConvexHull(const MeshBuilder& mesh, const VertexDataSource& pointCloud, bool CCW, bool useOriginalIndices) { + if (!useOriginalIndices) { + m_optimizedVertexBuffer.reset(new std::vector>()); + } + + std::vector faceProcessed(mesh.m_faces.size(),false); + std::vector faceStack; + std::unordered_map vertexIndexMapping; // Map vertex indices from original point cloud to the new mesh vertex indices + for (size_t i = 0;ipush_back(pointCloud[v]); + vertexIndexMapping[v] = m_optimizedVertexBuffer->size()-1; + v = m_optimizedVertexBuffer->size()-1; + } + else { + v = itV->second; + } + } + } + m_indices.push_back(vertices[0]); + m_indices.push_back(vertices[1 + iCCW]); + m_indices.push_back(vertices[2 - iCCW]); + } + } + + if (!useOriginalIndices) { + m_vertices = VertexDataSource(*m_optimizedVertexBuffer); + } + else { + m_vertices = pointCloud; + } + } + + std::vector& getIndexBuffer() { + return m_indices; + } + + const std::vector& getIndexBuffer() const { + return m_indices; + } + + VertexDataSource& getVertexBuffer() { + return m_vertices; + } + + const VertexDataSource& getVertexBuffer() const { + return m_vertices; + } + + // Export the mesh to a Waveform OBJ file + void writeWaveformOBJ(const std::string& filename, const std::string& objectName = "quickhull") const + { + std::ofstream objFile; + objFile.open (filename); + objFile << "o " << objectName << "\n"; + for (const auto& v : getVertexBuffer()) { + objFile << "v " << v.x << " " << v.y << " " << v.z << "\n"; + } + const auto& indBuf = getIndexBuffer(); + size_t triangleCount = indBuf.size()/3; + for (size_t i=0;i + class HalfEdgeMesh { + public: + + struct HalfEdge { + IndexType m_endVertex; + IndexType m_opp; + IndexType m_face; + IndexType m_next; + }; + + struct Face { + IndexType m_halfEdgeIndex; // Index of one of the half edges of this face + }; + + std::vector> m_vertices; + std::vector m_faces; + std::vector m_halfEdges; + + HalfEdgeMesh(const MeshBuilder& builderObject, const VertexDataSource& vertexData ) + { + std::unordered_map faceMapping; + std::unordered_map halfEdgeMapping; + std::unordered_map vertexMapping; + + size_t i=0; + for (const auto& face : builderObject.m_faces) { + if (!face.isDisabled()) { + m_faces.push_back({static_cast(face.m_he)}); + faceMapping[i] = m_faces.size()-1; + + const auto heIndices = builderObject.getHalfEdgeIndicesOfFace(face); + for (const auto heIndex : heIndices) { + const IndexType vertexIndex = builderObject.m_halfEdges[heIndex].m_endVertex; + if (vertexMapping.count(vertexIndex)==0) { + m_vertices.push_back(vertexData[vertexIndex]); + vertexMapping[vertexIndex] = m_vertices.size()-1; + } + } + } + i++; + } + + i=0; + for (const auto& halfEdge : builderObject.m_halfEdges) { + if (!halfEdge.isDisabled()) { + m_halfEdges.push_back({static_cast(halfEdge.m_endVertex),static_cast(halfEdge.m_opp),static_cast(halfEdge.m_face),static_cast(halfEdge.m_next)}); + halfEdgeMapping[i] = m_halfEdges.size()-1; + } + i++; + } + + for (auto& face : m_faces) { + assert(halfEdgeMapping.count(face.m_halfEdgeIndex) == 1); + face.m_halfEdgeIndex = halfEdgeMapping[face.m_halfEdgeIndex]; + } + + for (auto& he : m_halfEdges) { + he.m_face = faceMapping[he.m_face]; + he.m_opp = halfEdgeMapping[he.m_opp]; + he.m_next = halfEdgeMapping[he.m_next]; + he.m_endVertex = vertexMapping[he.m_endVertex]; + } + } + + }; +} + + +#endif /* HalfEdgeMesh_h */ diff --git a/src/other/manifold/include/MathUtils.hpp b/src/other/manifold/include/MathUtils.hpp new file mode 100644 index 00000000000..b87b3b93409 --- /dev/null +++ b/src/other/manifold/include/MathUtils.hpp @@ -0,0 +1,46 @@ + +#ifndef QuickHull_MathUtils_hpp +#define QuickHull_MathUtils_hpp + +#include "Structs/Vector3.hpp" +#include "Structs/Ray.hpp" + +namespace quickhull { + + namespace mathutils { + + template + inline T getSquaredDistanceBetweenPointAndRay(const Vector3& p, const Ray& r) { + const Vector3 s = p-r.m_S; + T t = s.dotProduct(r.m_V); + return s.getLengthSquared() - t*t*r.m_VInvLengthSquared; + } + + // Note that the unit of distance returned is relative to plane's normal's length (divide by N.getNormalized() if needed to get the "real" distance). + template + inline T getSignedDistanceToPlane(const Vector3& v, const Plane& p) { + return p.m_N.dotProduct(v) + p.m_D; + } + + template + inline Vector3 getTriangleNormal(const Vector3& a,const Vector3& b,const Vector3& c) { + // We want to get (a-c).crossProduct(b-c) without constructing temp vectors + T x = a.x - c.x; + T y = a.y - c.y; + T z = a.z - c.z; + T rhsx = b.x - c.x; + T rhsy = b.y - c.y; + T rhsz = b.z - c.z; + T px = y * rhsz - z * rhsy ; + T py = z * rhsx - x * rhsz ; + T pz = x * rhsy - y * rhsx ; + return Vector3(px,py,pz); + } + + + } + +} + + +#endif diff --git a/src/other/manifold/include/QuickHull.hpp b/src/other/manifold/include/QuickHull.hpp new file mode 100644 index 00000000000..436c4d9f165 --- /dev/null +++ b/src/other/manifold/include/QuickHull.hpp @@ -0,0 +1,223 @@ +#ifndef QUICKHULL_HPP_ +#define QUICKHULL_HPP_ +#include +#include +#include +#include +#include "Structs/Vector3.hpp" +#include "Structs/Plane.hpp" +#include "Structs/Pool.hpp" +#include "Structs/Mesh.hpp" +#include "ConvexHull.hpp" +#include "HalfEdgeMesh.hpp" +#include "MathUtils.hpp" + +/* + * Implementation of the 3D QuickHull algorithm by Antti Kuukka + * + * No copyrights. What follows is 100% Public Domain. + * + * + * + * INPUT: a list of points in 3D space (for example, vertices of a 3D mesh) + * + * OUTPUT: a ConvexHull object which provides vertex and index buffers of the generated convex hull as a triangle mesh. + * + * + * + * The implementation is thread-safe if each thread is using its own QuickHull object. + * + * + * SUMMARY OF THE ALGORITHM: + * - Create initial simplex (tetrahedron) using extreme points. We have four faces now and they form a convex mesh M. + * - For each point, assign them to the first face for which they are on the positive side of (so each point is assigned to at most + * one face). Points inside the initial tetrahedron are left behind now and no longer affect the calculations. + * - Add all faces that have points assigned to them to Face Stack. + * - Iterate until Face Stack is empty: + * - Pop topmost face F from the stack + * - From the points assigned to F, pick the point P that is farthest away from the plane defined by F. + * - Find all faces of M that have P on their positive side. Let us call these the "visible faces". + * - Because of the way M is constructed, these faces are connected. Solve their horizon edge loop. + * - "Extrude to P": Create new faces by connecting P with the points belonging to the horizon edge. Add the new faces to M and remove the visible + * faces from M. + * - Each point that was assigned to visible faces is now assigned to at most one of the newly created faces. + * - Those new faces that have points assigned to them are added to the top of Face Stack. + * - M is now the convex hull. + * + * TO DO: + * - Implement a proper 2D QuickHull and use that to solve the degenerate 2D case (when all the points lie on the same plane in 3D space). + * */ + +namespace quickhull { + + struct DiagnosticsData { + size_t m_failedHorizonEdges; // How many times QuickHull failed to solve the horizon edge. Failures lead to degenerated convex hulls. + + DiagnosticsData() : m_failedHorizonEdges(0) { } + }; + + template + FloatType defaultEps(); + + template + class QuickHull { + using vec3 = Vector3; + + FloatType m_epsilon, m_epsilonSquared, m_scale; + bool m_planar; + std::vector m_planarPointCloudTemp; + VertexDataSource m_vertexData; + MeshBuilder m_mesh; + std::array m_extremeValues; + DiagnosticsData m_diagnostics; + + // Temporary variables used during iteration process + std::vector m_newFaceIndices; + std::vector m_newHalfEdgeIndices; + std::vector< std::unique_ptr> > m_disabledFacePointVectors; + std::vector m_visibleFaces; + std::vector m_horizonEdges; + struct FaceData { + size_t m_faceIndex; + size_t m_enteredFromHalfEdge; // If the face turns out not to be visible, this half edge will be marked as horizon edge + FaceData(size_t fi, size_t he) : m_faceIndex(fi),m_enteredFromHalfEdge(he) {} + }; + std::vector m_possiblyVisibleFaces; + std::deque m_faceList; + + // Create a half edge mesh representing the base tetrahedron from which the QuickHull iteration proceeds. m_extremeValues must be properly set up when this is called. + void setupInitialTetrahedron(); + + // Given a list of half edges, try to rearrange them so that they form a loop. Return true on success. + bool reorderHorizonEdges(std::vector& horizonEdges); + + // Find indices of extreme values (max x, min x, max y, min y, max z, min z) for the given point cloud + std::array getExtremeValues(); + + // Compute scale of the vertex data. + FloatType getScale(const std::array& extremeValues); + + // Each face contains a unique pointer to a vector of indices. However, many - often most - faces do not have any points on the positive + // side of them especially at the the end of the iteration. When a face is removed from the mesh, its associated point vector, if such + // exists, is moved to the index vector pool, and when we need to add new faces with points on the positive side to the mesh, + // we reuse these vectors. This reduces the amount of std::vectors we have to deal with, and impact on performance is remarkable. + Pool> m_indexVectorPool; + inline std::unique_ptr> getIndexVectorFromPool(); + inline void reclaimToIndexVectorPool(std::unique_ptr>& ptr); + + // Associates a point with a face if the point resides on the positive side of the plane. Returns true if the points was on the positive side. + inline bool addPointToFace(typename MeshBuilder::Face& f, size_t pointIndex); + + // This will update m_mesh from which we create the ConvexHull object that getConvexHull function returns + void createConvexHalfEdgeMesh(); + + // Constructs the convex hull into a MeshBuilder object which can be converted to a ConvexHull or Mesh object + void buildMesh(const VertexDataSource& pointCloud, bool CCW, bool useOriginalIndices, FloatType eps); + + // The public getConvexHull functions will setup a VertexDataSource object and call this + ConvexHull getConvexHull(const VertexDataSource& pointCloud, bool CCW, bool useOriginalIndices, FloatType eps); + public: + // Computes convex hull for a given point cloud. + // Params: + // pointCloud: a vector of of 3D points + // CCW: whether the output mesh triangles should have CCW orientation + // useOriginalIndices: should the output mesh use same vertex indices as the original point cloud. If this is false, + // then we generate a new vertex buffer which contains only the vertices that are part of the convex hull. + // eps: minimum distance to a plane to consider a point being on positive of it (for a point cloud with scale 1) + ConvexHull getConvexHull(const std::vector>& pointCloud, + bool CCW, + bool useOriginalIndices, + FloatType eps = defaultEps()); + + // Computes convex hull for a given point cloud. + // Params: + // vertexData: pointer to the first 3D point of the point cloud + // vertexCount: number of vertices in the point cloud + // CCW: whether the output mesh triangles should have CCW orientation + // useOriginalIndices: should the output mesh use same vertex indices as the original point cloud. If this is false, + // then we generate a new vertex buffer which contains only the vertices that are part of the convex hull. + // eps: minimum distance to a plane to consider a point being on positive side of it (for a point cloud with scale 1) + ConvexHull getConvexHull(const Vector3* vertexData, + size_t vertexCount, + bool CCW, + bool useOriginalIndices, + FloatType eps = defaultEps()); + + // Computes convex hull for a given point cloud. This function assumes that the vertex data resides in memory + // in the following format: x_0,y_0,z_0,x_1,y_1,z_1,... + // Params: + // vertexData: pointer to the X component of the first point of the point cloud. + // vertexCount: number of vertices in the point cloud + // CCW: whether the output mesh triangles should have CCW orientation + // useOriginalIndices: should the output mesh use same vertex indices as the original point cloud. If this is false, + // then we generate a new vertex buffer which contains only the vertices that are part of the convex hull. + // eps: minimum distance to a plane to consider a point being on positive side of it (for a point cloud with scale 1) + ConvexHull getConvexHull(const FloatType* vertexData, + size_t vertexCount, + bool CCW, + bool useOriginalIndices, + FloatType eps = defaultEps()); + + // Computes convex hull for a given point cloud. This function assumes that the vertex data resides in memory + // in the following format: x_0,y_0,z_0,x_1,y_1,z_1,... + // Params: + // vertexData: pointer to the X component of the first point of the point cloud. + // vertexCount: number of vertices in the point cloud + // CCW: whether the output mesh triangles should have CCW orientation + // eps: minimum distance to a plane to consider a point being on positive side of it (for a point cloud with scale 1) + // Returns: + // Convex hull of the point cloud as a mesh object with half edge structure. + HalfEdgeMesh getConvexHullAsMesh(const FloatType* vertexData, + size_t vertexCount, + bool CCW, + FloatType eps = defaultEps()); + + // Get diagnostics about last generated convex hull + const DiagnosticsData& getDiagnostics() { + return m_diagnostics; + } + }; + + /* + * Inline function definitions + */ + + template + std::unique_ptr> QuickHull::getIndexVectorFromPool() { + auto r = m_indexVectorPool.get(); + r->clear(); + return r; + } + + template + void QuickHull::reclaimToIndexVectorPool(std::unique_ptr>& ptr) { + const size_t oldSize = ptr->size(); + if ((oldSize+1)*128 < ptr->capacity()) { + // Reduce memory usage! Huge vectors are needed at the beginning of iteration when faces have many points on their positive side. Later on, smaller vectors will suffice. + ptr.reset(nullptr); + return; + } + m_indexVectorPool.reclaim(ptr); + } + + template + bool QuickHull::addPointToFace(typename MeshBuilder::Face& f, size_t pointIndex) { + const T D = mathutils::getSignedDistanceToPlane(m_vertexData[ pointIndex ],f.m_P); + if (D>0 && D*D > m_epsilonSquared*f.m_P.m_sqrNLength) { + if (!f.m_pointsOnPositiveSide) { + f.m_pointsOnPositiveSide = std::move(getIndexVectorFromPool()); + } + f.m_pointsOnPositiveSide->push_back( pointIndex ); + if (D > f.m_mostDistantPointDist) { + f.m_mostDistantPointDist = D; + f.m_mostDistantPoint = pointIndex; + } + return true; + } + return false; + } + +} + + +#endif /* QUICKHULL_HPP_ */ diff --git a/src/other/manifold/include/Structs/Mesh.hpp b/src/other/manifold/include/Structs/Mesh.hpp new file mode 100644 index 00000000000..f58c5afcdfb --- /dev/null +++ b/src/other/manifold/include/Structs/Mesh.hpp @@ -0,0 +1,255 @@ +#ifndef MESH_HPP_ +#define MESH_HPP_ + +#include +#include "Vector3.hpp" +#include "Plane.hpp" +#include "Pool.hpp" +#include +#include +#include +#include +#include "VertexDataSource.hpp" +#include +#include + +namespace quickhull { + + template + class MeshBuilder { + public: + struct HalfEdge { + size_t m_endVertex; + size_t m_opp; + size_t m_face; + size_t m_next; + + void disable() { + m_endVertex = std::numeric_limits::max(); + } + + bool isDisabled() const { + return m_endVertex == std::numeric_limits::max(); + } + }; + + struct Face { + size_t m_he; + Plane m_P{}; + T m_mostDistantPointDist; + size_t m_mostDistantPoint; + size_t m_visibilityCheckedOnIteration; + std::uint8_t m_isVisibleFaceOnCurrentIteration : 1; + std::uint8_t m_inFaceStack : 1; + std::uint8_t m_horizonEdgesOnCurrentIteration : 3; // Bit for each half edge assigned to this face, each being 0 or 1 depending on whether the edge belongs to horizon edge + std::unique_ptr> m_pointsOnPositiveSide; + + Face() : m_he(std::numeric_limits::max()), + m_mostDistantPointDist(0), + m_mostDistantPoint(0), + m_visibilityCheckedOnIteration(0), + m_isVisibleFaceOnCurrentIteration(0), + m_inFaceStack(0), + m_horizonEdgesOnCurrentIteration(0) + { + + } + + void disable() { + m_he = std::numeric_limits::max(); + } + + bool isDisabled() const { + return m_he == std::numeric_limits::max(); + } + }; + + // Mesh data + std::vector m_faces; + std::vector m_halfEdges; + + // When the mesh is modified and faces and half edges are removed from it, we do not actually remove them from the container vectors. + // Insted, they are marked as disabled which means that the indices can be reused when we need to add new faces and half edges to the mesh. + // We store the free indices in the following vectors. + std::vector m_disabledFaces,m_disabledHalfEdges; + + size_t addFace() { + if (m_disabledFaces.size()) { + size_t index = m_disabledFaces.back(); + auto& f = m_faces[index]; + assert(f.isDisabled()); + assert(!f.m_pointsOnPositiveSide); + f.m_mostDistantPointDist = 0; + m_disabledFaces.pop_back(); + return index; + } + m_faces.emplace_back(); + return m_faces.size()-1; + } + + size_t addHalfEdge() { + if (m_disabledHalfEdges.size()) { + const size_t index = m_disabledHalfEdges.back(); + m_disabledHalfEdges.pop_back(); + return index; + } + m_halfEdges.emplace_back(); + return m_halfEdges.size()-1; + } + + // Mark a face as disabled and return a pointer to the points that were on the positive of it. + std::unique_ptr> disableFace(size_t faceIndex) { + auto& f = m_faces[faceIndex]; + f.disable(); + m_disabledFaces.push_back(faceIndex); + return std::move(f.m_pointsOnPositiveSide); + } + + void disableHalfEdge(size_t heIndex) { + auto& he = m_halfEdges[heIndex]; + he.disable(); + m_disabledHalfEdges.push_back(heIndex); + } + + MeshBuilder() = default; + + // Create a mesh with initial tetrahedron ABCD. Dot product of AB with the normal of triangle ABC should be negative. + void setup(size_t a, size_t b, size_t c, size_t d) { + m_faces.clear(); + m_halfEdges.clear(); + m_disabledFaces.clear(); + m_disabledHalfEdges.clear(); + + m_faces.reserve(4); + m_halfEdges.reserve(12); + + // Create halfedges + HalfEdge AB; + AB.m_endVertex = b; + AB.m_opp = 6; + AB.m_face = 0; + AB.m_next = 1; + m_halfEdges.push_back(AB); + + HalfEdge BC; + BC.m_endVertex = c; + BC.m_opp = 9; + BC.m_face = 0; + BC.m_next = 2; + m_halfEdges.push_back(BC); + + HalfEdge CA; + CA.m_endVertex = a; + CA.m_opp = 3; + CA.m_face = 0; + CA.m_next = 0; + m_halfEdges.push_back(CA); + + HalfEdge AC; + AC.m_endVertex = c; + AC.m_opp = 2; + AC.m_face = 1; + AC.m_next = 4; + m_halfEdges.push_back(AC); + + HalfEdge CD; + CD.m_endVertex = d; + CD.m_opp = 11; + CD.m_face = 1; + CD.m_next = 5; + m_halfEdges.push_back(CD); + + HalfEdge DA; + DA.m_endVertex = a; + DA.m_opp = 7; + DA.m_face = 1; + DA.m_next = 3; + m_halfEdges.push_back(DA); + + HalfEdge BA; + BA.m_endVertex = a; + BA.m_opp = 0; + BA.m_face = 2; + BA.m_next = 7; + m_halfEdges.push_back(BA); + + HalfEdge AD; + AD.m_endVertex = d; + AD.m_opp = 5; + AD.m_face = 2; + AD.m_next = 8; + m_halfEdges.push_back(AD); + + HalfEdge DB; + DB.m_endVertex = b; + DB.m_opp = 10; + DB.m_face = 2; + DB.m_next = 6; + m_halfEdges.push_back(DB); + + HalfEdge CB; + CB.m_endVertex = b; + CB.m_opp = 1; + CB.m_face = 3; + CB.m_next = 10; + m_halfEdges.push_back(CB); + + HalfEdge BD; + BD.m_endVertex = d; + BD.m_opp = 8; + BD.m_face = 3; + BD.m_next = 11; + m_halfEdges.push_back(BD); + + HalfEdge DC; + DC.m_endVertex = c; + DC.m_opp = 4; + DC.m_face = 3; + DC.m_next = 9; + m_halfEdges.push_back(DC); + + // Create faces + Face ABC; + ABC.m_he = 0; + m_faces.push_back(std::move(ABC)); + + Face ACD; + ACD.m_he = 3; + m_faces.push_back(std::move(ACD)); + + Face BAD; + BAD.m_he = 6; + m_faces.push_back(std::move(BAD)); + + Face CBD; + CBD.m_he = 9; + m_faces.push_back(std::move(CBD)); + } + + std::array getVertexIndicesOfFace(const Face& f) const { + std::array v; + const HalfEdge* he = &m_halfEdges[f.m_he]; + v[0] = he->m_endVertex; + he = &m_halfEdges[he->m_next]; + v[1] = he->m_endVertex; + he = &m_halfEdges[he->m_next]; + v[2] = he->m_endVertex; + return v; + } + + std::array getVertexIndicesOfHalfEdge(const HalfEdge& he) const { + return {m_halfEdges[he.m_opp].m_endVertex,he.m_endVertex}; + } + + std::array getHalfEdgeIndicesOfFace(const Face& f) const { + return {f.m_he,m_halfEdges[f.m_he].m_next,m_halfEdges[m_halfEdges[f.m_he].m_next].m_next}; + } + }; + + + +} + + + +#endif diff --git a/src/other/manifold/include/Structs/Plane.hpp b/src/other/manifold/include/Structs/Plane.hpp new file mode 100644 index 00000000000..903a7efe363 --- /dev/null +++ b/src/other/manifold/include/Structs/Plane.hpp @@ -0,0 +1,36 @@ +#ifndef QHPLANE_HPP_ +#define QHPLANE_HPP_ + +#include "Vector3.hpp" + +namespace quickhull { + + template + class Plane { + public: + Vector3 m_N; + + // Signed distance (if normal is of length 1) to the plane from origin + T m_D; + + // Normal length squared + T m_sqrNLength; + + bool isPointOnPositiveSide(const Vector3& Q) const { + T d = m_N.dotProduct(Q)+m_D; + if (d>=0) return true; + return false; + } + + Plane() = default; + + // Construct a plane using normal N and any point P on the plane + Plane(const Vector3& N, const Vector3& P) : m_N(N), m_D(-N.dotProduct(P)), m_sqrNLength(m_N.x*m_N.x+m_N.y*m_N.y+m_N.z*m_N.z) { + + } + }; + +} + + +#endif /* PLANE_HPP_ */ diff --git a/src/other/manifold/include/Structs/Pool.hpp b/src/other/manifold/include/Structs/Pool.hpp new file mode 100644 index 00000000000..4216b4a1533 --- /dev/null +++ b/src/other/manifold/include/Structs/Pool.hpp @@ -0,0 +1,35 @@ +#ifndef Pool_h +#define Pool_h + +#include +#include + +namespace quickhull { + + template + class Pool { + std::vector> m_data; + public: + void clear() { + m_data.clear(); + } + + void reclaim(std::unique_ptr& ptr) { + m_data.push_back(std::move(ptr)); + } + + std::unique_ptr get() { + if (m_data.size()==0) { + return std::unique_ptr(new T()); + } + auto it = m_data.end()-1; + std::unique_ptr r = std::move(*it); + m_data.erase(it); + return r; + } + + }; + +} + +#endif /* Pool_h */ diff --git a/src/other/manifold/include/Structs/Ray.hpp b/src/other/manifold/include/Structs/Ray.hpp new file mode 100644 index 00000000000..19b60728e5b --- /dev/null +++ b/src/other/manifold/include/Structs/Ray.hpp @@ -0,0 +1,21 @@ +#ifndef QuickHull_Ray_hpp +#define QuickHull_Ray_hpp + +#include "Vector3.hpp" + +namespace quickhull { + + template + struct Ray { + const Vector3 m_S; + const Vector3 m_V; + const T m_VInvLengthSquared; + + Ray(const Vector3& S,const Vector3& V) : m_S(S), m_V(V), m_VInvLengthSquared(1/m_V.getLengthSquared()) { + } + }; + +} + + +#endif diff --git a/src/other/manifold/include/Structs/Vector3.hpp b/src/other/manifold/include/Structs/Vector3.hpp new file mode 100644 index 00000000000..47a5f74617d --- /dev/null +++ b/src/other/manifold/include/Structs/Vector3.hpp @@ -0,0 +1,140 @@ +#ifndef QuickHull_Vector3_hpp +#define QuickHull_Vector3_hpp + +#include +#include + +namespace quickhull { + + template + class Vector3 + { + public: + Vector3() = default; + + Vector3(T x, T y, T z) : x(x), y(y), z(z) { + + } + + T x,y,z; + + T dotProduct(const Vector3& other) const { + return x*other.x+y*other.y+z*other.z; + } + + void normalize() { + const T len = getLength(); + x/=len; + y/=len; + z/=len; + } + + Vector3 getNormalized() const { + const T len = getLength(); + return Vector3(x/len,y/len,z/len); + } + + T getLength() const { + return std::sqrt(x*x+y*y+z*z); + } + + Vector3 operator-(const Vector3& other) const { + return Vector3(x-other.x,y-other.y,z-other.z); + } + + Vector3 operator+(const Vector3& other) const { + return Vector3(x+other.x,y+other.y,z+other.z); + } + + Vector3& operator+=(const Vector3& other) { + x+=other.x; + y+=other.y; + z+=other.z; + return *this; + } + Vector3& operator-=(const Vector3& other) { + x-=other.x; + y-=other.y; + z-=other.z; + return *this; + } + Vector3& operator*=(T c) { + x*=c; + y*=c; + z*=c; + return *this; + } + + Vector3& operator/=(T c) { + x/=c; + y/=c; + z/=c; + return *this; + } + + Vector3 operator-() const { + return Vector3(-x,-y,-z); + } + + template + Vector3 operator*(S c) const { + return Vector3(x*c,y*c,z*c); + } + + template + Vector3 operator/(S c) const { + return Vector3(x/c,y/c,z/c); + } + + T getLengthSquared() const { + return x*x + y*y + z*z; + } + + bool operator!=(const Vector3& o) const { + return x != o.x || y != o.y || z != o.z; + } + + // Projection onto another vector + Vector3 projection(const Vector3& o) const { + T C = dotProduct(o)/o.getLengthSquared(); + return o*C; + } + + Vector3 crossProduct (const Vector3& rhs ) { + T a = y * rhs.z - z * rhs.y ; + T b = z * rhs.x - x * rhs.z ; + T c = x * rhs.y - y * rhs.x ; + Vector3 product( a , b , c ) ; + return product ; + } + + T getDistanceTo(const Vector3& other) const { + Vector3 diff = *this - other; + return diff.getLength(); + } + + T getSquaredDistanceTo(const Vector3& other) const { + const T dx = x-other.x; + const T dy = y-other.y; + const T dz = z-other.z; + return dx*dx+dy*dy+dz*dz; + } + + }; + + // Overload also << operator for easy printing of debug data + template + inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) { + os << "(" << vec.x << "," << vec.y << "," << vec.z << ")"; + return os; + } + + template + inline Vector3 operator*(T c, const Vector3& v) { + return Vector3(v.x*c,v.y*c,v.z*c); + } + +} + + +#endif diff --git a/src/other/manifold/include/Structs/VertexDataSource.hpp b/src/other/manifold/include/Structs/VertexDataSource.hpp new file mode 100644 index 00000000000..162b643bd09 --- /dev/null +++ b/src/other/manifold/include/Structs/VertexDataSource.hpp @@ -0,0 +1,48 @@ +#ifndef VertexDataSource_h +#define VertexDataSource_h + +#include "Vector3.hpp" + +namespace quickhull { + + template + class VertexDataSource { + const Vector3* m_ptr; + size_t m_count; + + public: + VertexDataSource(const Vector3* ptr, size_t count) : m_ptr(ptr), m_count(count) { + + } + + VertexDataSource(const std::vector>& vec) : m_ptr(&vec[0]), m_count(vec.size()) { + + } + + VertexDataSource() : m_ptr(nullptr), m_count(0) { + + } + + VertexDataSource& operator=(const VertexDataSource& other) = default; + + size_t size() const { + return m_count; + } + + const Vector3& operator[](size_t index) const { + return m_ptr[index]; + } + + const Vector3* begin() const { + return m_ptr; + } + + const Vector3* end() const { + return m_ptr + m_count; + } + }; + +} + + +#endif /* VertexDataSource_h */ diff --git a/src/other/manifold/include/clipper2/clipper.core.h b/src/other/manifold/include/clipper2/clipper.core.h new file mode 100644 index 00000000000..7a32d4c4aa2 --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.core.h @@ -0,0 +1,830 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 26 July 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : Core Clipper Library structures and functions * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_CORE_H +#define CLIPPER_CORE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Clipper2Lib +{ + +#if (defined(__cpp_exceptions) && __cpp_exceptions) || (defined(__EXCEPTIONS) && __EXCEPTIONS) + + class Clipper2Exception : public std::exception { + public: + explicit Clipper2Exception(const char* description) : + m_descr(description) {} + virtual const char* what() const throw() override { return m_descr.c_str(); } + private: + std::string m_descr; + }; + + static const char* precision_error = + "Precision exceeds the permitted range"; + static const char* range_error = + "Values exceed permitted range"; + static const char* scale_error = + "Invalid scale (either 0 or too large)"; + static const char* non_pair_error = + "There must be 2 values for each coordinate"; +#endif + + // error codes (2^n) + const int precision_error_i = 1; // non-fatal + const int scale_error_i = 2; // non-fatal + const int non_pair_error_i = 4; // non-fatal + const int range_error_i = 64; + +#ifndef PI + static const double PI = 3.141592653589793238; +#endif + static const int MAX_DECIMAL_PRECISION = 8; // see https://github.com/AngusJohnson/Clipper2/discussions/564 + static const int64_t MAX_COORD = INT64_MAX >> 2; + static const int64_t MIN_COORD = -MAX_COORD; + static const int64_t INVALID = INT64_MAX; + const double max_coord = static_cast(MAX_COORD); + const double min_coord = static_cast(MIN_COORD); + + static const double MAX_DBL = (std::numeric_limits::max)(); + + static void DoError(int error_code) + { +#if (defined(__cpp_exceptions) && __cpp_exceptions) || (defined(__EXCEPTIONS) && __EXCEPTIONS) + switch (error_code) + { + case precision_error_i: + throw Clipper2Exception(precision_error); + case scale_error_i: + throw Clipper2Exception(scale_error); + case non_pair_error_i: + throw Clipper2Exception(non_pair_error); + case range_error_i: + throw Clipper2Exception(range_error); + } +#else + ++error_code; // only to stop compiler warning +#endif + } + + //By far the most widely used filling rules for polygons are EvenOdd + //and NonZero, sometimes called Alternate and Winding respectively. + //https://en.wikipedia.org/wiki/Nonzero-rule + enum class FillRule { EvenOdd, NonZero, Positive, Negative }; + + // Point ------------------------------------------------------------------------ + + template + struct Point { + T x; + T y; +#ifdef USINGZ + int64_t z; + + template + inline void Init(const T2 x_ = 0, const T2 y_ = 0, const int64_t z_ = 0) + { + if constexpr (std::numeric_limits::is_integer && + !std::numeric_limits::is_integer) + { + x = static_cast(std::round(x_)); + y = static_cast(std::round(y_)); + z = z_; + } + else + { + x = static_cast(x_); + y = static_cast(y_); + z = z_; + } + } + + explicit Point() : x(0), y(0), z(0) {}; + + template + Point(const T2 x_, const T2 y_, const int64_t z_ = 0) + { + Init(x_, y_); + z = z_; + } + + template + explicit Point(const Point& p) + { + Init(p.x, p.y, p.z); + } + + Point operator * (const double scale) const + { + return Point(x * scale, y * scale, z); + } + + void SetZ(const int64_t z_value) { z = z_value; } + + friend std::ostream& operator<<(std::ostream& os, const Point& point) + { + os << point.x << "," << point.y << "," << point.z << " "; + return os; + } + +#else + + template + inline void Init(const T2 x_ = 0, const T2 y_ = 0) + { + if constexpr (std::numeric_limits::is_integer && + !std::numeric_limits::is_integer) + { + x = static_cast(std::round(x_)); + y = static_cast(std::round(y_)); + } + else + { + x = static_cast(x_); + y = static_cast(y_); + } + } + + explicit Point() : x(0), y(0) {}; + + template + Point(const T2 x_, const T2 y_) { Init(x_, y_); } + + template + explicit Point(const Point& p) { Init(p.x, p.y); } + + Point operator * (const double scale) const + { + return Point(x * scale, y * scale); + } + + friend std::ostream& operator<<(std::ostream& os, const Point& point) + { + os << point.x << "," << point.y << " "; + return os; + } +#endif + + friend bool operator==(const Point& a, const Point& b) + { + return a.x == b.x && a.y == b.y; + } + + friend bool operator!=(const Point& a, const Point& b) + { + return !(a == b); + } + + inline Point operator-() const + { + return Point(-x, -y); + } + + inline Point operator+(const Point& b) const + { + return Point(x + b.x, y + b.y); + } + + inline Point operator-(const Point& b) const + { + return Point(x - b.x, y - b.y); + } + + inline void Negate() { x = -x; y = -y; } + + }; + + //nb: using 'using' here (instead of typedef) as they can be used in templates + using Point64 = Point; + using PointD = Point; + + template + using Path = std::vector>; + template + using Paths = std::vector>; + + using Path64 = Path; + using PathD = Path; + using Paths64 = std::vector< Path64>; + using PathsD = std::vector< PathD>; + + // Rect ------------------------------------------------------------------------ + + template + struct Rect; + + using Rect64 = Rect; + using RectD = Rect; + + template + struct Rect { + T left; + T top; + T right; + T bottom; + + Rect() : + left(0), + top(0), + right(0), + bottom(0) {} + + Rect(T l, T t, T r, T b) : + left(l), + top(t), + right(r), + bottom(b) {} + + Rect(bool is_valid) + { + if (is_valid) + { + left = right = top = bottom = 0; + } + else + { + left = top = (std::numeric_limits::max)(); + right = bottom = -(std::numeric_limits::max)(); + } + } + + T Width() const { return right - left; } + T Height() const { return bottom - top; } + void Width(T width) { right = left + width; } + void Height(T height) { bottom = top + height; } + + Point MidPoint() const + { + return Point((left + right) / 2, (top + bottom) / 2); + } + + Path AsPath() const + { + Path result; + result.reserve(4); + result.push_back(Point(left, top)); + result.push_back(Point(right, top)); + result.push_back(Point(right, bottom)); + result.push_back(Point(left, bottom)); + return result; + } + + bool Contains(const Point& pt) const + { + return pt.x > left && pt.x < right&& pt.y > top && pt.y < bottom; + } + + bool Contains(const Rect& rec) const + { + return rec.left >= left && rec.right <= right && + rec.top >= top && rec.bottom <= bottom; + } + + void Scale(double scale) { + left *= scale; + top *= scale; + right *= scale; + bottom *= scale; + } + + bool IsEmpty() const { return bottom <= top || right <= left; }; + + bool Intersects(const Rect& rec) const + { + return ((std::max)(left, rec.left) <= (std::min)(right, rec.right)) && + ((std::max)(top, rec.top) <= (std::min)(bottom, rec.bottom)); + }; + + friend std::ostream& operator<<(std::ostream& os, const Rect& rect) { + os << "(" + << rect.left << "," << rect.top << "," << rect.right << "," << rect.bottom + << ")"; + return os; + } + }; + + template + inline Rect ScaleRect(const Rect& rect, double scale) + { + Rect result; + + if constexpr (std::numeric_limits::is_integer && + !std::numeric_limits::is_integer) + { + result.left = static_cast(std::round(rect.left * scale)); + result.top = static_cast(std::round(rect.top * scale)); + result.right = static_cast(std::round(rect.right * scale)); + result.bottom = static_cast(std::round(rect.bottom * scale)); + } + else + { + result.left = rect.left * scale; + result.top = rect.top * scale; + result.right = rect.right * scale; + result.bottom = rect.bottom * scale; + } + return result; + } + + static const Rect64 MaxInvalidRect64 = Rect64( + INT64_MAX, INT64_MAX, INT64_MIN, INT64_MIN); + static const RectD MaxInvalidRectD = RectD( + MAX_DBL, MAX_DBL, -MAX_DBL, -MAX_DBL); + + template + Rect GetBounds(const Path& path) + { + auto xmin = (std::numeric_limits::max)(); + auto ymin = (std::numeric_limits::max)(); + auto xmax = std::numeric_limits::lowest(); + auto ymax = std::numeric_limits::lowest(); + for (const auto& p : path) + { + if (p.x < xmin) xmin = p.x; + if (p.x > xmax) xmax = p.x; + if (p.y < ymin) ymin = p.y; + if (p.y > ymax) ymax = p.y; + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + Rect GetBounds(const Paths& paths) + { + auto xmin = (std::numeric_limits::max)(); + auto ymin = (std::numeric_limits::max)(); + auto xmax = std::numeric_limits::lowest(); + auto ymax = std::numeric_limits::lowest(); + for (const Path& path : paths) + for (const Point& p : path) + { + if (p.x < xmin) xmin = p.x; + if (p.x > xmax) xmax = p.x; + if (p.y < ymin) ymin = p.y; + if (p.y > ymax) ymax = p.y; + } + return Rect(xmin, ymin, xmax, ymax); + } + + template + std::ostream& operator << (std::ostream& outstream, const Path& path) + { + if (!path.empty()) + { + auto pt = path.cbegin(), last = path.cend() - 1; + while (pt != last) + outstream << *pt++ << ", "; + outstream << *last << std::endl; + } + return outstream; + } + + template + std::ostream& operator << (std::ostream& outstream, const Paths& paths) + { + for (auto p : paths) + outstream << p; + return outstream; + } + + + template + inline Path ScalePath(const Path& path, + double scale_x, double scale_y, int& error_code) + { + Path result; + if (scale_x == 0 || scale_y == 0) + { + error_code |= scale_error_i; + DoError(scale_error_i); + // if no exception, treat as non-fatal error + if (scale_x == 0) scale_x = 1.0; + if (scale_y == 0) scale_y = 1.0; + } + + result.reserve(path.size()); +#ifdef USINGZ + std::transform(path.begin(), path.end(), back_inserter(result), + [scale_x, scale_y](const auto& pt) + { return Point(pt.x * scale_x, pt.y * scale_y, pt.z); }); +#else + std::transform(path.begin(), path.end(), back_inserter(result), + [scale_x, scale_y](const auto& pt) + { return Point(pt.x * scale_x, pt.y * scale_y); }); +#endif + return result; + } + + template + inline Path ScalePath(const Path& path, + double scale, int& error_code) + { + return ScalePath(path, scale, scale, error_code); + } + + template + inline Paths ScalePaths(const Paths& paths, + double scale_x, double scale_y, int& error_code) + { + Paths result; + + if constexpr (std::numeric_limits::is_integer && + !std::numeric_limits::is_integer) + { + RectD r = GetBounds(paths); + if ((r.left * scale_x) < min_coord || + (r.right * scale_x) > max_coord || + (r.top * scale_y) < min_coord || + (r.bottom * scale_y) > max_coord) + { + error_code |= range_error_i; + DoError(range_error_i); + return result; // empty path + } + } + + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [=, &error_code](const auto& path) + { return ScalePath(path, scale_x, scale_y, error_code); }); + return result; + } + + template + inline Paths ScalePaths(const Paths& paths, + double scale, int& error_code) + { + return ScalePaths(paths, scale, scale, error_code); + } + + template + inline Path TransformPath(const Path& path) + { + Path result; + result.reserve(path.size()); + std::transform(path.cbegin(), path.cend(), std::back_inserter(result), + [](const Point& pt) {return Point(pt); }); + return result; + } + + template + inline Paths TransformPaths(const Paths& paths) + { + Paths result; + std::transform(paths.cbegin(), paths.cend(), std::back_inserter(result), + [](const Path& path) {return TransformPath(path); }); + return result; + } + + inline PathD Path64ToPathD(const Path64& path) + { + return TransformPath(path); + } + + inline PathsD Paths64ToPathsD(const Paths64& paths) + { + return TransformPaths(paths); + } + + inline Path64 PathDToPath64(const PathD& path) + { + return TransformPath(path); + } + + inline Paths64 PathsDToPaths64(const PathsD& paths) + { + return TransformPaths(paths); + } + + template + inline double Sqr(T val) + { + return static_cast(val) * static_cast(val); + } + + template + inline bool NearEqual(const Point& p1, + const Point& p2, double max_dist_sqrd) + { + return Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y) < max_dist_sqrd; + } + + template + inline Path StripNearEqual(const Path& path, + double max_dist_sqrd, bool is_closed_path) + { + if (path.size() == 0) return Path(); + Path result; + result.reserve(path.size()); + typename Path::const_iterator path_iter = path.cbegin(); + Point first_pt = *path_iter++, last_pt = first_pt; + result.push_back(first_pt); + for (; path_iter != path.cend(); ++path_iter) + { + if (!NearEqual(*path_iter, last_pt, max_dist_sqrd)) + { + last_pt = *path_iter; + result.push_back(last_pt); + } + } + if (!is_closed_path) return result; + while (result.size() > 1 && + NearEqual(result.back(), first_pt, max_dist_sqrd)) result.pop_back(); + return result; + } + + template + inline Paths StripNearEqual(const Paths& paths, + double max_dist_sqrd, bool is_closed_path) + { + Paths result; + result.reserve(paths.size()); + for (typename Paths::const_iterator paths_citer = paths.cbegin(); + paths_citer != paths.cend(); ++paths_citer) + { + result.push_back(StripNearEqual(*paths_citer, max_dist_sqrd, is_closed_path)); + } + return result; + } + + template + inline void StripDuplicates( Path& path, bool is_closed_path) + { + //https://stackoverflow.com/questions/1041620/whats-the-most-efficient-way-to-erase-duplicates-and-sort-a-vector#:~:text=Let%27s%20compare%20three%20approaches%3A + path.erase(std::unique(path.begin(), path.end()),path.end()); + if (is_closed_path) + while (path.size() > 1 && path.back() == path.front()) path.pop_back(); + } + + template + inline void StripDuplicates( Paths& paths, bool is_closed_path) + { + for (typename Paths::iterator paths_citer = paths.begin(); + paths_citer != paths.end(); ++paths_citer) + { + StripDuplicates(*paths_citer, is_closed_path); + } + } + + // Miscellaneous ------------------------------------------------------------ + + inline void CheckPrecision(int& precision, int& error_code) + { + if (precision >= -MAX_DECIMAL_PRECISION && precision <= MAX_DECIMAL_PRECISION) return; + error_code |= precision_error_i; // non-fatal error + DoError(precision_error_i); // does nothing unless exceptions enabled + precision = precision > 0 ? MAX_DECIMAL_PRECISION : -MAX_DECIMAL_PRECISION; + } + + inline void CheckPrecision(int& precision) + { + int error_code = 0; + CheckPrecision(precision, error_code); + } + + template + inline double CrossProduct(const Point& pt1, const Point& pt2, const Point& pt3) { + return (static_cast(pt2.x - pt1.x) * static_cast(pt3.y - + pt2.y) - static_cast(pt2.y - pt1.y) * static_cast(pt3.x - pt2.x)); + } + + template + inline double CrossProduct(const Point& vec1, const Point& vec2) + { + return static_cast(vec1.y * vec2.x) - static_cast(vec2.y * vec1.x); + } + + template + inline double DotProduct(const Point& pt1, const Point& pt2, const Point& pt3) { + return (static_cast(pt2.x - pt1.x) * static_cast(pt3.x - pt2.x) + + static_cast(pt2.y - pt1.y) * static_cast(pt3.y - pt2.y)); + } + + template + inline double DotProduct(const Point& vec1, const Point& vec2) + { + return static_cast(vec1.x * vec2.x) + static_cast(vec1.y * vec2.y); + } + + template + inline double DistanceSqr(const Point pt1, const Point pt2) + { + return Sqr(pt1.x - pt2.x) + Sqr(pt1.y - pt2.y); + } + + template + inline double DistanceFromLineSqrd(const Point& pt, const Point& ln1, const Point& ln2) + { + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) + //see http://en.wikipedia.org/wiki/Perpendicular_distance + double A = static_cast(ln1.y - ln2.y); + double B = static_cast(ln2.x - ln1.x); + double C = A * ln1.x + B * ln1.y; + C = A * pt.x + B * pt.y - C; + return (C * C) / (A * A + B * B); + } + + template + inline double Area(const Path& path) + { + size_t cnt = path.size(); + if (cnt < 3) return 0.0; + double a = 0.0; + typename Path::const_iterator it1, it2 = path.cend() - 1, stop = it2; + if (!(cnt & 1)) ++stop; + for (it1 = path.cbegin(); it1 != stop;) + { + a += static_cast(it2->y + it1->y) * (it2->x - it1->x); + it2 = it1 + 1; + a += static_cast(it1->y + it2->y) * (it1->x - it2->x); + it1 += 2; + } + if (cnt & 1) + a += static_cast(it2->y + it1->y) * (it2->x - it1->x); + return a * 0.5; + } + + template + inline double Area(const Paths& paths) + { + double a = 0.0; + for (typename Paths::const_iterator paths_iter = paths.cbegin(); + paths_iter != paths.cend(); ++paths_iter) + { + a += Area(*paths_iter); + } + return a; + } + + template + inline bool IsPositive(const Path& poly) + { + // A curve has positive orientation [and area] if a region 'R' + // is on the left when traveling around the outside of 'R'. + //https://mathworld.wolfram.com/CurveOrientation.html + //nb: This statement is premised on using Cartesian coordinates + return Area(poly) >= 0; + } + + inline bool GetIntersectPoint(const Point64& ln1a, const Point64& ln1b, + const Point64& ln2a, const Point64& ln2b, Point64& ip) + { + // https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection + double dx1 = static_cast(ln1b.x - ln1a.x); + double dy1 = static_cast(ln1b.y - ln1a.y); + double dx2 = static_cast(ln2b.x - ln2a.x); + double dy2 = static_cast(ln2b.y - ln2a.y); + + double det = dy1 * dx2 - dy2 * dx1; + if (det == 0.0) return false; + double t = ((ln1a.x - ln2a.x) * dy2 - (ln1a.y - ln2a.y) * dx2) / det; + if (t <= 0.0) ip = ln1a; // ?? check further (see also #568) + else if (t >= 1.0) ip = ln1b; // ?? check further + else + { + ip.x = static_cast(ln1a.x + t * dx1); + ip.y = static_cast(ln1a.y + t * dy1); + } + return true; + } + + inline bool SegmentsIntersect(const Point64& seg1a, const Point64& seg1b, + const Point64& seg2a, const Point64& seg2b, bool inclusive = false) + { + if (inclusive) + { + double res1 = CrossProduct(seg1a, seg2a, seg2b); + double res2 = CrossProduct(seg1b, seg2a, seg2b); + if (res1 * res2 > 0) return false; + double res3 = CrossProduct(seg2a, seg1a, seg1b); + double res4 = CrossProduct(seg2b, seg1a, seg1b); + if (res3 * res4 > 0) return false; + return (res1 || res2 || res3 || res4); // ensures not collinear + } + else { + return (CrossProduct(seg1a, seg2a, seg2b) * + CrossProduct(seg1b, seg2a, seg2b) < 0) && + (CrossProduct(seg2a, seg1a, seg1b) * + CrossProduct(seg2b, seg1a, seg1b) < 0); + } + } + + inline Point64 GetClosestPointOnSegment(const Point64& offPt, + const Point64& seg1, const Point64& seg2) + { + if (seg1.x == seg2.x && seg1.y == seg2.y) return seg1; + double dx = static_cast(seg2.x - seg1.x); + double dy = static_cast(seg2.y - seg1.y); + double q = + (static_cast(offPt.x - seg1.x) * dx + + static_cast(offPt.y - seg1.y) * dy) / + (Sqr(dx) + Sqr(dy)); + if (q < 0) q = 0; else if (q > 1) q = 1; + return Point64( + seg1.x + static_cast(nearbyint(q * dx)), + seg1.y + static_cast(nearbyint(q * dy))); + } + + enum class PointInPolygonResult { IsOn, IsInside, IsOutside }; + + template + inline PointInPolygonResult PointInPolygon(const Point& pt, const Path& polygon) + { + if (polygon.size() < 3) + return PointInPolygonResult::IsOutside; + + int val = 0; + typename Path::const_iterator cbegin = polygon.cbegin(), first = cbegin, curr, prev; + typename Path::const_iterator cend = polygon.cend(); + + while (first != cend && first->y == pt.y) ++first; + if (first == cend) // not a proper polygon + return PointInPolygonResult::IsOutside; + + bool is_above = first->y < pt.y, starting_above = is_above; + curr = first +1; + while (true) + { + if (curr == cend) + { + if (cend == first || first == cbegin) break; + cend = first; + curr = cbegin; + } + + if (is_above) + { + while (curr != cend && curr->y < pt.y) ++curr; + if (curr == cend) continue; + } + else + { + while (curr != cend && curr->y > pt.y) ++curr; + if (curr == cend) continue; + } + + if (curr == cbegin) + prev = polygon.cend() - 1; //nb: NOT cend (since might equal first) + else + prev = curr - 1; + + if (curr->y == pt.y) + { + if (curr->x == pt.x || + (curr->y == prev->y && + ((pt.x < prev->x) != (pt.x < curr->x)))) + return PointInPolygonResult::IsOn; + ++curr; + if (curr == first) break; + continue; + } + + if (pt.x < curr->x && pt.x < prev->x) + { + // we're only interested in edges crossing on the left + } + else if (pt.x > prev->x && pt.x > curr->x) + val = 1 - val; // toggle val + else + { + double d = CrossProduct(*prev, *curr, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + is_above = !is_above; + ++curr; + } + + if (is_above != starting_above) + { + cend = polygon.cend(); + if (curr == cend) curr = cbegin; + if (curr == cbegin) prev = cend - 1; + else prev = curr - 1; + double d = CrossProduct(*prev, *curr, pt); + if (d == 0) return PointInPolygonResult::IsOn; + if ((d < 0) == is_above) val = 1 - val; + } + + return (val == 0) ? + PointInPolygonResult::IsOutside : + PointInPolygonResult::IsInside; + } + +} // namespace + +#endif // CLIPPER_CORE_H diff --git a/src/other/manifold/include/clipper2/clipper.engine.h b/src/other/manifold/include/clipper2/clipper.engine.h new file mode 100644 index 00000000000..5aca121b5a8 --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.engine.h @@ -0,0 +1,626 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 26 July 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : This is the main polygon clipping module * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_ENGINE_H +#define CLIPPER_ENGINE_H + +constexpr auto CLIPPER2_VERSION = "1.2.2"; + +#include +#include //#541 +#include +#include +#include +#include +#include +#include + +#include "clipper.core.h" + +namespace Clipper2Lib { + + struct Scanline; + struct IntersectNode; + struct Active; + struct Vertex; + struct LocalMinima; + struct OutRec; + struct HorzSegment; + + //Note: all clipping operations except for Difference are commutative. + enum class ClipType { None, Intersection, Union, Difference, Xor }; + + enum class PathType { Subject, Clip }; + enum class JoinWith { None, Left, Right }; + + enum class VertexFlags : uint32_t { + None = 0, OpenStart = 1, OpenEnd = 2, LocalMax = 4, LocalMin = 8 + }; + + constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b) + { + return (enum VertexFlags)(uint32_t(a) & uint32_t(b)); + } + + constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b) + { + return (enum VertexFlags)(uint32_t(a) | uint32_t(b)); + } + + struct Vertex { + Point64 pt; + Vertex* next = nullptr; + Vertex* prev = nullptr; + VertexFlags flags = VertexFlags::None; + }; + + struct OutPt { + Point64 pt; + OutPt* next = nullptr; + OutPt* prev = nullptr; + OutRec* outrec; + HorzSegment* horz = nullptr; + + OutPt(const Point64& pt_, OutRec* outrec_): pt(pt_), outrec(outrec_) { + next = this; + prev = this; + } + }; + + class PolyPath; + class PolyPath64; + class PolyPathD; + using PolyTree64 = PolyPath64; + using PolyTreeD = PolyPathD; + + struct OutRec; + typedef std::vector OutRecList; + + //OutRec: contains a path in the clipping solution. Edges in the AEL will + //have OutRec pointers assigned when they form part of the clipping solution. + struct OutRec { + size_t idx = 0; + OutRec* owner = nullptr; + Active* front_edge = nullptr; + Active* back_edge = nullptr; + OutPt* pts = nullptr; + PolyPath* polypath = nullptr; + OutRecList* splits = nullptr; + OutRec* recursive_split = nullptr; + Rect64 bounds = {}; + Path64 path; + bool is_open = false; + + ~OutRec() { + if (splits) delete splits; + // nb: don't delete the split pointers + // as these are owned by ClipperBase's outrec_list_ + }; + }; + + /////////////////////////////////////////////////////////////////// + //Important: UP and DOWN here are premised on Y-axis positive down + //displays, which is the orientation used in Clipper's development. + /////////////////////////////////////////////////////////////////// + + struct Active { + Point64 bot; + Point64 top; + int64_t curr_x = 0; //current (updated at every new scanline) + double dx = 0.0; + int wind_dx = 1; //1 or -1 depending on winding direction + int wind_cnt = 0; + int wind_cnt2 = 0; //winding count of the opposite polytype + OutRec* outrec = nullptr; + //AEL: 'active edge list' (Vatti's AET - active edge table) + // a linked list of all edges (from left to right) that are present + // (or 'active') within the current scanbeam (a horizontal 'beam' that + // sweeps from bottom to top over the paths in the clipping operation). + Active* prev_in_ael = nullptr; + Active* next_in_ael = nullptr; + //SEL: 'sorted edge list' (Vatti's ST - sorted table) + // linked list used when sorting edges into their new positions at the + // top of scanbeams, but also (re)used to process horizontals. + Active* prev_in_sel = nullptr; + Active* next_in_sel = nullptr; + Active* jump = nullptr; + Vertex* vertex_top = nullptr; + LocalMinima* local_min = nullptr; // the bottom of an edge 'bound' (also Vatti) + bool is_left_bound = false; + JoinWith join_with = JoinWith::None; + }; + + struct LocalMinima { + Vertex* vertex; + PathType polytype; + bool is_open; + LocalMinima(Vertex* v, PathType pt, bool open) : + vertex(v), polytype(pt), is_open(open){} + }; + + struct IntersectNode { + Point64 pt; + Active* edge1; + Active* edge2; + IntersectNode() : pt(Point64(0,0)), edge1(NULL), edge2(NULL) {} + IntersectNode(Active* e1, Active* e2, Point64& pt_) : + pt(pt_), edge1(e1), edge2(e2) {} + }; + + struct HorzSegment { + OutPt* left_op; + OutPt* right_op = nullptr; + bool left_to_right = true; + HorzSegment() : left_op(nullptr) { } + explicit HorzSegment(OutPt* op) : left_op(op) { } + }; + + struct HorzJoin { + OutPt* op1 = nullptr; + OutPt* op2 = nullptr; + HorzJoin() {}; + explicit HorzJoin(OutPt* ltr, OutPt* rtl) : op1(ltr), op2(rtl) { } + }; + +#ifdef USINGZ + typedef std::function ZCallback64; + + typedef std::function ZCallbackD; +#endif + + typedef std::vector HorzSegmentList; + typedef std::unique_ptr LocalMinima_ptr; + typedef std::vector LocalMinimaList; + typedef std::vector IntersectNodeList; + + // ReuseableDataContainer64 ------------------------------------------------ + + class ReuseableDataContainer64 { + private: + friend class ClipperBase; + LocalMinimaList minima_list_; + std::vector vertex_lists_; + void AddLocMin(Vertex& vert, PathType polytype, bool is_open); + public: + virtual ~ReuseableDataContainer64(); + void Clear(); + void AddPaths(const Paths64& paths, PathType polytype, bool is_open); + }; + + // ClipperBase ------------------------------------------------------------- + + class ClipperBase { + private: + ClipType cliptype_ = ClipType::None; + FillRule fillrule_ = FillRule::EvenOdd; + FillRule fillpos = FillRule::Positive; + int64_t bot_y_ = 0; + bool minima_list_sorted_ = false; + bool using_polytree_ = false; + Active* actives_ = nullptr; + Active *sel_ = nullptr; + LocalMinimaList minima_list_; //pointers in case of memory reallocs + LocalMinimaList::iterator current_locmin_iter_; + std::vector vertex_lists_; + std::priority_queue scanline_list_; + IntersectNodeList intersect_nodes_; + HorzSegmentList horz_seg_list_; + std::vector horz_join_list_; + void Reset(); + inline void InsertScanline(int64_t y); + inline bool PopScanline(int64_t &y); + inline bool PopLocalMinima(int64_t y, LocalMinima*& local_minima); + void DisposeAllOutRecs(); + void DisposeVerticesAndLocalMinima(); + void DeleteEdges(Active*& e); + inline void AddLocMin(Vertex &vert, PathType polytype, bool is_open); + bool IsContributingClosed(const Active &e) const; + inline bool IsContributingOpen(const Active &e) const; + void SetWindCountForClosedPathEdge(Active &edge); + void SetWindCountForOpenPathEdge(Active &e); + void InsertLocalMinimaIntoAEL(int64_t bot_y); + void InsertLeftEdge(Active &e); + inline void PushHorz(Active &e); + inline bool PopHorz(Active *&e); + inline OutPt* StartOpenPath(Active &e, const Point64& pt); + inline void UpdateEdgeIntoAEL(Active *e); + OutPt* IntersectEdges(Active &e1, Active &e2, const Point64& pt); + inline void DeleteFromAEL(Active &e); + inline void AdjustCurrXAndCopyToSEL(const int64_t top_y); + void DoIntersections(const int64_t top_y); + void AddNewIntersectNode(Active &e1, Active &e2, const int64_t top_y); + bool BuildIntersectList(const int64_t top_y); + void ProcessIntersectList(); + void SwapPositionsInAEL(Active& edge1, Active& edge2); + OutRec* NewOutRec(); + OutPt* AddOutPt(const Active &e, const Point64& pt); + OutPt* AddLocalMinPoly(Active &e1, Active &e2, + const Point64& pt, bool is_new = false); + OutPt* AddLocalMaxPoly(Active &e1, Active &e2, const Point64& pt); + void DoHorizontal(Active &horz); + bool ResetHorzDirection(const Active &horz, const Vertex* max_vertex, + int64_t &horz_left, int64_t &horz_right); + void DoTopOfScanbeam(const int64_t top_y); + Active *DoMaxima(Active &e); + void JoinOutrecPaths(Active &e1, Active &e2); + void FixSelfIntersects(OutRec* outrec); + void DoSplitOp(OutRec* outRec, OutPt* splitOp); + + inline void AddTrialHorzJoin(OutPt* op); + void ConvertHorzSegsToJoins(); + void ProcessHorzJoins(); + + void Split(Active& e, const Point64& pt); + inline void CheckJoinLeft(Active& e, + const Point64& pt, bool check_curr_x = false); + inline void CheckJoinRight(Active& e, + const Point64& pt, bool check_curr_x = false); + protected: + int error_code_ = 0; + bool has_open_paths_ = false; + bool succeeded_ = true; + OutRecList outrec_list_; //pointers in case list memory reallocated + bool ExecuteInternal(ClipType ct, FillRule ft, bool use_polytrees); + void CleanCollinear(OutRec* outrec); + bool CheckBounds(OutRec* outrec); + bool CheckSplitOwner(OutRec* outrec, OutRecList* splits); + void RecursiveCheckOwners(OutRec* outrec, PolyPath* polypath); +#ifdef USINGZ + ZCallback64 zCallback_ = nullptr; + void SetZ(const Active& e1, const Active& e2, Point64& pt); +#endif + void CleanUp(); // unlike Clear, CleanUp preserves added paths + void AddPath(const Path64& path, PathType polytype, bool is_open); + void AddPaths(const Paths64& paths, PathType polytype, bool is_open); + public: + virtual ~ClipperBase(); + int ErrorCode() { return error_code_; }; + bool PreserveCollinear = true; + bool ReverseSolution = false; + void Clear(); + void AddReuseableData(const ReuseableDataContainer64& reuseable_data); +#ifdef USINGZ + int64_t DefaultZ = 0; +#endif + }; + + // PolyPath / PolyTree -------------------------------------------------------- + + //PolyTree: is intended as a READ-ONLY data structure for CLOSED paths returned + //by clipping operations. While this structure is more complex than the + //alternative Paths structure, it does preserve path 'ownership' - ie those + //paths that contain (or own) other paths. This will be useful to some users. + + class PolyPath { + protected: + PolyPath* parent_; + public: + PolyPath(PolyPath* parent = nullptr): parent_(parent){} + virtual ~PolyPath() {}; + //https://en.cppreference.com/w/cpp/language/rule_of_three + PolyPath(const PolyPath&) = delete; + PolyPath& operator=(const PolyPath&) = delete; + + unsigned Level() const + { + unsigned result = 0; + const PolyPath* p = parent_; + while (p) { ++result; p = p->parent_; } + return result; + } + + virtual PolyPath* AddChild(const Path64& path) = 0; + + virtual void Clear() = 0; + virtual size_t Count() const { return 0; } + + const PolyPath* Parent() const { return parent_; } + + bool IsHole() const + { + unsigned lvl = Level(); + //Even levels except level 0 + return lvl && !(lvl & 1); + } + }; + + typedef typename std::vector> PolyPath64List; + typedef typename std::vector> PolyPathDList; + + class PolyPath64 : public PolyPath { + private: + PolyPath64List childs_; + Path64 polygon_; + public: + explicit PolyPath64(PolyPath64* parent = nullptr) : PolyPath(parent) {} + + ~PolyPath64() { + childs_.resize(0); + } + + const PolyPath64* operator [] (size_t index) const + { + return childs_[index].get(); //std::unique_ptr + } + + const PolyPath64* Child(size_t index) const + { + return childs_[index].get(); + } + + PolyPath64List::const_iterator begin() const { return childs_.cbegin(); } + PolyPath64List::const_iterator end() const { return childs_.cend(); } + + PolyPath64* AddChild(const Path64& path) override + { + auto p = std::make_unique(this); + auto* result = childs_.emplace_back(std::move(p)).get(); + result->polygon_ = path; + return result; + } + + void Clear() override + { + childs_.resize(0); + } + + size_t Count() const override + { + return childs_.size(); + } + + const Path64& Polygon() const { return polygon_; }; + + double Area() const + { + return std::accumulate(childs_.cbegin(), childs_.cend(), + Clipper2Lib::Area(polygon_), + [](double a, const auto& child) {return a + child->Area(); }); + } + + }; + + class PolyPathD : public PolyPath { + private: + PolyPathDList childs_; + double scale_; + PathD polygon_; + public: + explicit PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent) + { + scale_ = parent ? parent->scale_ : 1.0; + } + + ~PolyPathD() { + childs_.resize(0); + } + + const PolyPathD* operator [] (size_t index) const + { + return childs_[index].get(); + } + + const PolyPathD* Child(size_t index) const + { + return childs_[index].get(); + } + + PolyPathDList::const_iterator begin() const { return childs_.cbegin(); } + PolyPathDList::const_iterator end() const { return childs_.cend(); } + + void SetScale(double value) { scale_ = value; } + double Scale() { return scale_; } + PolyPathD* AddChild(const Path64& path) override + { + int error_code = 0; + auto p = std::make_unique(this); + PolyPathD* result = childs_.emplace_back(std::move(p)).get(); + result->polygon_ = ScalePath(path, scale_, error_code); + return result; + } + + void Clear() override + { + childs_.resize(0); + } + + size_t Count() const override + { + return childs_.size(); + } + + const PathD& Polygon() const { return polygon_; }; + + double Area() const + { + return std::accumulate(childs_.begin(), childs_.end(), + Clipper2Lib::Area(polygon_), + [](double a, const auto& child) {return a + child->Area(); }); + } + }; + + class Clipper64 : public ClipperBase + { + private: + void BuildPaths64(Paths64& solutionClosed, Paths64* solutionOpen); + void BuildTree64(PolyPath64& polytree, Paths64& open_paths); + public: +#ifdef USINGZ + void SetZCallback(ZCallback64 cb) { zCallback_ = cb; } +#endif + + void AddSubject(const Paths64& subjects) + { + AddPaths(subjects, PathType::Subject, false); + } + void AddOpenSubject(const Paths64& open_subjects) + { + AddPaths(open_subjects, PathType::Subject, true); + } + void AddClip(const Paths64& clips) + { + AddPaths(clips, PathType::Clip, false); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, Paths64& closed_paths) + { + Paths64 dummy; + return Execute(clip_type, fill_rule, closed_paths, dummy); + } + + bool Execute(ClipType clip_type, FillRule fill_rule, + Paths64& closed_paths, Paths64& open_paths) + { + closed_paths.clear(); + open_paths.clear(); + if (ExecuteInternal(clip_type, fill_rule, false)) + BuildPaths64(closed_paths, &open_paths); + CleanUp(); + return succeeded_; + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PolyTree64& polytree) + { + Paths64 dummy; + return Execute(clip_type, fill_rule, polytree, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PolyTree64& polytree, Paths64& open_paths) + { + if (ExecuteInternal(clip_type, fill_rule, true)) + { + open_paths.clear(); + polytree.Clear(); + BuildTree64(polytree, open_paths); + } + CleanUp(); + return succeeded_; + } + }; + + class ClipperD : public ClipperBase { + private: + double scale_ = 1.0, invScale_ = 1.0; +#ifdef USINGZ + ZCallbackD zCallbackD_ = nullptr; +#endif + void BuildPathsD(PathsD& solutionClosed, PathsD* solutionOpen); + void BuildTreeD(PolyPathD& polytree, PathsD& open_paths); + public: + explicit ClipperD(int precision = 2) : ClipperBase() + { + CheckPrecision(precision, error_code_); + // to optimize scaling / descaling precision + // set the scale to a power of double's radix (2) (#25) + scale_ = std::pow(std::numeric_limits::radix, + std::ilogb(std::pow(10, precision)) + 1); + invScale_ = 1 / scale_; + } + +#ifdef USINGZ + void SetZCallback(ZCallbackD cb) { zCallbackD_ = cb; }; + + void ZCB(const Point64& e1bot, const Point64& e1top, + const Point64& e2bot, const Point64& e2top, Point64& pt) + { + // de-scale (x & y) + // temporarily convert integers to their initial float values + // this will slow clipping marginally but will make it much easier + // to understand the coordinates passed to the callback function + PointD tmp = PointD(pt) * invScale_; + PointD e1b = PointD(e1bot) * invScale_; + PointD e1t = PointD(e1top) * invScale_; + PointD e2b = PointD(e2bot) * invScale_; + PointD e2t = PointD(e2top) * invScale_; + zCallbackD_(e1b,e1t, e2b, e2t, tmp); + pt.z = tmp.z; // only update 'z' + }; + + void CheckCallback() + { + if(zCallbackD_) + // if the user defined float point callback has been assigned + // then assign the proxy callback function + ClipperBase::zCallback_ = + std::bind(&ClipperD::ZCB, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5); + else + ClipperBase::zCallback_ = nullptr; + } + +#endif + + void AddSubject(const PathsD& subjects) + { + AddPaths(ScalePaths(subjects, scale_, error_code_), PathType::Subject, false); + } + + void AddOpenSubject(const PathsD& open_subjects) + { + AddPaths(ScalePaths(open_subjects, scale_, error_code_), PathType::Subject, true); + } + + void AddClip(const PathsD& clips) + { + AddPaths(ScalePaths(clips, scale_, error_code_), PathType::Clip, false); + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PathsD& closed_paths) + { + PathsD dummy; + return Execute(clip_type, fill_rule, closed_paths, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PathsD& closed_paths, PathsD& open_paths) + { +#ifdef USINGZ + CheckCallback(); +#endif + if (ExecuteInternal(clip_type, fill_rule, false)) + { + BuildPathsD(closed_paths, &open_paths); + } + CleanUp(); + return succeeded_; + } + + bool Execute(ClipType clip_type, FillRule fill_rule, PolyTreeD& polytree) + { + PathsD dummy; + return Execute(clip_type, fill_rule, polytree, dummy); + } + + bool Execute(ClipType clip_type, + FillRule fill_rule, PolyTreeD& polytree, PathsD& open_paths) + { +#ifdef USINGZ + CheckCallback(); +#endif + if (ExecuteInternal(clip_type, fill_rule, true)) + { + polytree.Clear(); + polytree.SetScale(invScale_); + open_paths.clear(); + BuildTreeD(polytree, open_paths); + } + CleanUp(); + return succeeded_; + } + + }; + +} // namespace + +#endif // CLIPPER_ENGINE_H diff --git a/src/other/manifold/include/clipper2/clipper.export.h b/src/other/manifold/include/clipper2/clipper.export.h new file mode 100644 index 00000000000..f5f81d2a8b4 --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.export.h @@ -0,0 +1,772 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 30 May 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : This module exports the Clipper2 Library (ie DLL/so) * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +// The exported functions below refer to simple structures that +// can be understood across multiple languages. Consequently +// Path64, PathD, Polytree64 etc are converted from C++ classes +// (std::vector<> etc) into the following data structures: +// +// CPath64 (int64_t*) & CPathD (double_t*): +// Path64 and PathD are converted into arrays of x,y coordinates. +// However in these arrays the first x,y coordinate pair is a +// counter with 'x' containing the number of following coordinate +// pairs. ('y' should be 0, with one exception explained below.) +// __________________________________ +// |counter|coord1|coord2|...|coordN| +// |N ,0 |x1, y1|x2, y2|...|xN, yN| +// __________________________________ +// +// CPaths64 (int64_t**) & CPathsD (double_t**): +// These are arrays of pointers to CPath64 and CPathD where +// the first pointer is to a 'counter path'. This 'counter +// path' has a single x,y coord pair with 'y' (not 'x') +// containing the number of paths that follow. ('x' = 0). +// _______________________________ +// |counter|path1|path2|...|pathN| +// |addr0 |addr1|addr2|...|addrN| (*addr0[0]=0; *addr0[1]=N) +// _______________________________ +// +// The structures of CPolytree64 and CPolytreeD are defined +// below and these structures don't need to be explained here. + +#ifndef CLIPPER2_EXPORT_H +#define CLIPPER2_EXPORT_H + +#include +#include + +#include "clipper2/clipper.core.h" +#include "clipper2/clipper.engine.h" +#include "clipper2/clipper.offset.h" +#include "clipper2/clipper.rectclip.h" + +namespace Clipper2Lib { + +typedef int64_t* CPath64; +typedef int64_t** CPaths64; +typedef double* CPathD; +typedef double** CPathsD; + +typedef struct CPolyPath64 { + CPath64 polygon; + uint32_t is_hole; + uint32_t child_count; + CPolyPath64* childs; +} +CPolyTree64; + +typedef struct CPolyPathD { + CPathD polygon; + uint32_t is_hole; + uint32_t child_count; + CPolyPathD* childs; +} +CPolyTreeD; + +template +struct CRect { + T left; + T top; + T right; + T bottom; +}; + +typedef CRect CRect64; +typedef CRect CRectD; + +template +inline bool CRectIsEmpty(const CRect& rect) +{ + return (rect.right <= rect.left) || (rect.bottom <= rect.top); +} + +template +inline Rect CRectToRect(const CRect& rect) +{ + Rect result; + result.left = rect.left; + result.top = rect.top; + result.right = rect.right; + result.bottom = rect.bottom; + return result; +} + +#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport) + +////////////////////////////////////////////////////// +// EXPORTED FUNCTION DEFINITIONS +////////////////////////////////////////////////////// + +EXTERN_DLL_EXPORT const char* Version(); + +// Some of the functions below will return data in the various CPath +// and CPolyTree structures which are pointers to heap allocated +// memory. Eventually this memory will need to be released with one +// of the following 'DisposeExported' functions. (This may be the +// only safe way to release this memory since the executable +// accessing these exported functions may use a memory manager that +// allocates and releases heap memory in a different way. Also, +// CPath structures that have been constructed by the executable +// should not be destroyed using these 'DisposeExported' functions.) +EXTERN_DLL_EXPORT void DisposeExportedCPath64(CPath64 p); +EXTERN_DLL_EXPORT void DisposeExportedCPaths64(CPaths64& pp); +EXTERN_DLL_EXPORT void DisposeExportedCPathD(CPathD p); +EXTERN_DLL_EXPORT void DisposeExportedCPathsD(CPathsD& pp); +EXTERN_DLL_EXPORT void DisposeExportedCPolyTree64(CPolyTree64*& cpt); +EXTERN_DLL_EXPORT void DisposeExportedCPolyTreeD(CPolyTreeD*& cpt); + +// Boolean clipping: +// cliptype: None=0, Intersection=1, Union=2, Difference=3, Xor=4 +// fillrule: EvenOdd=0, NonZero=1, Positive=2, Negative=3 +EXTERN_DLL_EXPORT int BooleanOp64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPaths64& solution, CPaths64& solution_open, + bool preserve_collinear = true, bool reverse_solution = false); +EXTERN_DLL_EXPORT int BooleanOpPt64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPolyTree64*& solution, CPaths64& solution_open, + bool preserve_collinear = true, bool reverse_solution = false); +EXTERN_DLL_EXPORT int BooleanOpD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPathsD& solution, CPathsD& solution_open, int precision = 2, + bool preserve_collinear = true, bool reverse_solution = false); +EXTERN_DLL_EXPORT int BooleanOpPtD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPolyTreeD*& solution, CPathsD& solution_open, int precision = 2, + bool preserve_collinear = true, bool reverse_solution = false); + +// Polygon offsetting (inflate/deflate): +// jointype: Square=0, Round=1, Miter=2 +// endtype: Polygon=0, Joined=1, Butt=2, Square=3, Round=4 +EXTERN_DLL_EXPORT CPaths64 InflatePaths64(const CPaths64 paths, + double delta, uint8_t jointype, uint8_t endtype, + double miter_limit = 2.0, double arc_tolerance = 0.0, + bool reverse_solution = false); +EXTERN_DLL_EXPORT CPathsD InflatePathsD(const CPathsD paths, + double delta, uint8_t jointype, uint8_t endtype, + int precision = 2, double miter_limit = 2.0, + double arc_tolerance = 0.0, bool reverse_solution = false); + +// RectClip & RectClipLines: +EXTERN_DLL_EXPORT CPaths64 RectClip64(const CRect64& rect, + const CPaths64 paths); +EXTERN_DLL_EXPORT CPathsD RectClipD(const CRectD& rect, + const CPathsD paths, int precision = 2); +EXTERN_DLL_EXPORT CPaths64 RectClipLines64(const CRect64& rect, + const CPaths64 paths); +EXTERN_DLL_EXPORT CPathsD RectClipLinesD(const CRectD& rect, + const CPathsD paths, int precision = 2); + +////////////////////////////////////////////////////// +// INTERNAL FUNCTIONS +////////////////////////////////////////////////////// + +inline CPath64 CreateCPath64(size_t cnt1, size_t cnt2); +inline CPath64 CreateCPath64(const Path64& p); +inline CPaths64 CreateCPaths64(const Paths64& pp); +inline Path64 ConvertCPath64(const CPath64& p); +inline Paths64 ConvertCPaths64(const CPaths64& pp); + +inline CPathD CreateCPathD(size_t cnt1, size_t cnt2); +inline CPathD CreateCPathD(const PathD& p); +inline CPathsD CreateCPathsD(const PathsD& pp); +inline PathD ConvertCPathD(const CPathD& p); +inline PathsD ConvertCPathsD(const CPathsD& pp); + +// the following function avoid multiple conversions +inline CPathD CreateCPathD(const Path64& p, double scale); +inline CPathsD CreateCPathsD(const Paths64& pp, double scale); +inline Path64 ConvertCPathD(const CPathD& p, double scale); +inline Paths64 ConvertCPathsD(const CPathsD& pp, double scale); + +inline CPolyTree64* CreateCPolyTree64(const PolyTree64& pt); +inline CPolyTreeD* CreateCPolyTreeD(const PolyTree64& pt, double scale); + +EXTERN_DLL_EXPORT const char* Version() +{ + return CLIPPER2_VERSION; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPath64(CPath64 p) +{ + if (p) delete[] p; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPaths64(CPaths64& pp) +{ + if (!pp) return; + CPaths64 v = pp; + CPath64 cnts = *v; + const size_t cnt = static_cast(cnts[1]); + for (size_t i = 0; i <= cnt; ++i) //nb: cnt +1 + DisposeExportedCPath64(*v++); + delete[] pp; + pp = nullptr; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPathD(CPathD p) +{ + if (p) delete[] p; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPathsD(CPathsD& pp) +{ + if (!pp) return; + CPathsD v = pp; + CPathD cnts = *v; + size_t cnt = static_cast(cnts[1]); + for (size_t i = 0; i <= cnt; ++i) //nb: cnt +1 + DisposeExportedCPathD(*v++); + delete[] pp; + pp = nullptr; +} + +EXTERN_DLL_EXPORT int BooleanOp64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPaths64& solution, CPaths64& solution_open, + bool preserve_collinear, bool reverse_solution) +{ + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + + Paths64 sub, sub_open, clp, sol, sol_open; + sub = ConvertCPaths64(subjects); + sub_open = ConvertCPaths64(subjects_open); + clp = ConvertCPaths64(clips); + + Clipper64 clipper; + clipper.PreserveCollinear = preserve_collinear; + clipper.ReverseSolution = reverse_solution; + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), FillRule(fillrule), sol, sol_open)) + return -1; // clipping bug - should never happen :) + solution = CreateCPaths64(sol); + solution_open = CreateCPaths64(sol_open); + return 0; //success !! +} + +EXTERN_DLL_EXPORT int BooleanOpPt64(uint8_t cliptype, + uint8_t fillrule, const CPaths64 subjects, + const CPaths64 subjects_open, const CPaths64 clips, + CPolyTree64*& solution, CPaths64& solution_open, + bool preserve_collinear, bool reverse_solution) +{ + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + Paths64 sub, sub_open, clp, sol_open; + sub = ConvertCPaths64(subjects); + sub_open = ConvertCPaths64(subjects_open); + clp = ConvertCPaths64(clips); + + PolyTree64 pt; + Clipper64 clipper; + clipper.PreserveCollinear = preserve_collinear; + clipper.ReverseSolution = reverse_solution; + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), FillRule(fillrule), pt, sol_open)) + return -1; // clipping bug - should never happen :) + + solution = CreateCPolyTree64(pt); + solution_open = CreateCPaths64(sol_open); + return 0; //success !! +} + +EXTERN_DLL_EXPORT int BooleanOpD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPathsD& solution, CPathsD& solution_open, int precision, + bool preserve_collinear, bool reverse_solution) +{ + if (precision < -8 || precision > 8) return -5; + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + const double scale = std::pow(10, precision); + + Paths64 sub, sub_open, clp, sol, sol_open; + sub = ConvertCPathsD(subjects, scale); + sub_open = ConvertCPathsD(subjects_open, scale); + clp = ConvertCPathsD(clips, scale); + + Clipper64 clipper; + clipper.PreserveCollinear = preserve_collinear; + clipper.ReverseSolution = reverse_solution; + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) + clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), + FillRule(fillrule), sol, sol_open)) return -1; + + if (sol.size() > 0) solution = CreateCPathsD(sol, 1 / scale); + if (sol_open.size() > 0) + solution_open = CreateCPathsD(sol_open, 1 / scale); + return 0; +} + +EXTERN_DLL_EXPORT int BooleanOpPtD(uint8_t cliptype, + uint8_t fillrule, const CPathsD subjects, + const CPathsD subjects_open, const CPathsD clips, + CPolyTreeD*& solution, CPathsD& solution_open, int precision, + bool preserve_collinear, bool reverse_solution) +{ + if (precision < -8 || precision > 8) return -5; + if (cliptype > static_cast(ClipType::Xor)) return -4; + if (fillrule > static_cast(FillRule::Negative)) return -3; + + const double scale = std::pow(10, precision); + Paths64 sub, sub_open, clp, sol_open; + sub = ConvertCPathsD(subjects, scale); + sub_open = ConvertCPathsD(subjects_open, scale); + clp = ConvertCPathsD(clips, scale); + + PolyTree64 sol; + Clipper64 clipper; + clipper.PreserveCollinear = preserve_collinear; + clipper.ReverseSolution = reverse_solution; + if (sub.size() > 0) clipper.AddSubject(sub); + if (sub_open.size() > 0) + clipper.AddOpenSubject(sub_open); + if (clp.size() > 0) clipper.AddClip(clp); + if (!clipper.Execute(ClipType(cliptype), + FillRule(fillrule), sol, sol_open)) return -1; + + solution = CreateCPolyTreeD(sol, 1 / scale); + if (sol_open.size() > 0) + solution_open = CreateCPathsD(sol_open, 1 / scale); + return 0; +} + +EXTERN_DLL_EXPORT CPaths64 InflatePaths64(const CPaths64 paths, + double delta, uint8_t jointype, uint8_t endtype, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + Paths64 pp; + pp = ConvertCPaths64(paths); + + ClipperOffset clip_offset( miter_limit, + arc_tolerance, reverse_solution); + clip_offset.AddPaths(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta, result); + return CreateCPaths64(result); +} + +EXTERN_DLL_EXPORT CPathsD InflatePathsD(const CPathsD paths, + double delta, uint8_t jointype, uint8_t endtype, + int precision, double miter_limit, + double arc_tolerance, bool reverse_solution) +{ + if (precision < -8 || precision > 8 || !paths) return nullptr; + const double scale = std::pow(10, precision); + ClipperOffset clip_offset(miter_limit, arc_tolerance, reverse_solution); + Paths64 pp = ConvertCPathsD(paths, scale); + clip_offset.AddPaths(pp, JoinType(jointype), EndType(endtype)); + Paths64 result; + clip_offset.Execute(delta * scale, result); + return CreateCPathsD(result, 1/scale); +} + +EXTERN_DLL_EXPORT CPaths64 RectClip64(const CRect64& rect, const CPaths64 paths) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + Rect64 r64 = CRectToRect(rect); + class RectClip64 rc(r64); + Paths64 pp = ConvertCPaths64(paths); + Paths64 result = rc.Execute(pp); + return CreateCPaths64(result); +} + +EXTERN_DLL_EXPORT CPathsD RectClipD(const CRectD& rect, const CPathsD paths, int precision) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + if (precision < -8 || precision > 8) return nullptr; + const double scale = std::pow(10, precision); + + RectD r = CRectToRect(rect); + Rect64 rec = ScaleRect(r, scale); + Paths64 pp = ConvertCPathsD(paths, scale); + class RectClip64 rc(rec); + Paths64 result = rc.Execute(pp); + return CreateCPathsD(result, 1/scale); +} + +EXTERN_DLL_EXPORT CPaths64 RectClipLines64(const CRect64& rect, + const CPaths64 paths) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + Rect64 r = CRectToRect(rect); + class RectClipLines64 rcl (r); + Paths64 pp = ConvertCPaths64(paths); + Paths64 result = rcl.Execute(pp); + return CreateCPaths64(result); +} + +EXTERN_DLL_EXPORT CPathsD RectClipLinesD(const CRectD& rect, + const CPathsD paths, int precision) +{ + if (CRectIsEmpty(rect) || !paths) return nullptr; + if (precision < -8 || precision > 8) return nullptr; + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(CRectToRect(rect), scale); + class RectClipLines64 rcl(r); + Paths64 pp = ConvertCPathsD(paths, scale); + Paths64 result = rcl.Execute(pp); + return CreateCPathsD(result, 1/scale); +} + +inline CPath64 CreateCPath64(size_t cnt1, size_t cnt2) +{ + // allocates memory for CPath64, fills in the counter, and + // returns the structure ready to be filled with path data + CPath64 result = new int64_t[2 + cnt1 *2]; + result[0] = cnt1; + result[1] = cnt2; + return result; +} + +inline CPath64 CreateCPath64(const Path64& p) +{ + // allocates memory for CPath64, fills the counter + // and returns the memory filled with path data + size_t cnt = p.size(); + if (!cnt) return nullptr; + CPath64 result = CreateCPath64(cnt, 0); + CPath64 v = result; + v += 2; // skip counters + for (const Point64& pt : p) + { + *v++ = pt.x; + *v++ = pt.y; + } + return result; +} + +inline Path64 ConvertCPath64(const CPath64& p) +{ + Path64 result; + if (p && *p) + { + CPath64 v = p; + const size_t cnt = static_cast(p[0]); + v += 2; // skip counters + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + { + // x,y here avoids right to left function evaluation + // result.push_back(Point64(*v++, *v++)); + int64_t x = *v++; + int64_t y = *v++; + result.push_back(Point64(x, y)); + } + } + return result; +} + +inline CPaths64 CreateCPaths64(const Paths64& pp) +{ + // allocates memory for multiple CPath64 and + // and returns this memory filled with path data + size_t cnt = pp.size(), cnt2 = cnt; + + // don't allocate space for empty paths + for (size_t i = 0; i < cnt; ++i) + if (!pp[i].size()) --cnt2; + if (!cnt2) return nullptr; + + CPaths64 result = new int64_t* [cnt2 + 1]; + CPaths64 v = result; + *v++ = CreateCPath64(0, cnt2); // assign a counter path + for (const Path64& p : pp) + { + *v = CreateCPath64(p); + if (*v) ++v; + } + return result; +} + +inline Paths64 ConvertCPaths64(const CPaths64& pp) +{ + Paths64 result; + if (pp) + { + CPaths64 v = pp; + CPath64 cnts = pp[0]; + const size_t cnt = static_cast(cnts[1]); // nb 2nd cnt + ++v; // skip cnts + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + result.push_back(ConvertCPath64(*v++)); + } + return result; +} + +inline CPathD CreateCPathD(size_t cnt1, size_t cnt2) +{ + // allocates memory for CPathD, fills in the counter, and + // returns the structure ready to be filled with path data + CPathD result = new double[2 + cnt1 * 2]; + result[0] = static_cast(cnt1); + result[1] = static_cast(cnt2); + return result; +} + +inline CPathD CreateCPathD(const PathD& p) +{ + // allocates memory for CPath, fills the counter + // and returns the memory fills with path data + size_t cnt = p.size(); + if (!cnt) return nullptr; + CPathD result = CreateCPathD(cnt, 0); + CPathD v = result; + v += 2; // skip counters + for (const PointD& pt : p) + { + *v++ = pt.x; + *v++ = pt.y; + } + return result; +} + +inline PathD ConvertCPathD(const CPathD& p) +{ + PathD result; + if (p) + { + CPathD v = p; + size_t cnt = static_cast(v[0]); + v += 2; // skip counters + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + { + // x,y here avoids right to left function evaluation + // result.push_back(PointD(*v++, *v++)); + double x = *v++; + double y = *v++; + result.push_back(PointD(x, y)); + } + } + return result; +} + +inline CPathsD CreateCPathsD(const PathsD& pp) +{ + size_t cnt = pp.size(), cnt2 = cnt; + // don't allocate space for empty paths + for (size_t i = 0; i < cnt; ++i) + if (!pp[i].size()) --cnt2; + if (!cnt2) return nullptr; + CPathsD result = new double * [cnt2 + 1]; + CPathsD v = result; + *v++ = CreateCPathD(0, cnt2); // assign counter path + for (const PathD& p : pp) + { + *v = CreateCPathD(p); + if (*v) { ++v; } + } + return result; +} + +inline PathsD ConvertCPathsD(const CPathsD& pp) +{ + PathsD result; + if (pp) + { + CPathsD v = pp; + CPathD cnts = v[0]; + size_t cnt = static_cast(cnts[1]); + ++v; // skip cnts path + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + result.push_back(ConvertCPathD(*v++)); + } + return result; +} + +inline Path64 ConvertCPathD(const CPathD& p, double scale) +{ + Path64 result; + if (p) + { + CPathD v = p; + size_t cnt = static_cast(*v); + v += 2; // skip counters + result.reserve(cnt); + for (size_t i = 0; i < cnt; ++i) + { + // x,y here avoids right to left function evaluation + // result.push_back(PointD(*v++, *v++)); + double x = *v++ * scale; + double y = *v++ * scale; + result.push_back(Point64(x, y)); + } + } + return result; +} + +inline Paths64 ConvertCPathsD(const CPathsD& pp, double scale) +{ + Paths64 result; + if (pp) + { + CPathsD v = pp; + CPathD cnts = v[0]; + size_t cnt = static_cast(cnts[1]); + result.reserve(cnt); + ++v; // skip cnts path + for (size_t i = 0; i < cnt; ++i) + result.push_back(ConvertCPathD(*v++, scale)); + } + return result; +} + +inline CPathD CreateCPathD(const Path64& p, double scale) +{ + // allocates memory for CPathD, fills in the counter, and + // returns the structure filled with *scaled* path data + size_t cnt = p.size(); + if (!cnt) return nullptr; + CPathD result = CreateCPathD(cnt, 0); + CPathD v = result; + v += 2; // skip cnts + for (const Point64& pt : p) + { + *v++ = pt.x * scale; + *v++ = pt.y * scale; + } + return result; +} + +inline CPathsD CreateCPathsD(const Paths64& pp, double scale) +{ + // allocates memory for *multiple* CPathD, and + // returns the structure filled with scaled path data + size_t cnt = pp.size(), cnt2 = cnt; + // don't allocate space for empty paths + for (size_t i = 0; i < cnt; ++i) + if (!pp[i].size()) --cnt2; + if (!cnt2) return nullptr; + CPathsD result = new double* [cnt2 + 1]; + CPathsD v = result; + *v++ = CreateCPathD(0, cnt2); + for (const Path64& p : pp) + { + *v = CreateCPathD(p, scale); + if (*v) ++v; + } + return result; +} + +inline void InitCPolyPath64(CPolyTree64* cpt, + bool is_hole, const std::unique_ptr & pp) +{ + cpt->polygon = CreateCPath64(pp->Polygon()); + cpt->is_hole = is_hole; + size_t child_cnt = pp->Count(); + cpt->child_count = static_cast(child_cnt); + cpt->childs = nullptr; + if (!child_cnt) return; + cpt->childs = new CPolyPath64[child_cnt]; + CPolyPath64* child = cpt->childs; + for (const std::unique_ptr & pp_child : *pp) + InitCPolyPath64(child++, !is_hole, pp_child); +} + +inline CPolyTree64* CreateCPolyTree64(const PolyTree64& pt) +{ + CPolyTree64* result = new CPolyTree64(); + result->polygon = nullptr; + result->is_hole = false; + size_t child_cnt = pt.Count(); + result->childs = nullptr; + result->child_count = static_cast(child_cnt); + if (!child_cnt) return result; + result->childs = new CPolyPath64[child_cnt]; + CPolyPath64* child = result->childs; + for (const std::unique_ptr & pp : pt) + InitCPolyPath64(child++, true, pp); + return result; +} + +inline void DisposeCPolyPath64(CPolyPath64* cpp) +{ + if (!cpp->child_count) return; + CPolyPath64* child = cpp->childs; + for (size_t i = 0; i < cpp->child_count; ++i) + DisposeCPolyPath64(child); + delete[] cpp->childs; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPolyTree64(CPolyTree64*& cpt) +{ + if (!cpt) return; + DisposeCPolyPath64(cpt); + delete cpt; + cpt = nullptr; +} + +inline void InitCPolyPathD(CPolyTreeD* cpt, + bool is_hole, const std::unique_ptr & pp, double scale) +{ + cpt->polygon = CreateCPathD(pp->Polygon(), scale); + cpt->is_hole = is_hole; + size_t child_cnt = pp->Count(); + cpt->child_count = static_cast(child_cnt); + cpt->childs = nullptr; + if (!child_cnt) return; + cpt->childs = new CPolyPathD[child_cnt]; + CPolyPathD* child = cpt->childs; + for (const std::unique_ptr & pp_child : *pp) + InitCPolyPathD(child++, !is_hole, pp_child, scale); +} + +inline CPolyTreeD* CreateCPolyTreeD(const PolyTree64& pt, double scale) +{ + CPolyTreeD* result = new CPolyTreeD(); + result->polygon = nullptr; + result->is_hole = false; + size_t child_cnt = pt.Count(); + result->child_count = static_cast(child_cnt); + result->childs = nullptr; + if (!child_cnt) return result; + result->childs = new CPolyPathD[child_cnt]; + CPolyPathD* child = result->childs; + for (const std::unique_ptr & pp : pt) + InitCPolyPathD(child++, true, pp, scale); + return result; +} + +inline void DisposeCPolyPathD(CPolyPathD* cpp) +{ + if (!cpp->child_count) return; + CPolyPathD* child = cpp->childs; + for (size_t i = 0; i < cpp->child_count; ++i) + DisposeCPolyPathD(child++); + delete[] cpp->childs; +} + +EXTERN_DLL_EXPORT void DisposeExportedCPolyTreeD(CPolyTreeD*& cpt) +{ + if (!cpt) return; + DisposeCPolyPathD(cpt); + delete cpt; + cpt = nullptr; +} + +} // end Clipper2Lib namespace + +#endif // CLIPPER2_EXPORT_H diff --git a/src/other/manifold/include/clipper2/clipper.h b/src/other/manifold/include/clipper2/clipper.h new file mode 100644 index 00000000000..b5ac6aa9a1f --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.h @@ -0,0 +1,785 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 16 July 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : This module provides a simple interface to the Clipper Library * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_H +#define CLIPPER_H + +#include +#include +#include + +#include "clipper.core.h" +#include "clipper.engine.h" +#include "clipper.offset.h" +#include "clipper.minkowski.h" +#include "clipper.rectclip.h" + +namespace Clipper2Lib { + + inline Paths64 BooleanOp(ClipType cliptype, FillRule fillrule, + const Paths64& subjects, const Paths64& clips) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, result); + return result; + } + + inline void BooleanOp(ClipType cliptype, FillRule fillrule, + const Paths64& subjects, const Paths64& clips, PolyTree64& solution) + { + Paths64 sol_open; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, solution, sol_open); + } + + inline PathsD BooleanOp(ClipType cliptype, FillRule fillrule, + const PathsD& subjects, const PathsD& clips, int precision = 2) + { + int error_code = 0; + CheckPrecision(precision, error_code); + PathsD result; + if (error_code) return result; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, result); + return result; + } + + inline void BooleanOp(ClipType cliptype, FillRule fillrule, + const PathsD& subjects, const PathsD& clips, + PolyTreeD& polytree, int precision = 2) + { + polytree.Clear(); + int error_code = 0; + CheckPrecision(precision, error_code); + if (error_code) return; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.AddClip(clips); + clipper.Execute(cliptype, fillrule, polytree); + } + + inline Paths64 Intersect(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Intersection, fillrule, subjects, clips); + } + + inline PathsD Intersect(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Intersection, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Union(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Union, fillrule, subjects, clips); + } + + inline PathsD Union(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Union, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Union(const Paths64& subjects, FillRule fillrule) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + inline PathsD Union(const PathsD& subjects, FillRule fillrule, int precision = 2) + { + PathsD result; + int error_code = 0; + CheckPrecision(precision, error_code); + if (error_code) return result; + ClipperD clipper(precision); + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + inline Paths64 Difference(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Difference, fillrule, subjects, clips); + } + + inline PathsD Difference(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Difference, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 Xor(const Paths64& subjects, const Paths64& clips, FillRule fillrule) + { + return BooleanOp(ClipType::Xor, fillrule, subjects, clips); + } + + inline PathsD Xor(const PathsD& subjects, const PathsD& clips, FillRule fillrule, int decimal_prec = 2) + { + return BooleanOp(ClipType::Xor, fillrule, subjects, clips, decimal_prec); + } + + inline Paths64 InflatePaths(const Paths64& paths, double delta, + JoinType jt, EndType et, double miter_limit = 2.0, + double arc_tolerance = 0.0) + { + if (!delta) return paths; + ClipperOffset clip_offset(miter_limit, arc_tolerance); + clip_offset.AddPaths(paths, jt, et); + Paths64 solution; + clip_offset.Execute(delta, solution); + return solution; + } + + inline PathsD InflatePaths(const PathsD& paths, double delta, + JoinType jt, EndType et, double miter_limit = 2.0, + int precision = 2, double arc_tolerance = 0.0) + { + int error_code = 0; + CheckPrecision(precision, error_code); + if (!delta) return paths; + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + ClipperOffset clip_offset(miter_limit, arc_tolerance); + clip_offset.AddPaths(ScalePaths(paths, scale, error_code), jt, et); + if (error_code) return PathsD(); + Paths64 solution; + clip_offset.Execute(delta * scale, solution); + return ScalePaths(solution, 1 / scale, error_code); + } + + template + inline Path TranslatePath(const Path& path, T dx, T dy) + { + Path result; + result.reserve(path.size()); + std::transform(path.begin(), path.end(), back_inserter(result), + [dx, dy](const auto& pt) { return Point(pt.x + dx, pt.y +dy); }); + return result; + } + + inline Path64 TranslatePath(const Path64& path, int64_t dx, int64_t dy) + { + return TranslatePath(path, dx, dy); + } + + inline PathD TranslatePath(const PathD& path, double dx, double dy) + { + return TranslatePath(path, dx, dy); + } + + template + inline Paths TranslatePaths(const Paths& paths, T dx, T dy) + { + Paths result; + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [dx, dy](const auto& path) { return TranslatePath(path, dx, dy); }); + return result; + } + + inline Paths64 TranslatePaths(const Paths64& paths, int64_t dx, int64_t dy) + { + return TranslatePaths(paths, dx, dy); + } + + inline PathsD TranslatePaths(const PathsD& paths, double dx, double dy) + { + return TranslatePaths(paths, dx, dy); + } + + inline Paths64 RectClip(const Rect64& rect, const Paths64& paths) + { + if (rect.IsEmpty() || paths.empty()) return Paths64(); + RectClip64 rc(rect); + return rc.Execute(paths); + } + + inline Paths64 RectClip(const Rect64& rect, const Path64& path) + { + if (rect.IsEmpty() || path.empty()) return Paths64(); + RectClip64 rc(rect); + return rc.Execute(Paths64{ path }); + } + + inline PathsD RectClip(const RectD& rect, const PathsD& paths, int precision = 2) + { + if (rect.IsEmpty() || paths.empty()) return PathsD(); + int error_code = 0; + CheckPrecision(precision, error_code); + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(rect, scale); + RectClip64 rc(r); + Paths64 pp = ScalePaths(paths, scale, error_code); + if (error_code) return PathsD(); // ie: error_code result is lost + return ScalePaths( + rc.Execute(pp), 1 / scale, error_code); + } + + inline PathsD RectClip(const RectD& rect, const PathD& path, int precision = 2) + { + return RectClip(rect, PathsD{ path }, precision); + } + + inline Paths64 RectClipLines(const Rect64& rect, const Paths64& lines) + { + if (rect.IsEmpty() || lines.empty()) return Paths64(); + RectClipLines64 rcl(rect); + return rcl.Execute(lines); + } + + inline Paths64 RectClipLines(const Rect64& rect, const Path64& line) + { + return RectClipLines(rect, Paths64{ line }); + } + + inline PathsD RectClipLines(const RectD& rect, const PathsD& lines, int precision = 2) + { + if (rect.IsEmpty() || lines.empty()) return PathsD(); + int error_code = 0; + CheckPrecision(precision, error_code); + if (error_code) return PathsD(); + const double scale = std::pow(10, precision); + Rect64 r = ScaleRect(rect, scale); + RectClipLines64 rcl(r); + Paths64 p = ScalePaths(lines, scale, error_code); + if (error_code) return PathsD(); + p = rcl.Execute(p); + return ScalePaths(p, 1 / scale, error_code); + } + + inline PathsD RectClipLines(const RectD& rect, const PathD& line, int precision = 2) + { + return RectClipLines(rect, PathsD{ line }, precision); + } + + namespace details + { + + inline void PolyPathToPaths64(const PolyPath64& polypath, Paths64& paths) + { + paths.push_back(polypath.Polygon()); + for (const auto& child : polypath) + PolyPathToPaths64(*child, paths); + } + + inline void PolyPathToPathsD(const PolyPathD& polypath, PathsD& paths) + { + paths.push_back(polypath.Polygon()); + for (const auto& child : polypath) + PolyPathToPathsD(*child, paths); + } + + inline bool PolyPath64ContainsChildren(const PolyPath64& pp) + { + for (const auto& child : pp) + { + // return false if this child isn't fully contained by its parent + + // checking for a single vertex outside is a bit too crude since + // it doesn't account for rounding errors. It's better to check + // for consecutive vertices found outside the parent's polygon. + + int outsideCnt = 0; + for (const Point64& pt : child->Polygon()) + { + PointInPolygonResult result = PointInPolygon(pt, pp.Polygon()); + if (result == PointInPolygonResult::IsInside) --outsideCnt; + else if (result == PointInPolygonResult::IsOutside) ++outsideCnt; + if (outsideCnt > 1) return false; + else if (outsideCnt < -1) break; + } + + // now check any nested children too + if (child->Count() > 0 && !PolyPath64ContainsChildren(*child)) + return false; + } + return true; + } + + static void OutlinePolyPath(std::ostream& os, + size_t idx, bool isHole, size_t count, const std::string& preamble) + { + std::string plural = (count == 1) ? "." : "s."; + if (isHole) + os << preamble << "+- Hole (" << idx << ") contains " << count << + " nested polygon" << plural << std::endl; + else + os << preamble << "+- Polygon (" << idx << ") contains " << count << + " hole" << plural << std::endl; + } + + static void OutlinePolyPath64(std::ostream& os, const PolyPath64& pp, + size_t idx, std::string preamble) + { + OutlinePolyPath(os, idx, pp.IsHole(), pp.Count(), preamble); + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPath64(os, *pp.Child(i), i, preamble + " "); + } + + static void OutlinePolyPathD(std::ostream& os, const PolyPathD& pp, + size_t idx, std::string preamble) + { + OutlinePolyPath(os, idx, pp.IsHole(), pp.Count(), preamble); + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPathD(os, *pp.Child(i), i, preamble + " "); + } + + } // end details namespace + + inline std::ostream& operator<< (std::ostream& os, const PolyTree64& pp) + { + std::string plural = (pp.Count() == 1) ? " polygon." : " polygons."; + os << std::endl << "Polytree with " << pp.Count() << plural << std::endl; + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPath64(os, *pp.Child(i), i, " "); + os << std::endl << std::endl; + return os; + } + + inline std::ostream& operator<< (std::ostream& os, const PolyTreeD& pp) + { + std::string plural = (pp.Count() == 1) ? " polygon." : " polygons."; + os << std::endl << "Polytree with " << pp.Count() << plural << std::endl; + for (size_t i = 0; i < pp.Count(); ++i) + if (pp.Child(i)->Count()) + details::OutlinePolyPathD(os, *pp.Child(i), i, " "); + os << std::endl << std::endl; + if (!pp.Level()) os << std::endl; + return os; + } + + inline Paths64 PolyTreeToPaths64(const PolyTree64& polytree) + { + Paths64 result; + for (const auto& child : polytree) + details::PolyPathToPaths64(*child, result); + return result; + } + + inline PathsD PolyTreeToPathsD(const PolyTreeD& polytree) + { + PathsD result; + for (const auto& child : polytree) + details::PolyPathToPathsD(*child, result); + return result; + } + + inline bool CheckPolytreeFullyContainsChildren(const PolyTree64& polytree) + { + for (const auto& child : polytree) + if (child->Count() > 0 && + !details::PolyPath64ContainsChildren(*child)) + return false; + return true; + } + + namespace details { + + template + inline constexpr void MakePathGeneric(const T list, size_t size, + std::vector& result) + { + for (size_t i = 0; i < size; ++i) +#ifdef USINGZ + result[i / 2] = U{list[i], list[++i], 0}; +#else + result[i / 2] = U{list[i], list[++i]}; +#endif + } + + } // end details namespace + + template::value && + !std::is_same::value, bool + >::type = true> + inline Path64 MakePath(const std::vector& list) + { + const auto size = list.size() - list.size() % 2; + if (list.size() != size) + DoError(non_pair_error_i); // non-fatal without exception handling + Path64 result(size / 2); // else ignores unpaired value + details::MakePathGeneric(list, size, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline Path64 MakePath(const T(&list)[N]) + { + // Make the compiler error on unpaired value (i.e. no runtime effects). + static_assert(N % 2 == 0, "MakePath requires an even number of arguments"); + Path64 result(N / 2); + details::MakePathGeneric(list, N, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline PathD MakePathD(const std::vector& list) + { + const auto size = list.size() - list.size() % 2; + if (list.size() != size) + DoError(non_pair_error_i); // non-fatal without exception handling + PathD result(size / 2); // else ignores unpaired value + details::MakePathGeneric(list, size, result); + return result; + } + + template::value && + !std::is_same::value, bool + >::type = true> + inline PathD MakePathD(const T(&list)[N]) + { + // Make the compiler error on unpaired value (i.e. no runtime effects). + static_assert(N % 2 == 0, "MakePath requires an even number of arguments"); + PathD result(N / 2); + details::MakePathGeneric(list, N, result); + return result; + } + +#ifdef USINGZ + template + inline Path64 MakePathZ(const T2(&list)[N]) + { + static_assert(N % 3 == 0 && std::numeric_limits::is_integer, + "MakePathZ requires integer values in multiples of 3"); + std::size_t size = N / 3; + Path64 result(size); + for (size_t i = 0; i < size; ++i) + result[i] = Point64(list[i * 3], + list[i * 3 + 1], list[i * 3 + 2]); + return result; + } + + template + inline PathD MakePathZD(const T2(&list)[N]) + { + static_assert(N % 3 == 0, + "MakePathZD requires values in multiples of 3"); + std::size_t size = N / 3; + PathD result(size); + if constexpr (std::numeric_limits::is_integer) + for (size_t i = 0; i < size; ++i) + result[i] = PointD(list[i * 3], + list[i * 3 + 1], list[i * 3 + 2]); + else + for (size_t i = 0; i < size; ++i) + result[i] = PointD(list[i * 3], list[i * 3 + 1], + static_cast(list[i * 3 + 2])); + return result; + } +#endif + + inline Path64 TrimCollinear(const Path64& p, bool is_open_path = false) + { + size_t len = p.size(); + if (len < 3) + { + if (!is_open_path || len < 2 || p[0] == p[1]) return Path64(); + else return p; + } + + Path64 dst; + dst.reserve(len); + Path64::const_iterator srcIt = p.cbegin(), prevIt, stop = p.cend() - 1; + + if (!is_open_path) + { + while (srcIt != stop && !CrossProduct(*stop, *srcIt, *(srcIt + 1))) + ++srcIt; + while (srcIt != stop && !CrossProduct(*(stop - 1), *stop, *srcIt)) + --stop; + if (srcIt == stop) return Path64(); + } + + prevIt = srcIt++; + dst.push_back(*prevIt); + for (; srcIt != stop; ++srcIt) + { + if (CrossProduct(*prevIt, *srcIt, *(srcIt + 1))) + { + prevIt = srcIt; + dst.push_back(*prevIt); + } + } + + if (is_open_path) + dst.push_back(*srcIt); + else if (CrossProduct(*prevIt, *stop, dst[0])) + dst.push_back(*stop); + else + { + while (dst.size() > 2 && + !CrossProduct(dst[dst.size() - 1], dst[dst.size() - 2], dst[0])) + dst.pop_back(); + if (dst.size() < 3) return Path64(); + } + return dst; + } + + inline PathD TrimCollinear(const PathD& path, int precision, bool is_open_path = false) + { + int error_code = 0; + CheckPrecision(precision, error_code); + if (error_code) return PathD(); + const double scale = std::pow(10, precision); + Path64 p = ScalePath(path, scale, error_code); + if (error_code) return PathD(); + p = TrimCollinear(p, is_open_path); + return ScalePath(p, 1/scale, error_code); + } + + template + inline double Distance(const Point pt1, const Point pt2) + { + return std::sqrt(DistanceSqr(pt1, pt2)); + } + + template + inline double Length(const Path& path, bool is_closed_path = false) + { + double result = 0.0; + if (path.size() < 2) return result; + auto it = path.cbegin(), stop = path.end() - 1; + for (; it != stop; ++it) + result += Distance(*it, *(it + 1)); + if (is_closed_path) + result += Distance(*stop, *path.cbegin()); + return result; + } + + + template + inline bool NearCollinear(const Point& pt1, const Point& pt2, const Point& pt3, double sin_sqrd_min_angle_rads) + { + double cp = std::abs(CrossProduct(pt1, pt2, pt3)); + return (cp * cp) / (DistanceSqr(pt1, pt2) * DistanceSqr(pt2, pt3)) < sin_sqrd_min_angle_rads; + } + + template + inline Path Ellipse(const Rect& rect, int steps = 0) + { + return Ellipse(rect.MidPoint(), + static_cast(rect.Width()) *0.5, + static_cast(rect.Height()) * 0.5, steps); + } + + template + inline Path Ellipse(const Point& center, + double radiusX, double radiusY = 0, int steps = 0) + { + if (radiusX <= 0) return Path(); + if (radiusY <= 0) radiusY = radiusX; + if (steps <= 2) + steps = static_cast(PI * sqrt((radiusX + radiusY) / 2)); + + double si = std::sin(2 * PI / steps); + double co = std::cos(2 * PI / steps); + double dx = co, dy = si; + Path result; + result.reserve(steps); + result.push_back(Point(center.x + radiusX, static_cast(center.y))); + for (int i = 1; i < steps; ++i) + { + result.push_back(Point(center.x + radiusX * dx, center.y + radiusY * dy)); + double x = dx * co - dy * si; + dy = dy * co + dx * si; + dx = x; + } + return result; + } + + template + inline double PerpendicDistFromLineSqrd(const Point& pt, + const Point& line1, const Point& line2) + { + double a = static_cast(pt.x - line1.x); + double b = static_cast(pt.y - line1.y); + double c = static_cast(line2.x - line1.x); + double d = static_cast(line2.y - line1.y); + if (c == 0 && d == 0) return 0; + return Sqr(a * d - c * b) / (c * c + d * d); + } + + inline size_t GetNext(size_t current, size_t high, + const std::vector& flags) + { + ++current; + while (current <= high && flags[current]) ++current; + if (current <= high) return current; + current = 0; + while (flags[current]) ++current; + return current; + } + + inline size_t GetPrior(size_t current, size_t high, + const std::vector& flags) + { + if (current == 0) current = high; + else --current; + while (current > 0 && flags[current]) --current; + if (!flags[current]) return current; + current = high; + while (flags[current]) --current; + return current; + } + + template + inline Path SimplifyPath(const Path path, + double epsilon, bool isClosedPath = true) + { + const size_t len = path.size(), high = len -1; + const double epsSqr = Sqr(epsilon); + if (len < 4) return Path(path); + + std::vector flags(len); + std::vector distSqr(len); + size_t prior = high, curr = 0, start, next, prior2, next2; + if (isClosedPath) + { + distSqr[0] = PerpendicDistFromLineSqrd(path[0], path[high], path[1]); + distSqr[high] = PerpendicDistFromLineSqrd(path[high], path[0], path[high - 1]); + } + else + { + distSqr[0] = MAX_DBL; + distSqr[high] = MAX_DBL; + } + for (size_t i = 1; i < high; ++i) + distSqr[i] = PerpendicDistFromLineSqrd(path[i], path[i - 1], path[i + 1]); + + for (;;) + { + if (distSqr[curr] > epsSqr) + { + start = curr; + do + { + curr = GetNext(curr, high, flags); + } while (curr != start && distSqr[curr] > epsSqr); + if (curr == start) break; + } + + prior = GetPrior(curr, high, flags); + next = GetNext(curr, high, flags); + if (next == prior) break; + + if (distSqr[next] < distSqr[curr]) + { + flags[next] = true; + next = GetNext(next, high, flags); + next2 = GetNext(next, high, flags); + distSqr[curr] = PerpendicDistFromLineSqrd(path[curr], path[prior], path[next]); + if (next != high || isClosedPath) + distSqr[next] = PerpendicDistFromLineSqrd(path[next], path[curr], path[next2]); + curr = next; + } + else + { + flags[curr] = true; + curr = next; + next = GetNext(next, high, flags); + prior2 = GetPrior(prior, high, flags); + distSqr[curr] = PerpendicDistFromLineSqrd(path[curr], path[prior], path[next]); + if (prior != 0 || isClosedPath) + distSqr[prior] = PerpendicDistFromLineSqrd(path[prior], path[prior2], path[curr]); + } + } + Path result; + result.reserve(len); + for (typename Path::size_type i = 0; i < len; ++i) + if (!flags[i]) result.push_back(path[i]); + return result; + } + + template + inline Paths SimplifyPaths(const Paths paths, + double epsilon, bool isClosedPath = true) + { + Paths result; + result.reserve(paths.size()); + for (const auto& path : paths) + result.push_back(SimplifyPath(path, epsilon, isClosedPath)); + return result; + } + + template + inline void RDP(const Path path, std::size_t begin, + std::size_t end, double epsSqrd, std::vector& flags) + { + typename Path::size_type idx = 0; + double max_d = 0; + while (end > begin && path[begin] == path[end]) flags[end--] = false; + for (typename Path::size_type i = begin + 1; i < end; ++i) + { + // PerpendicDistFromLineSqrd - avoids expensive Sqrt() + double d = PerpendicDistFromLineSqrd(path[i], path[begin], path[end]); + if (d <= max_d) continue; + max_d = d; + idx = i; + } + if (max_d <= epsSqrd) return; + flags[idx] = true; + if (idx > begin + 1) RDP(path, begin, idx, epsSqrd, flags); + if (idx < end - 1) RDP(path, idx, end, epsSqrd, flags); + } + + template + inline Path RamerDouglasPeucker(const Path& path, double epsilon) + { + const typename Path::size_type len = path.size(); + if (len < 5) return Path(path); + std::vector flags(len); + flags[0] = true; + flags[len - 1] = true; + RDP(path, 0, len - 1, Sqr(epsilon), flags); + Path result; + result.reserve(len); + for (typename Path::size_type i = 0; i < len; ++i) + if (flags[i]) + result.push_back(path[i]); + return result; + } + + template + inline Paths RamerDouglasPeucker(const Paths& paths, double epsilon) + { + Paths result; + result.reserve(paths.size()); + std::transform(paths.begin(), paths.end(), back_inserter(result), + [epsilon](const auto& path) + { return RamerDouglasPeucker(path, epsilon); }); + return result; + } + +} // end Clipper2Lib namespace + +#endif // CLIPPER_H diff --git a/src/other/manifold/include/clipper2/clipper.minkowski.h b/src/other/manifold/include/clipper2/clipper.minkowski.h new file mode 100644 index 00000000000..71c221bb50a --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.minkowski.h @@ -0,0 +1,120 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 28 January 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : Minkowski Sum and Difference * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_MINKOWSKI_H +#define CLIPPER_MINKOWSKI_H + +#include +#include +#include +#include "clipper.core.h" + +namespace Clipper2Lib +{ + + namespace detail + { + inline Paths64 Minkowski(const Path64& pattern, const Path64& path, bool isSum, bool isClosed) + { + size_t delta = isClosed ? 0 : 1; + size_t patLen = pattern.size(), pathLen = path.size(); + if (patLen == 0 || pathLen == 0) return Paths64(); + Paths64 tmp; + tmp.reserve(pathLen); + + if (isSum) + { + for (const Point64& p : path) + { + Path64 path2(pattern.size()); + std::transform(pattern.cbegin(), pattern.cend(), + path2.begin(), [p](const Point64& pt2) {return p + pt2; }); + tmp.push_back(path2); + } + } + else + { + for (const Point64& p : path) + { + Path64 path2(pattern.size()); + std::transform(pattern.cbegin(), pattern.cend(), + path2.begin(), [p](const Point64& pt2) {return p - pt2; }); + tmp.push_back(path2); + } + } + + Paths64 result; + result.reserve((pathLen - delta) * patLen); + size_t g = isClosed ? pathLen - 1 : 0; + for (size_t h = patLen - 1, i = delta; i < pathLen; ++i) + { + for (size_t j = 0; j < patLen; j++) + { + Path64 quad; + quad.reserve(4); + { + quad.push_back(tmp[g][h]); + quad.push_back(tmp[i][h]); + quad.push_back(tmp[i][j]); + quad.push_back(tmp[g][j]); + }; + if (!IsPositive(quad)) + std::reverse(quad.begin(), quad.end()); + result.push_back(quad); + h = j; + } + g = i; + } + return result; + } + + inline Paths64 Union(const Paths64& subjects, FillRule fillrule) + { + Paths64 result; + Clipper64 clipper; + clipper.AddSubject(subjects); + clipper.Execute(ClipType::Union, fillrule, result); + return result; + } + + } // namespace internal + + inline Paths64 MinkowskiSum(const Path64& pattern, const Path64& path, bool isClosed) + { + return detail::Union(detail::Minkowski(pattern, path, true, isClosed), FillRule::NonZero); + } + + inline PathsD MinkowskiSum(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) + { + int error_code = 0; + double scale = pow(10, decimalPlaces); + Path64 pat64 = ScalePath(pattern, scale, error_code); + Path64 path64 = ScalePath(path, scale, error_code); + Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, true, isClosed), FillRule::NonZero); + return ScalePaths(tmp, 1 / scale, error_code); + } + + inline Paths64 MinkowskiDiff(const Path64& pattern, const Path64& path, bool isClosed) + { + return detail::Union(detail::Minkowski(pattern, path, false, isClosed), FillRule::NonZero); + } + + inline PathsD MinkowskiDiff(const PathD& pattern, const PathD& path, bool isClosed, int decimalPlaces = 2) + { + int error_code = 0; + double scale = pow(10, decimalPlaces); + Path64 pat64 = ScalePath(pattern, scale, error_code); + Path64 path64 = ScalePath(path, scale, error_code); + Paths64 tmp = detail::Union(detail::Minkowski(pat64, path64, false, isClosed), FillRule::NonZero); + return ScalePaths(tmp, 1 / scale, error_code); + } + +} // Clipper2Lib namespace + +#endif // CLIPPER_MINKOWSKI_H diff --git a/src/other/manifold/include/clipper2/clipper.offset.h b/src/other/manifold/include/clipper2/clipper.offset.h new file mode 100644 index 00000000000..8835fb0f45e --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.offset.h @@ -0,0 +1,118 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 15 May 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : Path Offset (Inflate/Shrink) * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_OFFSET_H_ +#define CLIPPER_OFFSET_H_ + +#include "clipper.core.h" +#include "clipper.engine.h" + +namespace Clipper2Lib { + +enum class JoinType { Square, Round, Miter }; + +enum class EndType {Polygon, Joined, Butt, Square, Round}; +//Butt : offsets both sides of a path, with square blunt ends +//Square : offsets both sides of a path, with square extended ends +//Round : offsets both sides of a path, with round extended ends +//Joined : offsets both sides of a path, with joined ends +//Polygon: offsets only one side of a closed path + +typedef std::function DeltaCallback64; + +class ClipperOffset { +private: + + class Group { + public: + Paths64 paths_in; + Paths64 paths_out; + Path64 path; + bool is_reversed = false; + JoinType join_type; + EndType end_type; + Group(const Paths64& _paths, JoinType _join_type, EndType _end_type) : + paths_in(_paths), join_type(_join_type), end_type(_end_type) {} + }; + + int error_code_ = 0; + double delta_ = 0.0; + double group_delta_ = 0.0; + double temp_lim_ = 0.0; + double steps_per_rad_ = 0.0; + double step_sin_ = 0.0; + double step_cos_ = 0.0; + PathD norms; + Paths64 solution; + std::vector groups_; + JoinType join_type_ = JoinType::Square; + EndType end_type_ = EndType::Polygon; + + double miter_limit_ = 0.0; + double arc_tolerance_ = 0.0; + bool preserve_collinear_ = false; + bool reverse_solution_ = false; + +#ifdef USINGZ + ZCallback64 zCallback64_ = nullptr; +#endif + DeltaCallback64 deltaCallback64_ = nullptr; + + void DoSquare(Group& group, const Path64& path, size_t j, size_t k); + void DoMiter(Group& group, const Path64& path, size_t j, size_t k, double cos_a); + void DoRound(Group& group, const Path64& path, size_t j, size_t k, double angle); + void BuildNormals(const Path64& path); + void OffsetPolygon(Group& group, Path64& path); + void OffsetOpenJoined(Group& group, Path64& path); + void OffsetOpenPath(Group& group, Path64& path); + void OffsetPoint(Group& group, Path64& path, size_t j, size_t k); + void DoGroupOffset(Group &group); + void ExecuteInternal(double delta); +public: + explicit ClipperOffset(double miter_limit = 2.0, + double arc_tolerance = 0.0, + bool preserve_collinear = false, + bool reverse_solution = false) : + miter_limit_(miter_limit), arc_tolerance_(arc_tolerance), + preserve_collinear_(preserve_collinear), + reverse_solution_(reverse_solution) { }; + + ~ClipperOffset() { Clear(); }; + + int ErrorCode() { return error_code_; }; + void AddPath(const Path64& path, JoinType jt_, EndType et_); + void AddPaths(const Paths64& paths, JoinType jt_, EndType et_); + void Clear() { groups_.clear(); norms.clear(); }; + + void Execute(double delta, Paths64& paths); + void Execute(double delta, PolyTree64& polytree); + void Execute(DeltaCallback64 delta_cb, Paths64& paths); + + double MiterLimit() const { return miter_limit_; } + void MiterLimit(double miter_limit) { miter_limit_ = miter_limit; } + + //ArcTolerance: needed for rounded offsets (See offset_triginometry2.svg) + double ArcTolerance() const { return arc_tolerance_; } + void ArcTolerance(double arc_tolerance) { arc_tolerance_ = arc_tolerance; } + + bool PreserveCollinear() const { return preserve_collinear_; } + void PreserveCollinear(bool preserve_collinear){preserve_collinear_ = preserve_collinear;} + + bool ReverseSolution() const { return reverse_solution_; } + void ReverseSolution(bool reverse_solution) {reverse_solution_ = reverse_solution;} + +#ifdef USINGZ + void SetZCallback(ZCallback64 cb) { zCallback64_ = cb; } +#endif + void SetDeltaCallback(DeltaCallback64 cb) { deltaCallback64_ = cb; } + +}; + +} +#endif /* CLIPPER_OFFSET_H_ */ diff --git a/src/other/manifold/include/clipper2/clipper.rectclip.h b/src/other/manifold/include/clipper2/clipper.rectclip.h new file mode 100644 index 00000000000..bcbe7f436c9 --- /dev/null +++ b/src/other/manifold/include/clipper2/clipper.rectclip.h @@ -0,0 +1,82 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 30 May 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* Purpose : FAST rectangular clipping * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +#ifndef CLIPPER_RECTCLIP_H +#define CLIPPER_RECTCLIP_H + +#include +#include +#include +#include "clipper.h" +#include "clipper.core.h" + +namespace Clipper2Lib +{ + + enum class Location { Left, Top, Right, Bottom, Inside }; + + class OutPt2; + typedef std::vector OutPt2List; + + class OutPt2 { + public: + Point64 pt; + size_t owner_idx; + OutPt2List* edge; + OutPt2* next; + OutPt2* prev; + }; + + //------------------------------------------------------------------------------ + // RectClip64 + //------------------------------------------------------------------------------ + + class RectClip64 { + private: + void ExecuteInternal(const Path64& path); + Path64 GetPath(OutPt2*& op); + protected: + const Rect64 rect_; + const Path64 rect_as_path_; + const Point64 rect_mp_; + Rect64 path_bounds_; + std::deque op_container_; + OutPt2List results_; // each path can be broken into multiples + OutPt2List edges_[8]; // clockwise and counter-clockwise + std::vector start_locs_; + void CheckEdges(); + void TidyEdges(int idx, OutPt2List& cw, OutPt2List& ccw); + void GetNextLocation(const Path64& path, + Location& loc, int& i, int highI); + OutPt2* Add(Point64 pt, bool start_new = false); + void AddCorner(Location prev, Location curr); + void AddCorner(Location& loc, bool isClockwise); + public: + explicit RectClip64(const Rect64& rect) : + rect_(rect), + rect_as_path_(rect.AsPath()), + rect_mp_(rect.MidPoint()) {} + Paths64 Execute(const Paths64& paths); + }; + + //------------------------------------------------------------------------------ + // RectClipLines64 + //------------------------------------------------------------------------------ + + class RectClipLines64 : public RectClip64 { + private: + void ExecuteInternal(const Path64& path); + Path64 GetPath(OutPt2*& op); + public: + explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {}; + Paths64 Execute(const Paths64& paths); + }; + +} // Clipper2Lib namespace +#endif // CLIPPER_RECTCLIP_H diff --git a/src/other/manifold/include/collider.h b/src/other/manifold/include/collider.h new file mode 100644 index 00000000000..7d81821fe8b --- /dev/null +++ b/src/other/manifold/include/collider.h @@ -0,0 +1,44 @@ +// Copyright 2021 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include "public.h" +#include "sparse.h" +#include "vec.h" + +namespace manifold { + +/** @ingroup Private */ +class Collider { + public: + Collider() {} + Collider(const VecView& leafBB, + const VecView& leafMorton); + bool Transform(glm::mat4x3); + void UpdateBoxes(const VecView& leafBB); + template + SparseIndices Collisions(const VecView& queriesIn) const; + + private: + Vec nodeBBox_; + Vec nodeParent_; + // even nodes are leaves, odd nodes are internal, root is 1 + Vec> internalChildren_; + + int NumInternal() const { return internalChildren_.size(); }; + int NumLeaves() const { return NumInternal() + 1; }; +}; + +} // namespace manifold diff --git a/src/other/manifold/include/hashtable.h b/src/other/manifold/include/hashtable.h new file mode 100644 index 00000000000..7a1f28ccbd9 --- /dev/null +++ b/src/other/manifold/include/hashtable.h @@ -0,0 +1,155 @@ +// Copyright 2022 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once +#include + +#include + +#include "public.h" +#include "utils.h" +#include "vec.h" + +namespace { +typedef unsigned long long int Uint64; +typedef Uint64 (*hash_fun_t)(Uint64); +inline constexpr Uint64 kOpen = std::numeric_limits::max(); + +template +T AtomicCAS(T& target, T compare, T val) { + std::atomic& tar = reinterpret_cast&>(target); + tar.compare_exchange_strong(compare, val, std::memory_order_acq_rel); + return compare; +} + +template +void AtomicStore(T& target, T val) { + std::atomic& tar = reinterpret_cast&>(target); + // release is good enough, although not really something general + tar.store(val, std::memory_order_release); +} + +template +T AtomicLoad(const T& target) { + const std::atomic& tar = reinterpret_cast&>(target); + // acquire is good enough, although not general + return tar.load(std::memory_order_acquire); +} + +// https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key +inline Uint64 hash64bit(Uint64 x) { + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ull; + x = (x ^ (x >> 27)) * 0x94d049bb133111ebull; + x = x ^ (x >> 31); + return x; +} +} // namespace + +namespace manifold { +/** @addtogroup Private + * @{ + */ + +template +class HashTableD { + public: + HashTableD(Vec& keys, Vec& values, Vec& used, + uint32_t step = 1) + : step_{step}, keys_{keys}, values_{values}, used_{used} {} + + int Size() const { return keys_.size(); } + + bool Full() const { return AtomicLoad(used_[0]) * 2 > Size(); } + + void Insert(Uint64 key, const V& val) { + uint32_t idx = H(key) & (Size() - 1); + while (1) { + if (Full()) return; + Uint64& k = keys_[idx]; + const Uint64 found = AtomicCAS(k, kOpen, key); + if (found == kOpen) { + AtomicAdd(used_[0], 0x1u); + values_[idx] = val; + return; + } + if (found == key) return; + idx = (idx + step_) & (Size() - 1); + } + } + + V& operator[](Uint64 key) { + uint32_t idx = H(key) & (Size() - 1); + while (1) { + const Uint64 k = AtomicLoad(keys_[idx]); + if (k == key || k == kOpen) { + return values_[idx]; + } + idx = (idx + step_) & (Size() - 1); + } + } + + const V& operator[](Uint64 key) const { + uint32_t idx = H(key) & (Size() - 1); + while (1) { + const Uint64 k = AtomicLoad(keys_[idx]); + if (k == key || k == kOpen) { + return values_[idx]; + } + idx = (idx + step_) & (Size() - 1); + } + } + + Uint64 KeyAt(int idx) const { return AtomicLoad(keys_[idx]); } + V& At(int idx) { return values_[idx]; } + const V& At(int idx) const { return values_[idx]; } + + private: + uint32_t step_; + VecView keys_; + VecView values_; + VecView used_; +}; + +template +class HashTable { + public: + HashTable(uint32_t size, uint32_t step = 1) + : keys_{1 << (int)ceil(log2(size)), kOpen}, + values_{1 << (int)ceil(log2(size)), {}}, + table_{keys_, values_, used_, step} {} + + HashTableD D() { return table_; } + + int Entries() const { return AtomicLoad(used_[0]); } + + int Size() const { return table_.Size(); } + + bool Full() const { return AtomicLoad(used_[0]) * 2 > Size(); } + + float FilledFraction() const { + return static_cast(AtomicLoad(used_[0])) / Size(); + } + + Vec& GetValueStore() { return values_; } + + static Uint64 Open() { return kOpen; } + + private: + Vec keys_; + Vec values_; + Vec used_ = Vec(1, 0); + HashTableD table_; +}; + +/** @} */ +} // namespace manifold diff --git a/src/other/manifold/include/manifold/cross_section.h b/src/other/manifold/include/manifold/cross_section.h new file mode 100644 index 00000000000..abe32bce534 --- /dev/null +++ b/src/other/manifold/include/manifold/cross_section.h @@ -0,0 +1,173 @@ +// Copyright 2023 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +#include "glm/ext/matrix_float3x2.hpp" +#include "glm/ext/vector_float2.hpp" +#include "public.h" + +namespace manifold { + +/** @addtogroup Core + * @{ + */ + +struct PathImpl; + +/** + * Two-dimensional cross sections guaranteed to be without self-intersections, + * or overlaps between polygons (from construction onwards). This class makes + * use of the [Clipper2](http://www.angusj.com/clipper2/Docs/Overview.htm) + * library for polygon clipping (boolean) and offsetting operations. + */ +class CrossSection { + public: + /** @name Creation + * Constructors + */ + ///@{ + + CrossSection(); + ~CrossSection(); + + CrossSection(const CrossSection& other); + CrossSection& operator=(const CrossSection& other); + CrossSection(CrossSection&&) noexcept; + CrossSection& operator=(CrossSection&&) noexcept; + + // Adapted from Clipper2 docs: + // http://www.angusj.com/clipper2/Docs/Units/Clipper/Types/FillRule.htm + // (Copyright © 2010-2023 Angus Johnson) + /** + * Filling rules defining which polygon sub-regions are considered to be + * inside a given polygon, and which sub-regions will not (based on winding + * numbers). See the [Clipper2 + * docs](http://www.angusj.com/clipper2/Docs/Units/Clipper/Types/FillRule.htm) + * for a detailed explaination with illusrations. + */ + enum class FillRule { + EvenOdd, ///< Only odd numbered sub-regions are filled. + NonZero, ///< Only non-zero sub-regions are filled. + Positive, ///< Only sub-regions with winding counts > 0 are filled. + Negative ///< Only sub-regions with winding counts < 0 are filled. + }; + + CrossSection(const SimplePolygon& contour, + FillRule fillrule = FillRule::Positive); + CrossSection(const Polygons& contours, + FillRule fillrule = FillRule::Positive); + CrossSection(const Rect& rect); + static CrossSection Square(const glm::vec2 dims, bool center = false); + static CrossSection Circle(float radius, int circularSegments = 0); + ///@} + + /** @name Information + * Details of the cross-section + */ + ///@{ + double Area() const; + int NumVert() const; + int NumContour() const; + bool IsEmpty() const; + Rect Bounds() const; + ///@} + + /** @name Modification + */ + ///@{ + CrossSection Translate(const glm::vec2 v) const; + CrossSection Rotate(float degrees) const; + CrossSection Scale(const glm::vec2 s) const; + CrossSection Mirror(const glm::vec2 ax) const; + CrossSection Transform(const glm::mat3x2& m) const; + CrossSection Warp(std::function warpFunc) const; + CrossSection Simplify(double epsilon = 1e-6) const; + + // Adapted from Clipper2 docs: + // http://www.angusj.com/clipper2/Docs/Units/Clipper/Types/JoinType.htm + // (Copyright © 2010-2023 Angus Johnson) + /** + * Specifies the treatment of path/contour joins (corners) when offseting + * CrossSections. See the [Clipper2 + * doc](http://www.angusj.com/clipper2/Docs/Units/Clipper/Types/JoinType.htm) + * for illustrations. + */ + enum class JoinType { + Square, /*!< Squaring is applied uniformly at all joins where the internal + join angle is less that 90 degrees. The squared edge will be at + exactly the offset distance from the join vertex. */ + Round, /*!< Rounding is applied to all joins that have convex external + angles, and it maintains the exact offset distance from the join + vertex. */ + Miter /*!< There's a necessary limit to mitered joins (to avoid narrow + angled joins producing excessively long and narrow + [spikes](http://www.angusj.com/clipper2/Docs/Units/Clipper.Offset/Classes/ClipperOffset/Properties/MiterLimit.htm)). + So where mitered joins would exceed a given maximum miter distance + (relative to the offset distance), these are 'squared' instead. */ + }; + + CrossSection Offset(double delta, JoinType jt, double miter_limit = 2.0, + int circularSegments = 0) const; + ///@} + + /** @name Boolean + * Combine two manifolds + */ + ///@{ + CrossSection Boolean(const CrossSection& second, OpType op) const; + static CrossSection BatchBoolean( + const std::vector& crossSections, OpType op); + CrossSection operator+(const CrossSection&) const; + CrossSection& operator+=(const CrossSection&); + CrossSection operator-(const CrossSection&) const; + CrossSection& operator-=(const CrossSection&); + CrossSection operator^(const CrossSection&) const; + CrossSection& operator^=(const CrossSection&); + ///@} + + /** @name Topological + */ + ///@{ + static CrossSection Compose(std::vector&); + std::vector Decompose() const; + ///@} + + /** @name Convex Hulling + */ + ///@{ + CrossSection Hull() const; + static CrossSection Hull(const std::vector& crossSections); + static CrossSection Hull(const SimplePolygon poly); + static CrossSection Hull(const Polygons polys); + ///@} + /// + /** @name Conversion + */ + ///@{ + Polygons ToPolygons() const; + ///@} + + private: + mutable std::shared_ptr paths_; + mutable glm::mat3x2 transform_ = glm::mat3x2(1.0f); + CrossSection(std::shared_ptr paths); + std::shared_ptr GetPaths() const; +}; +/** @} */ +} // namespace manifold diff --git a/src/other/manifold/include/manifold/manifold.h b/src/other/manifold/include/manifold/manifold.h new file mode 100644 index 00000000000..e5dbdd8570b --- /dev/null +++ b/src/other/manifold/include/manifold/manifold.h @@ -0,0 +1,261 @@ +// Copyright 2021 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include +#include + +#include "cross_section.h" +#include "public.h" + +namespace manifold { + +/** + * @ingroup Debug + * + * Allows modification of the assertions checked in MANIFOLD_DEBUG mode. + * + * @return ExecutionParams& + */ +ExecutionParams& ManifoldParams(); + +class CsgNode; +class CsgLeafNode; + +/** @ingroup Connections + * @{ + */ + +/** + * An alternative to Mesh for output suitable for pushing into graphics + * libraries directly. This may not be manifold since the verts are duplicated + * along property boundaries that do not match. The additional merge vectors + * store this missing information, allowing the manifold to be reconstructed. + */ +struct MeshGL { + /// Number of property vertices + uint32_t NumVert() const { return vertProperties.size() / numProp; }; + /// Number of triangles + uint32_t NumTri() const { return triVerts.size() / 3; }; + + /// Number of properties per vertex, always >= 3. + uint32_t numProp = 3; + /// Flat, GL-style interleaved list of all vertex properties: propVal = + /// vertProperties[vert * numProp + propIdx]. The first three properties are + /// always the position x, y, z. + std::vector vertProperties; + /// The vertex indices of the three triangle corners in CCW (from the outside) + /// order, for each triangle. + std::vector triVerts; + /// Optional: A list of only the vertex indicies that need to be merged to + /// reconstruct the manifold. + std::vector mergeFromVert; + /// Optional: The same length as mergeFromVert, and the corresponding value + /// contains the vertex to merge with. It will have an identical position, but + /// the other properties may differ. + std::vector mergeToVert; + /// Optional: Indicates runs of triangles that correspond to a particular + /// input mesh instance. The runs encompass all of triVerts and are sorted + /// by runOriginalID. Run i begins at triVerts[runIndex[i]] and ends at + /// triVerts[runIndex[i+1]]. All runIndex values are divisible by 3. + std::vector runIndex; + /// Optional: The OriginalID of the mesh this triangle run came from. This ID + /// is ideal for reapplying materials to the output mesh. Multiple runs may + /// have the same ID, e.g. representing different copies of the same input + /// mesh. If you create an input MeshGL that you want to be able to reference + /// as one or more originals, be sure to set unique values from ReserveIDs(). + std::vector runOriginalID; + /// Optional: For each run, a 3x4 transform is stored representing how the + /// corresponding original mesh was transformed to create this triangle run. + /// This matrix is stored in column-major order and the length of the overall + /// vector is 12 * runOriginalID.size(). + std::vector runTransform; + /// Optional: Length NumTri, contains an ID of the source face this triangle + /// comes from. When auto-generated, this ID will be a triangle index into the + /// original mesh. All neighboring coplanar triangles from that input mesh + /// will refer to a single triangle of that group as the faceID. When + /// supplying faceIDs, ensure that triangles with the same ID are in fact + /// coplanar and have consistent properties (within some tolerance) or the + /// output will be surprising. + std::vector faceID; + /// Optional: The X-Y-Z-W weighted tangent vectors for smooth Refine(). If + /// non-empty, must be exactly four times as long as Mesh.triVerts. Indexed + /// as 4 * (3 * tri + i) + j, i < 3, j < 4, representing the tangent value + /// Mesh.triVerts[tri][i] along the CCW edge. If empty, mesh is faceted. + std::vector halfedgeTangent; + /// The absolute precision of the vertex positions, based on accrued rounding + /// errors. When creating a Manifold, the precision used will be the maximum + /// of this and a baseline precision from the size of the bounding box. Any + /// edge shorter than precision may be collapsed. + float precision = 0; + + MeshGL() = default; + MeshGL(const Mesh& mesh); + + bool Merge(); +}; +/** @} */ + +/** @defgroup Core + * @brief The central classes of the library + * @{ + */ +class Manifold { + public: + /** @name Creation + * Constructors + */ + ///@{ + MANIFOLD_EXPORT Manifold(); + MANIFOLD_EXPORT ~Manifold(); + MANIFOLD_EXPORT Manifold(const Manifold& other); + MANIFOLD_EXPORT Manifold& operator=(const Manifold& other); + MANIFOLD_EXPORT Manifold(Manifold&&) noexcept; + MANIFOLD_EXPORT Manifold& operator=(Manifold&&) noexcept; + + Manifold(const MeshGL&, const std::vector& propertyTolerance = {}); + MANIFOLD_EXPORT Manifold(const Mesh&); + + static Manifold Smooth(const MeshGL&, + const std::vector& sharpenedEdges = {}); + static Manifold Smooth(const Mesh&, + const std::vector& sharpenedEdges = {}); + static Manifold Tetrahedron(); + static Manifold Cube(glm::vec3 size = glm::vec3(1.0f), bool center = false); + static Manifold Cylinder(float height, float radiusLow, + float radiusHigh = -1.0f, int circularSegments = 0, + bool center = false); + static Manifold Sphere(float radius, int circularSegments = 0); + static Manifold Extrude(const CrossSection& crossSection, float height, + int nDivisions = 0, float twistDegrees = 0.0f, + glm::vec2 scaleTop = glm::vec2(1.0f)); + static Manifold Revolve(const CrossSection& crossSection, + int circularSegments = 0, + float revolveDegrees = 360.0f); + ///@} + + /** @name Topological + * No geometric calculations. + */ + ///@{ + static Manifold Compose(const std::vector&); + std::vector Decompose() const; + ///@} + + /** @name Information + * Details of the manifold + */ + ///@{ + MANIFOLD_EXPORT Mesh GetMesh() const; + MeshGL GetMeshGL(glm::ivec3 normalIdx = glm::ivec3(0)) const; + bool IsEmpty() const; + enum class Error { + NoError, + NonFiniteVertex, + NotManifold, + VertexOutOfBounds, + PropertiesWrongLength, + MissingPositionProperties, + MergeVectorsDifferentLengths, + MergeIndexOutOfBounds, + TransformWrongLength, + RunIndexWrongLength, + FaceIDWrongLength, + InvalidConstruction, + }; + MANIFOLD_EXPORT Error Status() const; + int NumVert() const; + int NumEdge() const; + int NumTri() const; + int NumProp() const; + int NumPropVert() const; + Box BoundingBox() const; + float Precision() const; + int Genus() const; + Properties GetProperties() const; + ///@} + + /** @name Mesh ID + * Details of the manifold's relation to its input meshes, for the purposes + * of reapplying mesh properties. + */ + ///@{ + int OriginalID() const; + Manifold AsOriginal() const; + static uint32_t ReserveIDs(uint32_t); + ///@} + + /** @name Modification + */ + ///@{ + Manifold Translate(glm::vec3) const; + Manifold Scale(glm::vec3) const; + Manifold Rotate(float xDegrees, float yDegrees = 0.0f, + float zDegrees = 0.0f) const; + Manifold Transform(const glm::mat4x3&) const; + Manifold Mirror(glm::vec3) const; + Manifold Warp(std::function) const; + Manifold SetProperties( + int, std::function) const; + Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const; + Manifold Refine(int) const; + // Manifold RefineToLength(float); + // Manifold RefineToPrecision(float); + ///@} + + /** @name Boolean + * Combine two manifolds + */ + ///@{ + MANIFOLD_EXPORT Manifold Boolean(const Manifold& second, OpType op) const; + static Manifold BatchBoolean(const std::vector& manifolds, + OpType op); + // Boolean operation shorthand + Manifold operator+(const Manifold&) const; // Add (Union) + Manifold& operator+=(const Manifold&); + Manifold operator-(const Manifold&) const; // Subtract (Difference) + Manifold& operator-=(const Manifold&); + Manifold operator^(const Manifold&) const; // Intersect + Manifold& operator^=(const Manifold&); + std::pair Split(const Manifold&) const; + std::pair SplitByPlane(glm::vec3 normal, + float originOffset) const; + Manifold TrimByPlane(glm::vec3 normal, float originOffset) const; + ///@} + + Manifold Hull() const; + static Manifold Hull(const std::vector& manifolds); + static Manifold Hull(const std::vector& pts); + + /** @name Testing hooks + * These are just for internal testing. + */ + ///@{ + bool MatchesTriNormals() const; + int NumDegenerateTris() const; + int NumOverlaps(const Manifold& second) const; + ///@} + + struct Impl; + + private: + Manifold(std::shared_ptr pNode_); + Manifold(std::shared_ptr pImpl_); + static Manifold Invalid(); + mutable std::shared_ptr pNode_; + + CsgLeafNode& GetCsgLeafNode() const; +}; +/** @} */ +} // namespace manifold diff --git a/src/other/manifold/include/manifold/public.h b/src/other/manifold/include/manifold/public.h new file mode 100644 index 00000000000..901a7e4ae9c --- /dev/null +++ b/src/other/manifold/include/manifold/public.h @@ -0,0 +1,704 @@ +// Copyright 2021 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#define GLM_FORCE_EXPLICIT_CTOR +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MANIFOLD_DEBUG +#include +#include +#include +#endif + +#if defined(_WIN32) +# define COMPILER_DLLEXPORT __declspec(dllexport) +# define COMPILER_DLLIMPORT __declspec(dllimport) +#else +# define COMPILER_DLLEXPORT __attribute__ ((visibility ("default"))) +# define COMPILER_DLLIMPORT __attribute__ ((visibility ("default"))) +#endif + +#ifndef MANIFOLD_EXPORT +# if defined(MANIFOLD_DLL_EXPORTS) && defined(MANIFOLD_DLL_IMPORTS) +# error "Only MANIFOLD_DLL_EXPORTS or MANIFOLD_DLL_IMPORTS can be defined, not both." +# elif defined(MANIFOLD_DLL_EXPORTS) +# define MANIFOLD_EXPORT COMPILER_DLLEXPORT +# elif defined(MANIFOLD_DLL_IMPORTS) +# define MANIFOLD_EXPORT COMPILER_DLLIMPORT +# else +# define MANIFOLD_EXPORT +# endif +#endif + +namespace manifold { + +constexpr float kTolerance = 1e-5; + +/** @defgroup Connections + * @brief Move data in and out of the Manifold class. + * @{ + */ + +/** + * Sine function where multiples of 90 degrees come out exact. + * + * @param x Angle in degrees. + */ +inline float sind(float x) { + if (!std::isfinite(x)) return sin(x); + if (x < 0.0f) return -sind(-x); + int quo; + x = remquo(fabs(x), 90.0f, &quo); + switch (quo % 4) { + case 0: + return sin(glm::radians(x)); + case 1: + return cos(glm::radians(x)); + case 2: + return -sin(glm::radians(x)); + case 3: + return -cos(glm::radians(x)); + } + return 0.0f; +} + +/** + * Cosine function where multiples of 90 degrees come out exact. + * + * @param x Angle in degrees. + */ +inline float cosd(float x) { return sind(x + 90.0f); } + +/** + * This 4x3 matrix can be used as an input to Manifold.Transform() to turn an + * object. Turns along the shortest path from given up-vector to (0, 0, 1). + * + * @param up The vector to be turned to point upwards. Length does not matter. + */ +inline glm::mat4x3 RotateUp(glm::vec3 up) { + up = glm::normalize(up); + glm::vec3 axis = glm::cross(up, {0, 0, 1}); + float angle = glm::asin(glm::length(axis)); + if (glm::dot(up, {0, 0, 1}) < 0) angle = glm::pi() - angle; + return glm::mat4x3(glm::rotate(glm::mat4(1), angle, axis)); +} + +/** + * Determines if the three points are wound counter-clockwise, clockwise, or + * colinear within the specified tolerance. + * + * @param p0 First point + * @param p1 Second point + * @param p2 Third point + * @param tol Tolerance value for colinearity + * @return int, like Signum, this returns 1 for CCW, -1 for CW, and 0 if within + * tol of colinear. + */ +inline int CCW(glm::vec2 p0, glm::vec2 p1, glm::vec2 p2, float tol) { + glm::vec2 v1 = p1 - p0; + glm::vec2 v2 = p2 - p0; + float area = v1.x * v2.y - v1.y * v2.x; + float base2 = glm::max(glm::dot(v1, v1), glm::dot(v2, v2)); + if (area * area * 4 <= base2 * tol * tol) + return 0; + else + return area > 0 ? 1 : -1; +} + +/** + * Single polygon contour, wound CCW. First and last point are implicitly + * connected. Should ensure all input is + * [ε-valid](https://github.com/elalish/manifold/wiki/Manifold-Library#definition-of-%CE%B5-valid). + */ +using SimplePolygon = std::vector; + +/** + * Set of polygons with holes. Order of contours is arbitrary. Can contain any + * depth of nested holes and any number of separate polygons. Should ensure all + * input is + * [ε-valid](https://github.com/elalish/manifold/wiki/Manifold-Library#definition-of-%CE%B5-valid). + */ +using Polygons = std::vector; + +/** + * The triangle-mesh input and output of this library. + */ +struct Mesh { + /// Required: The X-Y-Z positions of all vertices. + std::vector vertPos; + /// Required: The vertex indices of the three triangle corners in CCW (from + /// the outside) order, for each triangle. + std::vector triVerts; + /// Optional: The X-Y-Z normal vectors of each vertex. If non-empty, must have + /// the same length as vertPos. If empty, these will be calculated + /// automatically. + std::vector vertNormal; + /// Optional: The X-Y-Z-W weighted tangent vectors for smooth Refine(). If + /// non-empty, must be exactly three times as long as Mesh.triVerts. Indexed + /// as 3 * tri + i, representing the tangent from Mesh.triVerts[tri][i] along + /// the CCW edge. If empty, mesh is faceted. + std::vector halfedgeTangent; + /// The absolute precision of the vertex positions, based on accrued rounding + /// errors. When creating a Manifold, the precision used will be the maximum + /// of this and a baseline precision from the size of the bounding box. Any + /// edge shorter than precision may be collapsed. + float precision = 0; +}; + +/** + * Defines which edges to sharpen and how much for the Manifold.Smooth() + * constructor. + */ +struct Smoothness { + /// The halfedge index = 3 * tri + i, referring to Mesh.triVerts[tri][i]. + int halfedge; + /// A value between 0 and 1, where 0 is sharp and 1 is the default and the + /// curvature is interpolated between these values. The two paired halfedges + /// can have different values while maintaining C-1 continuity (except for 0). + float smoothness; +}; + +/** + * Geometric properties of the manifold, created with Manifold.GetProperties(). + */ +struct Properties { + float surfaceArea, volume; +}; + +struct Box { + glm::vec3 min = glm::vec3(std::numeric_limits::infinity()); + glm::vec3 max = glm::vec3(-std::numeric_limits::infinity()); + + /** + * Default constructor is an infinite box that contains all space. + */ + Box() {} + + /** + * Creates a box that contains the two given points. + */ + Box(const glm::vec3 p1, const glm::vec3 p2) { + min = glm::min(p1, p2); + max = glm::max(p1, p2); + } + + /** + * Returns the dimensions of the Box. + */ + glm::vec3 Size() const { return max - min; } + + /** + * Returns the center point of the Box. + */ + glm::vec3 Center() const { return 0.5f * (max + min); } + + /** + * Returns the absolute-largest coordinate value of any contained + * point. + */ + float Scale() const { + glm::vec3 absMax = glm::max(glm::abs(min), glm::abs(max)); + return glm::max(absMax.x, glm::max(absMax.y, absMax.z)); + } + + /** + * Does this box contain (includes equal) the given point? + */ + bool Contains(const glm::vec3& p) const { + return glm::all(glm::greaterThanEqual(p, min)) && + glm::all(glm::greaterThanEqual(max, p)); + } + + /** + * Does this box contain (includes equal) the given box? + */ + bool Contains(const Box& box) const { + return glm::all(glm::greaterThanEqual(box.min, min)) && + glm::all(glm::greaterThanEqual(max, box.max)); + } + + /** + * Expand this box to include the given point. + */ + void Union(const glm::vec3 p) { + min = glm::min(min, p); + max = glm::max(max, p); + } + + /** + * Expand this box to include the given box. + */ + Box Union(const Box& box) const { + Box out; + out.min = glm::min(min, box.min); + out.max = glm::max(max, box.max); + return out; + } + + /** + * Transform the given box by the given axis-aligned affine transform. + * + * Ensure the transform passed in is axis-aligned (rotations are all + * multiples of 90 degrees), or else the resulting bounding box will no longer + * bound properly. + */ + Box Transform(const glm::mat4x3& transform) const { + Box out; + glm::vec3 minT = transform * glm::vec4(min, 1.0f); + glm::vec3 maxT = transform * glm::vec4(max, 1.0f); + out.min = glm::min(minT, maxT); + out.max = glm::max(minT, maxT); + return out; + } + + /** + * Shift this box by the given vector. + */ + Box operator+(glm::vec3 shift) const { + Box out; + out.min = min + shift; + out.max = max + shift; + return out; + } + + /** + * Shift this box in-place by the given vector. + */ + Box& operator+=(glm::vec3 shift) { + min += shift; + max += shift; + return *this; + } + + /** + * Scale this box by the given vector. + */ + Box operator*(glm::vec3 scale) const { + Box out; + out.min = min * scale; + out.max = max * scale; + return out; + } + + /** + * Scale this box in-place by the given vector. + */ + Box& operator*=(glm::vec3 scale) { + min *= scale; + max *= scale; + return *this; + } + + /** + * Does this box overlap the one given (including equality)? + */ + inline bool DoesOverlap(const Box& box) const { + return min.x <= box.max.x && min.y <= box.max.y && min.z <= box.max.z && + max.x >= box.min.x && max.y >= box.min.y && max.z >= box.min.z; + } + + /** + * Does the given point project within the XY extent of this box + * (including equality)? + */ + inline bool DoesOverlap(glm::vec3 p) const { // projected in z + return p.x <= max.x && p.x >= min.x && p.y <= max.y && p.y >= min.y; + } + + /** + * Does this box have finite bounds? + */ + bool IsFinite() const { + return glm::all(glm::isfinite(min)) && glm::all(glm::isfinite(max)); + } +}; + +/** + * Axis-aligned rectangular bounds. + */ +struct Rect { + glm::vec2 min = glm::vec2(std::numeric_limits::infinity()); + glm::vec2 max = glm::vec2(-std::numeric_limits::infinity()); + + /** + * Default constructor is an empty rectangle.. + */ + Rect() {} + + /** + * Create a rectangle that contains the two given points. + */ + Rect(const glm::vec2 a, const glm::vec2 b) { + min = glm::min(a, b); + max = glm::max(a, b); + } + + /** @name Information + * Details of the rectangle + */ + ///@{ + + /** + * Return the dimensions of the rectangle. + */ + glm::vec2 Size() const { return max - min; } + + /** + * Return the area of the rectangle. + */ + float Area() const { + auto sz = Size(); + return sz.x * sz.y; + } + + /** + * Returns the absolute-largest coordinate value of any contained + * point. + */ + float Scale() const { + glm::vec2 absMax = glm::max(glm::abs(min), glm::abs(max)); + return glm::max(absMax.x, absMax.y); + } + + /** + * Returns the center point of the rectangle. + */ + glm::vec2 Center() const { return 0.5f * (max + min); } + + /** + * Does this rectangle contain (includes on border) the given point? + */ + bool Contains(const glm::vec2& p) const { + return glm::all(glm::greaterThanEqual(p, min)) && + glm::all(glm::greaterThanEqual(max, p)); + } + + /** + * Does this rectangle contain (includes equal) the given rectangle? + */ + bool Contains(const Rect& rect) const { + return glm::all(glm::greaterThanEqual(rect.min, min)) && + glm::all(glm::greaterThanEqual(max, rect.max)); + } + + /** + * Does this rectangle overlap the one given (including equality)? + */ + bool DoesOverlap(const Rect& rect) const { + return min.x <= rect.max.x && min.y <= rect.max.y && max.x >= rect.min.x && + max.y >= rect.min.y; + } + + /** + * Is the rectangle empty (containing no space)? + */ + bool IsEmpty() const { return max.y <= min.y || max.x <= min.x; }; + + /** + * Does this recangle have finite bounds? + */ + bool IsFinite() const { + return glm::all(glm::isfinite(min)) && glm::all(glm::isfinite(max)); + } + + ///@} + + /** @name Modification + */ + ///@{ + + /** + * Expand this rectangle (in place) to include the given point. + */ + void Union(const glm::vec2 p) { + min = glm::min(min, p); + max = glm::max(max, p); + } + + /** + * Expand this rectangle to include the given Rect. + */ + Rect Union(const Rect& rect) const { + Rect out; + out.min = glm::min(min, rect.min); + out.max = glm::max(max, rect.max); + return out; + } + + /** + * Shift this rectangle by the given vector. + */ + Rect operator+(const glm::vec2 shift) const { + Rect out; + out.min = min + shift; + out.max = max + shift; + return out; + } + + /** + * Shift this rectangle in-place by the given vector. + */ + Rect& operator+=(const glm::vec2 shift) { + min += shift; + max += shift; + return *this; + } + + /** + * Scale this rectangle by the given vector. + */ + Rect operator*(const glm::vec2 scale) const { + Rect out; + out.min = min * scale; + out.max = max * scale; + return out; + } + + /** + * Scale this rectangle in-place by the given vector. + */ + Rect& operator*=(const glm::vec2 scale) { + min *= scale; + max *= scale; + return *this; + } + + /** + * Transform the rectangle by the given axis-aligned affine transform. + * + * Ensure the transform passed in is axis-aligned (rotations are all + * multiples of 90 degrees), or else the resulting rectangle will no longer + * bound properly. + */ + Rect Transform(const glm::mat3x2& m) const { + Rect rect; + rect.min = m * glm::vec3(min, 1); + rect.max = m * glm::vec3(max, 1); + return rect; + } + ///@} +}; +/** @} */ + +/** @addtogroup Core + * @{ + */ + +/** + * Boolean operation type: Add (Union), Subtract (Difference), and Intersect. + */ +enum class OpType { Add, Subtract, Intersect }; + +/** + * These static properties control how circular shapes are quantized by + * default on construction. If circularSegments is specified, it takes + * precedence. If it is zero, then instead the minimum is used of the segments + * calculated based on edge length and angle, rounded up to the nearest + * multiple of four. To get numbers not divisible by four, circularSegments + * must be specified. + */ +class Quality { + private: + inline static int circularSegments_ = 0; + inline static float circularAngle_ = 10.0f; + inline static float circularEdgeLength_ = 1.0f; + + public: + /** + * Sets an angle constraint the default number of circular segments for the + * CrossSection::Circle(), Manifold::Cylinder(), Manifold::Sphere(), and + * Manifold::Revolve() constructors. The number of segments will be rounded up + * to the nearest factor of four. + * + * @param angle The minimum angle in degrees between consecutive segments. The + * angle will increase if the the segments hit the minimum edge length. + * Default is 10 degrees. + */ + static void SetMinCircularAngle(float angle) { + if (angle <= 0) return; + circularAngle_ = angle; + } + + /** + * Sets a length constraint the default number of circular segments for the + * CrossSection::Circle(), Manifold::Cylinder(), Manifold::Sphere(), and + * Manifold::Revolve() constructors. The number of segments will be rounded up + * to the nearest factor of four. + * + * @param length The minimum length of segments. The length will + * increase if the the segments hit the minimum angle. Default is 1.0. + */ + static void SetMinCircularEdgeLength(float length) { + if (length <= 0) return; + circularEdgeLength_ = length; + } + + /** + * Sets the default number of circular segments for the + * CrossSection::Circle(), Manifold::Cylinder(), Manifold::Sphere(), and + * Manifold::Revolve() constructors. Overrides the edge length and angle + * constraints and sets the number of segments to exactly this value. + * + * @param number Number of circular segments. Default is 0, meaning no + * constraint is applied. + */ + static void SetCircularSegments(int number) { + if (number < 3 && number != 0) return; + circularSegments_ = number; + } + + /** + * Determine the result of the SetMinCircularAngle(), + * SetMinCircularEdgeLength(), and SetCircularSegments() defaults. + * + * @param radius For a given radius of circle, determine how many default + * segments there will be. + */ + static int GetCircularSegments(float radius) { + if (circularSegments_ > 0) return circularSegments_; + int nSegA = 360.0f / circularAngle_; + int nSegL = 2.0f * radius * glm::pi() / circularEdgeLength_; + int nSeg = fmin(nSegA, nSegL) + 3; + nSeg -= nSeg % 4; + return std::max(nSeg, 3); + } +}; +/** @} */ + +/** @defgroup Debug + * @brief Debugging features + * + * The features require compiler flags to be enabled. Assertions are enabled + * with the MANIFOLD_DEBUG flag and then controlled with ExecutionParams. + * Exceptions are only thrown if the MANIFOLD_EXCEPTIONS flag is set. Import and + * Export of 3D models is only supported with the MANIFOLD_EXPORT flag, which + * also requires linking in the Assimp dependency. + * @{ + */ + +/** @defgroup Exceptions + * @brief Custom Exceptions + * @{ + */ +#ifdef MANIFOLD_DEBUG +struct userErr : public virtual std::runtime_error { + using std::runtime_error::runtime_error; +}; +struct topologyErr : public virtual std::runtime_error { + using std::runtime_error::runtime_error; +}; +struct geometryErr : public virtual std::runtime_error { + using std::runtime_error::runtime_error; +}; +using logicErr = std::logic_error; +#endif +/** @} */ + +/** + * Global parameters that control debugging output. Only has an + * effect when compiled with the MANIFOLD_DEBUG flag. + */ +struct ExecutionParams { + /// Perform extra sanity checks and assertions on the intermediate data + /// structures. + bool intermediateChecks = false; + /// Verbose output primarily of the Boolean, including timing info and vector + /// sizes. + bool verbose = false; + /// If processOverlaps is false, a geometric check will be performed to assert + /// all triangles are CCW. + bool processOverlaps = true; + /// Suppresses printed errors regarding CW triangles. Has no effect if + /// processOverlaps is true. + bool suppressErrors = false; + /// Deterministic outputs. Will disable some parallel optimizations. + bool deterministic = false; +}; + +#ifdef MANIFOLD_DEBUG + +template +inline std::ostream& operator<<(std::ostream& stream, const glm::tvec2& v) { + return stream << "x = " << v.x << ", y = " << v.y; +} + +template +inline std::ostream& operator<<(std::ostream& stream, const glm::tvec3& v) { + return stream << "x = " << v.x << ", y = " << v.y << ", z = " << v.z; +} + +template +inline std::ostream& operator<<(std::ostream& stream, const glm::tvec4& v) { + return stream << "x = " << v.x << ", y = " << v.y << ", z = " << v.z + << ", w = " << v.w; +} + +inline std::ostream& operator<<(std::ostream& stream, const glm::mat4x3& mat) { + glm::mat3x4 tam = glm::transpose(mat); + return stream << tam[0] << std::endl + << tam[1] << std::endl + << tam[2] << std::endl; +} + +inline std::ostream& operator<<(std::ostream& stream, const Box& box) { + return stream << "min: " << box.min << ", " + << "max: " << box.max; +} + +inline std::ostream& operator<<(std::ostream& stream, const Rect& box) { + return stream << "min: " << box.min << ", " + << "max: " << box.max; +} + +/** + * Print the contents of this vector to standard output. Only exists if compiled + * with MANIFOLD_DEBUG flag. + */ +template +void Dump(const std::vector& vec) { + std::cout << "Vec = " << std::endl; + for (int i = 0; i < vec.size(); ++i) { + std::cout << i << ", " << vec[i] << ", " << std::endl; + } + std::cout << std::endl; +} + +template +void Diff(const std::vector& a, const std::vector& b) { + std::cout << "Diff = " << std::endl; + if (a.size() != b.size()) { + std::cout << "a and b must have the same length, aborting Diff" + << std::endl; + return; + } + for (int i = 0; i < a.size(); ++i) { + if (a[i] != b[i]) + std::cout << i << ": " << a[i] << ", " << b[i] << std::endl; + } + std::cout << std::endl; +} +/** @} */ +#endif +} // namespace manifold + +#undef HOST_DEVICE diff --git a/src/other/manifold/include/manifold/sdf.h b/src/other/manifold/include/manifold/sdf.h new file mode 100644 index 00000000000..d65afe803da --- /dev/null +++ b/src/other/manifold/include/manifold/sdf.h @@ -0,0 +1,24 @@ +// Copyright 2023 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#include "public.h" + +namespace manifold { +Mesh LevelSet(std::function sdf, Box bounds, float edgeLength, + float level = 0, bool canParallel = true); +} diff --git a/src/other/manifold/include/optional_assert.h b/src/other/manifold/include/optional_assert.h new file mode 100644 index 00000000000..75f32684a12 --- /dev/null +++ b/src/other/manifold/include/optional_assert.h @@ -0,0 +1,38 @@ +// Copyright 2022 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "public.h" + +#ifdef MANIFOLD_DEBUG +#include +#include +#include + +template +void Assert(bool condition, const char* file, int line, const std::string& cond, + const std::string& msg) { + if (!condition) { + std::ostringstream output; + output << "Error in file: " << file << " (" << line << "): \'" << cond + << "\' is false: " << msg; + throw Ex(output.str()); + } +} +#define ASSERT(condition, EX, msg) \ + Assert(condition, __FILE__, __LINE__, #condition, msg); +#else +#define ASSERT(condition, EX, msg) +#endif \ No newline at end of file diff --git a/src/other/manifold/include/par.h b/src/other/manifold/include/par.h new file mode 100644 index 00000000000..6340ce058e4 --- /dev/null +++ b/src/other/manifold/include/par.h @@ -0,0 +1,195 @@ +// Copyright 2022 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if MANIFOLD_PAR == 'T' +#include + +#if MANIFOLD_PAR == 'T' && TBB_INTERFACE_VERSION >= 10000 && \ + __has_include() +#include +#endif + +#include "tbb/tbb.h" +#define MANIFOLD_PAR_NS tbb +#else +#define MANIFOLD_PAR_NS cpp +#endif + +namespace manifold { + +enum class ExecutionPolicy { + Par, + Seq, +}; + +// ExecutionPolicy: +// - Sequential for small workload, +// - Parallel (CPU) for medium workload, +// - GPU for large workload if available. +inline constexpr ExecutionPolicy autoPolicy(int size) { + // some random numbers + if (size <= (1 << 12)) { + return ExecutionPolicy::Seq; + } + return ExecutionPolicy::Par; +} + +#define THRUST_DYNAMIC_BACKEND_VOID(NAME) \ + template \ + void NAME(ExecutionPolicy policy, Args... args) { \ + switch (policy) { \ + case ExecutionPolicy::Par: \ + thrust::NAME(thrust::MANIFOLD_PAR_NS::par, args...); \ + break; \ + case ExecutionPolicy::Seq: \ + thrust::NAME(thrust::cpp::par, args...); \ + break; \ + } \ + } + +#define THRUST_DYNAMIC_BACKEND(NAME, RET) \ + template \ + Ret NAME(ExecutionPolicy policy, Args... args) { \ + switch (policy) { \ + case ExecutionPolicy::Par: \ + return thrust::NAME(thrust::MANIFOLD_PAR_NS::par, args...); \ + case ExecutionPolicy::Seq: \ + break; \ + } \ + return thrust::NAME(thrust::cpp::par, args...); \ + } + +#if MANIFOLD_PAR != 'T' || \ + (TBB_INTERFACE_VERSION >= 10000 && __has_include()) +#if MANIFOLD_PAR == 'T' +#define STL_DYNAMIC_BACKEND(NAME, RET) \ + template \ + Ret NAME(ExecutionPolicy policy, Args... args) { \ + switch (policy) { \ + case ExecutionPolicy::Par: \ + return std::NAME(std::execution::par_unseq, args...); \ + case ExecutionPolicy::Seq: \ + break; \ + } \ + return std::NAME(args...); \ + } +#define STL_DYNAMIC_BACKEND_VOID(NAME) \ + template \ + void NAME(ExecutionPolicy policy, Args... args) { \ + switch (policy) { \ + case ExecutionPolicy::Par: \ + std::NAME(std::execution::par_unseq, args...); \ + break; \ + case ExecutionPolicy::Seq: \ + std::NAME(args...); \ + break; \ + } \ + } +#else +#define STL_DYNAMIC_BACKEND(NAME, RET) \ + template \ + Ret NAME(ExecutionPolicy policy, Args... args) { \ + return std::NAME(args...); \ + } +#define STL_DYNAMIC_BACKEND_VOID(NAME) \ + template \ + void NAME(ExecutionPolicy policy, Args... args) { \ + std::NAME(args...); \ + } +#endif + +template +void exclusive_scan(ExecutionPolicy policy, Args... args) { + // https://github.com/llvm/llvm-project/issues/59810 + std::exclusive_scan(args...); +} +template +OutputIterator copy_if(ExecutionPolicy policy, InputIterator1 first, + InputIterator1 last, InputIterator2 stencil, + OutputIterator result, Predicate pred) { + if (policy == ExecutionPolicy::Seq) + return thrust::copy_if(thrust::cpp::par, first, last, stencil, result, + pred); + else + // note: this is not a typo, see + // https://github.com/NVIDIA/thrust/issues/1977 + return thrust::copy_if(first, last, stencil, result, pred); +} +template +OutputIterator copy_if(ExecutionPolicy policy, InputIterator1 first, + InputIterator1 last, OutputIterator result, + Predicate pred) { +#if MANIFOLD_PAR == 'T' + if (policy == ExecutionPolicy::Seq) + return std::copy_if(first, last, result, pred); + else + return std::copy_if(std::execution::par_unseq, first, last, result, pred); +#else + return std::copy_if(first, last, result, pred); +#endif +} + +#else +#define STL_DYNAMIC_BACKEND(NAME, RET) THRUST_DYNAMIC_BACKEND(NAME, RET) +#define STL_DYNAMIC_BACKEND_VOID(NAME) THRUST_DYNAMIC_BACKEND_VOID(NAME) + +THRUST_DYNAMIC_BACKEND_VOID(exclusive_scan) +THRUST_DYNAMIC_BACKEND(copy_if, void) +#endif + +THRUST_DYNAMIC_BACKEND_VOID(gather) +THRUST_DYNAMIC_BACKEND_VOID(scatter) +THRUST_DYNAMIC_BACKEND_VOID(for_each) +THRUST_DYNAMIC_BACKEND_VOID(for_each_n) +THRUST_DYNAMIC_BACKEND_VOID(sequence) +STL_DYNAMIC_BACKEND_VOID(transform) +STL_DYNAMIC_BACKEND_VOID(uninitialized_fill) +STL_DYNAMIC_BACKEND_VOID(uninitialized_copy) +STL_DYNAMIC_BACKEND_VOID(stable_sort) +STL_DYNAMIC_BACKEND_VOID(fill) +STL_DYNAMIC_BACKEND_VOID(copy) +STL_DYNAMIC_BACKEND_VOID(inclusive_scan) +STL_DYNAMIC_BACKEND_VOID(copy_n) + +// void implies that the user have to specify the return type in the template +// argument, as we are unable to deduce it +THRUST_DYNAMIC_BACKEND(transform_reduce, void) +THRUST_DYNAMIC_BACKEND(gather_if, void) +THRUST_DYNAMIC_BACKEND(reduce_by_key, void) +STL_DYNAMIC_BACKEND(remove, void) +STL_DYNAMIC_BACKEND(find, void) +STL_DYNAMIC_BACKEND(find_if, void) +STL_DYNAMIC_BACKEND(all_of, bool) +STL_DYNAMIC_BACKEND(is_sorted, bool) +STL_DYNAMIC_BACKEND(reduce, void) +STL_DYNAMIC_BACKEND(count_if, int) +STL_DYNAMIC_BACKEND(remove_if, void) + +} // namespace manifold diff --git a/src/other/manifold/include/polygon.h b/src/other/manifold/include/polygon.h new file mode 100644 index 00000000000..8e5f11f0bd0 --- /dev/null +++ b/src/other/manifold/include/polygon.h @@ -0,0 +1,51 @@ +// Copyright 2021 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include + +#include "public.h" + +namespace manifold { + +/** @addtogroup Private + * @{ + */ + +/** + * Polygon vertex. + */ +struct PolyVert { + /// X-Y position + glm::vec2 pos; + /// ID or index into another vertex vector + int idx; +}; + +using SimplePolygonIdx = std::vector; +using PolygonsIdx = std::vector; + +std::vector TriangulateIdx(const PolygonsIdx &polys, + float precision = -1); +/** @} */ + +/** @ingroup Connections + * @{ + */ +std::vector Triangulate(const Polygons &polygons, + float precision = -1); + +ExecutionParams &PolygonParams(); +/** @} */ +} // namespace manifold \ No newline at end of file diff --git a/src/other/manifold/include/sparse.h b/src/other/manifold/include/sparse.h new file mode 100644 index 00000000000..a25eeae072a --- /dev/null +++ b/src/other/manifold/include/sparse.h @@ -0,0 +1,201 @@ +// Copyright 2021 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include + +#include "optional_assert.h" +#include "par.h" +#include "public.h" +#include "utils.h" +#include "vec.h" + +namespace manifold { + +/** @ingroup Private */ +class SparseIndices { + // sparse indices where {p1: q1, p2: q2, ...} are laid out as + // p1 q1 p2 q2 or q1 p1 q2 p2, depending on endianness + // such that the indices are sorted by (p << 32) | q + public: +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ + defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || \ + defined(__MIBSEB__) + static constexpr size_t pOffset = 0; +#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ + defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ + defined(__MIPSEL) || defined(__MIPSEL__) || defined(__EMSCRIPTEN__) || \ + defined(_WIN32) + static constexpr size_t pOffset = 1; +#else +#error "unknown architecture" +#endif + static constexpr int64_t EncodePQ(int p, int q) { + return (int64_t(p) << 32) | q; + } + + SparseIndices() = default; + SparseIndices(size_t size) : data_(size * sizeof(int64_t)) {} + + int size() const { return data_.size() / sizeof(int64_t); } + + Vec Copy(bool use_q) const { + Vec out(size()); + int offset = pOffset; + if (use_q) offset = 1 - offset; + const int* p = ptr(); + for_each(autoPolicy(out.size()), countAt(0), countAt((int)out.size()), + [&](int i) { out[i] = p[i * 2 + offset]; }); + return out; + } + + void Sort() { + VecView view = AsVec64(); + stable_sort(autoPolicy(size()), view.begin(), view.end()); + } + + void Resize(int size) { data_.resize(size * sizeof(int64_t), -1); } + + inline int& Get(int i, bool use_q) { + if (use_q) + return ptr()[2 * i + 1 - pOffset]; + else + return ptr()[2 * i + pOffset]; + } + + inline int Get(int i, bool use_q) const { + if (use_q) + return ptr()[2 * i + 1 - pOffset]; + else + return ptr()[2 * i + pOffset]; + } + + inline int64_t GetPQ(int i) const { + VecView view = AsVec64(); + return view[i]; + } + + inline void Set(int i, int p, int q) { + VecView view = AsVec64(); + view[i] = EncodePQ(p, q); + } + + inline void SetPQ(int i, int64_t pq) { + VecView view = AsVec64(); + view[i] = pq; + } + + VecView AsVec64() { + return VecView(reinterpret_cast(data_.data()), + data_.size() / sizeof(int64_t)); + } + + VecView AsVec64() const { + return VecView( + reinterpret_cast(data_.data()), + data_.size() / sizeof(int64_t)); + } + + VecView AsVec32() { + return VecView(reinterpret_cast(data_.data()), + data_.size() / sizeof(int32_t)); + } + + VecView AsVec32() const { + return VecView( + reinterpret_cast(data_.data()), + data_.size() / sizeof(int32_t)); + } + + inline void Add(int p, int q) { + for (int i = 0; i < sizeof(int64_t); ++i) data_.push_back(-1); + Set(size() - 1, p, q); + } + + void Unique() { + Sort(); + VecView view = AsVec64(); + int newSize = std::unique(view.begin(), view.end()) - view.begin(); + Resize(newSize); + } + + size_t RemoveZeros(Vec& S) { + ASSERT(S.size() == size(), userErr, + "Different number of values than indicies!"); + VecView view = AsVec64(); + auto zBegin = zip(S.begin(), view.begin()); + auto zEnd = zip(S.end(), view.end()); + size_t size = + remove_if(autoPolicy(S.size()), zBegin, zEnd, + [](thrust::tuple x) { + return thrust::get<0>(x) == 0; + }) - + zBegin; + S.resize(size, -1); + Resize(size); + return size; + } + + template + struct firstNonFinite { + bool NotFinite(float v) const { return !isfinite(v); } + bool NotFinite(glm::vec2 v) const { return !isfinite(v[0]); } + bool NotFinite(glm::vec3 v) const { return !isfinite(v[0]); } + bool NotFinite(glm::vec4 v) const { return !isfinite(v[0]); } + + bool operator()(thrust::tuple x) const { + bool result = NotFinite(thrust::get<0>(x)); + return result; + } + }; + + template + size_t KeepFinite(Vec& v, Vec& x) { + ASSERT(x.size() == size(), userErr, + "Different number of values than indicies!"); + VecView view = AsVec64(); + auto zBegin = zip(v.begin(), x.begin(), view.begin()); + auto zEnd = zip(v.end(), x.end(), view.end()); + size_t size = remove_if(autoPolicy(v.size()), zBegin, + zEnd, firstNonFinite()) - + zBegin; + v.resize(size); + x.resize(size); + Resize(size); + return size; + } + +#ifdef MANIFOLD_DEBUG + void Dump() const { + std::cout << "SparseIndices = " << std::endl; + const int* p = ptr(); + for (int i = 0; i < size(); ++i) { + std::cout << i << ", p = " << Get(i, false) << ", q = " << Get(i, true) + << std::endl; + } + std::cout << std::endl; + } +#endif + + private: + Vec data_; + inline int* ptr() { return reinterpret_cast(data_.data()); } + inline const int* ptr() const { + return reinterpret_cast(data_.data()); + } +}; + +} // namespace manifold diff --git a/src/other/manifold/include/thrust/addressof.h b/src/other/manifold/include/thrust/addressof.h new file mode 100644 index 00000000000..d21df0c76a5 --- /dev/null +++ b/src/other/manifold/include/thrust/addressof.h @@ -0,0 +1,31 @@ +// Copyright (c) 2018 NVIDIA Corporation +// Author: Bryce Adelstein Lelbach +// +// Distributed under the Boost Software License v1.0 (boost.org/LICENSE_1_0.txt) + +#pragma once + +#include + +#if THRUST_CPP_DIALECT >= 2011 +# include +#endif + +THRUST_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// + +/*! Obtains the actual address of the object or function arg, even in presence of overloaded operator&. + */ +template +__host__ __device__ +T* addressof(T& arg) +{ + return reinterpret_cast( + &const_cast(reinterpret_cast(arg)) + ); +} + +/////////////////////////////////////////////////////////////////////////////// + +THRUST_NAMESPACE_END diff --git a/src/other/manifold/include/thrust/adjacent_difference.h b/src/other/manifold/include/thrust/adjacent_difference.h new file mode 100644 index 00000000000..e8385c240dd --- /dev/null +++ b/src/other/manifold/include/thrust/adjacent_difference.h @@ -0,0 +1,244 @@ +/* + * Copyright 2008-2013 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/*! \file adjacent_difference.h + * \brief Compute difference between consecutive elements of a range + */ + +#pragma once + +#include +#include + +THRUST_NAMESPACE_BEGIN + +/*! \addtogroup transformations Transformations + * \{ + */ + + +/*! \p adjacent_difference calculates the differences of adjacent elements in the + * range [first, last). That is, \*first is assigned to + * \*result, and, for each iterator \p i in the range + * [first + 1, last), the difference of \*i and *(i - 1) + * is assigned to \*(result + (i - first)). + * + * This version of \p adjacent_difference uses operator- to calculate + * differences. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the input range. + * \param last The end of the input range. + * \param result The beginning of the output range. + * \return The iterator result + (last - first) + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam InputIterator is a model of Input Iterator, + * and \c x and \c y are objects of \p InputIterator's \c value_type, then \c x - \c is defined, + * and \p InputIterator's \c value_type is convertible to a type in \p OutputIterator's set of \c value_types, + * and the return type of x - y is convertible to a type in \p OutputIterator's set of \c value_types. + * \tparam OutputIterator is a model of Output Iterator. + * + * \remark Note that \p result is permitted to be the same iterator as \p first. This is + * useful for computing differences "in place". + * + * The following code snippet demonstrates how to use \p adjacent_difference to compute + * the difference between adjacent elements of a range using the \p thrust::device execution policy: + * + * \code + * #include + * #include + * #include + * ... + * int h_data[8] = {1, 2, 1, 2, 1, 2, 1, 2}; + * thrust::device_vector d_data(h_data, h_data + 8); + * thrust::device_vector d_result(8); + * + * thrust::adjacent_difference(thrust::device, d_data.begin(), d_data.end(), d_result.begin()); + * + * // d_result is now [1, 1, -1, 1, -1, 1, -1, 1] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/adjacent_difference + * \see inclusive_scan + */ +template +__host__ __device__ +OutputIterator adjacent_difference(const thrust::detail::execution_policy_base &exec, + InputIterator first, InputIterator last, + OutputIterator result); + +/*! \p adjacent_difference calculates the differences of adjacent elements in the + * range [first, last). That is, *first is assigned to + * \*result, and, for each iterator \p i in the range + * [first + 1, last), binary_op(\*i, \*(i - 1)) is assigned to + * \*(result + (i - first)). + * + * This version of \p adjacent_difference uses the binary function \p binary_op to + * calculate differences. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the input range. + * \param last The end of the input range. + * \param result The beginning of the output range. + * \param binary_op The binary function used to compute differences. + * \return The iterator result + (last - first) + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam InputIterator is a model of Input Iterator, + * and \p InputIterator's \c value_type is convertible to \p BinaryFunction's \c first_argument_type and \c second_argument_type, + * and \p InputIterator's \c value_type is convertible to a type in \p OutputIterator's set of \c value_types. + * \tparam OutputIterator is a model of Output Iterator. + * \tparam BinaryFunction's \c result_type is convertible to a type in \p OutputIterator's set of \c value_types. + * + * \remark Note that \p result is permitted to be the same iterator as \p first. This is + * useful for computing differences "in place". + * + * The following code snippet demonstrates how to use \p adjacent_difference to compute + * the sum between adjacent elements of a range using the \p thrust::device execution policy: + * + * \code + * #include + * #include + * #include + * #include + * ... + * int h_data[8] = {1, 2, 1, 2, 1, 2, 1, 2}; + * thrust::device_vector d_data(h_data, h_data + 8); + * thrust::device_vector d_result(8); + * + * thrust::adjacent_difference(thrust::device, d_data.begin(), d_data.end(), d_result.begin(), thrust::plus()); + * + * // d_result is now [1, 3, 3, 3, 3, 3, 3, 3] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/adjacent_difference + * \see inclusive_scan + */ +template +__host__ __device__ +OutputIterator adjacent_difference(const thrust::detail::execution_policy_base &exec, + InputIterator first, InputIterator last, + OutputIterator result, + BinaryFunction binary_op); + +/*! \p adjacent_difference calculates the differences of adjacent elements in the + * range [first, last). That is, \*first is assigned to + * \*result, and, for each iterator \p i in the range + * [first + 1, last), the difference of \*i and *(i - 1) + * is assigned to \*(result + (i - first)). + * + * This version of \p adjacent_difference uses operator- to calculate + * differences. + * + * \param first The beginning of the input range. + * \param last The end of the input range. + * \param result The beginning of the output range. + * \return The iterator result + (last - first) + * + * \tparam InputIterator is a model of Input Iterator, + * and \c x and \c y are objects of \p InputIterator's \c value_type, then \c x - \c is defined, + * and \p InputIterator's \c value_type is convertible to a type in \p OutputIterator's set of \c value_types, + * and the return type of x - y is convertible to a type in \p OutputIterator's set of \c value_types. + * \tparam OutputIterator is a model of Output Iterator. + * + * \remark Note that \p result is permitted to be the same iterator as \p first. This is + * useful for computing differences "in place". + * + * The following code snippet demonstrates how to use \p adjacent_difference to compute + * the difference between adjacent elements of a range. + * + * \code + * #include + * #include + * ... + * int h_data[8] = {1, 2, 1, 2, 1, 2, 1, 2}; + * thrust::device_vector d_data(h_data, h_data + 8); + * thrust::device_vector d_result(8); + * + * thrust::adjacent_difference(d_data.begin(), d_data.end(), d_result.begin()); + * + * // d_result is now [1, 1, -1, 1, -1, 1, -1, 1] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/adjacent_difference + * \see inclusive_scan + */ +template +OutputIterator adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result); + +/*! \p adjacent_difference calculates the differences of adjacent elements in the + * range [first, last). That is, *first is assigned to + * \*result, and, for each iterator \p i in the range + * [first + 1, last), binary_op(\*i, \*(i - 1)) is assigned to + * \*(result + (i - first)). + * + * This version of \p adjacent_difference uses the binary function \p binary_op to + * calculate differences. + * + * \param first The beginning of the input range. + * \param last The end of the input range. + * \param result The beginning of the output range. + * \param binary_op The binary function used to compute differences. + * \return The iterator result + (last - first) + * + * \tparam InputIterator is a model of Input Iterator, + * and \p InputIterator's \c value_type is convertible to \p BinaryFunction's \c first_argument_type and \c second_argument_type, + * and \p InputIterator's \c value_type is convertible to a type in \p OutputIterator's set of \c value_types. + * \tparam OutputIterator is a model of Output Iterator. + * \tparam BinaryFunction's \c result_type is convertible to a type in \p OutputIterator's set of \c value_types. + * + * \remark Note that \p result is permitted to be the same iterator as \p first. This is + * useful for computing differences "in place". + * + * The following code snippet demonstrates how to use \p adjacent_difference to compute + * the sum between adjacent elements of a range. + * + * \code + * #include + * #include + * #include + * ... + * int h_data[8] = {1, 2, 1, 2, 1, 2, 1, 2}; + * thrust::device_vector d_data(h_data, h_data + 8); + * thrust::device_vector d_result(8); + * + * thrust::adjacent_difference(d_data.begin(), d_data.end(), d_result.begin(), thrust::plus()); + * + * // d_result is now [1, 3, 3, 3, 3, 3, 3, 3] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/adjacent_difference + * \see inclusive_scan + */ +template +OutputIterator adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, + BinaryFunction binary_op); + +/*! \} + */ + +THRUST_NAMESPACE_END + +#include + diff --git a/src/other/manifold/include/thrust/advance.h b/src/other/manifold/include/thrust/advance.h new file mode 100644 index 00000000000..a5162e20300 --- /dev/null +++ b/src/other/manifold/include/thrust/advance.h @@ -0,0 +1,140 @@ +/* + * Copyright 2008-2013 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/*! \file advance.h + * \brief Advance an iterator by a given distance. + */ + +#pragma once + +#include + +THRUST_NAMESPACE_BEGIN + +/*! \addtogroup iterators + * \{ + */ + +/*! \p advance(i, n) increments the iterator \p i by the distance \p n. + * If n > 0 it is equivalent to executing ++i \p n + * times, and if n < 0 it is equivalent to executing --i + * \p n times. If n == 0, the call has no effect. + * + * \param i The iterator to be advanced. + * \param n The distance by which to advance the iterator. + * + * \tparam InputIterator is a model of Input Iterator. + * \tparam Distance is an integral type that is convertible to \p InputIterator's distance type. + * + * \pre \p n shall be negative only for bidirectional and random access iterators. + * + * The following code snippet demonstrates how to use \p advance to increment + * an iterator a given number of times. + * + * \code + * #include + * #include + * ... + * thrust::device_vector vec(13); + * thrust::device_vector::iterator iter = vec.begin(); + * + * thrust::advance(iter, 7); + * + * // iter - vec.begin() == 7 + * \endcode + * + * \see https://en.cppreference.com/w/cpp/iterator/advance + */ +template +__host__ __device__ +void advance(InputIterator& i, Distance n); + +/*! \p next(i, n) returns the \p n th successor of the iterator \p i. + * + * \param i An iterator. + * \param n The number of elements to advance. + * + * \tparam InputIterator must meet the InputIterator. + * + * \pre \p n shall be negative only for bidirectional and random access iterators. + * + * The following code snippet demonstrates how to use \p next. + * + * \code + * #include + * #include + * ... + * thrust::device_vector vec(13); + * thrust::device_vector::iterator i0 = vec.begin(); + * + * auto i1 = thrust::next(i0); + * + * // i0 - vec.begin() == 0 + * // i1 - vec.begin() == 1 + * \endcode + * + * \see https://en.cppreference.com/w/cpp/iterator/next + */ +#if 0 // Doxygen only +template +__host__ __device__ +InputIterator next( + InputIterator i +, typename iterator_traits::difference_type n = 1 +); +#endif + +/*! \p prev(i, n) returns the \p n th predecessor of the iterator \p i. + * + * \param i An iterator. + * \param n The number of elements to descend. + * + * \tparam BidirectionalIterator must meet the BidirectionalIterator. + * + * The following code snippet demonstrates how to use \p prev. + * + * \code + * #include + * #include + * ... + * thrust::device_vector vec(13); + * thrust::device_vector::iterator i0 = vec.end(); + * + * auto i1 = thrust::prev(i0); + * + * // vec.end() - i0 == 0 + * // vec.end() - i1 == 1 + * \endcode + * + * \see https://en.cppreference.com/w/cpp/iterator/prev + */ +#if 0 // Doxygen only +template +__host__ __device__ +BidirectionalIterator prev( + BidirectionalIterator i +, typename iterator_traits::difference_type n = 1 +); +#endif + +/*! \} // end iterators + */ + +THRUST_NAMESPACE_END + +#include + diff --git a/src/other/manifold/include/thrust/allocate_unique.h b/src/other/manifold/include/thrust/allocate_unique.h new file mode 100644 index 00000000000..ff10cb51cd1 --- /dev/null +++ b/src/other/manifold/include/thrust/allocate_unique.h @@ -0,0 +1,443 @@ +// Copyright (c) 2018 NVIDIA Corporation +// Author: Bryce Adelstein Lelbach +// +// Distributed under the Boost Software License v1.0 (boost.org/LICENSE_1_0.txt) + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2011 + +#include +#include +#include +#include + +#include +#include + +THRUST_NAMESPACE_BEGIN + +// wg21.link/p0316r0 + +/////////////////////////////////////////////////////////////////////////////// + +namespace detail +{ + +template +void allocator_delete_impl( + Allocator const& alloc, Pointer p, std::false_type +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >; + + typename traits::allocator_type alloc_T(alloc); + + if (nullptr != pointer_traits::get(p)) + { + traits::destroy(alloc_T, thrust::raw_pointer_cast(p)); + traits::deallocate(alloc_T, p, 1); + } +} + +template +void allocator_delete_impl( + Allocator const& alloc, Pointer p, std::true_type +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >; + + typename traits::allocator_type alloc_T(alloc); + + if (nullptr != pointer_traits::get(p)) + { + traits::deallocate(alloc_T, p, 1); + } +} + +} // namespace detail + +template +struct allocator_delete final +{ + using allocator_type + = typename std::remove_cv< + typename std::remove_reference::type + >::type::template rebind::other; + using pointer = typename detail::allocator_traits::pointer; + + template + allocator_delete(UAllocator&& other) noexcept + : alloc_(THRUST_FWD(other)) + {} + + template + allocator_delete( + allocator_delete const& other + ) noexcept + : alloc_(other.get_allocator()) + {} + template + allocator_delete( + allocator_delete&& other + ) noexcept + : alloc_(std::move(other.get_allocator())) + {} + + template + allocator_delete& operator=( + allocator_delete const& other + ) noexcept + { + alloc_ = other.get_allocator(); + return *this; + } + template + allocator_delete& operator=( + allocator_delete&& other + ) noexcept + { + alloc_ = std::move(other.get_allocator()); + return *this; + } + + void operator()(pointer p) + { + std::integral_constant ic; + + detail::allocator_delete_impl(get_allocator(), p, ic); + } + + allocator_type& get_allocator() noexcept { return alloc_; } + allocator_type const& get_allocator() const noexcept { return alloc_; } + + void swap(allocator_delete& other) noexcept + { + using std::swap; + swap(alloc_, other.alloc_); + } + +private: + allocator_type alloc_; +}; + +template +using uninitialized_allocator_delete = allocator_delete; + +namespace detail { + +template +void array_allocator_delete_impl( + Allocator const& alloc, Pointer p, Size count, std::false_type +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >; + + typename traits::allocator_type alloc_T(alloc); + + if (nullptr != pointer_traits::get(p)) + { + destroy_n(alloc_T, p, count); + traits::deallocate(alloc_T, p, count); + } +} + +template +void array_allocator_delete_impl( + Allocator const& alloc, Pointer p, Size count, std::true_type +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >; + + typename traits::allocator_type alloc_T(alloc); + + if (nullptr != pointer_traits::get(p)) + { + traits::deallocate(alloc_T, p, count); + } +} + +} // namespace detail + +template +struct array_allocator_delete final +{ + using allocator_type + = typename std::remove_cv< + typename std::remove_reference::type + >::type::template rebind::other; + using pointer = typename detail::allocator_traits::pointer; + + template + array_allocator_delete(UAllocator&& other, std::size_t n) noexcept + : alloc_(THRUST_FWD(other)), count_(n) + {} + + template + array_allocator_delete( + array_allocator_delete const& other + ) noexcept + : alloc_(other.get_allocator()), count_(other.count_) + {} + template + array_allocator_delete( + array_allocator_delete&& other + ) noexcept + : alloc_(std::move(other.get_allocator())), count_(other.count_) + {} + + template + array_allocator_delete& operator=( + array_allocator_delete const& other + ) noexcept + { + alloc_ = other.get_allocator(); + count_ = other.count_; + return *this; + } + template + array_allocator_delete& operator=( + array_allocator_delete&& other + ) noexcept + { + alloc_ = std::move(other.get_allocator()); + count_ = other.count_; + return *this; + } + + void operator()(pointer p) + { + std::integral_constant ic; + + detail::array_allocator_delete_impl(get_allocator(), p, count_, ic); + } + + allocator_type& get_allocator() noexcept { return alloc_; } + allocator_type const& get_allocator() const noexcept { return alloc_; } + + void swap(array_allocator_delete& other) noexcept + { + using std::swap; + swap(alloc_, other.alloc_); + swap(count_, other.count_); + } + +private: + allocator_type alloc_; + std::size_t count_; +}; + +template +using uninitialized_array_allocator_delete + = array_allocator_delete; + +/////////////////////////////////////////////////////////////////////////////// + +template +struct tagged_deleter : Lambda +{ + __host__ __device__ + tagged_deleter(Lambda&& l) : Lambda(THRUST_FWD(l)) {} + + using pointer = Pointer; +}; + +template +__host__ __device__ +tagged_deleter +make_tagged_deleter(Lambda&& l) +{ + return tagged_deleter(THRUST_FWD(l)); +} + +/////////////////////////////////////////////////////////////////////////////// + +template +__host__ +std::unique_ptr< + T, + allocator_delete< + T + , typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits::allocator_type + > +> +allocate_unique( + Allocator const& alloc, Args&&... args +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits; + + typename traits::allocator_type alloc_T(alloc); + + auto hold_deleter = make_tagged_deleter( + [&alloc_T] (typename traits::pointer p) { + traits::deallocate(alloc_T, p, 1); + } + ); + using hold_t = std::unique_ptr; + auto hold = hold_t(traits::allocate(alloc_T, 1), hold_deleter); + + traits::construct( + alloc_T, thrust::raw_pointer_cast(hold.get()), THRUST_FWD(args)... + ); + auto deleter = allocator_delete(alloc); + return std::unique_ptr + (hold.release(), std::move(deleter)); +} + +template +__host__ +std::unique_ptr< + T, + uninitialized_allocator_delete< + T + , typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits::allocator_type + > +> +uninitialized_allocate_unique( + Allocator const& alloc +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits; + + typename traits::allocator_type alloc_T(alloc); + + auto hold_deleter = make_tagged_deleter( + [&alloc_T] (typename traits::pointer p) { + traits::deallocate(alloc_T, p, 1); + } + ); + using hold_t = std::unique_ptr; + auto hold = hold_t(traits::allocate(alloc_T, 1), hold_deleter); + + auto deleter = uninitialized_allocator_delete< + T, typename traits::allocator_type + >(alloc_T); + return std::unique_ptr + (hold.release(), std::move(deleter)); +} + +template +__host__ +std::unique_ptr< + T[], + array_allocator_delete< + T + , typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits::allocator_type + > +> +allocate_unique_n( + Allocator const& alloc, Size n, Args&&... args +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits; + + typename traits::allocator_type alloc_T(alloc); + + auto hold_deleter = make_tagged_deleter( + [n, &alloc_T] (typename traits::pointer p) { + traits::deallocate(alloc_T, p, n); + } + ); + using hold_t = std::unique_ptr; + auto hold = hold_t(traits::allocate(alloc_T, n), hold_deleter); + + uninitialized_construct_n_with_allocator( + alloc_T, hold.get(), n, THRUST_FWD(args)... + ); + auto deleter = array_allocator_delete< + T, typename traits::allocator_type + >(alloc_T, n); + return std::unique_ptr + (hold.release(), std::move(deleter)); +} + +template +__host__ +std::unique_ptr< + T[], + uninitialized_array_allocator_delete< + T + , typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits::allocator_type + > +> +uninitialized_allocate_unique_n( + Allocator const& alloc, Size n +) +{ + using traits = typename detail::allocator_traits< + typename std::remove_cv< + typename std::remove_reference::type + >::type + >::template rebind_traits; + + typename traits::allocator_type alloc_T(alloc); + + auto hold_deleter = make_tagged_deleter( + [n, &alloc_T] (typename traits::pointer p) { + traits::deallocate(alloc_T, p, n); + } + ); + using hold_t = std::unique_ptr; + auto hold = hold_t(traits::allocate(alloc_T, n), hold_deleter); + + auto deleter = uninitialized_array_allocator_delete< + T, typename traits::allocator_type + >(alloc_T, n); + return std::unique_ptr + (hold.release(), std::move(deleter)); +} + +/////////////////////////////////////////////////////////////////////////////// + +THRUST_NAMESPACE_END + +#endif // THRUST_CPP_DIALECT >= 2011 + diff --git a/src/other/manifold/include/thrust/async/copy.h b/src/other/manifold/include/thrust/async/copy.h new file mode 100644 index 00000000000..a8edc7411e5 --- /dev/null +++ b/src/other/manifold/include/thrust/async/copy.h @@ -0,0 +1,154 @@ +/* + * Copyright 2008-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file + * \brief Algorithms for asynchronously copying a range. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +/*! \cond + */ + +namespace unimplemented +{ + +template < + typename FromPolicy, typename ToPolicy +, typename ForwardIt, typename Sentinel, typename OutputIt +> +__host__ +event +async_copy( + thrust::execution_policy& from_exec +, thrust::execution_policy& to_exec +, ForwardIt first, Sentinel last, OutputIt output +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace copy_detail +{ + +using thrust::async::unimplemented::async_copy; + +struct copy_fn final +{ + template < + typename FromPolicy, typename ToPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& from_exec + , thrust::detail::execution_policy_base const& to_exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + ) + // ADL dispatch. + THRUST_RETURNS( + async_copy( + thrust::detail::derived_cast(thrust::detail::strip_const(from_exec)) + , thrust::detail::derived_cast(thrust::detail::strip_const(to_exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + ) + THRUST_RETURNS( + copy_fn::call( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + // Synthesize a suitable new execution policy, because we don't want to + // try and extract twice from the one we were passed. + , typename remove_cvref_t< + decltype(thrust::detail::derived_cast(thrust::detail::strip_const(exec))) + >::tag_type{} + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + ) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last, OutputIt&& output) + THRUST_RETURNS( + copy_fn::call( + thrust::detail::select_system( + typename thrust::iterator_system>::type{} + ) + , thrust::detail::select_system( + typename thrust::iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace copy_detail + +THRUST_INLINE_CONSTANT copy_detail::copy_fn copy{}; + +/*! \endcond + */ + +} // namespace async + +THRUST_NAMESPACE_END + +#endif + diff --git a/src/other/manifold/include/thrust/async/for_each.h b/src/other/manifold/include/thrust/async/for_each.h new file mode 100644 index 00000000000..0d3b3a18905 --- /dev/null +++ b/src/other/manifold/include/thrust/async/for_each.h @@ -0,0 +1,123 @@ +/* + * Copyright 2008-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file + * \brief Algorithms for asynchronously iterating over the elements of a range. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +/*! \cond + */ + +namespace unimplemented +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename UnaryFunction +> +__host__ +event +async_for_each( + thrust::execution_policy&, ForwardIt, Sentinel, UnaryFunction +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace for_each_detail +{ + +using thrust::async::unimplemented::async_for_each; + +struct for_each_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename UnaryFunction + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , UnaryFunction&& f + ) + // ADL dispatch. + THRUST_RETURNS( + async_for_each( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(f) + ) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last, UnaryFunction&& f) + THRUST_RETURNS( + for_each_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(f) + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace for_each_detail + +THRUST_INLINE_CONSTANT for_each_detail::for_each_fn for_each{}; + +/*! \endcond + */ + +} // namespace async + +THRUST_NAMESPACE_END + +#endif diff --git a/src/other/manifold/include/thrust/async/reduce.h b/src/other/manifold/include/thrust/async/reduce.h new file mode 100644 index 00000000000..8f4fe3133e6 --- /dev/null +++ b/src/other/manifold/include/thrust/async/reduce.h @@ -0,0 +1,446 @@ +/* + * Copyright 2008-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file + * \brief Algorithms for asynchronously reducing a range to a single value. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +/*! \cond + */ + +namespace unimplemented +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename T, typename BinaryOp +> +__host__ +future +async_reduce( + thrust::execution_policy&, ForwardIt, Sentinel, T, BinaryOp +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace reduce_detail +{ + +using thrust::async::unimplemented::async_reduce; + +struct reduce_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename T, typename BinaryOp + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , T&& init + , BinaryOp&& op + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(init) + , THRUST_FWD(op) + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename T + > + __host__ + static auto call4( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , T&& init + , thrust::true_type + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(init) + , thrust::plus>{} + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel + > + __host__ + static auto + call3( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , thrust::true_type + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , typename iterator_traits>::value_type{} + , thrust::plus< + remove_cvref_t< + typename iterator_traits>::value_type + > + >{} + ) + ) + + template + __host__ + static auto call4(ForwardIt&& first, Sentinel&& last, + T&& init, + BinaryOp&& op, + thrust::false_type) + THRUST_RETURNS( + reduce_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(init) + , THRUST_FWD(op) + ) + ) + + template + __host__ + static auto call3(ForwardIt&& first, Sentinel&& last, + T&& init, + thrust::false_type) + THRUST_RETURNS( + reduce_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(init) + , thrust::plus>{} + ) + ) + + // MSVC WAR: MSVC gets angsty and eats all available RAM when we try to detect + // if T1 is an execution_policy by using SFINAE. Switching to a static + // dispatch pattern to prevent this. + template + __host__ + static auto call(T1&& t1, T2&& t2, T3&& t3) + THRUST_RETURNS( + reduce_fn::call3(THRUST_FWD(t1), THRUST_FWD(t2), THRUST_FWD(t3), + thrust::is_execution_policy>{}) + ) + + template + __host__ + static auto call(T1&& t1, T2&& t2, T3&& t3, T4&& t4) + THRUST_RETURNS( + reduce_fn::call4(THRUST_FWD(t1), THRUST_FWD(t2), THRUST_FWD(t3), THRUST_FWD(t4), + thrust::is_execution_policy>{}) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last) + THRUST_RETURNS( + reduce_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , typename iterator_traits>::value_type{} + , thrust::plus< + remove_cvref_t< + typename iterator_traits>::value_type + > + >{} + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace reduce_detail + +THRUST_INLINE_CONSTANT reduce_detail::reduce_fn reduce{}; + +/////////////////////////////////////////////////////////////////////////////// + +namespace unimplemented +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename OutputIt +, typename T, typename BinaryOp +> +__host__ +event +async_reduce_into( + thrust::execution_policy& +, ForwardIt, Sentinel, OutputIt, T, BinaryOp +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace reduce_into_detail +{ + +using thrust::async::unimplemented::async_reduce_into; + +struct reduce_into_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + , typename T, typename BinaryOp + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , T&& init + , BinaryOp&& op + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce_into( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(init) + , THRUST_FWD(op) + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + , typename T + > + __host__ + static auto call5( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , T&& init + , thrust::true_type + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce_into( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(init) + , thrust::plus>{} + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + > + __host__ + static auto + call4( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , thrust::true_type + ) + // ADL dispatch. + THRUST_RETURNS( + async_reduce_into( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , typename iterator_traits>::value_type{} + , thrust::plus< + remove_cvref_t< + typename iterator_traits>::value_type + > + >{} + ) + ) + + template < + typename ForwardIt, typename Sentinel, typename OutputIt + , typename T, typename BinaryOp + > + __host__ + static auto call5( + ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , T&& init + , BinaryOp&& op + , thrust::false_type + ) + THRUST_RETURNS( + reduce_into_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + , typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(init) + , THRUST_FWD(op) + ) + ) + + template < + typename ForwardIt, typename Sentinel, typename OutputIt + , typename T + > + __host__ + static auto call4( + ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , T&& init + , thrust::false_type + ) + THRUST_RETURNS( + reduce_into_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + , typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(init) + , thrust::plus>{} + ) + ) + + template < + typename ForwardIt, typename Sentinel, typename OutputIt + > + __host__ + static auto call( + ForwardIt&& first, Sentinel&& last + , OutputIt&& output + ) + THRUST_RETURNS( + reduce_into_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + , typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , typename iterator_traits>::value_type{} + , thrust::plus< + remove_cvref_t< + typename iterator_traits>::value_type + > + >{} + ) + ) + + // MSVC WAR: MSVC gets angsty and eats all available RAM when we try to detect + // if T1 is an execution_policy by using SFINAE. Switching to a static + // dispatch pattern to prevent this. + template + __host__ + static auto call(T1&& t1, T2&& t2, T3&& t3, T4&& t4) + THRUST_RETURNS( + reduce_into_fn::call4( + THRUST_FWD(t1), THRUST_FWD(t2), THRUST_FWD(t3), THRUST_FWD(t4), + thrust::is_execution_policy>{}) + ) + + template + __host__ + static auto call(T1&& t1, T2&& t2, T3&& t3, T4&& t4, T5&& t5) + THRUST_RETURNS( + reduce_into_fn::call5( + THRUST_FWD(t1), THRUST_FWD(t2), THRUST_FWD(t3), THRUST_FWD(t4), + THRUST_FWD(t5), thrust::is_execution_policy>{}) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace reduce_into_detail + +THRUST_INLINE_CONSTANT reduce_into_detail::reduce_into_fn reduce_into{}; + +/*! \endcond + */ + +} // namespace async + +THRUST_NAMESPACE_END + +#endif + diff --git a/src/other/manifold/include/thrust/async/scan.h b/src/other/manifold/include/thrust/async/scan.h new file mode 100644 index 00000000000..1bcf8125780 --- /dev/null +++ b/src/other/manifold/include/thrust/async/scan.h @@ -0,0 +1,344 @@ +/* + * Copyright 2008-2020 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file async/scan.h + * \brief Functions for asynchronously computing prefix scans. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +// Fallback implementations used when no overloads are found via ADL: +namespace unimplemented +{ + +template +event +async_inclusive_scan(thrust::execution_policy&, + ForwardIt, + Sentinel, + OutputIt, + BinaryOp) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value), + "this algorithm is not implemented for the specified system" + ); + return {}; +} + +template +event +async_exclusive_scan(thrust::execution_policy&, + ForwardIt, + Sentinel, + OutputIt, + InitialValueType, + BinaryOp) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value), + "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace inclusive_scan_detail +{ + +// Include fallback implementation for ADL failures +using thrust::async::unimplemented::async_inclusive_scan; + +// Implementation of the thrust::async::inclusive_scan CPO. +struct inclusive_scan_fn final +{ + template + auto + operator()(thrust::detail::execution_policy_base const& exec, + ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + BinaryOp&& op) const + // ADL dispatch. + THRUST_RETURNS( + async_inclusive_scan( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(op) + ) + ) + + template + auto + operator()(thrust::detail::execution_policy_base const& exec, + ForwardIt&& first, + Sentinel&& last, + OutputIt&& out) const + // ADL dispatch. + THRUST_RETURNS( + async_inclusive_scan( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + thrust::plus<>{} + ) + ) + + template >>> + auto operator()(ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + BinaryOp&& op) const + // ADL dispatch. + THRUST_RETURNS( + async_inclusive_scan( + thrust::detail::select_system( + iterator_system_t>{}, + iterator_system_t>{} + ), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(op) + ) + ) + + template + auto operator()(ForwardIt&& first, Sentinel&& last, OutputIt&& out) const + // ADL dispatch. + THRUST_RETURNS( + async_inclusive_scan( + thrust::detail::select_system( + iterator_system_t>{}, + iterator_system_t>{} + ), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + thrust::plus<>{} + ) + ) +}; + +} // namespace inclusive_scan_detail + +THRUST_INLINE_CONSTANT inclusive_scan_detail::inclusive_scan_fn inclusive_scan{}; + +namespace exclusive_scan_detail +{ + +// Include fallback implementation for ADL failures +using thrust::async::unimplemented::async_exclusive_scan; + +// Implementation of the thrust::async::exclusive_scan CPO. +struct exclusive_scan_fn final +{ + template + auto + operator()(thrust::detail::execution_policy_base const& exec, + ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + InitialValueType&& init, + BinaryOp&& op) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(init), + THRUST_FWD(op) + ) + ) + + template + auto + operator()(thrust::detail::execution_policy_base const& exec, + ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + InitialValueType&& init) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(init), + thrust::plus<>{} + ) + ) + + template + auto + operator()(thrust::detail::execution_policy_base const& exec, + ForwardIt&& first, + Sentinel&& last, + OutputIt&& out) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + iterator_value_t>{}, + thrust::plus<>{} + ) + ) + + template >>> + auto + operator()(ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + InitialValueType&& init, + BinaryOp&& op) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::select_system( + iterator_system_t>{}, + iterator_system_t>{} + ), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(init), + THRUST_FWD(op) + ) + ) + + template >>> + auto + operator()(ForwardIt&& first, + Sentinel&& last, + OutputIt&& out, + InitialValueType&& init) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::select_system( + iterator_system_t>{}, + iterator_system_t>{} + ), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + THRUST_FWD(init), + thrust::plus<>{} + ) + ) + + template + auto operator()(ForwardIt&& first, + Sentinel&& last, + OutputIt&& out) const + // ADL dispatch. + THRUST_RETURNS( + async_exclusive_scan( + thrust::detail::select_system( + iterator_system_t>{}, + iterator_system_t>{} + ), + THRUST_FWD(first), + THRUST_FWD(last), + THRUST_FWD(out), + iterator_value_t>{}, + thrust::plus<>{} + ) + ) +}; + +} // namespace exclusive_scan_detail + +THRUST_INLINE_CONSTANT exclusive_scan_detail::exclusive_scan_fn exclusive_scan{}; + +} // namespace async + +THRUST_NAMESPACE_END + +#endif diff --git a/src/other/manifold/include/thrust/async/sort.h b/src/other/manifold/include/thrust/async/sort.h new file mode 100644 index 00000000000..8881793970b --- /dev/null +++ b/src/other/manifold/include/thrust/async/sort.h @@ -0,0 +1,280 @@ +/* + * Copyright 2008-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file + * \brief Algorithms for asynchronously sorting a range. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +/*! \cond + */ + +namespace unimplemented +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename StrictWeakOrdering +> +__host__ +event +async_stable_sort( + thrust::execution_policy& +, ForwardIt, Sentinel, StrictWeakOrdering +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace stable_sort_detail +{ + +using thrust::async::unimplemented::async_stable_sort; + +struct stable_sort_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename StrictWeakOrdering + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , StrictWeakOrdering&& comp + ) + // ADL dispatch. + THRUST_RETURNS( + async_stable_sort( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(comp) + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + ) + // ADL dispatch. + THRUST_RETURNS( + async_stable_sort( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , thrust::less< + typename iterator_traits>::value_type + >{} + ) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last, StrictWeakOrdering&& comp) + THRUST_RETURNS( + stable_sort_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(comp) + ) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last) + THRUST_RETURNS( + stable_sort_fn::call( + THRUST_FWD(first), THRUST_FWD(last) + , thrust::less< + typename iterator_traits>::value_type + >{} + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace stable_sort_detail + +THRUST_INLINE_CONSTANT stable_sort_detail::stable_sort_fn stable_sort{}; + +namespace fallback +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename StrictWeakOrdering +> +__host__ +event +async_sort( + thrust::execution_policy& exec +, ForwardIt&& first, Sentinel&& last, StrictWeakOrdering&& comp +) +{ + return async_stable_sort( + thrust::detail::derived_cast(exec) + , THRUST_FWD(first), THRUST_FWD(last), THRUST_FWD(comp) + ); +} + +} // namespace fallback + +namespace sort_detail +{ + +using thrust::async::fallback::async_sort; + +struct sort_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename StrictWeakOrdering + > + __host__ + static auto call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , StrictWeakOrdering&& comp + ) + // ADL dispatch. + THRUST_RETURNS( + async_sort( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(comp) + ) + ) + + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel + > + __host__ + static auto call3( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , thrust::true_type + ) + THRUST_RETURNS( + sort_fn::call( + exec + , THRUST_FWD(first), THRUST_FWD(last) + , thrust::less< + typename iterator_traits>::value_type + >{} + ) + ) + + template + __host__ + static auto call3(ForwardIt&& first, Sentinel&& last, + StrictWeakOrdering&& comp, + thrust::false_type) + THRUST_RETURNS( + sort_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(comp) + ) + ) + + // MSVC WAR: MSVC gets angsty and eats all available RAM when we try to detect + // if T1 is an execution_policy by using SFINAE. Switching to a static + // dispatch pattern to prevent this. + template + __host__ + static auto call(T1&& t1, T2&& t2, T3&& t3) + THRUST_RETURNS( + sort_fn::call3(THRUST_FWD(t1), THRUST_FWD(t2), THRUST_FWD(t3), + thrust::is_execution_policy>{}) + ) + + template + __host__ + static auto call(ForwardIt&& first, Sentinel&& last) + THRUST_RETURNS( + sort_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , thrust::less< + typename iterator_traits>::value_type + >{} + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace sort_detail + +THRUST_INLINE_CONSTANT sort_detail::sort_fn sort{}; + +/*! \endcond + */ + +} // namespace async + +THRUST_NAMESPACE_END + +#endif + diff --git a/src/other/manifold/include/thrust/async/transform.h b/src/other/manifold/include/thrust/async/transform.h new file mode 100644 index 00000000000..de72549bf01 --- /dev/null +++ b/src/other/manifold/include/thrust/async/transform.h @@ -0,0 +1,138 @@ +/* + * Copyright 2008-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! \file + * \brief Algorithms for asynchronously transforming a range. + */ + +#pragma once + +#include +#include + +#if THRUST_CPP_DIALECT >= 2014 + +#include +#include +#include +#include + +#include + +THRUST_NAMESPACE_BEGIN + +namespace async +{ + +/*! \cond + */ + +namespace unimplemented +{ + +template < + typename DerivedPolicy +, typename ForwardIt, typename Sentinel, typename OutputIt +, typename UnaryOperation +> +__host__ +event +async_transform( + thrust::execution_policy& exec +, ForwardIt first, Sentinel last, OutputIt output, UnaryOperation op +) +{ + THRUST_STATIC_ASSERT_MSG( + (thrust::detail::depend_on_instantiation::value) + , "this algorithm is not implemented for the specified system" + ); + return {}; +} + +} // namespace unimplemented + +namespace transform_detail +{ + +using thrust::async::unimplemented::async_transform; + +struct transform_fn final +{ + template < + typename DerivedPolicy + , typename ForwardIt, typename Sentinel, typename OutputIt + , typename UnaryOperation + > + __host__ + static auto + call( + thrust::detail::execution_policy_base const& exec + , ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , UnaryOperation&& op + ) + // ADL dispatch. + THRUST_RETURNS( + async_transform( + thrust::detail::derived_cast(thrust::detail::strip_const(exec)) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(op) + ) + ) + + template < + typename ForwardIt, typename Sentinel, typename OutputIt + , typename UnaryOperation + > + __host__ + static auto call( + ForwardIt&& first, Sentinel&& last + , OutputIt&& output + , UnaryOperation&& op + ) + THRUST_RETURNS( + transform_fn::call( + thrust::detail::select_system( + typename iterator_system>::type{} + , typename iterator_system>::type{} + ) + , THRUST_FWD(first), THRUST_FWD(last) + , THRUST_FWD(output) + , THRUST_FWD(op) + ) + ) + + template + THRUST_NODISCARD __host__ + auto operator()(Args&&... args) const + THRUST_RETURNS( + call(THRUST_FWD(args)...) + ) +}; + +} // namespace tranform_detail + +THRUST_INLINE_CONSTANT transform_detail::transform_fn transform{}; + +/*! \endcond + */ + +} // namespace async + +THRUST_NAMESPACE_END + +#endif diff --git a/src/other/manifold/include/thrust/binary_search.h b/src/other/manifold/include/thrust/binary_search.h new file mode 100644 index 00000000000..7a4746e0b16 --- /dev/null +++ b/src/other/manifold/include/thrust/binary_search.h @@ -0,0 +1,1899 @@ +/* + * Copyright 2008-2013 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/*! \file binary_search.h + * \brief Search for values in sorted ranges. + */ + +#pragma once + +#include +#include +#include + +THRUST_NAMESPACE_BEGIN + +/*! \addtogroup algorithms + */ + + +/*! \addtogroup searching + * \ingroup algorithms + * \{ + */ + + +/*! \addtogroup binary_search Binary Search + * \ingroup searching + * \{ + */ + + +////////////////////// +// Scalar Functions // +////////////////////// + + +/*! \p lower_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the first position where value could be + * inserted without violating the ordering. This version of + * \p lower_bound uses operator< for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), *j < value. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return The furthermost iterator \c i, such that *i < value. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 0); // returns input.begin() + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 1); // returns input.begin() + 1 + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 2); // returns input.begin() + 1 + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 3); // returns input.begin() + 2 + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 8); // returns input.begin() + 4 + * thrust::lower_bound(thrust::device, input.begin(), input.end(), 9); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +ForwardIterator lower_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const LessThanComparable &value); + + +/*! \p lower_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the first position where value could be + * inserted without violating the ordering. This version of + * \p lower_bound uses operator< for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), *j < value. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return The furthermost iterator \c i, such that *i < value. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::lower_bound(input.begin(), input.end(), 0); // returns input.begin() + * thrust::lower_bound(input.begin(), input.end(), 1); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 2); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 3); // returns input.begin() + 2 + * thrust::lower_bound(input.begin(), input.end(), 8); // returns input.begin() + 4 + * thrust::lower_bound(input.begin(), input.end(), 9); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +ForwardIterator lower_bound(ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p lower_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the first position where value could be + * inserted without violating the ordering. This version of + * \p lower_bound uses function object \c comp for comparison + * and returns the furthermost iterator \c i in [first, last) + * such that, for every iterator \c j in [first, i), + * comp(*j, value) is \c true. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return The furthermost iterator \c i, such that comp(*i, value) is \c true. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::lower_bound(input.begin(), input.end(), 0, thrust::less()); // returns input.begin() + * thrust::lower_bound(input.begin(), input.end(), 1, thrust::less()); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 2, thrust::less()); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 3, thrust::less()); // returns input.begin() + 2 + * thrust::lower_bound(input.begin(), input.end(), 8, thrust::less()); // returns input.begin() + 4 + * thrust::lower_bound(input.begin(), input.end(), 9, thrust::less()); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +ForwardIterator lower_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const T &value, + StrictWeakOrdering comp); + + +/*! \p lower_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the first position where value could be + * inserted without violating the ordering. This version of + * \p lower_bound uses function object \c comp for comparison + * and returns the furthermost iterator \c i in [first, last) + * such that, for every iterator \c j in [first, i), + * comp(*j, value) is \c true. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return The furthermost iterator \c i, such that comp(*i, value) is \c true. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::lower_bound(input.begin(), input.end(), 0, thrust::less()); // returns input.begin() + * thrust::lower_bound(input.begin(), input.end(), 1, thrust::less()); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 2, thrust::less()); // returns input.begin() + 1 + * thrust::lower_bound(input.begin(), input.end(), 3, thrust::less()); // returns input.begin() + 2 + * thrust::lower_bound(input.begin(), input.end(), 8, thrust::less()); // returns input.begin() + 4 + * thrust::lower_bound(input.begin(), input.end(), 9, thrust::less()); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +ForwardIterator lower_bound(ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \p upper_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the last position where value could be + * inserted without violating the ordering. This version of + * \p upper_bound uses operator< for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), value < *j + * is \c false. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return The furthermost iterator \c i, such that value < *i is \c false. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for values in a ordered range using the \p thrust::device execution policy for parallelism: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 0); // returns input.begin() + 1 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 1); // returns input.begin() + 1 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 2); // returns input.begin() + 2 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 3); // returns input.begin() + 2 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 8); // returns input.end() + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 9); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +ForwardIterator upper_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const LessThanComparable &value); + + +/*! \p upper_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the last position where value could be + * inserted without violating the ordering. This version of + * \p upper_bound uses operator< for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), value < *j + * is \c false. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return The furthermost iterator \c i, such that value < *i is \c false. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::upper_bound(input.begin(), input.end(), 0); // returns input.begin() + 1 + * thrust::upper_bound(input.begin(), input.end(), 1); // returns input.begin() + 1 + * thrust::upper_bound(input.begin(), input.end(), 2); // returns input.begin() + 2 + * thrust::upper_bound(input.begin(), input.end(), 3); // returns input.begin() + 2 + * thrust::upper_bound(input.begin(), input.end(), 8); // returns input.end() + * thrust::upper_bound(input.begin(), input.end(), 9); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +ForwardIterator upper_bound(ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p upper_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the last position where value could be + * inserted without violating the ordering. This version of + * \p upper_bound uses function object \c comp for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), comp(value, *j) + * is \c false. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return The furthermost iterator \c i, such that comp(value, *i) is \c false. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 0, thrust::less()); // returns input.begin() + 1 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 1, thrust::less()); // returns input.begin() + 1 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 2, thrust::less()); // returns input.begin() + 2 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 3, thrust::less()); // returns input.begin() + 2 + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 8, thrust::less()); // returns input.end() + * thrust::upper_bound(thrust::device, input.begin(), input.end(), 9, thrust::less()); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +ForwardIterator upper_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const T &value, + StrictWeakOrdering comp); + +/*! \p upper_bound is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * Specifically, it returns the last position where value could be + * inserted without violating the ordering. This version of + * \p upper_bound uses function object \c comp for comparison and returns + * the furthermost iterator \c i in [first, last) such that, + * for every iterator \c j in [first, i), comp(value, *j) + * is \c false. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return The furthermost iterator \c i, such that comp(value, *i) is \c false. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::upper_bound(input.begin(), input.end(), 0, thrust::less()); // returns input.begin() + 1 + * thrust::upper_bound(input.begin(), input.end(), 1, thrust::less()); // returns input.begin() + 1 + * thrust::upper_bound(input.begin(), input.end(), 2, thrust::less()); // returns input.begin() + 2 + * thrust::upper_bound(input.begin(), input.end(), 3, thrust::less()); // returns input.begin() + 2 + * thrust::upper_bound(input.begin(), input.end(), 8, thrust::less()); // returns input.end() + * thrust::upper_bound(input.begin(), input.end(), 9, thrust::less()); // returns input.end() + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +ForwardIterator upper_bound(ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \p binary_search is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. Specifically, this version returns \c true if and only if + * there exists an iterator \c i in [first, last) such that + * *i < value and value < *i are both \c false. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return \c true if an equivalent element exists in [first, last), otherwise \c false. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::binary_search(thrust::device, input.begin(), input.end(), 0); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 1); // returns false + * thrust::binary_search(thrust::device, input.begin(), input.end(), 2); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 3); // returns false + * thrust::binary_search(thrust::device, input.begin(), input.end(), 8); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 9); // returns false + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +__host__ __device__ +bool binary_search(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p binary_search is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. Specifically, this version returns \c true if and only if + * there exists an iterator \c i in [first, last) such that + * *i < value and value < *i are both \c false. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return \c true if an equivalent element exists in [first, last), otherwise \c false. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::binary_search(input.begin(), input.end(), 0); // returns true + * thrust::binary_search(input.begin(), input.end(), 1); // returns false + * thrust::binary_search(input.begin(), input.end(), 2); // returns true + * thrust::binary_search(input.begin(), input.end(), 3); // returns false + * thrust::binary_search(input.begin(), input.end(), 8); // returns true + * thrust::binary_search(input.begin(), input.end(), 9); // returns false + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +bool binary_search(ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p binary_search is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. Specifically, this version returns \c true if and only if + * there exists an iterator \c i in [first, last) such that + * comp(*i, value) and comp(value, *i) are both \c false. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return \c true if an equivalent element exists in [first, last), otherwise \c false. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::binary_search(thrust::device, input.begin(), input.end(), 0, thrust::less()); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 1, thrust::less()); // returns false + * thrust::binary_search(thrust::device, input.begin(), input.end(), 2, thrust::less()); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 3, thrust::less()); // returns false + * thrust::binary_search(thrust::device, input.begin(), input.end(), 8, thrust::less()); // returns true + * thrust::binary_search(thrust::device, input.begin(), input.end(), 9, thrust::less()); // returns false + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +__host__ __device__ +bool binary_search(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \p binary_search is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. Specifically, this version returns \c true if and only if + * there exists an iterator \c i in [first, last) such that + * comp(*i, value) and comp(value, *i) are both \c false. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return \c true if an equivalent element exists in [first, last), otherwise \c false. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::binary_search(input.begin(), input.end(), 0, thrust::less()); // returns true + * thrust::binary_search(input.begin(), input.end(), 1, thrust::less()); // returns false + * thrust::binary_search(input.begin(), input.end(), 2, thrust::less()); // returns true + * thrust::binary_search(input.begin(), input.end(), 3, thrust::less()); // returns false + * thrust::binary_search(input.begin(), input.end(), 8, thrust::less()); // returns true + * thrust::binary_search(input.begin(), input.end(), 9, thrust::less()); // returns false + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +bool binary_search(ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \p equal_range is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). The + * value returned by \p equal_range is essentially a combination of + * the values returned by \p lower_bound and \p upper_bound: it returns + * a \p pair of iterators \c i and \c j such that \c i is the first + * position where value could be inserted without violating the + * ordering and \c j is the last position where value could be inserted + * without violating the ordering. It follows that every element in the + * range [i, j) is equivalent to value, and that + * [i, j) is the largest subrange of [first, last) that + * has this property. + * + * This version of \p equal_range returns a \p pair of iterators + * [i, j), where \c i is the furthermost iterator in + * [first, last) such that, for every iterator \c k in + * [first, i), *k < value. \c j is the furthermost + * iterator in [first, last) such that, for every iterator + * \c k in [first, j), value < *k is \c false. + * For every iterator \c k in [i, j), neither + * value < *k nor *k < value is \c true. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return A \p pair of iterators [i, j) that define the range of equivalent elements. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p equal_range + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::equal_range(thrust::device, input.begin(), input.end(), 0); // returns [input.begin(), input.begin() + 1) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 1); // returns [input.begin() + 1, input.begin() + 1) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 2); // returns [input.begin() + 1, input.begin() + 2) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 3); // returns [input.begin() + 2, input.begin() + 2) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 8); // returns [input.begin() + 4, input.end) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 9); // returns [input.end(), input.end) + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/equal_range + * \see \p lower_bound + * \see \p upper_bound + * \see \p binary_search + */ +template +__host__ __device__ +thrust::pair +equal_range(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p equal_range is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). The + * value returned by \p equal_range is essentially a combination of + * the values returned by \p lower_bound and \p upper_bound: it returns + * a \p pair of iterators \c i and \c j such that \c i is the first + * position where value could be inserted without violating the + * ordering and \c j is the last position where value could be inserted + * without violating the ordering. It follows that every element in the + * range [i, j) is equivalent to value, and that + * [i, j) is the largest subrange of [first, last) that + * has this property. + * + * This version of \p equal_range returns a \p pair of iterators + * [i, j), where \c i is the furthermost iterator in + * [first, last) such that, for every iterator \c k in + * [first, i), *k < value. \c j is the furthermost + * iterator in [first, last) such that, for every iterator + * \c k in [first, j), value < *k is \c false. + * For every iterator \c k in [i, j), neither + * value < *k nor *k < value is \c true. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \return A \p pair of iterators [i, j) that define the range of equivalent elements. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam LessThanComparable is a model of LessThanComparable. + * + * The following code snippet demonstrates how to use \p equal_range + * to search for values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::equal_range(input.begin(), input.end(), 0); // returns [input.begin(), input.begin() + 1) + * thrust::equal_range(input.begin(), input.end(), 1); // returns [input.begin() + 1, input.begin() + 1) + * thrust::equal_range(input.begin(), input.end(), 2); // returns [input.begin() + 1, input.begin() + 2) + * thrust::equal_range(input.begin(), input.end(), 3); // returns [input.begin() + 2, input.begin() + 2) + * thrust::equal_range(input.begin(), input.end(), 8); // returns [input.begin() + 4, input.end) + * thrust::equal_range(input.begin(), input.end(), 9); // returns [input.end(), input.end) + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/equal_range + * \see \p lower_bound + * \see \p upper_bound + * \see \p binary_search + */ +template +thrust::pair +equal_range(ForwardIterator first, + ForwardIterator last, + const LessThanComparable& value); + + +/*! \p equal_range is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). The + * value returned by \p equal_range is essentially a combination of + * the values returned by \p lower_bound and \p upper_bound: it returns + * a \p pair of iterators \c i and \c j such that \c i is the first + * position where value could be inserted without violating the + * ordering and \c j is the last position where value could be inserted + * without violating the ordering. It follows that every element in the + * range [i, j) is equivalent to value, and that + * [i, j) is the largest subrange of [first, last) that + * has this property. + * + * This version of \p equal_range returns a \p pair of iterators + * [i, j). \c i is the furthermost iterator in + * [first, last) such that, for every iterator \c k in + * [first, i), comp(*k, value) is \c true. + * \c j is the furthermost iterator in [first, last) such + * that, for every iterator \c k in [first, last), + * comp(value, *k) is \c false. For every iterator \c k + * in [i, j), neither comp(value, *k) nor + * comp(*k, value) is \c true. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return A \p pair of iterators [i, j) that define the range of equivalent elements. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p equal_range + * to search for values in a ordered range using the \p thrust::device execution policy for parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::equal_range(thrust::device, input.begin(), input.end(), 0, thrust::less()); // returns [input.begin(), input.begin() + 1) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 1, thrust::less()); // returns [input.begin() + 1, input.begin() + 1) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 2, thrust::less()); // returns [input.begin() + 1, input.begin() + 2) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 3, thrust::less()); // returns [input.begin() + 2, input.begin() + 2) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 8, thrust::less()); // returns [input.begin() + 4, input.end) + * thrust::equal_range(thrust::device, input.begin(), input.end(), 9, thrust::less()); // returns [input.end(), input.end) + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/equal_range + * \see \p lower_bound + * \see \p upper_bound + * \see \p binary_search + */ +template +__host__ __device__ +thrust::pair +equal_range(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \p equal_range is a version of binary search: it attempts to find + * the element value in an ordered range [first, last). The + * value returned by \p equal_range is essentially a combination of + * the values returned by \p lower_bound and \p upper_bound: it returns + * a \p pair of iterators \c i and \c j such that \c i is the first + * position where value could be inserted without violating the + * ordering and \c j is the last position where value could be inserted + * without violating the ordering. It follows that every element in the + * range [i, j) is equivalent to value, and that + * [i, j) is the largest subrange of [first, last) that + * has this property. + * + * This version of \p equal_range returns a \p pair of iterators + * [i, j). \c i is the furthermost iterator in + * [first, last) such that, for every iterator \c k in + * [first, i), comp(*k, value) is \c true. + * \c j is the furthermost iterator in [first, last) such + * that, for every iterator \c k in [first, last), + * comp(value, *k) is \c false. For every iterator \c k + * in [i, j), neither comp(value, *k) nor + * comp(*k, value) is \c true. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param value The value to be searched. + * \param comp The comparison operator. + * \return A \p pair of iterators [i, j) that define the range of equivalent elements. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam T is comparable to \p ForwardIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * The following code snippet demonstrates how to use \p equal_range + * to search for values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::equal_range(input.begin(), input.end(), 0, thrust::less()); // returns [input.begin(), input.begin() + 1) + * thrust::equal_range(input.begin(), input.end(), 1, thrust::less()); // returns [input.begin() + 1, input.begin() + 1) + * thrust::equal_range(input.begin(), input.end(), 2, thrust::less()); // returns [input.begin() + 1, input.begin() + 2) + * thrust::equal_range(input.begin(), input.end(), 3, thrust::less()); // returns [input.begin() + 2, input.begin() + 2) + * thrust::equal_range(input.begin(), input.end(), 8, thrust::less()); // returns [input.begin() + 4, input.end) + * thrust::equal_range(input.begin(), input.end(), 9, thrust::less()); // returns [input.end(), input.end) + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/equal_range + * \see \p lower_bound + * \see \p upper_bound + * \see \p binary_search + */ +template +thrust::pair +equal_range(ForwardIterator first, + ForwardIterator last, + const T& value, + StrictWeakOrdering comp); + + +/*! \addtogroup vectorized_binary_search Vectorized Searches + * \ingroup binary_search + * \{ + */ + + +////////////////////// +// Vector Functions // +////////////////////// + + +/*! \p lower_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for multiple values in a ordered range using the \p thrust::device execution policy for + * parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::lower_bound(thrust::device, + * input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [0, 1, 1, 2, 4, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +OutputIterator lower_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p lower_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::lower_bound(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [0, 1, 1, 2, 4, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +OutputIterator lower_bound(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p lower_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. This version of + * \p lower_bound uses function object \c comp for comparison. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is comparable to \p ForwardIterator's \c value_type. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::lower_bound(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [0, 1, 1, 2, 4, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +OutputIterator lower_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \p lower_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. This version of + * \p lower_bound uses function object \c comp for comparison. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is comparable to \p ForwardIterator's \c value_type. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p lower_bound + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::lower_bound(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [0, 1, 1, 2, 4, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/lower_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +OutputIterator lower_bound(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \p upper_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of last position where value could + * be inserted without violating the ordering. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for multiple values in a ordered range using the \p thrust::device execution policy for + * parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::upper_bound(thrust::device, + * input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [1, 1, 2, 2, 5, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +OutputIterator upper_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p upper_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of last position where value could + * be inserted without violating the ordering. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::upper_bound(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [1, 1, 2, 2, 5, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p upper_bound + * \see \p equal_range + * \see \p binary_search + */ +template +OutputIterator upper_bound(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p upper_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. This version of + * \p upper_bound uses function object \c comp for comparison. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is comparable to \p ForwardIterator's \c value_type. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for multiple values in a ordered range using the \p thrust::device execution policy for + * parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::upper_bound(thrust::device, + * input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [1, 1, 2, 2, 5, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +__host__ __device__ +OutputIterator upper_bound(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \p upper_bound is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * Specifically, it returns the index of first position where value could + * be inserted without violating the ordering. This version of + * \p upper_bound uses function object \c comp for comparison. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is comparable to \p ForwardIterator's \c value_type. + * \tparam OutputIterator is a model of Output Iterator. + * and \c ForwardIterator's difference_type is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p upper_bound + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::upper_bound(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [1, 1, 2, 2, 5, 5] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/upper_bound + * \see \p lower_bound + * \see \p equal_range + * \see \p binary_search + */ +template +OutputIterator upper_bound(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \p binary_search is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and bool is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for multiple values in a ordered range using the \p thrust::device execution policy for + * parallelization: + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::binary_search(thrust::device, + * input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [true, false, true, false, true, false] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +__host__ __device__ +OutputIterator binary_search(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p binary_search is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and bool is convertible to \c OutputIterator's \c value_type. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::binary_search(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin()); + * + * // output is now [true, false, true, false, true, false] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +OutputIterator binary_search(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result); + + +/*! \p binary_search is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. This version of \p binary_search uses function object + * \c comp for comparison. + * + * The algorithm's execution is parallelized as determined by \p exec. + * + * \param exec The execution policy to use for parallelization. + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam DerivedPolicy The name of the derived execution policy. + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and bool is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for multiple values in a ordered range using the \p thrust::device execution policy for + * parallelization: + * + * \code + * #include + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::binary_search(thrust::device, + * input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [true, false, true, false, true, false] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +__host__ __device__ +OutputIterator binary_search(const thrust::detail::execution_policy_base &exec, + ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \p binary_search is a vectorized version of binary search: for each + * iterator \c v in [values_first, values_last) it attempts to + * find the value *v in an ordered range [first, last). + * It returns \c true if an element that is equivalent to \c value + * is present in [first, last) and \c false if no such element + * exists. This version of \p binary_search uses function object + * \c comp for comparison. + * + * \param first The beginning of the ordered sequence. + * \param last The end of the ordered sequence. + * \param values_first The beginning of the search values sequence. + * \param values_last The end of the search values sequence. + * \param result The beginning of the output sequence. + * \param comp The comparison operator. + * + * \tparam ForwardIterator is a model of Forward Iterator. + * \tparam InputIterator is a model of Input Iterator. + * and \c InputIterator's \c value_type is LessThanComparable. + * \tparam OutputIterator is a model of Output Iterator. + * and bool is convertible to \c OutputIterator's \c value_type. + * \tparam StrictWeakOrdering is a model of Strict Weak Ordering. + * + * \pre The ranges [first,last) and [result, result + (last - first)) shall not overlap. + * + * The following code snippet demonstrates how to use \p binary_search + * to search for multiple values in a ordered range. + * + * \code + * #include + * #include + * #include + * ... + * thrust::device_vector input(5); + * + * input[0] = 0; + * input[1] = 2; + * input[2] = 5; + * input[3] = 7; + * input[4] = 8; + * + * thrust::device_vector values(6); + * values[0] = 0; + * values[1] = 1; + * values[2] = 2; + * values[3] = 3; + * values[4] = 8; + * values[5] = 9; + * + * thrust::device_vector output(6); + * + * thrust::binary_search(input.begin(), input.end(), + * values.begin(), values.end(), + * output.begin(), + * thrust::less()); + * + * // output is now [true, false, true, false, true, false] + * \endcode + * + * \see https://en.cppreference.com/w/cpp/algorithm/binary_search + * \see \p lower_bound + * \see \p upper_bound + * \see \p equal_range + */ +template +OutputIterator binary_search(ForwardIterator first, + ForwardIterator last, + InputIterator values_first, + InputIterator values_last, + OutputIterator result, + StrictWeakOrdering comp); + + +/*! \} // end vectorized_binary_search + */ + + +/*! \} // end binary_search + */ + + +/*! \} // end searching + */ + +THRUST_NAMESPACE_END + +#include + diff --git a/src/other/manifold/include/thrust/cmake/FindTBB.cmake b/src/other/manifold/include/thrust/cmake/FindTBB.cmake new file mode 100644 index 00000000000..01e53d5e746 --- /dev/null +++ b/src/other/manifold/include/thrust/cmake/FindTBB.cmake @@ -0,0 +1,446 @@ +# - Find ThreadingBuildingBlocks include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(TBB +# [REQUIRED] # Fail with error if TBB is not found +# ) # +# Once done, this will define +# +# TBB_FOUND - system has TBB +# TBB_INCLUDE_DIRS - the TBB include directories +# TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or +# malloc proxy +# TBB::tbb - imported target for the TBB library +# +# TBB_VERSION - Product Version Number ("MAJOR.MINOR") +# TBB_VERSION_MAJOR - Major Product Version Number +# TBB_VERSION_MINOR - Minor Product Version Number +# TBB_INTERFACE_VERSION - Engineering Focused Version Number +# TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version +# still supported. This uses the engineering +# focused interface version numbers. +# +# TBB_MALLOC_FOUND - system has TBB malloc library +# TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories +# TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined +# TBB::malloc - imported target for the TBB malloc library +# +# TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library +# TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories +# TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined +# TBB::malloc_proxy - imported target for the TBB malloc proxy library +# +# +# This module reads hints about search locations from variables: +# ENV TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds +# ENV TBB_ROOT or just TBB_ROOT - root directory of tbb installation +# ENV TBB_BUILD_PREFIX - specifies the build prefix for user built tbb +# libraries. Should be specified with ENV TBB_ROOT +# and optionally... +# ENV TBB_BUILD_DIR - if build directory is different than ${TBB_ROOT}/build +# +# +# Modified by Robert Maynard from the original OGRE source +# +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- +# +#============================================================================= +# Copyright 2010-2012 Kitware, Inc. +# Copyright 2012 Rolf Eike Beer +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +#============================================================================= +# FindTBB helper functions and macros +# + +#==================================================== +# Fix the library path in case it is a linker script +#==================================================== +function(tbb_extract_real_library library real_library) + if(NOT UNIX OR NOT EXISTS ${library}) + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + #Read in the first 4 bytes and see if they are the ELF magic number + set(_elf_magic "7f454c46") + file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX) + if(_hex_data STREQUAL _elf_magic) + #we have opened a elf binary so this is what + #we should link to + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + file(READ ${library} _data OFFSET 0 LIMIT 1024) + if("${_data}" MATCHES "INPUT \\(([^(]+)\\)") + #extract out the .so name from REGEX MATCH command + set(_proper_so_name "${CMAKE_MATCH_1}") + + #construct path to the real .so which is presumed to be in the same directory + #as the input file + get_filename_component(_so_dir "${library}" DIRECTORY) + set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE) + else() + #unable to determine what this library is so just hope everything works + #and pass it unmodified. + set(${real_library} "${library}" PARENT_SCOPE) + endif() +endfunction() + +#=============================================== +# Do the final processing for the package find. +#=============================================== +macro(findpkg_finish PREFIX TARGET_NAME) + if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) + set(${PREFIX}_FOUND TRUE) + set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) + set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) + else () + if (${PREFIX}_FIND_REQUIRED) + message(FATAL_ERROR "Required library ${PREFIX} not found.") + elseif (NOT ${PREFIX}_FIND_QUIETLY) + message("Library ${PREFIX} not found.") + endif() + return() + endif () + + if (NOT TARGET "TBB::${TARGET_NAME}") + if (${PREFIX}_LIBRARY_RELEASE) + tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release) + endif () + if (${PREFIX}_LIBRARY_DEBUG) + tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug) + endif () + add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}") + if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}" + IMPORTED_LOCATION_DEBUG "${real_debug}" + IMPORTED_LOCATION_RELEASE "${real_release}") + elseif (${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}") + elseif (${PREFIX}_LIBRARY_DEBUG) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_debug}") + endif () + endif () + + #mark the following variables as internal variables + mark_as_advanced(${PREFIX}_INCLUDE_DIR + ${PREFIX}_LIBRARY + ${PREFIX}_LIBRARY_DEBUG + ${PREFIX}_LIBRARY_RELEASE) +endmacro() + +#=============================================== +# Generate debug names from given release names +#=============================================== +macro(get_debug_names PREFIX) + foreach(i ${${PREFIX}}) + set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i}) + endforeach() +endmacro() + +#=============================================== +# See if we have env vars to help us find tbb +#=============================================== +macro(getenv_path VAR) + set(ENV_${VAR} $ENV{${VAR}}) + # replace won't work if var is blank + if (ENV_${VAR}) + string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} ) + endif () +endmacro() + +#=============================================== +# Couple a set of release AND debug libraries +#=============================================== +macro(make_library_set PREFIX) + if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG) + set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG}) + elseif (${PREFIX}_RELEASE) + set(${PREFIX} ${${PREFIX}_RELEASE}) + elseif (${PREFIX}_DEBUG) + set(${PREFIX} ${${PREFIX}_DEBUG}) + endif () +endmacro() + + +#============================================================================= +# Now to actually find TBB +# + +# Get path, convert backslashes as ${ENV_${var}} +getenv_path(TBB_ROOT) + +# initialize search paths +set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT}) +set(TBB_INC_SEARCH_PATH "") +set(TBB_LIB_SEARCH_PATH "") + + +# If user built from sources +set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX}) +if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT) + getenv_path(TBB_BUILD_DIR) + if (NOT ENV_TBB_BUILD_DIR) + set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build) + endif () + + # include directory under ${ENV_TBB_ROOT}/include + list(APPEND TBB_LIB_SEARCH_PATH + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug) +endif () + + +# For Windows, let's assume that the user might be using the precompiled +# TBB packages from the main website. These use a rather awkward directory +# structure (at least for automatically finding the right files) depending +# on platform and compiler, but we'll do our best to accommodate it. +# Not adding the same effort for the precompiled linux builds, though. Those +# have different versions for CC compiler versions and linux kernels which +# will never adequately match the user's setup, so there is no feasible way +# to detect the "best" version to use. The user will have to manually +# select the right files. (Chances are the distributions are shipping their +# custom version of tbb, anyway, so the problem is probably nonexistent.) +if (WIN32 AND MSVC) + set(COMPILER_PREFIX "vc7.1") + if (MSVC_VERSION EQUAL 1400) + set(COMPILER_PREFIX "vc8") + elseif(MSVC_VERSION EQUAL 1500) + set(COMPILER_PREFIX "vc9") + elseif(MSVC_VERSION EQUAL 1600) + set(COMPILER_PREFIX "vc10") + elseif(MSVC_VERSION EQUAL 1700) + set(COMPILER_PREFIX "vc11") + elseif(MSVC_VERSION EQUAL 1800) + set(COMPILER_PREFIX "vc12") + elseif(MSVC_VERSION GREATER_EQUAL 1900 AND MSVC_VERSION LESS_EQUAL 1939) + # 1900-1925 actually spans three Visual Studio versions: + # 1900 = VS 14.0 (v140 toolset) a.k.a. MSVC 2015 + # 1910-1919 = VS 15.0 (v141 toolset) a.k.a. MSVC 2017 + # 1920-1929 = VS 16.0 (v142 toolset) a.k.a. MSVC 2019 + # 1930-1939 = VS 17.0 (v143 toolset) a.k.a. MSVC 2022 + # + # But these are binary compatible and TBB's open source distribution only + # ships a single vs14 lib (as of 2020.0) + set(COMPILER_PREFIX "vc14") + else() + # The next poor soul who finds themselves having to decode visual studio + # version conventions may find these helpful: + # - https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html + # - https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering + message(AUTHOR_WARNING + "Unrecognized MSVC version (${MSVC_VERSION}). " + "Please update FindTBB.cmake. " + "Some TBB_* CMake variables may need to be set manually." + ) + endif () + + # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path + foreach (dir IN LISTS TBB_PREFIX_PATH) + if (CMAKE_CL_64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX}) + else () + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX}) + endif () + endforeach () +endif () + +# For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9) +# and above and AppleClang +if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND + NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0) + set (USE_LIBCXX OFF) + cmake_policy(GET CMP0025 POLICY_VAR) + + if (POLICY_VAR STREQUAL "NEW") + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set (USE_LIBCXX ON) + endif () + else () + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set (USE_LIBCXX ON) + endif () + endif () + + if (USE_LIBCXX) + foreach (dir IN LISTS TBB_PREFIX_PATH) + list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib) + endforeach () + endif () +endif () + +# check compiler ABI +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(COMPILER_PREFIX) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + list(APPEND COMPILER_PREFIX "gcc4.4") + endif() + list(APPEND COMPILER_PREFIX "gcc4.1") +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(COMPILER_PREFIX) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + list(APPEND COMPILER_PREFIX "gcc4.4") +else() # Assume compatibility with 4.4 for other compilers + list(APPEND COMPILER_PREFIX "gcc4.4") +endif () + +# if platform architecture is explicitly specified +set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM}) +if (TBB_ARCH_PLATFORM) + foreach (dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM}) + endforeach () +endif () + +foreach (dir IN LISTS TBB_PREFIX_PATH) + foreach (prefix IN LISTS COMPILER_PREFIX) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib) + else () + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib) + endif () + endforeach() +endforeach () + +# add general search paths +foreach (dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb + ${dir}/Libs) + list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include + ${dir}/include/tbb) +endforeach () + +set(TBB_LIBRARY_NAMES tbb) +get_debug_names(TBB_LIBRARY_NAMES) + +find_path(TBB_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_LIBRARY_RELEASE + NAMES ${TBB_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_LIBRARY_DEBUG + NAMES ${TBB_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_LIBRARY) + +findpkg_finish(TBB tbb) + +#if we haven't found TBB no point on going any further +if (NOT TBB_FOUND) + return() +endif () + +#============================================================================= +# Look for TBB's malloc package +set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc) +get_debug_names(TBB_MALLOC_LIBRARY_NAMES) + +find_path(TBB_MALLOC_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_MALLOC_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_MALLOC_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_MALLOC_LIBRARY) + +findpkg_finish(TBB_MALLOC tbbmalloc) + +#============================================================================= +# Look for TBB's malloc proxy package +set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy) +get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES) + +find_path(TBB_MALLOC_PROXY_INCLUDE_DIR + NAMES tbb/tbbmalloc_proxy.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_MALLOC_PROXY_LIBRARY) + +findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy) + + +#============================================================================= +# Parse all the version numbers from tbb. +if(NOT TBB_VERSION) + if(EXISTS "${TBB_INCLUDE_DIR}/tbb/version.h") + # The newer oneTBB provides tbb/version.h but no tbb/tbb_stddef.h. + set(version_file "${TBB_INCLUDE_DIR}/tbb/version.h") + else() + # Older TBB provides tbb/tbb_stddef.h but no tbb/version.h. + set(version_file "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h") + endif() + + file(STRINGS + "${version_file}" + TBB_VERSION_CONTENTS + REGEX "VERSION") + + string(REGEX REPLACE + ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" + TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" + TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") + + set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}") +endif() diff --git a/src/other/manifold/include/thrust/cmake/README.md b/src/other/manifold/include/thrust/cmake/README.md new file mode 100644 index 00000000000..ae296b635b5 --- /dev/null +++ b/src/other/manifold/include/thrust/cmake/README.md @@ -0,0 +1,226 @@ +# Using Thrust with CMake + +Thrust provides configuration files that simplify using Thrust +from other CMake projects. Requirements: + +- Thrust >= 1.9.10 +- CMake >= 3.15 + +See the [Fixing Legacy FindThrust.cmake](#fixing-legacy-findthrustcmake) +section for solutions that work on older Thrust versions. + +## User Guide + +#### Default Configuration (CUDA) + +Thrust is configured using a `thrust_create_target` CMake function that +assembles a complete interface to the Thrust library: + +```cmake +find_package(Thrust REQUIRED CONFIG) +thrust_create_target(Thrust) +target_link_libraries(MyProgram Thrust) +``` + +The first argument is the name of the interface target to create, and any +additional options will be used to configure the target. By default, +`thrust_create_target` will configure its result to use CUDA acceleration. + +If desired, `thrust_create_target` may be called multiple times to build +several unique Thrust interface targets with different configurations, as +detailed below. + +**Note:** If CMake is unable to locate Thrust, specify the path to Thrust's CMake +configuration directory (where this README file is located) as `Thrust_DIR`. +If cloning Thrust from github, this would be + +``` +$ cmake . -DThrust_DIR=/thrust/cmake/ +``` + +#### TBB / OpenMP + +To explicitly specify host/device systems, `HOST` and `DEVICE` arguments can be +passed to `thrust_create_target`. If an explicit system is not specified, the +target will default to using CPP for host and/or CUDA for device. + +```cmake +thrust_create_target(ThrustTBB DEVICE TBB) +thrust_create_target(ThrustOMP HOST CPP DEVICE OMP) +``` + +will create targets `ThrustTBB` and `ThrustOMP`. Both will use the serial `CPP` +host system, but will find and use TBB or OpenMP for the device system. + +#### Configure Target from Cache Options + +To allow a Thrust target to be configurable easily via `cmake-gui` or +`ccmake`, pass the `FROM_OPTIONS` flag to `thrust_create_target`. This will add +`THRUST_HOST_SYSTEM` and `THRUST_DEVICE_SYSTEM` options to the CMake cache that +allow selection from the systems supported by this version of Thrust. + +```cmake +thrust_create_target(Thrust FROM_OPTIONS + [HOST_OPTION