Revert "BLI: Refactor vector types & functions to use templates"
Includes unwanted changes
This reverts commit 46e049d0ce.
			
			
This commit is contained in:
		@@ -559,12 +559,14 @@ if(WIN32)
 | 
				
			|||||||
  set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${})
 | 
					  set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compiler toolchain
 | 
					# Compiler tool-chain.
 | 
				
			||||||
if(CMAKE_COMPILER_IS_GNUCC)
 | 
					if(UNIX AND NOT APPLE)
 | 
				
			||||||
 | 
					  if(CMAKE_COMPILER_IS_GNUCC)
 | 
				
			||||||
    option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON)
 | 
					    option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON)
 | 
				
			||||||
    mark_as_advanced(WITH_LINKER_GOLD)
 | 
					    mark_as_advanced(WITH_LINKER_GOLD)
 | 
				
			||||||
    option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
 | 
					    option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
 | 
				
			||||||
    mark_as_advanced(WITH_LINKER_LLD)
 | 
					    mark_as_advanced(WITH_LINKER_LLD)
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
 | 
					option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,13 +38,6 @@ elseif(UNIX AND NOT APPLE)
 | 
				
			|||||||
  )
 | 
					  )
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(BLENDER_PLATFORM_ARM)
 | 
					 | 
				
			||||||
  set(GMP_OPTIONS
 | 
					 | 
				
			||||||
    ${GMP_OPTIONS}
 | 
					 | 
				
			||||||
    --disable-assembly
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ExternalProject_Add(external_gmp
 | 
					ExternalProject_Add(external_gmp
 | 
				
			||||||
  URL file://${PACKAGE_DIR}/${GMP_FILE}
 | 
					  URL file://${PACKAGE_DIR}/${GMP_FILE}
 | 
				
			||||||
  DOWNLOAD_DIR ${DOWNLOAD_DIR}
 | 
					  DOWNLOAD_DIR ${DOWNLOAD_DIR}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -474,9 +474,9 @@ set(ISPC_HASH 2e3abedbc0ea9aaec17d6562c632454d)
 | 
				
			|||||||
set(ISPC_HASH_TYPE MD5)
 | 
					set(ISPC_HASH_TYPE MD5)
 | 
				
			||||||
set(ISPC_FILE ispc-${ISPC_VERSION}.tar.gz)
 | 
					set(ISPC_FILE ispc-${ISPC_VERSION}.tar.gz)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(GMP_VERSION 6.2.0)
 | 
					set(GMP_VERSION 6.2.1)
 | 
				
			||||||
set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
 | 
					set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
 | 
				
			||||||
set(GMP_HASH a325e3f09e6d91e62101e59f9bda3ec1)
 | 
					set(GMP_HASH 0b82665c4a92fd2ade7440c13fcaa42b)
 | 
				
			||||||
set(GMP_HASH_TYPE MD5)
 | 
					set(GMP_HASH_TYPE MD5)
 | 
				
			||||||
set(GMP_FILE gmp-${GMP_VERSION}.tar.xz)
 | 
					set(GMP_FILE gmp-${GMP_VERSION}.tar.xz)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1292,29 +1292,6 @@ macro(openmp_delayload
 | 
				
			|||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
endmacro()
 | 
					endmacro()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro(blender_precompile_headers target cpp header)
 | 
					 | 
				
			||||||
  if(MSVC)
 | 
					 | 
				
			||||||
    # get the name for the pch output file
 | 
					 | 
				
			||||||
    get_filename_component(pchbase ${cpp} NAME_WE)
 | 
					 | 
				
			||||||
    set(pchfinal "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${pchbase}.pch")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # mark the cpp as the one outputting the pch
 | 
					 | 
				
			||||||
    set_property(SOURCE ${cpp} APPEND PROPERTY OBJECT_OUTPUTS "${pchfinal}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # get all sources for the target
 | 
					 | 
				
			||||||
    get_target_property(sources ${target} SOURCES)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # make all sources depend on the pch to enforce the build order
 | 
					 | 
				
			||||||
    foreach(src ${sources})
 | 
					 | 
				
			||||||
      set_property(SOURCE ${src} APPEND PROPERTY OBJECT_DEPENDS "${pchfinal}")
 | 
					 | 
				
			||||||
    endforeach()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    target_sources(${target} PRIVATE ${cpp} ${header})
 | 
					 | 
				
			||||||
    set_target_properties(${target} PROPERTIES COMPILE_FLAGS "/Yu${header} /Fp${pchfinal} /FI${header}")
 | 
					 | 
				
			||||||
    set_source_files_properties(${cpp} PROPERTIES COMPILE_FLAGS "/Yc${header} /Fp${pchfinal}")
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
endmacro()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro(set_and_warn_dependency
 | 
					macro(set_and_warn_dependency
 | 
				
			||||||
  _dependency _setting _val)
 | 
					  _dependency _setting _val)
 | 
				
			||||||
  # when $_dependency is disabled, forces $_setting = $_val
 | 
					  # when $_dependency is disabled, forces $_setting = $_val
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
# All rights reserved.
 | 
					# All rights reserved.
 | 
				
			||||||
# ***** END GPL LICENSE BLOCK *****
 | 
					# ***** END GPL LICENSE BLOCK *****
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Libraries configuration for any *nix system including Linux and Unix.
 | 
					# Libraries configuration for any *nix system including Linux and Unix (excluding APPLE).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Detect precompiled library directory
 | 
					# Detect precompiled library directory
 | 
				
			||||||
if(NOT DEFINED LIBDIR)
 | 
					if(NOT DEFINED LIBDIR)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								extern/hipew/src/hipew.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								extern/hipew/src/hipew.c
									
									
									
									
										vendored
									
									
								
							@@ -257,7 +257,7 @@ static int hipewHipInit(void) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
  static int initialized = 0;
 | 
					  static int initialized = 0;
 | 
				
			||||||
  static int result = 0;
 | 
					  static int result = 0;
 | 
				
			||||||
  int error, driver_version;
 | 
					  int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (initialized) {
 | 
					  if (initialized) {
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
@@ -565,8 +565,6 @@ int hipewCompilerVersion(void) {
 | 
				
			|||||||
  const char *path = hipewCompilerPath();
 | 
					  const char *path = hipewCompilerPath();
 | 
				
			||||||
  const char *marker = "Hip compilation tools, release ";
 | 
					  const char *marker = "Hip compilation tools, release ";
 | 
				
			||||||
  FILE *pipe;
 | 
					  FILE *pipe;
 | 
				
			||||||
  int major, minor;
 | 
					 | 
				
			||||||
  char *versionstr;
 | 
					 | 
				
			||||||
  char buf[128];
 | 
					  char buf[128];
 | 
				
			||||||
  char output[65536] = "\0";
 | 
					  char output[65536] = "\0";
 | 
				
			||||||
  char command[65536] = "\0";
 | 
					  char command[65536] = "\0";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -496,8 +496,6 @@ typedef struct {
 | 
				
			|||||||
  int target_start;
 | 
					  int target_start;
 | 
				
			||||||
  /** Represents the position of the end of the selection */
 | 
					  /** Represents the position of the end of the selection */
 | 
				
			||||||
  int target_end;
 | 
					  int target_end;
 | 
				
			||||||
  /** custom temporal data */
 | 
					 | 
				
			||||||
  GHOST_TUserDataPtr tmp;
 | 
					 | 
				
			||||||
} GHOST_TEventImeData;
 | 
					} GHOST_TEventImeData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 
 | 
				
			|||||||
 Submodule release/scripts/addons updated: 67f1fbca14...c08568cc37
									
								
							@@ -949,7 +949,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
 | 
				
			|||||||
            """Make all the newly created and the old objects of a collection """ \
 | 
					            """Make all the newly created and the old objects of a collection """ \
 | 
				
			||||||
                """to be properly setup for shadow catch"""
 | 
					                """to be properly setup for shadow catch"""
 | 
				
			||||||
            for ob in collection.objects:
 | 
					            for ob in collection.objects:
 | 
				
			||||||
                ob.cycles.is_shadow_catcher = True
 | 
					                ob.is_shadow_catcher = True
 | 
				
			||||||
                for child in collection.children:
 | 
					                for child in collection.children:
 | 
				
			||||||
                    setup_shadow_catcher_objects(child)
 | 
					                    setup_shadow_catcher_objects(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,7 +122,7 @@ void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2);
 | 
				
			|||||||
int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_NONNULL(2);
 | 
					int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_NONNULL(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef bool (*BLF_GlyphBoundsFn)(const char *str,
 | 
					typedef bool (*BLF_GlyphBoundsFn)(const char *str,
 | 
				
			||||||
                                  const size_t str_step_ofs,
 | 
					                                  size_t str_step_ofs,
 | 
				
			||||||
                                  const struct rcti *glyph_step_bounds,
 | 
					                                  const struct rcti *glyph_step_bounds,
 | 
				
			||||||
                                  int glyph_advance_x,
 | 
					                                  int glyph_advance_x,
 | 
				
			||||||
                                  const struct rctf *glyph_bounds,
 | 
					                                  const struct rctf *glyph_bounds,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,7 +121,7 @@ void blf_font_boundbox_foreach_glyph(struct FontBLF *font,
 | 
				
			|||||||
                                     const char *str,
 | 
					                                     const char *str,
 | 
				
			||||||
                                     size_t str_len,
 | 
					                                     size_t str_len,
 | 
				
			||||||
                                     bool (*user_fn)(const char *str,
 | 
					                                     bool (*user_fn)(const char *str,
 | 
				
			||||||
                                                     const size_t str_step_ofs,
 | 
					                                                     size_t str_step_ofs,
 | 
				
			||||||
                                                     const struct rcti *glyph_step_bounds,
 | 
					                                                     const struct rcti *glyph_step_bounds,
 | 
				
			||||||
                                                     int glyph_advance_x,
 | 
					                                                     int glyph_advance_x,
 | 
				
			||||||
                                                     const struct rctf *glyph_bounds,
 | 
					                                                     const struct rctf *glyph_bounds,
 | 
				
			||||||
@@ -132,7 +132,7 @@ void blf_font_boundbox_foreach_glyph(struct FontBLF *font,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int blf_font_count_missing_chars(struct FontBLF *font,
 | 
					int blf_font_count_missing_chars(struct FontBLF *font,
 | 
				
			||||||
                                 const char *str,
 | 
					                                 const char *str,
 | 
				
			||||||
                                 const size_t str_len,
 | 
					                                 size_t str_len,
 | 
				
			||||||
                                 int *r_tot_chars);
 | 
					                                 int *r_tot_chars);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void blf_font_free(struct FontBLF *font);
 | 
					void blf_font_free(struct FontBLF *font);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -140,7 +140,7 @@ bool BKE_appdir_font_folder_default(char *dir);
 | 
				
			|||||||
 * Find Python executable.
 | 
					 * Find Python executable.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool BKE_appdir_program_python_search(char *fullpath,
 | 
					bool BKE_appdir_program_python_search(char *fullpath,
 | 
				
			||||||
                                      const size_t fullpath_len,
 | 
					                                      size_t fullpath_len,
 | 
				
			||||||
                                      int version_major,
 | 
					                                      int version_major,
 | 
				
			||||||
                                      int version_minor);
 | 
					                                      int version_minor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,7 +73,7 @@ bool BKE_id_attribute_rename(struct ID *id,
 | 
				
			|||||||
                             const char *new_name,
 | 
					                             const char *new_name,
 | 
				
			||||||
                             struct ReportList *reports);
 | 
					                             struct ReportList *reports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int BKE_id_attributes_length(struct ID *id, const CustomDataMask mask);
 | 
					int BKE_id_attributes_length(struct ID *id, CustomDataMask mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id);
 | 
					struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id);
 | 
				
			||||||
void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer);
 | 
					void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,9 @@
 | 
				
			|||||||
#include "BKE_attribute.h"
 | 
					#include "BKE_attribute.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_color.hh"
 | 
					#include "BLI_color.hh"
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_function_ref.hh"
 | 
					#include "BLI_function_ref.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This file defines classes that help to provide access to attribute data on a #GeometryComponent.
 | 
					 * This file defines classes that help to provide access to attribute data on a #GeometryComponent.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
#include "BLI_color.hh"
 | 
					#include "BLI_color.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "DNA_customdata_types.h"
 | 
					#include "DNA_customdata_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -159,12 +160,12 @@ template<> inline float mix2(const float factor, const float &a, const float &b)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
 | 
					template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return math::interpolate(a, b, factor);
 | 
					  return float2::interpolate(a, b, factor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
 | 
					template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return math::interpolate(a, b, factor);
 | 
					  return float3::interpolate(a, b, factor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<>
 | 
					template<>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,7 +128,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
 | 
				
			|||||||
                                        float epsilon,
 | 
					                                        float epsilon,
 | 
				
			||||||
                                        int tree_type,
 | 
					                                        int tree_type,
 | 
				
			||||||
                                        int axis,
 | 
					                                        int axis,
 | 
				
			||||||
                                        const BVHCacheType bvh_cache_type,
 | 
					                                        BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                        struct BVHCache **bvh_cache_p,
 | 
					                                        struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                        ThreadMutex *mesh_eval_mutex);
 | 
					                                        ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,7 +148,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
                                    float epsilon,
 | 
					                                    float epsilon,
 | 
				
			||||||
                                    int tree_type,
 | 
					                                    int tree_type,
 | 
				
			||||||
                                    int axis,
 | 
					                                    int axis,
 | 
				
			||||||
                                    const BVHCacheType bvh_cache_type,
 | 
					                                    BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                    struct BVHCache **bvh_cache_p,
 | 
					                                    struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                    ThreadMutex *mesh_eval_mutex);
 | 
					                                    ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -165,7 +165,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
 | 
				
			|||||||
                                        float epsilon,
 | 
					                                        float epsilon,
 | 
				
			||||||
                                        int tree_type,
 | 
					                                        int tree_type,
 | 
				
			||||||
                                        int axis,
 | 
					                                        int axis,
 | 
				
			||||||
                                        const BVHCacheType bvh_cache_type,
 | 
					                                        BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                        struct BVHCache **bvh_cache_p,
 | 
					                                        struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                        ThreadMutex *mesh_eval_mutex);
 | 
					                                        ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -188,7 +188,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
                                    float epsilon,
 | 
					                                    float epsilon,
 | 
				
			||||||
                                    int tree_type,
 | 
					                                    int tree_type,
 | 
				
			||||||
                                    int axis,
 | 
					                                    int axis,
 | 
				
			||||||
                                    const BVHCacheType bvh_cache_type,
 | 
					                                    BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                    struct BVHCache **bvh_cache_p,
 | 
					                                    struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                    ThreadMutex *mesh_eval_mutex);
 | 
					                                    ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -212,7 +212,7 @@ BVHTree *bvhtree_from_mesh_faces_ex(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
                                    float epsilon,
 | 
					                                    float epsilon,
 | 
				
			||||||
                                    int tree_type,
 | 
					                                    int tree_type,
 | 
				
			||||||
                                    int axis,
 | 
					                                    int axis,
 | 
				
			||||||
                                    const BVHCacheType bvh_cache_type,
 | 
					                                    BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                    struct BVHCache **bvh_cache_p,
 | 
					                                    struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                    ThreadMutex *mesh_eval_mutex);
 | 
					                                    ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -229,7 +229,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
 | 
				
			|||||||
                                          float epsilon,
 | 
					                                          float epsilon,
 | 
				
			||||||
                                          int tree_type,
 | 
					                                          int tree_type,
 | 
				
			||||||
                                          int axis,
 | 
					                                          int axis,
 | 
				
			||||||
                                          const BVHCacheType bvh_cache_type,
 | 
					                                          BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                          struct BVHCache **bvh_cache_p,
 | 
					                                          struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                          ThreadMutex *mesh_eval_mutex);
 | 
					                                          ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -251,7 +251,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
                                      float epsilon,
 | 
					                                      float epsilon,
 | 
				
			||||||
                                      int tree_type,
 | 
					                                      int tree_type,
 | 
				
			||||||
                                      int axis,
 | 
					                                      int axis,
 | 
				
			||||||
                                      const BVHCacheType bvh_cache_type,
 | 
					                                      BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                      struct BVHCache **bvh_cache_p,
 | 
					                                      struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                      ThreadMutex *mesh_eval_mutex);
 | 
					                                      ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -263,7 +263,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
 | 
					BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
 | 
				
			||||||
                                   const struct Mesh *mesh,
 | 
					                                   const struct Mesh *mesh,
 | 
				
			||||||
                                   const BVHCacheType bvh_cache_type,
 | 
					                                   BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                   int tree_type);
 | 
					                                   int tree_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -272,7 +272,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
 | 
				
			|||||||
BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
 | 
					BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
 | 
				
			||||||
                                       struct BMEditMesh *em,
 | 
					                                       struct BMEditMesh *em,
 | 
				
			||||||
                                       int tree_type,
 | 
					                                       int tree_type,
 | 
				
			||||||
                                       const BVHCacheType bvh_cache_type,
 | 
					                                       BVHCacheType bvh_cache_type,
 | 
				
			||||||
                                       struct BVHCache **bvh_cache_p,
 | 
					                                       struct BVHCache **bvh_cache_p,
 | 
				
			||||||
                                       ThreadMutex *mesh_eval_mutex);
 | 
					                                       ThreadMutex *mesh_eval_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -323,7 +323,7 @@ void CustomData_bmesh_copy_data_exclude_by_type(const struct CustomData *source,
 | 
				
			|||||||
                                                struct CustomData *dest,
 | 
					                                                struct CustomData *dest,
 | 
				
			||||||
                                                void *src_block,
 | 
					                                                void *src_block,
 | 
				
			||||||
                                                void **dest_block,
 | 
					                                                void **dest_block,
 | 
				
			||||||
                                                const CustomDataMask mask_exclude);
 | 
					                                                CustomDataMask mask_exclude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Copies data of a single layer of a given type.
 | 
					 * Copies data of a single layer of a given type.
 | 
				
			||||||
@@ -496,7 +496,7 @@ void CustomData_bmesh_free_block_data(struct CustomData *data, void *block);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
 | 
					void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
 | 
				
			||||||
                                                      void *block,
 | 
					                                                      void *block,
 | 
				
			||||||
                                                      const CustomDataMask mask_exclude);
 | 
					                                                      CustomDataMask mask_exclude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh
 | 
					 * Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,11 +23,11 @@
 | 
				
			|||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_float4x4.hh"
 | 
					#include "BLI_float4x4.hh"
 | 
				
			||||||
#include "BLI_function_ref.hh"
 | 
					#include "BLI_function_ref.hh"
 | 
				
			||||||
#include "BLI_hash.hh"
 | 
					#include "BLI_hash.hh"
 | 
				
			||||||
#include "BLI_map.hh"
 | 
					#include "BLI_map.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_set.hh"
 | 
					#include "BLI_set.hh"
 | 
				
			||||||
#include "BLI_user_counter.hh"
 | 
					#include "BLI_user_counter.hh"
 | 
				
			||||||
#include "BLI_vector_set.hh"
 | 
					#include "BLI_vector_set.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -367,7 +367,7 @@ void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const ch
 | 
				
			|||||||
void BKE_image_packfiles_from_mem(struct ReportList *reports,
 | 
					void BKE_image_packfiles_from_mem(struct ReportList *reports,
 | 
				
			||||||
                                  struct Image *ima,
 | 
					                                  struct Image *ima,
 | 
				
			||||||
                                  char *data,
 | 
					                                  char *data,
 | 
				
			||||||
                                  const size_t data_len);
 | 
					                                  size_t data_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Prints memory statistics for images.
 | 
					 * Prints memory statistics for images.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "FN_generic_virtual_array.hh"
 | 
					#include "FN_generic_virtual_array.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BKE_attribute.h"
 | 
					#include "BKE_attribute.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1374,18 +1374,12 @@ void ntreeCompositTagRender(struct Scene *scene);
 | 
				
			|||||||
 * - Each render layer node calls the update function of the
 | 
					 * - Each render layer node calls the update function of the
 | 
				
			||||||
 *   render engine that's used for its scene.
 | 
					 *   render engine that's used for its scene.
 | 
				
			||||||
 * - The render engine calls RE_engine_register_pass for each pass.
 | 
					 * - The render engine calls RE_engine_register_pass for each pass.
 | 
				
			||||||
 * - #RE_engine_register_pass calls #ntreeCompositRegisterPass,
 | 
					 * - #RE_engine_register_pass calls #node_cmp_rlayers_register_pass.
 | 
				
			||||||
 *   which calls #node_cmp_rlayers_register_pass for every render layer node.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * TODO: This is *not* part of `blenkernel`, it's defined under "source/blender/nodes/".
 | 
					 * TODO: This is *not* part of `blenkernel`, it's defined under "source/blender/nodes/".
 | 
				
			||||||
 * This declaration should be moved out of BKE.
 | 
					 * This declaration should be moved out of BKE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void ntreeCompositUpdateRLayers(struct bNodeTree *ntree);
 | 
					void ntreeCompositUpdateRLayers(struct bNodeTree *ntree);
 | 
				
			||||||
void ntreeCompositRegisterPass(struct bNodeTree *ntree,
 | 
					 | 
				
			||||||
                               struct Scene *scene,
 | 
					 | 
				
			||||||
                               struct ViewLayer *view_layer,
 | 
					 | 
				
			||||||
                               const char *name,
 | 
					 | 
				
			||||||
                               eNodeSocketDatatype type);
 | 
					 | 
				
			||||||
void ntreeCompositClearTags(struct bNodeTree *ntree);
 | 
					void ntreeCompositClearTags(struct bNodeTree *ntree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree,
 | 
					struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -317,11 +317,8 @@ void BKE_scene_multiview_view_prefix_get(struct Scene *scene,
 | 
				
			|||||||
                                         const char *name,
 | 
					                                         const char *name,
 | 
				
			||||||
                                         char *r_prefix,
 | 
					                                         char *r_prefix,
 | 
				
			||||||
                                         const char **r_ext);
 | 
					                                         const char **r_ext);
 | 
				
			||||||
void BKE_scene_multiview_videos_dimensions_get(const struct RenderData *rd,
 | 
					void BKE_scene_multiview_videos_dimensions_get(
 | 
				
			||||||
                                               const size_t width,
 | 
					    const struct RenderData *rd, size_t width, size_t height, size_t *r_width, size_t *r_height);
 | 
				
			||||||
                                               const size_t height,
 | 
					 | 
				
			||||||
                                               size_t *r_width,
 | 
					 | 
				
			||||||
                                               size_t *r_height);
 | 
					 | 
				
			||||||
int BKE_scene_multiview_num_videos_get(const struct RenderData *rd);
 | 
					int BKE_scene_multiview_num_videos_get(const struct RenderData *rd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* depsgraph */
 | 
					/* depsgraph */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "FN_generic_virtual_array.hh"
 | 
					#include "FN_generic_virtual_array.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_float4x4.hh"
 | 
					#include "BLI_float4x4.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BKE_attribute_access.hh"
 | 
					#include "BKE_attribute_access.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,7 +104,7 @@ void BKE_vfont_select_clamp(struct Object *ob);
 | 
				
			|||||||
void BKE_vfont_clipboard_free(void);
 | 
					void BKE_vfont_clipboard_free(void);
 | 
				
			||||||
void BKE_vfont_clipboard_set(const char32_t *text_buf,
 | 
					void BKE_vfont_clipboard_set(const char32_t *text_buf,
 | 
				
			||||||
                             const struct CharInfo *info_buf,
 | 
					                             const struct CharInfo *info_buf,
 | 
				
			||||||
                             const size_t len);
 | 
					                             size_t len);
 | 
				
			||||||
void BKE_vfont_clipboard_get(char32_t **r_text_buf,
 | 
					void BKE_vfont_clipboard_get(char32_t **r_text_buf,
 | 
				
			||||||
                             struct CharInfo **r_info_buf,
 | 
					                             struct CharInfo **r_info_buf,
 | 
				
			||||||
                             size_t *r_len_utf8,
 | 
					                             size_t *r_len_utf8,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -163,8 +163,8 @@ bool BKE_volume_save(const struct Volume *volume,
 | 
				
			|||||||
 * file or copy shared grids to make them writeable. */
 | 
					 * file or copy shared grids to make them writeable. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					#  include "BLI_float3.hh"
 | 
				
			||||||
#  include "BLI_float4x4.hh"
 | 
					#  include "BLI_float4x4.hh"
 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#  include "BLI_string_ref.hh"
 | 
					#  include "BLI_string_ref.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool BKE_volume_min_max(const Volume *volume, blender::float3 &r_min, blender::float3 &r_max);
 | 
					bool BKE_volume_min_max(const Volume *volume, blender::float3 &r_min, blender::float3 &r_max);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,9 +38,9 @@
 | 
				
			|||||||
#include "BLI_array.h"
 | 
					#include "BLI_array.h"
 | 
				
			||||||
#include "BLI_bitmap.h"
 | 
					#include "BLI_bitmap.h"
 | 
				
			||||||
#include "BLI_blenlib.h"
 | 
					#include "BLI_blenlib.h"
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
#include "BLI_linklist.h"
 | 
					#include "BLI_linklist.h"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_task.h"
 | 
					#include "BLI_task.h"
 | 
				
			||||||
#include "BLI_task.hh"
 | 
					#include "BLI_task.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@
 | 
				
			|||||||
#include "DNA_pointcloud_types.h"
 | 
					#include "DNA_pointcloud_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_color.hh"
 | 
					#include "BLI_color.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLT_translation.h"
 | 
					#include "BLT_translation.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,9 +44,9 @@ void data_transfer_layersmapping_add_item(struct ListBase *r_map,
 | 
				
			|||||||
                                          void *data_dst,
 | 
					                                          void *data_dst,
 | 
				
			||||||
                                          int data_src_n,
 | 
					                                          int data_src_n,
 | 
				
			||||||
                                          int data_dst_n,
 | 
					                                          int data_dst_n,
 | 
				
			||||||
                                          const size_t elem_size,
 | 
					                                          size_t elem_size,
 | 
				
			||||||
                                          const size_t data_size,
 | 
					                                          size_t data_size,
 | 
				
			||||||
                                          const size_t data_offset,
 | 
					                                          size_t data_offset,
 | 
				
			||||||
                                          uint64_t data_flag,
 | 
					                                          uint64_t data_flag,
 | 
				
			||||||
                                          cd_datatransfer_interp interp,
 | 
					                                          cd_datatransfer_interp interp,
 | 
				
			||||||
                                          void *interp_data);
 | 
					                                          void *interp_data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -217,8 +217,9 @@ VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component,
 | 
				
			|||||||
       * calculating unnecessary values and to allow normalizing the result much more simply. */
 | 
					       * calculating unnecessary values and to allow normalizing the result much more simply. */
 | 
				
			||||||
      for (const int i : mask) {
 | 
					      for (const int i : mask) {
 | 
				
			||||||
        const MEdge &edge = edges[i];
 | 
					        const MEdge &edge = edges[i];
 | 
				
			||||||
        edge_normals[i] = math::normalize(
 | 
					        edge_normals[i] = float3::interpolate(
 | 
				
			||||||
            math::interpolate(vert_normals_span[edge.v1], vert_normals_span[edge.v2], 0.5f));
 | 
					                              vert_normals_span[edge.v1], vert_normals_span[edge.v2], 0.5f)
 | 
				
			||||||
 | 
					                              .normalized();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return VArray<float3>::ForContainer(std::move(edge_normals));
 | 
					      return VArray<float3>::ForContainer(std::move(edge_normals));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,10 +33,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "BLI_array_utils.h"
 | 
					#include "BLI_array_utils.h"
 | 
				
			||||||
#include "BLI_blenlib.h"
 | 
					#include "BLI_blenlib.h"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_ghash.h"
 | 
					#include "BLI_ghash.h"
 | 
				
			||||||
#include "BLI_hash.h"
 | 
					#include "BLI_hash.h"
 | 
				
			||||||
#include "BLI_heap.h"
 | 
					#include "BLI_heap.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_math_vector.h"
 | 
					#include "BLI_math_vector.h"
 | 
				
			||||||
#include "BLI_polyfill_2d.h"
 | 
					#include "BLI_polyfill_2d.h"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,9 +28,9 @@
 | 
				
			|||||||
#include "DNA_material_types.h"
 | 
					#include "DNA_material_types.h"
 | 
				
			||||||
#include "DNA_object_types.h"
 | 
					#include "DNA_object_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_listbase.h"
 | 
					#include "BLI_listbase.h"
 | 
				
			||||||
#include "BLI_math_base.h"
 | 
					#include "BLI_math_base.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_rand.h"
 | 
					#include "BLI_rand.h"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2446,7 +2446,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* and draw the text. */
 | 
					    /* and draw the text. */
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.file, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.file, sizeof(stamp_data.file));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* the extra pixel for background. */
 | 
					    /* the extra pixel for background. */
 | 
				
			||||||
    y -= BUFF_MARGIN_Y * 2;
 | 
					    y -= BUFF_MARGIN_Y * 2;
 | 
				
			||||||
@@ -2469,7 +2469,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.date, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.date, sizeof(stamp_data.date));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* the extra pixel for background. */
 | 
					    /* the extra pixel for background. */
 | 
				
			||||||
    y -= BUFF_MARGIN_Y * 2;
 | 
					    y -= BUFF_MARGIN_Y * 2;
 | 
				
			||||||
@@ -2492,7 +2492,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.rendertime, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.rendertime, sizeof(stamp_data.rendertime));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* the extra pixel for background. */
 | 
					    /* the extra pixel for background. */
 | 
				
			||||||
    y -= BUFF_MARGIN_Y * 2;
 | 
					    y -= BUFF_MARGIN_Y * 2;
 | 
				
			||||||
@@ -2515,7 +2515,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.memory, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.memory, sizeof(stamp_data.memory));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* the extra pixel for background. */
 | 
					    /* the extra pixel for background. */
 | 
				
			||||||
    y -= BUFF_MARGIN_Y * 2;
 | 
					    y -= BUFF_MARGIN_Y * 2;
 | 
				
			||||||
@@ -2538,7 +2538,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.hostname, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.hostname, sizeof(stamp_data.hostname));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* the extra pixel for background. */
 | 
					    /* the extra pixel for background. */
 | 
				
			||||||
    y -= BUFF_MARGIN_Y * 2;
 | 
					    y -= BUFF_MARGIN_Y * 2;
 | 
				
			||||||
@@ -2562,7 +2562,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs + (h - h_fixed), 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs + (h - h_fixed), 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.note, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.note, sizeof(stamp_data.note));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  BLF_disable(mono, BLF_WORD_WRAP);
 | 
					  BLF_disable(mono, BLF_WORD_WRAP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2586,7 +2586,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* and pad the text. */
 | 
					    /* and pad the text. */
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.marker, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.marker, sizeof(stamp_data.marker));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* space width. */
 | 
					    /* space width. */
 | 
				
			||||||
    x += w + pad;
 | 
					    x += w + pad;
 | 
				
			||||||
@@ -2609,7 +2609,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* and pad the text. */
 | 
					    /* and pad the text. */
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.time, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.time, sizeof(stamp_data.time));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* space width. */
 | 
					    /* space width. */
 | 
				
			||||||
    x += w + pad;
 | 
					    x += w + pad;
 | 
				
			||||||
@@ -2631,7 +2631,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* and pad the text. */
 | 
					    /* and pad the text. */
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.frame, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.frame, sizeof(stamp_data.frame));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* space width. */
 | 
					    /* space width. */
 | 
				
			||||||
    x += w + pad;
 | 
					    x += w + pad;
 | 
				
			||||||
@@ -2651,7 +2651,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      x + w + BUFF_MARGIN_X,
 | 
					                      x + w + BUFF_MARGIN_X,
 | 
				
			||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.camera, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.camera, sizeof(stamp_data.camera));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* space width. */
 | 
					    /* space width. */
 | 
				
			||||||
    x += w + pad;
 | 
					    x += w + pad;
 | 
				
			||||||
@@ -2671,7 +2671,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      x + w + BUFF_MARGIN_X,
 | 
					                      x + w + BUFF_MARGIN_X,
 | 
				
			||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.cameralens, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.cameralens, sizeof(stamp_data.cameralens));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (TEXT_SIZE_CHECK(stamp_data.scene, w, h)) {
 | 
					  if (TEXT_SIZE_CHECK(stamp_data.scene, w, h)) {
 | 
				
			||||||
@@ -2693,7 +2693,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* and pad the text. */
 | 
					    /* and pad the text. */
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.scene, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.scene, sizeof(stamp_data.scene));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (TEXT_SIZE_CHECK(stamp_data.strip, w, h)) {
 | 
					  if (TEXT_SIZE_CHECK(stamp_data.strip, w, h)) {
 | 
				
			||||||
@@ -2715,7 +2715,7 @@ void BKE_image_stamp_buf(Scene *scene,
 | 
				
			|||||||
                      y + h + BUFF_MARGIN_Y);
 | 
					                      y + h + BUFF_MARGIN_Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
					    BLF_position(mono, x, y + y_ofs, 0.0);
 | 
				
			||||||
    BLF_draw_buffer(mono, stamp_data.strip, BLF_DRAW_STR_DUMMY_MAX);
 | 
					    BLF_draw_buffer(mono, stamp_data.strip, sizeof(stamp_data.strip));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* cleanup the buffer. */
 | 
					  /* cleanup the buffer. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,13 +36,13 @@
 | 
				
			|||||||
#include "BLI_bitmap.h"
 | 
					#include "BLI_bitmap.h"
 | 
				
			||||||
#include "BLI_edgehash.h"
 | 
					#include "BLI_edgehash.h"
 | 
				
			||||||
#include "BLI_endian_switch.h"
 | 
					#include "BLI_endian_switch.h"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_ghash.h"
 | 
					#include "BLI_ghash.h"
 | 
				
			||||||
#include "BLI_hash.h"
 | 
					#include "BLI_hash.h"
 | 
				
			||||||
#include "BLI_index_range.hh"
 | 
					#include "BLI_index_range.hh"
 | 
				
			||||||
#include "BLI_linklist.h"
 | 
					#include "BLI_linklist.h"
 | 
				
			||||||
#include "BLI_listbase.h"
 | 
					#include "BLI_listbase.h"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_memarena.h"
 | 
					#include "BLI_memarena.h"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
#include "BLI_task.hh"
 | 
					#include "BLI_task.hh"
 | 
				
			||||||
@@ -1597,16 +1597,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
 | 
				
			|||||||
      [&](IndexRange range, const Result &init) {
 | 
					      [&](IndexRange range, const Result &init) {
 | 
				
			||||||
        Result result = init;
 | 
					        Result result = init;
 | 
				
			||||||
        for (const int i : range) {
 | 
					        for (const int i : range) {
 | 
				
			||||||
          math::min_max(float3(me->mvert[i].co), result.min, result.max);
 | 
					          float3::min_max(me->mvert[i].co, result.min, result.max);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      [](const Result &a, const Result &b) {
 | 
					      [](const Result &a, const Result &b) {
 | 
				
			||||||
        return Result{math::min(a.min, b.min), math::max(a.max, b.max)};
 | 
					        return Result{float3::min(a.min, b.min), float3::max(a.max, b.max)};
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  copy_v3_v3(r_min, math::min(minmax.min, float3(r_min)));
 | 
					  copy_v3_v3(r_min, float3::min(minmax.min, r_min));
 | 
				
			||||||
  copy_v3_v3(r_max, math::max(minmax.max, float3(r_max)));
 | 
					  copy_v3_v3(r_max, float3::max(minmax.max, r_max));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,9 +32,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "BLI_alloca.h"
 | 
					#include "BLI_alloca.h"
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
#include "BLI_float4x4.hh"
 | 
					#include "BLI_float4x4.hh"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_mesh_boolean.hh"
 | 
					#include "BLI_mesh_boolean.hh"
 | 
				
			||||||
#include "BLI_mesh_intersect.hh"
 | 
					#include "BLI_mesh_intersect.hh"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,8 +31,8 @@
 | 
				
			|||||||
#include "MEM_guardedalloc.h"
 | 
					#include "MEM_guardedalloc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_index_range.hh"
 | 
					#include "BLI_index_range.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "DNA_mesh_types.h"
 | 
					#include "DNA_mesh_types.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,9 +31,9 @@
 | 
				
			|||||||
#include "BLI_string_utf8.h"
 | 
					#include "BLI_string_utf8.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_float4x4.hh"
 | 
					#include "BLI_float4x4.hh"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_rand.h"
 | 
					#include "BLI_rand.h"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
@@ -1026,8 +1026,6 @@ static void get_dupliface_transform_from_coords(Span<float3> coords,
 | 
				
			|||||||
                                                const float scale_fac,
 | 
					                                                const float scale_fac,
 | 
				
			||||||
                                                float r_mat[4][4])
 | 
					                                                float r_mat[4][4])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Location. */
 | 
					  /* Location. */
 | 
				
			||||||
  float3 location(0);
 | 
					  float3 location(0);
 | 
				
			||||||
  for (const float3 &coord : coords) {
 | 
					  for (const float3 &coord : coords) {
 | 
				
			||||||
@@ -1038,7 +1036,9 @@ static void get_dupliface_transform_from_coords(Span<float3> coords,
 | 
				
			|||||||
  /* Rotation. */
 | 
					  /* Rotation. */
 | 
				
			||||||
  float quat[4];
 | 
					  float quat[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float3 f_no = normalize(cross_poly(coords));
 | 
					  float3 f_no;
 | 
				
			||||||
 | 
					  cross_poly_v3(f_no, (const float(*)[3])coords.data(), (uint)coords.size());
 | 
				
			||||||
 | 
					  f_no.normalize();
 | 
				
			||||||
  tri_to_quat_ex(quat, coords[0], coords[1], coords[2], f_no);
 | 
					  tri_to_quat_ex(quat, coords[0], coords[1], coords[2], f_no);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Scale. */
 | 
					  /* Scale. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,9 +25,9 @@
 | 
				
			|||||||
#include "DNA_object_types.h"
 | 
					#include "DNA_object_types.h"
 | 
				
			||||||
#include "DNA_pointcloud_types.h"
 | 
					#include "DNA_pointcloud_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_index_range.hh"
 | 
					#include "BLI_index_range.hh"
 | 
				
			||||||
#include "BLI_listbase.h"
 | 
					#include "BLI_listbase.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_rand.h"
 | 
					#include "BLI_rand.h"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
@@ -275,8 +275,6 @@ struct MinMaxResult {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static MinMaxResult min_max_no_radii(Span<float3> positions)
 | 
					static MinMaxResult min_max_no_radii(Span<float3> positions)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return blender::threading::parallel_reduce(
 | 
					  return blender::threading::parallel_reduce(
 | 
				
			||||||
      positions.index_range(),
 | 
					      positions.index_range(),
 | 
				
			||||||
      1024,
 | 
					      1024,
 | 
				
			||||||
@@ -284,19 +282,17 @@ static MinMaxResult min_max_no_radii(Span<float3> positions)
 | 
				
			|||||||
      [&](IndexRange range, const MinMaxResult &init) {
 | 
					      [&](IndexRange range, const MinMaxResult &init) {
 | 
				
			||||||
        MinMaxResult result = init;
 | 
					        MinMaxResult result = init;
 | 
				
			||||||
        for (const int i : range) {
 | 
					        for (const int i : range) {
 | 
				
			||||||
          min_max(positions[i], result.min, result.max);
 | 
					          float3::min_max(positions[i], result.min, result.max);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      [](const MinMaxResult &a, const MinMaxResult &b) {
 | 
					      [](const MinMaxResult &a, const MinMaxResult &b) {
 | 
				
			||||||
        return MinMaxResult{min(a.min, b.min), max(a.max, b.max)};
 | 
					        return MinMaxResult{float3::min(a.min, b.min), float3::max(a.max, b.max)};
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static MinMaxResult min_max_with_radii(Span<float3> positions, Span<float> radii)
 | 
					static MinMaxResult min_max_with_radii(Span<float3> positions, Span<float> radii)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return blender::threading::parallel_reduce(
 | 
					  return blender::threading::parallel_reduce(
 | 
				
			||||||
      positions.index_range(),
 | 
					      positions.index_range(),
 | 
				
			||||||
      1024,
 | 
					      1024,
 | 
				
			||||||
@@ -304,20 +300,18 @@ static MinMaxResult min_max_with_radii(Span<float3> positions, Span<float> radii
 | 
				
			|||||||
      [&](IndexRange range, const MinMaxResult &init) {
 | 
					      [&](IndexRange range, const MinMaxResult &init) {
 | 
				
			||||||
        MinMaxResult result = init;
 | 
					        MinMaxResult result = init;
 | 
				
			||||||
        for (const int i : range) {
 | 
					        for (const int i : range) {
 | 
				
			||||||
          result.min = min(positions[i] - radii[i], result.min);
 | 
					          result.min = float3::min(positions[i] - radii[i], result.min);
 | 
				
			||||||
          result.max = max(positions[i] + radii[i], result.max);
 | 
					          result.max = float3::max(positions[i] + radii[i], result.max);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      [](const MinMaxResult &a, const MinMaxResult &b) {
 | 
					      [](const MinMaxResult &a, const MinMaxResult &b) {
 | 
				
			||||||
        return MinMaxResult{min(a.min, b.min), max(a.max, b.max)};
 | 
					        return MinMaxResult{float3::min(a.min, b.min), float3::max(a.max, b.max)};
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool BKE_pointcloud_minmax(const PointCloud *pointcloud, float r_min[3], float r_max[3])
 | 
					bool BKE_pointcloud_minmax(const PointCloud *pointcloud, float r_min[3], float r_max[3])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!pointcloud->totpoint) {
 | 
					  if (!pointcloud->totpoint) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -328,8 +322,8 @@ bool BKE_pointcloud_minmax(const PointCloud *pointcloud, float r_min[3], float r
 | 
				
			|||||||
                                                      {pointcloud->radius, pointcloud->totpoint}) :
 | 
					                                                      {pointcloud->radius, pointcloud->totpoint}) :
 | 
				
			||||||
                                   min_max_no_radii(positions);
 | 
					                                   min_max_no_radii(positions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  copy_v3_v3(r_min, min(min_max.min, float3(r_min)));
 | 
					  copy_v3_v3(r_min, float3::min(min_max.min, r_min));
 | 
				
			||||||
  copy_v3_v3(r_max, max(min_max.max, float3(r_max)));
 | 
					  copy_v3_v3(r_max, float3::max(min_max.max, r_max));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -346,7 +340,7 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
 | 
				
			|||||||
    ob->runtime.bb = static_cast<BoundBox *>(MEM_callocN(sizeof(BoundBox), "pointcloud boundbox"));
 | 
					    ob->runtime.bb = static_cast<BoundBox *>(MEM_callocN(sizeof(BoundBox), "pointcloud boundbox"));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float3 min, max;
 | 
					  blender::float3 min, max;
 | 
				
			||||||
  INIT_MINMAX(min, max);
 | 
					  INIT_MINMAX(min, max);
 | 
				
			||||||
  if (ob->runtime.geometry_set_eval != nullptr) {
 | 
					  if (ob->runtime.geometry_set_eval != nullptr) {
 | 
				
			||||||
    ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max);
 | 
					    ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,9 +28,9 @@
 | 
				
			|||||||
#include "DNA_simulation_types.h"
 | 
					#include "DNA_simulation_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_compiler_compat.h"
 | 
					#include "BLI_compiler_compat.h"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_listbase.h"
 | 
					#include "BLI_listbase.h"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_rand.h"
 | 
					#include "BLI_rand.h"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -166,15 +166,13 @@ static void accumulate_lengths(Span<float3> positions,
 | 
				
			|||||||
                               const bool is_cyclic,
 | 
					                               const bool is_cyclic,
 | 
				
			||||||
                               MutableSpan<float> lengths)
 | 
					                               MutableSpan<float> lengths)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  float length = 0.0f;
 | 
					  float length = 0.0f;
 | 
				
			||||||
  for (const int i : IndexRange(positions.size() - 1)) {
 | 
					  for (const int i : IndexRange(positions.size() - 1)) {
 | 
				
			||||||
    length += distance(positions[i], positions[i + 1]);
 | 
					    length += float3::distance(positions[i], positions[i + 1]);
 | 
				
			||||||
    lengths[i] = length;
 | 
					    lengths[i] = length;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (is_cyclic) {
 | 
					  if (is_cyclic) {
 | 
				
			||||||
    lengths.last() = length + distance(positions.last(), positions.first());
 | 
					    lengths.last() = length + float3::distance(positions.last(), positions.first());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -202,13 +200,11 @@ Span<float> Spline::evaluated_lengths() const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static float3 direction_bisect(const float3 &prev, const float3 &middle, const float3 &next)
 | 
					static float3 direction_bisect(const float3 &prev, const float3 &middle, const float3 &next)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					  const float3 dir_prev = (middle - prev).normalized();
 | 
				
			||||||
 | 
					  const float3 dir_next = (next - middle).normalized();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const float3 dir_prev = normalize(middle - prev);
 | 
					  const float3 result = (dir_prev + dir_next).normalized();
 | 
				
			||||||
  const float3 dir_next = normalize(next - middle);
 | 
					  if (UNLIKELY(result.is_zero())) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const float3 result = normalize(dir_prev + dir_next);
 | 
					 | 
				
			||||||
  if (UNLIKELY(is_zero(result))) {
 | 
					 | 
				
			||||||
    return float3(0.0f, 0.0f, 1.0f);
 | 
					    return float3(0.0f, 0.0f, 1.0f);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
@@ -218,8 +214,6 @@ static void calculate_tangents(Span<float3> positions,
 | 
				
			|||||||
                               const bool is_cyclic,
 | 
					                               const bool is_cyclic,
 | 
				
			||||||
                               MutableSpan<float3> tangents)
 | 
					                               MutableSpan<float3> tangents)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (positions.size() == 1) {
 | 
					  if (positions.size() == 1) {
 | 
				
			||||||
    tangents.first() = float3(0.0f, 0.0f, 1.0f);
 | 
					    tangents.first() = float3(0.0f, 0.0f, 1.0f);
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
@@ -238,8 +232,8 @@ static void calculate_tangents(Span<float3> positions,
 | 
				
			|||||||
    tangents.last() = direction_bisect(second_to_last, last, first);
 | 
					    tangents.last() = direction_bisect(second_to_last, last, first);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    tangents.first() = normalize(positions[1] - positions[0]);
 | 
					    tangents.first() = (positions[1] - positions[0]).normalized();
 | 
				
			||||||
    tangents.last() = normalize(positions.last() - positions[positions.size() - 2]);
 | 
					    tangents.last() = (positions.last() - positions[positions.size() - 2]).normalized();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -270,22 +264,18 @@ static float3 rotate_direction_around_axis(const float3 &direction,
 | 
				
			|||||||
                                           const float3 &axis,
 | 
					                                           const float3 &axis,
 | 
				
			||||||
                                           const float angle)
 | 
					                                           const float angle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_ASSERT_UNIT_V3(direction);
 | 
					  BLI_ASSERT_UNIT_V3(direction);
 | 
				
			||||||
  BLI_ASSERT_UNIT_V3(axis);
 | 
					  BLI_ASSERT_UNIT_V3(axis);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const float3 axis_scaled = axis * dot(direction, axis);
 | 
					  const float3 axis_scaled = axis * float3::dot(direction, axis);
 | 
				
			||||||
  const float3 diff = direction - axis_scaled;
 | 
					  const float3 diff = direction - axis_scaled;
 | 
				
			||||||
  const float3 cross = blender::math::cross(axis, diff);
 | 
					  const float3 cross = float3::cross(axis, diff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return axis_scaled + diff * std::cos(angle) + cross * std::sin(angle);
 | 
					  return axis_scaled + diff * std::cos(angle) + cross * std::sin(angle);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void calculate_normals_z_up(Span<float3> tangents, MutableSpan<float3> r_normals)
 | 
					static void calculate_normals_z_up(Span<float3> tangents, MutableSpan<float3> r_normals)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_assert(r_normals.size() == tangents.size());
 | 
					  BLI_assert(r_normals.size() == tangents.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Same as in `vec_to_quat`. */
 | 
					  /* Same as in `vec_to_quat`. */
 | 
				
			||||||
@@ -296,7 +286,7 @@ static void calculate_normals_z_up(Span<float3> tangents, MutableSpan<float3> r_
 | 
				
			|||||||
      r_normals[i] = {1.0f, 0.0f, 0.0f};
 | 
					      r_normals[i] = {1.0f, 0.0f, 0.0f};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      r_normals[i] = normalize(float3(tangent.y, -tangent.x, 0.0f));
 | 
					      r_normals[i] = float3(tangent.y, -tangent.x, 0.0f).normalized();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -308,14 +298,12 @@ static float3 calculate_next_normal(const float3 &last_normal,
 | 
				
			|||||||
                                    const float3 &last_tangent,
 | 
					                                    const float3 &last_tangent,
 | 
				
			||||||
                                    const float3 ¤t_tangent)
 | 
					                                    const float3 ¤t_tangent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					  if (last_tangent.is_zero() || current_tangent.is_zero()) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (is_zero(last_tangent) || is_zero(current_tangent)) {
 | 
					 | 
				
			||||||
    return last_normal;
 | 
					    return last_normal;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  const float angle = angle_normalized_v3v3(last_tangent, current_tangent);
 | 
					  const float angle = angle_normalized_v3v3(last_tangent, current_tangent);
 | 
				
			||||||
  if (angle != 0.0) {
 | 
					  if (angle != 0.0) {
 | 
				
			||||||
    const float3 axis = normalize(cross(last_tangent, current_tangent));
 | 
					    const float3 axis = float3::cross(last_tangent, current_tangent).normalized();
 | 
				
			||||||
    return rotate_direction_around_axis(last_normal, axis, angle);
 | 
					    return rotate_direction_around_axis(last_normal, axis, angle);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return last_normal;
 | 
					  return last_normal;
 | 
				
			||||||
@@ -325,7 +313,6 @@ static void calculate_normals_minimum(Span<float3> tangents,
 | 
				
			|||||||
                                      const bool cyclic,
 | 
					                                      const bool cyclic,
 | 
				
			||||||
                                      MutableSpan<float3> r_normals)
 | 
					                                      MutableSpan<float3> r_normals)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
  BLI_assert(r_normals.size() == tangents.size());
 | 
					  BLI_assert(r_normals.size() == tangents.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (r_normals.is_empty()) {
 | 
					  if (r_normals.is_empty()) {
 | 
				
			||||||
@@ -340,7 +327,7 @@ static void calculate_normals_minimum(Span<float3> tangents,
 | 
				
			|||||||
    r_normals[0] = {1.0f, 0.0f, 0.0f};
 | 
					    r_normals[0] = {1.0f, 0.0f, 0.0f};
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    r_normals[0] = normalize(float3(first_tangent.y, -first_tangent.x, 0.0f));
 | 
					    r_normals[0] = float3(first_tangent.y, -first_tangent.x, 0.0f).normalized();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Forward normal with minimum twist along the entire spline. */
 | 
					  /* Forward normal with minimum twist along the entire spline. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -199,13 +199,11 @@ void BezierSpline::ensure_auto_handles() const
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (const int i : IndexRange(this->size())) {
 | 
					  for (const int i : IndexRange(this->size())) {
 | 
				
			||||||
    using namespace blender;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (ELEM(HandleType::Auto, handle_types_left_[i], handle_types_right_[i])) {
 | 
					    if (ELEM(HandleType::Auto, handle_types_left_[i], handle_types_right_[i])) {
 | 
				
			||||||
      const float3 prev_diff = positions_[i] - previous_position(positions_, is_cyclic_, i);
 | 
					      const float3 prev_diff = positions_[i] - previous_position(positions_, is_cyclic_, i);
 | 
				
			||||||
      const float3 next_diff = next_position(positions_, is_cyclic_, i) - positions_[i];
 | 
					      const float3 next_diff = next_position(positions_, is_cyclic_, i) - positions_[i];
 | 
				
			||||||
      float prev_len = math::length(prev_diff);
 | 
					      float prev_len = prev_diff.length();
 | 
				
			||||||
      float next_len = math::length(next_diff);
 | 
					      float next_len = next_diff.length();
 | 
				
			||||||
      if (prev_len == 0.0f) {
 | 
					      if (prev_len == 0.0f) {
 | 
				
			||||||
        prev_len = 1.0f;
 | 
					        prev_len = 1.0f;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -215,7 +213,7 @@ void BezierSpline::ensure_auto_handles() const
 | 
				
			|||||||
      const float3 dir = next_diff / next_len + prev_diff / prev_len;
 | 
					      const float3 dir = next_diff / next_len + prev_diff / prev_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* This magic number is unfortunate, but comes from elsewhere in Blender. */
 | 
					      /* This magic number is unfortunate, but comes from elsewhere in Blender. */
 | 
				
			||||||
      const float len = math::length(dir) * 2.5614f;
 | 
					      const float len = dir.length() * 2.5614f;
 | 
				
			||||||
      if (len != 0.0f) {
 | 
					      if (len != 0.0f) {
 | 
				
			||||||
        if (handle_types_left_[i] == HandleType::Auto) {
 | 
					        if (handle_types_left_[i] == HandleType::Auto) {
 | 
				
			||||||
          const float prev_len_clamped = std::min(prev_len, next_len * 5.0f);
 | 
					          const float prev_len_clamped = std::min(prev_len, next_len * 5.0f);
 | 
				
			||||||
@@ -230,12 +228,12 @@ void BezierSpline::ensure_auto_handles() const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (handle_types_left_[i] == HandleType::Vector) {
 | 
					    if (handle_types_left_[i] == HandleType::Vector) {
 | 
				
			||||||
      const float3 prev = previous_position(positions_, is_cyclic_, i);
 | 
					      const float3 prev = previous_position(positions_, is_cyclic_, i);
 | 
				
			||||||
      handle_positions_left_[i] = math::interpolate(positions_[i], prev, 1.0f / 3.0f);
 | 
					      handle_positions_left_[i] = float3::interpolate(positions_[i], prev, 1.0f / 3.0f);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (handle_types_right_[i] == HandleType::Vector) {
 | 
					    if (handle_types_right_[i] == HandleType::Vector) {
 | 
				
			||||||
      const float3 next = next_position(positions_, is_cyclic_, i);
 | 
					      const float3 next = next_position(positions_, is_cyclic_, i);
 | 
				
			||||||
      handle_positions_right_[i] = math::interpolate(positions_[i], next, 1.0f / 3.0f);
 | 
					      handle_positions_right_[i] = float3::interpolate(positions_[i], next, 1.0f / 3.0f);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -277,8 +275,6 @@ static void set_handle_position(const float3 &position,
 | 
				
			|||||||
                                float3 &handle,
 | 
					                                float3 &handle,
 | 
				
			||||||
                                float3 &handle_other)
 | 
					                                float3 &handle_other)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Don't bother when the handle positions are calculated automatically anyway. */
 | 
					  /* Don't bother when the handle positions are calculated automatically anyway. */
 | 
				
			||||||
  if (ELEM(type, BezierSpline::HandleType::Auto, BezierSpline::HandleType::Vector)) {
 | 
					  if (ELEM(type, BezierSpline::HandleType::Auto, BezierSpline::HandleType::Vector)) {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
@@ -287,9 +283,9 @@ static void set_handle_position(const float3 &position,
 | 
				
			|||||||
  handle = new_value;
 | 
					  handle = new_value;
 | 
				
			||||||
  if (type_other == BezierSpline::HandleType::Align) {
 | 
					  if (type_other == BezierSpline::HandleType::Align) {
 | 
				
			||||||
    /* Keep track of the old length of the opposite handle. */
 | 
					    /* Keep track of the old length of the opposite handle. */
 | 
				
			||||||
    const float length = distance(handle_other, position);
 | 
					    const float length = float3::distance(handle_other, position);
 | 
				
			||||||
    /* Set the other handle to directly opposite from the current handle. */
 | 
					    /* Set the other handle to directly opposite from the current handle. */
 | 
				
			||||||
    const float3 dir = normalize(handle - position);
 | 
					    const float3 dir = (handle - position).normalized();
 | 
				
			||||||
    handle_other = position - dir * length;
 | 
					    handle_other = position - dir * length;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -357,7 +353,6 @@ int BezierSpline::evaluated_points_size() const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void BezierSpline::correct_end_tangents() const
 | 
					void BezierSpline::correct_end_tangents() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
  if (is_cyclic_) {
 | 
					  if (is_cyclic_) {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -365,10 +360,10 @@ void BezierSpline::correct_end_tangents() const
 | 
				
			|||||||
  MutableSpan<float3> tangents(evaluated_tangents_cache_);
 | 
					  MutableSpan<float3> tangents(evaluated_tangents_cache_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (handle_positions_right_.first() != positions_.first()) {
 | 
					  if (handle_positions_right_.first() != positions_.first()) {
 | 
				
			||||||
    tangents.first() = normalize(handle_positions_right_.first() - positions_.first());
 | 
					    tangents.first() = (handle_positions_right_.first() - positions_.first()).normalized();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (handle_positions_left_.last() != positions_.last()) {
 | 
					  if (handle_positions_left_.last() != positions_.last()) {
 | 
				
			||||||
    tangents.last() = normalize(positions_.last() - handle_positions_left_.last());
 | 
					    tangents.last() = (positions_.last() - handle_positions_left_.last()).normalized();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -376,22 +371,20 @@ BezierSpline::InsertResult BezierSpline::calculate_segment_insertion(const int i
 | 
				
			|||||||
                                                                     const int next_index,
 | 
					                                                                     const int next_index,
 | 
				
			||||||
                                                                     const float parameter)
 | 
					                                                                     const float parameter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_assert(parameter <= 1.0f && parameter >= 0.0f);
 | 
					  BLI_assert(parameter <= 1.0f && parameter >= 0.0f);
 | 
				
			||||||
  BLI_assert(next_index == 0 || next_index == index + 1);
 | 
					  BLI_assert(next_index == 0 || next_index == index + 1);
 | 
				
			||||||
  const float3 &point_prev = positions_[index];
 | 
					  const float3 &point_prev = positions_[index];
 | 
				
			||||||
  const float3 &handle_prev = handle_positions_right_[index];
 | 
					  const float3 &handle_prev = handle_positions_right_[index];
 | 
				
			||||||
  const float3 &handle_next = handle_positions_left_[next_index];
 | 
					  const float3 &handle_next = handle_positions_left_[next_index];
 | 
				
			||||||
  const float3 &point_next = positions_[next_index];
 | 
					  const float3 &point_next = positions_[next_index];
 | 
				
			||||||
  const float3 center_point = interpolate(handle_prev, handle_next, parameter);
 | 
					  const float3 center_point = float3::interpolate(handle_prev, handle_next, parameter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BezierSpline::InsertResult result;
 | 
					  BezierSpline::InsertResult result;
 | 
				
			||||||
  result.handle_prev = interpolate(point_prev, handle_prev, parameter);
 | 
					  result.handle_prev = float3::interpolate(point_prev, handle_prev, parameter);
 | 
				
			||||||
  result.handle_next = interpolate(handle_next, point_next, parameter);
 | 
					  result.handle_next = float3::interpolate(handle_next, point_next, parameter);
 | 
				
			||||||
  result.left_handle = interpolate(result.handle_prev, center_point, parameter);
 | 
					  result.left_handle = float3::interpolate(result.handle_prev, center_point, parameter);
 | 
				
			||||||
  result.right_handle = interpolate(center_point, result.handle_next, parameter);
 | 
					  result.right_handle = float3::interpolate(center_point, result.handle_next, parameter);
 | 
				
			||||||
  result.position = interpolate(result.left_handle, result.right_handle, parameter);
 | 
					  result.position = float3::interpolate(result.left_handle, result.right_handle, parameter);
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
#include "DNA_tracking_types.h"
 | 
					#include "DNA_tracking_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BKE_tracking.h"
 | 
					#include "BKE_tracking.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender {
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,8 @@
 | 
				
			|||||||
#include "FN_multi_function_builder.hh"
 | 
					#include "FN_multi_function_builder.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_color.hh"
 | 
					#include "BLI_color.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender::bke {
 | 
					namespace blender::bke {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "BLI_compiler_compat.h"
 | 
					#include "BLI_compiler_compat.h"
 | 
				
			||||||
#include "BLI_fileops.h"
 | 
					#include "BLI_fileops.h"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_float4x4.hh"
 | 
					#include "BLI_float4x4.hh"
 | 
				
			||||||
#include "BLI_ghash.h"
 | 
					#include "BLI_ghash.h"
 | 
				
			||||||
#include "BLI_index_range.hh"
 | 
					#include "BLI_index_range.hh"
 | 
				
			||||||
#include "BLI_map.hh"
 | 
					#include "BLI_map.hh"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_path_util.h"
 | 
					#include "BLI_path_util.h"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
#include "BLI_string_ref.hh"
 | 
					#include "BLI_string_ref.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,8 +21,8 @@
 | 
				
			|||||||
#include "MEM_guardedalloc.h"
 | 
					#include "MEM_guardedalloc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_math_matrix.h"
 | 
					#include "BLI_math_matrix.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_math_vector.h"
 | 
					#include "BLI_math_vector.h"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,7 +84,7 @@ size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
BArrayState *BLI_array_store_state_add(BArrayStore *bs,
 | 
					BArrayState *BLI_array_store_state_add(BArrayStore *bs,
 | 
				
			||||||
                                       const void *data,
 | 
					                                       const void *data,
 | 
				
			||||||
                                       const size_t data_len,
 | 
					                                       size_t data_len,
 | 
				
			||||||
                                       const BArrayState *state_reference);
 | 
					                                       const BArrayState *state_reference);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Remove a state and free any unused #BChunk data.
 | 
					 * Remove a state and free any unused #BChunk data.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,7 @@ void _bli_array_wrap(void *arr, uint arr_len, size_t arr_stride, int dir);
 | 
				
			|||||||
 * Access via #BLI_array_wrap
 | 
					 * Access via #BLI_array_wrap
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void _bli_array_permute(
 | 
					void _bli_array_permute(
 | 
				
			||||||
    void *arr, uint arr_len, const size_t arr_stride, const uint *order, void *arr_temp);
 | 
					    void *arr, uint arr_len, size_t arr_stride, const uint *order, void *arr_temp);
 | 
				
			||||||
#define BLI_array_permute(arr, arr_len, order) \
 | 
					#define BLI_array_permute(arr, arr_len, order) \
 | 
				
			||||||
  _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, NULL)
 | 
					  _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, NULL)
 | 
				
			||||||
#define BLI_array_permute_ex(arr, arr_len, order, arr_temp) \
 | 
					#define BLI_array_permute_ex(arr, arr_len, order, arr_temp) \
 | 
				
			||||||
@@ -152,7 +152,7 @@ bool _bli_array_is_zeroed(const void *arr, uint arr_len, size_t arr_stride);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
bool _bli_array_iter_spiral_square(const void *arr_v,
 | 
					bool _bli_array_iter_spiral_square(const void *arr_v,
 | 
				
			||||||
                                   const int arr_shape[2],
 | 
					                                   const int arr_shape[2],
 | 
				
			||||||
                                   const size_t elem_size,
 | 
					                                   size_t elem_size,
 | 
				
			||||||
                                   const int center[2],
 | 
					                                   const int center[2],
 | 
				
			||||||
                                   bool (*test_fn)(const void *arr_item, void *user_data),
 | 
					                                   bool (*test_fn)(const void *arr_item, void *user_data),
 | 
				
			||||||
                                   void *user_data);
 | 
					                                   void *user_data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,7 @@ enum {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * \note Never decreases the amount of memory allocated.
 | 
					 * \note Never decreases the amount of memory allocated.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count);
 | 
					void BLI_buffer_resize(BLI_Buffer *buffer, size_t new_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Ensure size, throwing away old data, respecting #BLI_BUFFER_USE_CALLOC.
 | 
					 * Ensure size, throwing away old data, respecting #BLI_BUFFER_USE_CALLOC.
 | 
				
			||||||
@@ -83,7 +83,7 @@ void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count);
 | 
				
			|||||||
 * - Ignored (malloc'd).
 | 
					 * - Ignored (malloc'd).
 | 
				
			||||||
 * - Cleared (when #BLI_BUFFER_USE_CALLOC is set).
 | 
					 * - Cleared (when #BLI_BUFFER_USE_CALLOC is set).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_buffer_reinit(BLI_Buffer *buffer, const size_t new_count);
 | 
					void BLI_buffer_reinit(BLI_Buffer *buffer, size_t new_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Append an array of elements.
 | 
					 * Append an array of elements.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -215,9 +215,9 @@ void BLI_delaunay_2d_cdt_free(CDT_result *result);
 | 
				
			|||||||
/* C++ Interface. */
 | 
					/* C++ Interface. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#  include "BLI_array.hh"
 | 
					#  include "BLI_array.hh"
 | 
				
			||||||
 | 
					#  include "BLI_double2.hh"
 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
#  include "BLI_math_vec_mpq_types.hh"
 | 
					#  include "BLI_mpq2.hh"
 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#  include "BLI_vector.hh"
 | 
					#  include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender::meshintersect {
 | 
					namespace blender::meshintersect {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										143
									
								
								source/blender/blenlib/BLI_double2.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								source/blender/blenlib/BLI_double2.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * \ingroup bli
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_double3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct double2 {
 | 
				
			||||||
 | 
					  double x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double2() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double2(const double *ptr) : x{ptr[0]}, y{ptr[1]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double2(double x, double y) : x(x), y(y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double2(const double3 &other) : x(other.x), y(other.y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator double *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const double *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_v2_db(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double2 operator+(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double2 operator-(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double2 operator*(const double2 &a, double b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double2 operator/(const double2 &a, double b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0.0);
 | 
				
			||||||
 | 
					    return {a.x / b, a.y / b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double2 operator*(double a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x != b.x || a.y != b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const double2 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double dot(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double2 interpolate(const double2 &a, const double2 &b, double t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double2 abs(const double2 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return double2(fabs(a.x), fabs(a.y));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double distance(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double distance_squared(const double2 &a, const double2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double2 diff = a - b;
 | 
				
			||||||
 | 
					    return double2::dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct isect_result {
 | 
				
			||||||
 | 
					    enum {
 | 
				
			||||||
 | 
					      LINE_LINE_COLINEAR = -1,
 | 
				
			||||||
 | 
					      LINE_LINE_NONE = 0,
 | 
				
			||||||
 | 
					      LINE_LINE_EXACT = 1,
 | 
				
			||||||
 | 
					      LINE_LINE_CROSS = 2,
 | 
				
			||||||
 | 
					    } kind;
 | 
				
			||||||
 | 
					    double lambda;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isect_result isect_seg_seg(const double2 &v1,
 | 
				
			||||||
 | 
					                                    const double2 &v2,
 | 
				
			||||||
 | 
					                                    const double2 &v3,
 | 
				
			||||||
 | 
					                                    const double2 &v4);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
							
								
								
									
										246
									
								
								source/blender/blenlib/BLI_double3.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								source/blender/blenlib/BLI_double3.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,246 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * \ingroup bli
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_math_vector.h"
 | 
				
			||||||
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct double3 {
 | 
				
			||||||
 | 
					  double x, y, z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3(const double *ptr) : x{ptr[0]}, y{ptr[1]}, z{ptr[2]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3(const double (*ptr)[3]) : double3((const double *)ptr)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit double3(double value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit double3(int value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3(double x, double y, double z) : x{x}, y{y}, z{z}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const double *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator double *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double normalize_and_get_length()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return normalize_v3_db(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3 normalized() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 result;
 | 
				
			||||||
 | 
					    normalize_v3_v3_db(result, *this);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_v3_db(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double length_squared() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_squared_v3_db(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reflect(const double3 &normal)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *this = this->reflected(normal);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double3 reflected(const double3 &normal) const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 result;
 | 
				
			||||||
 | 
					    reflect_v3_v3v3_db(result, *this, normal);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 safe_divide(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 result;
 | 
				
			||||||
 | 
					    result.x = (b.x == 0.0) ? 0.0 : a.x / b.x;
 | 
				
			||||||
 | 
					    result.y = (b.y == 0.0) ? 0.0 : a.y / b.y;
 | 
				
			||||||
 | 
					    result.z = (b.z == 0.0) ? 0.0 : a.z / b.z;
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void invert()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x = -x;
 | 
				
			||||||
 | 
					    y = -y;
 | 
				
			||||||
 | 
					    z = -z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator+(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y, a.z + b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator+=(const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x += b.x;
 | 
				
			||||||
 | 
					    this->y += b.y;
 | 
				
			||||||
 | 
					    this->z += b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator-(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y, a.z - b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator-(const double3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {-a.x, -a.y, -a.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator-=(const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x -= b.x;
 | 
				
			||||||
 | 
					    this->y -= b.y;
 | 
				
			||||||
 | 
					    this->z -= b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator*=(const double &scalar)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= scalar;
 | 
				
			||||||
 | 
					    this->y *= scalar;
 | 
				
			||||||
 | 
					    this->z *= scalar;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator*=(const double3 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= other.x;
 | 
				
			||||||
 | 
					    this->y *= other.y;
 | 
				
			||||||
 | 
					    this->z *= other.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator*(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b.x, a.y * b.y, a.z * b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator*(const double3 &a, const double &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b, a.z * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator*(const double &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend double3 operator/(const double3 &a, const double &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0.0);
 | 
				
			||||||
 | 
					    return {a.x / b, a.y / b, a.z / b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y && a.z == b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x != b.x || a.y != b.y || a.z != b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const double3 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double dot(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y + a.z * b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 cross_high_precision(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 result;
 | 
				
			||||||
 | 
					    cross_v3_v3v3_db(result, a, b);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 project(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 result;
 | 
				
			||||||
 | 
					    project_v3_v3v3_db(result, a, b);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double distance(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double distance_squared(const double3 &a, const double3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double3 diff = a - b;
 | 
				
			||||||
 | 
					    return double3::dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 interpolate(const double3 &a, const double3 &b, double t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 abs(const double3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return double3(fabs(a.x), fabs(a.y), fabs(a.z));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static int dominant_axis(const double3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double x = (a.x >= 0) ? a.x : -a.x;
 | 
				
			||||||
 | 
					    double y = (a.y >= 0) ? a.y : -a.y;
 | 
				
			||||||
 | 
					    double z = (a.z >= 0) ? a.z : -a.z;
 | 
				
			||||||
 | 
					    return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static double3 cross_poly(Span<double3> poly);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
@@ -155,8 +155,7 @@ double BLI_dir_free_space(const char *dir) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \note can return NULL when the size is not big enough
 | 
					 * \note can return NULL when the size is not big enough
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
char *BLI_current_working_dir(char *dir, const size_t maxncpy) ATTR_WARN_UNUSED_RESULT
 | 
					char *BLI_current_working_dir(char *dir, size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					 | 
				
			||||||
eFileAttributes BLI_file_attributes(const char *path);
 | 
					eFileAttributes BLI_file_attributes(const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** \} */
 | 
					/** \} */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										218
									
								
								source/blender/blenlib/BLI_float2.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								source/blender/blenlib/BLI_float2.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct float2 {
 | 
				
			||||||
 | 
					  float x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2(const float *ptr) : x{ptr[0]}, y{ptr[1]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float2(float value) : x(value), y(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float2(int value) : x(value), y(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2(float x, float y) : x(x), y(y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2(const float3 &other) : x(other.x), y(other.y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator float *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const float *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_v2(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float length_squared() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_squared_v2(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool is_zero() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return this->x == 0.0f && this->y == 0.0f;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2 &operator+=(const float2 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x += other.x;
 | 
				
			||||||
 | 
					    y += other.y;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2 &operator-=(const float2 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x -= other.x;
 | 
				
			||||||
 | 
					    y -= other.y;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2 &operator*=(float factor)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x *= factor;
 | 
				
			||||||
 | 
					    y *= factor;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float2 &operator/=(float divisor)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x /= divisor;
 | 
				
			||||||
 | 
					    y /= divisor;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint64_t hash() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    uint64_t x1 = *reinterpret_cast<const uint32_t *>(&x);
 | 
				
			||||||
 | 
					    uint64_t x2 = *reinterpret_cast<const uint32_t *>(&y);
 | 
				
			||||||
 | 
					    return (x1 * 812519) ^ (x2 * 707951);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator+(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator-(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator-(const float2 &a, const float &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b, a.y - b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator*(const float2 &a, float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator/(const float2 &a, float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0.0f);
 | 
				
			||||||
 | 
					    return {a.x / b, a.y / b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float2 operator*(float a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const float2 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float2 safe_divide(const float2 &a, const float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (b != 0.0f) ? a / b : float2(0.0f);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float2 floor(const float2 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return float2(floorf(a.x), floorf(a.y));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Returns a normalized vector. The original vector is not changed.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  float2 normalized() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float2 result;
 | 
				
			||||||
 | 
					    normalize_v2_v2(result, *this);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float dot(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float2 interpolate(const float2 &a, const float2 &b, float t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float2 abs(const float2 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return float2(fabsf(a.x), fabsf(a.y));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float distance(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float distance_squared(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float2 diff = a - b;
 | 
				
			||||||
 | 
					    return float2::dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct isect_result {
 | 
				
			||||||
 | 
					    enum {
 | 
				
			||||||
 | 
					      LINE_LINE_COLINEAR = -1,
 | 
				
			||||||
 | 
					      LINE_LINE_NONE = 0,
 | 
				
			||||||
 | 
					      LINE_LINE_EXACT = 1,
 | 
				
			||||||
 | 
					      LINE_LINE_CROSS = 2,
 | 
				
			||||||
 | 
					    } kind;
 | 
				
			||||||
 | 
					    float lambda;
 | 
				
			||||||
 | 
					    float mu;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isect_result isect_seg_seg(const float2 &v1,
 | 
				
			||||||
 | 
					                                    const float2 &v2,
 | 
				
			||||||
 | 
					                                    const float2 &v3,
 | 
				
			||||||
 | 
					                                    const float2 &v4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const float2 &a, const float2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return !(a == b);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
							
								
								
									
										320
									
								
								source/blender/blenlib/BLI_float3.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								source/blender/blenlib/BLI_float3.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,320 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_math_vector.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct float3 {
 | 
				
			||||||
 | 
					  float x, y, z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3(const float *ptr) : x{ptr[0]}, y{ptr[1]}, z{ptr[2]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3(const float (*ptr)[3]) : float3(static_cast<const float *>(ptr[0]))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float3(float value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float3(int value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3(float x, float y, float z) : x{x}, y{y}, z{z}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const float *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator float *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator+(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y, a.z + b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator+(const float3 &a, const float &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b, a.y + b, a.z + b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3 &operator+=(const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x += b.x;
 | 
				
			||||||
 | 
					    this->y += b.y;
 | 
				
			||||||
 | 
					    this->z += b.z;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator-(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y, a.z - b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator-(const float3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {-a.x, -a.y, -a.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator-(const float3 &a, const float &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b, a.y - b, a.z - b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3 &operator-=(const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x -= b.x;
 | 
				
			||||||
 | 
					    this->y -= b.y;
 | 
				
			||||||
 | 
					    this->z -= b.z;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3 &operator*=(float scalar)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= scalar;
 | 
				
			||||||
 | 
					    this->y *= scalar;
 | 
				
			||||||
 | 
					    this->z *= scalar;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3 &operator*=(const float3 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= other.x;
 | 
				
			||||||
 | 
					    this->y *= other.y;
 | 
				
			||||||
 | 
					    this->z *= other.z;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator*(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b.x, a.y * b.y, a.z * b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator*(const float3 &a, float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b, a.z * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator*(float a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float3 operator/(const float3 &a, float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0.0f);
 | 
				
			||||||
 | 
					    return {a.x / b, a.y / b, a.z / b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const float3 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y && a.z == b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return !(a == b);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float normalize_and_get_length()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return normalize_v3(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Normalizes the vector in place.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  void normalize()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    normalize_v3(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Returns a normalized vector. The original vector is not changed.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  float3 normalized() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    normalize_v3_v3(result, *this);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_v3(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float length_squared() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_squared_v3(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool is_zero() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return this->x == 0.0f && this->y == 0.0f && this->z == 0.0f;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reflect(const float3 &normal)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *this = this->reflected(normal);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float3 reflected(const float3 &normal) const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    reflect_v3_v3v3(result, *this, normal);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 refract(const float3 &incident, const float3 &normal, const float eta)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    float k = 1.0f - eta * eta * (1.0f - dot(normal, incident) * dot(normal, incident));
 | 
				
			||||||
 | 
					    if (k < 0.0f) {
 | 
				
			||||||
 | 
					      result = float3(0.0f);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      result = eta * incident - (eta * dot(normal, incident) + sqrt(k)) * normal;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 faceforward(const float3 &vector, const float3 &incident, const float3 &reference)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return dot(reference, incident) < 0.0f ? vector : -vector;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 safe_divide(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    result.x = (b.x == 0.0f) ? 0.0f : a.x / b.x;
 | 
				
			||||||
 | 
					    result.y = (b.y == 0.0f) ? 0.0f : a.y / b.y;
 | 
				
			||||||
 | 
					    result.z = (b.z == 0.0f) ? 0.0f : a.z / b.z;
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 min(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 max(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void min_max(const float3 &vector, float3 &min, float3 &max)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    min = float3::min(vector, min);
 | 
				
			||||||
 | 
					    max = float3::max(vector, max);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 safe_divide(const float3 &a, const float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (b != 0.0f) ? a / b : float3(0.0f);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 floor(const float3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return float3(floorf(a.x), floorf(a.y), floorf(a.z));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void invert()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x = -x;
 | 
				
			||||||
 | 
					    y = -y;
 | 
				
			||||||
 | 
					    z = -z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint64_t hash() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    uint64_t x1 = *reinterpret_cast<const uint32_t *>(&x);
 | 
				
			||||||
 | 
					    uint64_t x2 = *reinterpret_cast<const uint32_t *>(&y);
 | 
				
			||||||
 | 
					    uint64_t x3 = *reinterpret_cast<const uint32_t *>(&z);
 | 
				
			||||||
 | 
					    return (x1 * 435109) ^ (x2 * 380867) ^ (x3 * 1059217);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float dot(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y + a.z * b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 cross_high_precision(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    cross_v3_v3v3_hi_prec(result, a, b);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 cross(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    cross_v3_v3v3(result, a, b);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 project(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 result;
 | 
				
			||||||
 | 
					    project_v3_v3v3(result, a, b);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float distance(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float distance_squared(const float3 &a, const float3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float3 diff = a - b;
 | 
				
			||||||
 | 
					    return float3::dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 interpolate(const float3 &a, const float3 &b, float t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float3 abs(const float3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
							
								
								
									
										138
									
								
								source/blender/blenlib/BLI_float4.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								source/blender/blenlib/BLI_float4.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct float4 {
 | 
				
			||||||
 | 
					  float x, y, z, w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float4() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float4(const float *ptr) : x{ptr[0]}, y{ptr[1]}, z{ptr[2]}, w{ptr[3]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float4(float value) : x(value), y(value), z(value), w(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit float4(int value) : x(value), y(value), z(value), w(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator float *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator+(const float4 &a, const float &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b, a.y + b, a.z + b, a.w + b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const float *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float4 &operator+=(const float4 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x += other.x;
 | 
				
			||||||
 | 
					    y += other.y;
 | 
				
			||||||
 | 
					    z += other.z;
 | 
				
			||||||
 | 
					    w += other.w;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator-(const float4 &a, const float4 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator-(const float4 &a, const float &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b, a.y - b, a.z - b, a.w - b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator+(const float4 &a, const float4 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator/(const float4 &a, float f)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(f != 0.0f);
 | 
				
			||||||
 | 
					    return a * (1.0f / f);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float4 &operator*=(float factor)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x *= factor;
 | 
				
			||||||
 | 
					    y *= factor;
 | 
				
			||||||
 | 
					    z *= factor;
 | 
				
			||||||
 | 
					    w *= factor;
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator*(const float4 &a, float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b, a.z * b, a.w * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend float4 operator*(float a, const float4 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return len_v4(*this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float distance(const float4 &a, const float4 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float4 safe_divide(const float4 &a, const float b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (b != 0.0f) ? a / b : float4(0.0f);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float4 interpolate(const float4 &a, const float4 &b, float t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float4 floor(const float4 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return float4(floorf(a.x), floorf(a.y), floorf(a.z), floorf(a.w));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static float4 normalize(const float4 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    const float t = len_v4(a);
 | 
				
			||||||
 | 
					    return (t != 0.0f) ? a / t : float4(0.0f);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
@@ -16,9 +16,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_math_matrix.h"
 | 
					#include "BLI_math_matrix.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_math_vector.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender {
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,7 +63,7 @@ struct float4x4 {
 | 
				
			|||||||
     * Without the negation, the result would be a so called improper rotation. That means it
 | 
					     * Without the negation, the result would be a so called improper rotation. That means it
 | 
				
			||||||
     * contains a reflection. Such an improper rotation matrix could not be converted to another
 | 
					     * contains a reflection. Such an improper rotation matrix could not be converted to another
 | 
				
			||||||
     * representation of a rotation such as euler angles. */
 | 
					     * representation of a rotation such as euler angles. */
 | 
				
			||||||
    const float3 cross = -math::cross(forward, up);
 | 
					    const float3 cross = -float3::cross(forward, up);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float4x4 matrix;
 | 
					    float4x4 matrix;
 | 
				
			||||||
    matrix.values[0][0] = forward.x;
 | 
					    matrix.values[0][0] = forward.x;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct _GSQueue GSQueue;
 | 
					typedef struct _GSQueue GSQueue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GSQueue *BLI_gsqueue_new(const size_t elem_size);
 | 
					GSQueue *BLI_gsqueue_new(size_t elem_size);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns true if the queue is empty, false otherwise.
 | 
					 * Returns true if the queue is empty, false otherwise.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,7 @@ void *BLI_findptr(const struct ListBase *listbase,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void *BLI_listbase_bytes_find(const ListBase *listbase,
 | 
					void *BLI_listbase_bytes_find(const ListBase *listbase,
 | 
				
			||||||
                              const void *bytes,
 | 
					                              const void *bytes,
 | 
				
			||||||
                              const size_t bytes_size,
 | 
					                              size_t bytes_size,
 | 
				
			||||||
                              int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
 | 
					                              int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Find the first item in the list that matches the given string, or the given index as fallback.
 | 
					 * Find the first item in the list that matches the given string, or the given index as fallback.
 | 
				
			||||||
@@ -96,7 +96,7 @@ void *BLI_listbase_bytes_find(const ListBase *listbase,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void *BLI_listbase_string_or_index_find(const struct ListBase *listbase,
 | 
					void *BLI_listbase_string_or_index_find(const struct ListBase *listbase,
 | 
				
			||||||
                                        const char *string,
 | 
					                                        const char *string,
 | 
				
			||||||
                                        const size_t string_offset,
 | 
					                                        size_t string_offset,
 | 
				
			||||||
                                        int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
 | 
					                                        int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Find backwards. */
 | 
					/* Find backwards. */
 | 
				
			||||||
@@ -133,7 +133,7 @@ void *BLI_rfindptr(const struct ListBase *listbase,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void *BLI_listbase_bytes_rfind(const ListBase *listbase,
 | 
					void *BLI_listbase_bytes_rfind(const ListBase *listbase,
 | 
				
			||||||
                               const void *bytes,
 | 
					                               const void *bytes,
 | 
				
			||||||
                               const size_t bytes_size,
 | 
					                               size_t bytes_size,
 | 
				
			||||||
                               int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
 | 
					                               int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,11 +21,13 @@
 | 
				
			|||||||
 * \brief Math vector functions needed specifically for mesh intersect and boolean.
 | 
					 * \brief Math vector functions needed specifically for mesh intersect and boolean.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_double2.hh"
 | 
				
			||||||
 | 
					#include "BLI_double3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
#  include "BLI_math_vec_mpq_types.hh"
 | 
					#  include "BLI_mpq2.hh"
 | 
				
			||||||
 | 
					#  include "BLI_mpq3.hh"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender {
 | 
					namespace blender {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,91 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU General Public License
 | 
					 | 
				
			||||||
 * as published by the Free Software Foundation; either version 2
 | 
					 | 
				
			||||||
 * of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
					 | 
				
			||||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** \file
 | 
					 | 
				
			||||||
 * \ingroup bli
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef WITH_GMP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace blender {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using mpq2 = vec_base<mpq_class, 2>;
 | 
					 | 
				
			||||||
using mpq3 = vec_base<mpq_class, 3>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace math {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint64_t hash_mpq_class(const mpq_class &value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<> inline uint64_t vector_hash(const mpq2 &vec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return hash_mpq_class(vec.x) ^ (hash_mpq_class(vec.y) * 33);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<> inline uint64_t vector_hash(const mpq3 &vec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return hash_mpq_class(vec.x) ^ (hash_mpq_class(vec.y) * 33) ^ (hash_mpq_class(vec.z) * 33 * 37);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Cannot do this exactly in rational arithmetic!
 | 
					 | 
				
			||||||
 * Approximate by going in and out of doubles.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
template<> inline mpq_class length(const mpq2 &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return mpq_class(sqrt(length_squared(a).get_d()));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Cannot do this exactly in rational arithmetic!
 | 
					 | 
				
			||||||
 * Approximate by going in and out of doubles.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
template<> inline mpq_class length(const mpq3 &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return mpq_class(sqrt(length_squared(a).get_d()));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The buffer avoids allocating a temporary variable.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
inline mpq_class distance_squared_with_buffer(const mpq3 &a, const mpq3 &b, mpq3 &buffer)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  buffer = a;
 | 
					 | 
				
			||||||
  buffer -= b;
 | 
					 | 
				
			||||||
  return dot(buffer, buffer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * The buffer avoids allocating a temporary variable.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
inline mpq_class dot_with_buffer(const mpq3 &a, const mpq3 &b, mpq3 &buffer)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  buffer = a;
 | 
					 | 
				
			||||||
  buffer *= b;
 | 
					 | 
				
			||||||
  buffer.x += buffer.y;
 | 
					 | 
				
			||||||
  buffer.x += buffer.z;
 | 
					 | 
				
			||||||
  return buffer.x;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace math
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace blender
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* WITH_GMP */
 | 
					 | 
				
			||||||
@@ -1,566 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU General Public License
 | 
					 | 
				
			||||||
 * as published by the Free Software Foundation; either version 2
 | 
					 | 
				
			||||||
 * of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
					 | 
				
			||||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright 2022, Blender Foundation.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** \file
 | 
					 | 
				
			||||||
 * \ingroup bli
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <array>
 | 
					 | 
				
			||||||
#include <cmath>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <type_traits>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "BLI_math_vector.hh"
 | 
					 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace blender {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* clang-format off */
 | 
					 | 
				
			||||||
template<typename T>
 | 
					 | 
				
			||||||
using as_uint_type = std::conditional_t<sizeof(T) == sizeof(uint8_t), uint8_t,
 | 
					 | 
				
			||||||
                     std::conditional_t<sizeof(T) == sizeof(uint16_t), uint16_t,
 | 
					 | 
				
			||||||
                     std::conditional_t<sizeof(T) == sizeof(uint32_t), uint32_t,
 | 
					 | 
				
			||||||
                     std::conditional_t<sizeof(T) == sizeof(uint64_t), uint64_t, void>>>>;
 | 
					 | 
				
			||||||
/* clang-format on */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, int Size> struct vec_struct_base {
 | 
					 | 
				
			||||||
  std::array<T, Size> values;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> struct vec_struct_base<T, 2> {
 | 
					 | 
				
			||||||
  T x, y;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> struct vec_struct_base<T, 3> {
 | 
					 | 
				
			||||||
  T x, y, z;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> struct vec_struct_base<T, 4> {
 | 
					 | 
				
			||||||
  T x, y, z, w;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static constexpr int type_length = Size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  using base_type = T;
 | 
					 | 
				
			||||||
  using uint_type = vec_base<as_uint_type<T>, Size>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  explicit vec_base(uint value)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  explicit vec_base(int value)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  explicit vec_base(float value)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  explicit vec_base(double value)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */
 | 
					 | 
				
			||||||
#define BLI_ENABLE_IF_VEC(_size, _test) int S = _size, BLI_ENABLE_IF((S _test))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<BLI_ENABLE_IF_VEC(Size, == 2)> vec_base(T _x, T _y)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    (*this)[0] = _x;
 | 
					 | 
				
			||||||
    (*this)[1] = _y;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<BLI_ENABLE_IF_VEC(Size, == 3)> vec_base(T _x, T _y, T _z)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    (*this)[0] = _x;
 | 
					 | 
				
			||||||
    (*this)[1] = _y;
 | 
					 | 
				
			||||||
    (*this)[2] = _z;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(T _x, T _y, T _z, T _w)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    (*this)[0] = _x;
 | 
					 | 
				
			||||||
    (*this)[1] = _y;
 | 
					 | 
				
			||||||
    (*this)[2] = _z;
 | 
					 | 
				
			||||||
    (*this)[3] = _w;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Mixed scalar-vector constructors. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
 | 
					 | 
				
			||||||
  constexpr vec_base(const vec_base<U, 2> &xy, T z)
 | 
					 | 
				
			||||||
      : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), z)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
 | 
					 | 
				
			||||||
  constexpr vec_base(T x, const vec_base<U, 2> &yz)
 | 
					 | 
				
			||||||
      : vec_base(x, static_cast<T>(yz.x), static_cast<T>(yz.y))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(vec_base<U, 3> xyz, T w)
 | 
					 | 
				
			||||||
      : vec_base(
 | 
					 | 
				
			||||||
            static_cast<T>(xyz.x), static_cast<T>(xyz.y), static_cast<T>(xyz.z), static_cast<T>(w))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(T x, vec_base<U, 3> yzw)
 | 
					 | 
				
			||||||
      : vec_base(
 | 
					 | 
				
			||||||
            static_cast<T>(x), static_cast<T>(yzw.x), static_cast<T>(yzw.y), static_cast<T>(yzw.z))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, typename V, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(vec_base<U, 2> xy, vec_base<V, 2> zw)
 | 
					 | 
				
			||||||
      : vec_base(
 | 
					 | 
				
			||||||
            static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(zw.x), static_cast<T>(zw.y))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(vec_base<U, 2> xy, T z, T w)
 | 
					 | 
				
			||||||
      : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(z), static_cast<T>(w))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(T x, vec_base<U, 2> yz, T w)
 | 
					 | 
				
			||||||
      : vec_base(static_cast<T>(x), static_cast<T>(yz.x), static_cast<T>(yz.y), static_cast<T>(w))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
 | 
					 | 
				
			||||||
  vec_base(T x, T y, vec_base<U, 2> zw)
 | 
					 | 
				
			||||||
      : vec_base(static_cast<T>(x), static_cast<T>(y), static_cast<T>(zw.x), static_cast<T>(zw.y))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Masking. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U, int OtherSize, BLI_ENABLE_IF(OtherSize > Size)>
 | 
					 | 
				
			||||||
  explicit vec_base(const vec_base<U, OtherSize> &other)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(other[i]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef BLI_ENABLE_IF_VEC
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Conversion from pointers (from C-style vectors). */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base(const T *ptr)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = ptr[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base(const T (*ptr)[Size]) : vec_base(static_cast<const T *>(ptr[0]))
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Conversion from other vector types. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<typename U> explicit vec_base(const vec_base<U, Size> &vec)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      (*this)[i] = static_cast<T>(vec[i]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** C-style pointer dereference. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  operator const T *() const
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return reinterpret_cast<const T *>(this);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  operator T *()
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return reinterpret_cast<T *>(this);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Array access. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const T &operator[](int index) const
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(index >= 0);
 | 
					 | 
				
			||||||
    BLI_assert(index < Size);
 | 
					 | 
				
			||||||
    return reinterpret_cast<const T *>(this)[index];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  T &operator[](int index)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(index >= 0);
 | 
					 | 
				
			||||||
    BLI_assert(index < Size);
 | 
					 | 
				
			||||||
    return reinterpret_cast<T *>(this)[index];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Internal Operators Macro. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BLI_INT_OP(_T) template<typename U = _T, BLI_ENABLE_IF((std::is_integral_v<U>))>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BLI_VEC_OP_IMPL(_result, _i, _op) \
 | 
					 | 
				
			||||||
  vec_base _result; \
 | 
					 | 
				
			||||||
  for (int _i = 0; _i < Size; _i++) { \
 | 
					 | 
				
			||||||
    _op; \
 | 
					 | 
				
			||||||
  } \
 | 
					 | 
				
			||||||
  return _result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BLI_VEC_OP_IMPL_SELF(_i, _op) \
 | 
					 | 
				
			||||||
  for (int _i = 0; _i < Size; _i++) { \
 | 
					 | 
				
			||||||
    _op; \
 | 
					 | 
				
			||||||
  } \
 | 
					 | 
				
			||||||
  return *this;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Arithmetic operators. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator+(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator+(const vec_base &a, const T &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator+(const T &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return b + a;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator+=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator+=(const T &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator-(const vec_base &a)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = -a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator-(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator-(const vec_base &a, const T &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator-(const T &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a - b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator-=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator-=(const T &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator*(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator*(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator*(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return b * a;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator*=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator*=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator/(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(!math::is_any_zero(b));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator/(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(b != T(0));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend vec_base operator/(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(!math::is_any_zero(b));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator/=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(b != T(0));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  vec_base &operator/=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(!math::is_any_zero(b));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Binary operators. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator&(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return b & a;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator&=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator&=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator|(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return b | a;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator|=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator|=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator^(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return b ^ a;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator^=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator^=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator~(const vec_base &a)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = ~a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Bit-shift operators. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator<<=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator<<=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator>>=(T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) vec_base &operator>>=(const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Modulo operators. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(!math::is_any_zero(b));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, T b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(b != 0);
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BLI_INT_OP(T) friend vec_base operator%(T a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    BLI_assert(!math::is_any_zero(b));
 | 
					 | 
				
			||||||
    BLI_VEC_OP_IMPL(ret, i, ret[i] = a % b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef BLI_INT_OP
 | 
					 | 
				
			||||||
#undef BLI_VEC_OP_IMPL
 | 
					 | 
				
			||||||
#undef BLI_VEC_OP_IMPL_SELF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Compare. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend bool operator==(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      if (a[i] != b[i]) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend bool operator!=(const vec_base &a, const vec_base &b)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return !(a == b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Misc. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  uint64_t hash() const
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    return math::vector_hash(*this);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  friend std::ostream &operator<<(std::ostream &stream, const vec_base &v)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    stream << "(";
 | 
					 | 
				
			||||||
    for (int i = 0; i < Size; i++) {
 | 
					 | 
				
			||||||
      stream << v[i];
 | 
					 | 
				
			||||||
      if (i != Size - 1) {
 | 
					 | 
				
			||||||
        stream << ", ";
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    stream << ")";
 | 
					 | 
				
			||||||
    return stream;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using int2 = vec_base<int32_t, 2>;
 | 
					 | 
				
			||||||
using int3 = vec_base<int32_t, 3>;
 | 
					 | 
				
			||||||
using int4 = vec_base<int32_t, 4>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using uint2 = vec_base<uint32_t, 2>;
 | 
					 | 
				
			||||||
using uint3 = vec_base<uint32_t, 3>;
 | 
					 | 
				
			||||||
using uint4 = vec_base<uint32_t, 4>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using float2 = vec_base<float, 2>;
 | 
					 | 
				
			||||||
using float3 = vec_base<float, 3>;
 | 
					 | 
				
			||||||
using float4 = vec_base<float, 4>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using double2 = vec_base<double, 2>;
 | 
					 | 
				
			||||||
using double3 = vec_base<double, 3>;
 | 
					 | 
				
			||||||
using double4 = vec_base<double, 4>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace blender
 | 
					 | 
				
			||||||
@@ -1,399 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * This program is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU General Public License
 | 
					 | 
				
			||||||
 * as published by the Free Software Foundation; either version 2
 | 
					 | 
				
			||||||
 * of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
					 | 
				
			||||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright 2022, Blender Foundation.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** \file
 | 
					 | 
				
			||||||
 * \ingroup bli
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <cmath>
 | 
					 | 
				
			||||||
#include <type_traits>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "BLI_math_base_safe.h"
 | 
					 | 
				
			||||||
#include "BLI_math_vector.h"
 | 
					 | 
				
			||||||
#include "BLI_span.hh"
 | 
					 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef WITH_GMP
 | 
					 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace blender::math {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef NDEBUG
 | 
					 | 
				
			||||||
#  define BLI_ASSERT_UNIT(v) \
 | 
					 | 
				
			||||||
    { \
 | 
					 | 
				
			||||||
      const float _test_unit = length_squared(v); \
 | 
					 | 
				
			||||||
      BLI_assert(!(std::abs(_test_unit - 1.0f) >= BLI_ASSERT_UNIT_EPSILON) || \
 | 
					 | 
				
			||||||
                 !(std::abs(_test_unit) >= BLI_ASSERT_UNIT_EPSILON)); \
 | 
					 | 
				
			||||||
    } \
 | 
					 | 
				
			||||||
    (void)0
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#  define BLI_ASSERT_UNIT(v) (void)(v)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define bT typename T::base_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef WITH_GMP
 | 
					 | 
				
			||||||
#  define BLI_ENABLE_IF_FLT_VEC(T) \
 | 
					 | 
				
			||||||
    BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type> || \
 | 
					 | 
				
			||||||
                   std::is_same_v<typename T::base_type, mpq_class>))
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#  define BLI_ENABLE_IF_FLT_VEC(T) BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type>))
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BLI_ENABLE_IF_INT_VEC(T) BLI_ENABLE_IF((std::is_integral_v<typename T::base_type>))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline bool is_zero(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    if (a[i] != bT(0)) {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline bool is_any_zero(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    if (a[i] == bT(0)) {
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline T abs(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = a[i] >= 0 ? a[i] : -a[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline T min(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = a[i] < b[i] ? a[i] : b[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline T max(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = a[i] > b[i] ? a[i] : b[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline T clamp(const T &a, const T &min_v, const T &max_v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result = a;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    CLAMP(result[i], min_v[i], max_v[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline T clamp(const T &a, const bT &min_v, const bT &max_v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result = a;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    CLAMP(result[i], min_v, max_v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    BLI_assert(b[i] != 0);
 | 
					 | 
				
			||||||
    result[i] = std::fmod(a[i], b[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, bT b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  BLI_assert(b != 0);
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = std::fmod(a[i], b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = (b[i] != 0) ? std::fmod(a[i], b[i]) : 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, bT b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (b == 0) {
 | 
					 | 
				
			||||||
    return T(0.0f);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = std::fmod(a[i], b);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline void min_max(const T &vector, T &min_vec, T &max_vec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  min_vec = min(vector, min_vec);
 | 
					 | 
				
			||||||
  max_vec = max(vector, max_vec);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = (b[i] == 0) ? 0 : a[i] / b[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const bT b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return (b != 0) ? a / b : T(0.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T floor(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = std::floor(a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T ceil(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = std::ceil(a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T fract(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T result;
 | 
					 | 
				
			||||||
  for (int i = 0; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result[i] = a[i] - std::floor(a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT dot(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  bT result = a[0] * b[0];
 | 
					 | 
				
			||||||
  for (int i = 1; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result += a[i] * b[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline bT length_manhattan(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  bT result = std::abs(a[0]);
 | 
					 | 
				
			||||||
  for (int i = 1; i < T::type_length; i++) {
 | 
					 | 
				
			||||||
    result += std::abs(a[i]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length_squared(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return dot(a, a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return std::sqrt(length_squared(a));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_manhattan(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return length_manhattan(a - b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_squared(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return length_squared(a - b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return length(a - b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> uint64_t vector_hash(const T &vec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  BLI_STATIC_ASSERT(T::type_length <= 4, "Longer types need to implement vector_hash themself.");
 | 
					 | 
				
			||||||
  const typename T::uint_type &uvec = *reinterpret_cast<const typename T::uint_type *>(&vec);
 | 
					 | 
				
			||||||
  uint64_t result;
 | 
					 | 
				
			||||||
  result = uvec[0] * uint64_t(435109);
 | 
					 | 
				
			||||||
  if constexpr (T::type_length > 1) {
 | 
					 | 
				
			||||||
    result ^= uvec[1] * uint64_t(380867);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if constexpr (T::type_length > 2) {
 | 
					 | 
				
			||||||
    result ^= uvec[2] * uint64_t(1059217);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if constexpr (T::type_length > 3) {
 | 
					 | 
				
			||||||
    result ^= uvec[3] * uint64_t(2002613);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T reflect(const T &incident, const T &normal)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  BLI_ASSERT_UNIT(normal);
 | 
					 | 
				
			||||||
  return incident - 2.0 * dot(normal, incident) * normal;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
 | 
					 | 
				
			||||||
inline T refract(const T &incident, const T &normal, const bT eta)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float dot_ni = dot(normal, incident);
 | 
					 | 
				
			||||||
  float k = 1.0f - eta * eta * (1.0f - dot_ni * dot_ni);
 | 
					 | 
				
			||||||
  if (k < 0.0f) {
 | 
					 | 
				
			||||||
    return T(0.0f);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return eta * incident - (eta * dot_ni + sqrt(k)) * normal;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T project(const T &p, const T &v_proj)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (UNLIKELY(is_zero(v_proj))) {
 | 
					 | 
				
			||||||
    return T(0.0f);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
 | 
					 | 
				
			||||||
inline T normalize_and_get_length(const T &v, bT &out_length)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  out_length = length_squared(v);
 | 
					 | 
				
			||||||
  /* A larger value causes normalize errors in a scaled down models with camera extreme close. */
 | 
					 | 
				
			||||||
  constexpr bT threshold = std::is_same_v<bT, double> ? 1.0e-70 : 1.0e-35f;
 | 
					 | 
				
			||||||
  if (out_length > threshold) {
 | 
					 | 
				
			||||||
    out_length = sqrt(out_length);
 | 
					 | 
				
			||||||
    return v / out_length;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  /* Either the vector is small or one of it's values contained `nan`. */
 | 
					 | 
				
			||||||
  out_length = 0.0;
 | 
					 | 
				
			||||||
  return T(0.0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T normalize(const T &v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  bT len;
 | 
					 | 
				
			||||||
  return normalize_and_get_length(v, len);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))>
 | 
					 | 
				
			||||||
inline T cross(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T,
 | 
					 | 
				
			||||||
         BLI_ENABLE_IF((std::is_same_v<bT, float>)),
 | 
					 | 
				
			||||||
         BLI_ENABLE_IF((T::type_length == 3))>
 | 
					 | 
				
			||||||
inline T cross_high_precision(const T &a, const T &b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return {(float)((double)a.y * b.z - (double)a.z * b.y),
 | 
					 | 
				
			||||||
          (float)((double)a.z * b.x - (double)a.x * b.z),
 | 
					 | 
				
			||||||
          (float)((double)a.x * b.y - (double)a.y * b.x)};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))>
 | 
					 | 
				
			||||||
inline T cross_poly(Span<T> poly)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  /* Newell's Method. */
 | 
					 | 
				
			||||||
  int nv = static_cast<int>(poly.size());
 | 
					 | 
				
			||||||
  if (nv < 3) {
 | 
					 | 
				
			||||||
    return T(0, 0, 0);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  const T *v_prev = &poly[nv - 1];
 | 
					 | 
				
			||||||
  const T *v_curr = &poly[0];
 | 
					 | 
				
			||||||
  T n(0, 0, 0);
 | 
					 | 
				
			||||||
  for (int i = 0; i < nv;) {
 | 
					 | 
				
			||||||
    n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]);
 | 
					 | 
				
			||||||
    n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]);
 | 
					 | 
				
			||||||
    n[2] = n[2] + ((*v_prev)[0] - (*v_curr)[0]) * ((*v_prev)[1] + (*v_curr)[1]);
 | 
					 | 
				
			||||||
    v_prev = v_curr;
 | 
					 | 
				
			||||||
    ++i;
 | 
					 | 
				
			||||||
    if (i < nv) {
 | 
					 | 
				
			||||||
      v_curr = &poly[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return n;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T interpolate(const T &a, const T &b, bT t)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return a * (1 - t) + b * t;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
 | 
					 | 
				
			||||||
inline T faceforward(const T &vector, const T &incident, const T &reference)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return (dot(reference, incident) < 0) ? vector : -vector;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> inline int dominant_axis(const T &a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  T b = abs(a);
 | 
					 | 
				
			||||||
  return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Intersections. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T> struct isect_result {
 | 
					 | 
				
			||||||
  enum {
 | 
					 | 
				
			||||||
    LINE_LINE_COLINEAR = -1,
 | 
					 | 
				
			||||||
    LINE_LINE_NONE = 0,
 | 
					 | 
				
			||||||
    LINE_LINE_EXACT = 1,
 | 
					 | 
				
			||||||
    LINE_LINE_CROSS = 2,
 | 
					 | 
				
			||||||
  } kind;
 | 
					 | 
				
			||||||
  bT lambda;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
 | 
					 | 
				
			||||||
isect_result<T> isect_seg_seg(const T &v1, const T &v2, const T &v3, const T &v4);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef BLI_ENABLE_IF_FLT_VEC
 | 
					 | 
				
			||||||
#undef BLI_ENABLE_IF_INT_VEC
 | 
					 | 
				
			||||||
#undef bT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace blender::math
 | 
					 | 
				
			||||||
@@ -38,13 +38,13 @@ extern "C" {
 | 
				
			|||||||
struct MemArena;
 | 
					struct MemArena;
 | 
				
			||||||
typedef struct MemArena MemArena;
 | 
					typedef struct MemArena MemArena;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct MemArena *BLI_memarena_new(const size_t bufsize,
 | 
					struct MemArena *BLI_memarena_new(size_t bufsize,
 | 
				
			||||||
                                  const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
 | 
					                                  const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
 | 
				
			||||||
    ATTR_NONNULL(2) ATTR_MALLOC;
 | 
					    ATTR_NONNULL(2) ATTR_MALLOC;
 | 
				
			||||||
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1);
 | 
					void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1);
 | 
				
			||||||
void BLI_memarena_use_malloc(struct MemArena *ma) ATTR_NONNULL(1);
 | 
					void BLI_memarena_use_malloc(struct MemArena *ma) ATTR_NONNULL(1);
 | 
				
			||||||
void BLI_memarena_use_calloc(struct MemArena *ma) ATTR_NONNULL(1);
 | 
					void BLI_memarena_use_calloc(struct MemArena *ma) ATTR_NONNULL(1);
 | 
				
			||||||
void BLI_memarena_use_align(struct MemArena *ma, const size_t align) ATTR_NONNULL(1);
 | 
					void BLI_memarena_use_align(struct MemArena *ma, size_t align) ATTR_NONNULL(1);
 | 
				
			||||||
void *BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT
 | 
					void *BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT
 | 
				
			||||||
    ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2);
 | 
					    ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2);
 | 
				
			||||||
void *BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT
 | 
					void *BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* it may be defined already */
 | 
					/* it may be defined already */
 | 
				
			||||||
#ifndef __BLI_UTILDEFINES_H__
 | 
					#ifndef __BLI_UTILDEFINES_H__
 | 
				
			||||||
bool BLI_memory_is_zero(const void *arr, const size_t size);
 | 
					bool BLI_memory_is_zero(const void *arr, size_t size);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -557,4 +557,13 @@ Container &move_assign_container(Container &dst, Container &&src) noexcept(
 | 
				
			|||||||
  return dst;
 | 
					  return dst;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Utility macro that wraps `std::enable_if` to make it a bit easier to use and less verbose for
 | 
				
			||||||
 | 
					 * SFINAE in common cases.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \note Often one has to invoke this macro with double parenthesis. That's because the condition
 | 
				
			||||||
 | 
					 * often contains a comma and angle brackets are not recognized as parenthesis by the preprocessor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define BLI_ENABLE_IF(condition) typename std::enable_if_t<condition> * = nullptr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace blender
 | 
					}  // namespace blender
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,11 +28,12 @@
 | 
				
			|||||||
#  include <iostream>
 | 
					#  include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#  include "BLI_array.hh"
 | 
					#  include "BLI_array.hh"
 | 
				
			||||||
 | 
					#  include "BLI_double3.hh"
 | 
				
			||||||
 | 
					#  include "BLI_float3.hh"
 | 
				
			||||||
#  include "BLI_index_range.hh"
 | 
					#  include "BLI_index_range.hh"
 | 
				
			||||||
#  include "BLI_map.hh"
 | 
					#  include "BLI_map.hh"
 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
#  include "BLI_math_vec_mpq_types.hh"
 | 
					#  include "BLI_mpq3.hh"
 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#  include "BLI_span.hh"
 | 
					#  include "BLI_span.hh"
 | 
				
			||||||
#  include "BLI_utility_mixins.hh"
 | 
					#  include "BLI_utility_mixins.hh"
 | 
				
			||||||
#  include "BLI_vector.hh"
 | 
					#  include "BLI_vector.hh"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										184
									
								
								source/blender/blenlib/BLI_mpq2.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								source/blender/blenlib/BLI_mpq2.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * \ingroup bli
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
 | 
					#  include "BLI_mpq3.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mpq2 {
 | 
				
			||||||
 | 
					  mpq_class x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2(const mpq_class *ptr) : x{ptr[0]}, y{ptr[1]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2(mpq_class x, mpq_class y) : x(x), y(y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2(const mpq2 &other) : x(other.x), y(other.y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2(mpq2 &&other) noexcept : x(std::move(other.x)), y(std::move(other.y))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ~mpq2() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2 &operator=(const mpq2 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (this != &other) {
 | 
				
			||||||
 | 
					      x = other.x;
 | 
				
			||||||
 | 
					      y = other.y;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2 &operator=(mpq2 &&other) noexcept
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x = std::move(other.x);
 | 
				
			||||||
 | 
					    y = std::move(other.y);
 | 
				
			||||||
 | 
					    return *this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq2(const mpq3 &other) : x(other.x), y(other.y)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator mpq_class *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const mpq_class *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Cannot do this exactly in rational arithmetic!
 | 
				
			||||||
 | 
					   * Approximate by going in and out of doubles.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  mpq_class length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class lsquared = dot(*this, *this);
 | 
				
			||||||
 | 
					    return mpq_class(sqrt(lsquared.get_d()));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq2 operator+(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x + b.x, a.y + b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq2 operator-(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x - b.x, a.y - b.y};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq2 operator*(const mpq2 &a, mpq_class b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b, a.y * b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq2 operator/(const mpq2 &a, mpq_class b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0);
 | 
				
			||||||
 | 
					    return {a.x / b, a.y / b};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq2 operator*(mpq_class a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return b * a;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x != b.x || a.y != b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const mpq2 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class dot(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq2 interpolate(const mpq2 &a, const mpq2 &b, mpq_class t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a * (1 - t) + b * t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq2 abs(const mpq2 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
 | 
				
			||||||
 | 
					    mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
 | 
				
			||||||
 | 
					    return mpq2(abs_x, abs_y);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class distance(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return (a - b).length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class distance_squared(const mpq2 &a, const mpq2 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq2 diff = a - b;
 | 
				
			||||||
 | 
					    return dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct isect_result {
 | 
				
			||||||
 | 
					    enum {
 | 
				
			||||||
 | 
					      LINE_LINE_COLINEAR = -1,
 | 
				
			||||||
 | 
					      LINE_LINE_NONE = 0,
 | 
				
			||||||
 | 
					      LINE_LINE_EXACT = 1,
 | 
				
			||||||
 | 
					      LINE_LINE_CROSS = 2,
 | 
				
			||||||
 | 
					    } kind;
 | 
				
			||||||
 | 
					    mpq_class lambda;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static isect_result isect_seg_seg(const mpq2 &v1,
 | 
				
			||||||
 | 
					                                    const mpq2 &v2,
 | 
				
			||||||
 | 
					                                    const mpq2 &v3,
 | 
				
			||||||
 | 
					                                    const mpq2 &v4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** There is a sensible use for hashing on exact arithmetic types. */
 | 
				
			||||||
 | 
					  uint64_t hash() const;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* WITH_GMP */
 | 
				
			||||||
							
								
								
									
										297
									
								
								source/blender/blenlib/BLI_mpq3.hh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								source/blender/blenlib/BLI_mpq3.hh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2
 | 
				
			||||||
 | 
					 * of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software Foundation,
 | 
				
			||||||
 | 
					 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \file
 | 
				
			||||||
 | 
					 * \ingroup bli
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  include "BLI_math.h"
 | 
				
			||||||
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
 | 
					#  include "BLI_span.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mpq3 {
 | 
				
			||||||
 | 
					  mpq_class x, y, z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3(const mpq_class *ptr) : x{ptr[0]}, y{ptr[1]}, z{ptr[2]}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3(const mpq_class (*ptr)[3]) : mpq3((const mpq_class *)ptr)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit mpq3(mpq_class value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit mpq3(int value) : x(value), y(value), z(value)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3(mpq_class x, mpq_class y, mpq_class z) : x{x}, y{y}, z{z}
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator const mpq_class *() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  operator mpq_class *()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return &x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Cannot do this exactly in rational arithmetic!
 | 
				
			||||||
 | 
					   * Approximate by going in and out of doubles.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  mpq_class normalize_and_get_length()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double dv[3] = {x.get_d(), y.get_d(), z.get_d()};
 | 
				
			||||||
 | 
					    double len = normalize_v3_db(dv);
 | 
				
			||||||
 | 
					    this->x = mpq_class(dv[0]);
 | 
				
			||||||
 | 
					    this->y = mpq_class(dv[1]);
 | 
				
			||||||
 | 
					    this->z = mpq_class(dv[2]);
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3 normalized() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    double dv[3] = {x.get_d(), y.get_d(), z.get_d()};
 | 
				
			||||||
 | 
					    double dr[3];
 | 
				
			||||||
 | 
					    normalize_v3_v3_db(dr, dv);
 | 
				
			||||||
 | 
					    return mpq3(mpq_class(dr[0]), mpq_class(dr[1]), mpq_class(dr[2]));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Cannot do this exactly in rational arithmetic!
 | 
				
			||||||
 | 
					   * Approximate by going in and out of double.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  mpq_class length() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class lsquared = this->length_squared();
 | 
				
			||||||
 | 
					    double dsquared = lsquared.get_d();
 | 
				
			||||||
 | 
					    double d = sqrt(dsquared);
 | 
				
			||||||
 | 
					    return mpq_class(d);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq_class length_squared() const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return x * x + y * y + z * z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void reflect(const mpq3 &normal)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *this = this->reflected(normal);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mpq3 reflected(const mpq3 &normal) const
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq3 result;
 | 
				
			||||||
 | 
					    const mpq_class dot2 = 2 * dot(*this, normal);
 | 
				
			||||||
 | 
					    result.x = this->x - (dot2 * normal.x);
 | 
				
			||||||
 | 
					    result.y = this->y - (dot2 * normal.y);
 | 
				
			||||||
 | 
					    result.z = this->z - (dot2 * normal.z);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 safe_divide(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq3 result;
 | 
				
			||||||
 | 
					    result.x = (b.x == 0) ? mpq_class(0) : a.x / b.x;
 | 
				
			||||||
 | 
					    result.y = (b.y == 0) ? mpq_class(0) : a.y / b.y;
 | 
				
			||||||
 | 
					    result.z = (b.z == 0) ? mpq_class(0) : a.z / b.z;
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void invert()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    x = -x;
 | 
				
			||||||
 | 
					    y = -y;
 | 
				
			||||||
 | 
					    z = -z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator+(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(a.x + b.x, a.y + b.y, a.z + b.z);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator+=(const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x += b.x;
 | 
				
			||||||
 | 
					    this->y += b.y;
 | 
				
			||||||
 | 
					    this->z += b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator-(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(a.x - b.x, a.y - b.y, a.z - b.z);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator-(const mpq3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(-a.x, -a.y, -a.z);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator-=(const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x -= b.x;
 | 
				
			||||||
 | 
					    this->y -= b.y;
 | 
				
			||||||
 | 
					    this->z -= b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator*=(mpq_class scalar)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= scalar;
 | 
				
			||||||
 | 
					    this->y *= scalar;
 | 
				
			||||||
 | 
					    this->z *= scalar;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator*=(const mpq3 &other)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    this->x *= other.x;
 | 
				
			||||||
 | 
					    this->y *= other.y;
 | 
				
			||||||
 | 
					    this->z *= other.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator*(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return {a.x * b.x, a.y * b.y, a.z * b.z};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator*(const mpq3 &a, const mpq_class &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(a.x * b, a.y * b, a.z * b);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator*(const mpq_class &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(a * b.x, a * b.y, a * b.z);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend mpq3 operator/(const mpq3 &a, const mpq_class &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    BLI_assert(b != 0);
 | 
				
			||||||
 | 
					    return mpq3(a.x / b, a.y / b, a.z / b);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator==(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x == b.x && a.y == b.y && a.z == b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend bool operator!=(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x != b.x || a.y != b.y || a.z != b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &stream, const mpq3 &v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class dot(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return a.x * b.x + a.y * b.y + a.z * b.z;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class dot_with_buffer(const mpq3 &a, const mpq3 &b, mpq3 &buffer)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    buffer = a;
 | 
				
			||||||
 | 
					    buffer *= b;
 | 
				
			||||||
 | 
					    buffer.x += buffer.y;
 | 
				
			||||||
 | 
					    buffer.x += buffer.z;
 | 
				
			||||||
 | 
					    return buffer.x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 cross(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return mpq3(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 cross_high_precision(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    return cross(a, b);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 project(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    const mpq_class mul = mpq3::dot(a, b) / mpq3::dot(b, b);
 | 
				
			||||||
 | 
					    return mpq3(mul * b[0], mul * b[1], mul * b[2]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class distance(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq3 diff(a.x - b.x, a.y - b.y, a.z - b.z);
 | 
				
			||||||
 | 
					    return diff.length();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class distance_squared(const mpq3 &a, const mpq3 &b)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq3 diff(a.x - b.x, a.y - b.y, a.z - b.z);
 | 
				
			||||||
 | 
					    return mpq3::dot(diff, diff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq_class distance_squared_with_buffer(const mpq3 &a, const mpq3 &b, mpq3 &buffer)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    buffer = a;
 | 
				
			||||||
 | 
					    buffer -= b;
 | 
				
			||||||
 | 
					    return mpq3::dot(buffer, buffer);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 interpolate(const mpq3 &a, const mpq3 &b, mpq_class t)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class s = 1 - t;
 | 
				
			||||||
 | 
					    return mpq3(a.x * s + b.x * t, a.y * s + b.y * t, a.z * s + b.z * t);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 abs(const mpq3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
 | 
				
			||||||
 | 
					    mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
 | 
				
			||||||
 | 
					    mpq_class abs_z = (a.z >= 0) ? a.z : -a.z;
 | 
				
			||||||
 | 
					    return mpq3(abs_x, abs_y, abs_z);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static int dominant_axis(const mpq3 &a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mpq_class x = (a.x >= 0) ? a.x : -a.x;
 | 
				
			||||||
 | 
					    mpq_class y = (a.y >= 0) ? a.y : -a.y;
 | 
				
			||||||
 | 
					    mpq_class z = (a.z >= 0) ? a.z : -a.z;
 | 
				
			||||||
 | 
					    return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static mpq3 cross_poly(Span<mpq3> poly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** There is a sensible use for hashing on exact arithmetic types. */
 | 
				
			||||||
 | 
					  uint64_t hash() const;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t hash_mpq_class(const mpq_class &value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace blender
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* WITH_GMP */
 | 
				
			||||||
@@ -16,7 +16,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					#include "BLI_float4.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender::noise {
 | 
					namespace blender::noise {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,16 +75,15 @@ bool BLI_make_existing_file(const char *name);
 | 
				
			|||||||
 * - Doesn't use CWD, or deal with relative paths.
 | 
					 * - Doesn't use CWD, or deal with relative paths.
 | 
				
			||||||
 * - Only fill's in \a dir and \a file when they are non NULL.
 | 
					 * - Only fill's in \a dir and \a file when they are non NULL.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_split_dirfile(
 | 
					void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen);
 | 
				
			||||||
    const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Copies the parent directory part of string into `dir`, max length `dirlen`.
 | 
					 * Copies the parent directory part of string into `dir`, max length `dirlen`.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
 | 
					void BLI_split_dir_part(const char *string, char *dir, size_t dirlen);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Copies the leaf filename part of string into `file`, max length `filelen`.
 | 
					 * Copies the leaf filename part of string into `file`, max length `filelen`.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_split_file_part(const char *string, char *file, const size_t filelen);
 | 
					void BLI_split_file_part(const char *string, char *file, size_t filelen);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns a pointer to the last extension (e.g. the position of the last period).
 | 
					 * Returns a pointer to the last extension (e.g. the position of the last period).
 | 
				
			||||||
 * Returns NULL if there is no extension.
 | 
					 * Returns NULL if there is no extension.
 | 
				
			||||||
@@ -94,7 +93,7 @@ const char *BLI_path_extension(const char *filepath) ATTR_NONNULL();
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Append a filename to a dir, ensuring slash separates.
 | 
					 * Append a filename to a dir, ensuring slash separates.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)
 | 
					void BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file)
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Simple appending of filename to dir, does not check for valid path!
 | 
					 * Simple appending of filename to dir, does not check for valid path!
 | 
				
			||||||
@@ -104,7 +103,7 @@ void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__re
 | 
				
			|||||||
 * that de-duplicates separators and can handle an arbitrary number of paths.
 | 
					 * that de-duplicates separators and can handle an arbitrary number of paths.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_join_dirfile(char *__restrict dst,
 | 
					void BLI_join_dirfile(char *__restrict dst,
 | 
				
			||||||
                      const size_t maxlen,
 | 
					                      size_t maxlen,
 | 
				
			||||||
                      const char *__restrict dir,
 | 
					                      const char *__restrict dir,
 | 
				
			||||||
                      const char *__restrict file) ATTR_NONNULL();
 | 
					                      const char *__restrict file) ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -114,7 +113,7 @@ void BLI_join_dirfile(char *__restrict dst,
 | 
				
			|||||||
 * \note If you want a trailing slash, add `SEP_STR` as the last path argument,
 | 
					 * \note If you want a trailing slash, add `SEP_STR` as the last path argument,
 | 
				
			||||||
 * duplicate slashes will be cleaned up.
 | 
					 * duplicate slashes will be cleaned up.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path_first, ...)
 | 
					size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first, ...)
 | 
				
			||||||
    ATTR_NONNULL(1, 3) ATTR_SENTINEL(0);
 | 
					    ATTR_NONNULL(1, 3) ATTR_SENTINEL(0);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Like Python's `os.path.basename()`
 | 
					 * Like Python's `os.path.basename()`
 | 
				
			||||||
@@ -164,12 +163,12 @@ void BLI_path_slash_rstrip(char *string) ATTR_NONNULL();
 | 
				
			|||||||
void BLI_path_slash_native(char *path) ATTR_NONNULL();
 | 
					void BLI_path_slash_native(char *path) ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
bool BLI_path_program_extensions_add_win32(char *name, const size_t maxlen);
 | 
					bool BLI_path_program_extensions_add_win32(char *name, size_t maxlen);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Search for a binary (executable)
 | 
					 * Search for a binary (executable)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *name);
 | 
					bool BLI_path_program_search(char *fullname, size_t maxlen, const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \return true when `str` end with `ext` (case insensitive).
 | 
					 * \return true when `str` end with `ext` (case insensitive).
 | 
				
			||||||
@@ -353,7 +352,7 @@ bool BLI_path_is_abs_from_cwd(const char *path) ATTR_NONNULL();
 | 
				
			|||||||
 * This is _not_ something Blender's internal paths support, instead they use the "//" prefix.
 | 
					 * This is _not_ something Blender's internal paths support, instead they use the "//" prefix.
 | 
				
			||||||
 * In most cases #BLI_path_abs should be used instead.
 | 
					 * In most cases #BLI_path_abs should be used instead.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool BLI_path_abs_from_cwd(char *path, const size_t maxlen) ATTR_NONNULL();
 | 
					bool BLI_path_abs_from_cwd(char *path, size_t maxlen) ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Replaces `file` with a relative version (prefixed by "//") such that #BLI_path_abs, given
 | 
					 * Replaces `file` with a relative version (prefixed by "//") such that #BLI_path_abs, given
 | 
				
			||||||
 * the same `relfile`, will convert it back to its original value.
 | 
					 * the same `relfile`, will convert it back to its original value.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_math.h"
 | 
					#include "BLI_math.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,13 +28,13 @@ extern "C" {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct BLI_Stack BLI_Stack;
 | 
					typedef struct BLI_Stack BLI_Stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BLI_Stack *BLI_stack_new_ex(const size_t elem_size,
 | 
					BLI_Stack *BLI_stack_new_ex(size_t elem_size,
 | 
				
			||||||
                            const char *description,
 | 
					                            const char *description,
 | 
				
			||||||
                            const size_t chunk_size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
					                            size_t chunk_size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Create a new homogeneous stack with elements of 'elem_size' bytes.
 | 
					 * Create a new homogeneous stack with elements of 'elem_size' bytes.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
BLI_Stack *BLI_stack_new(const size_t elem_size, const char *description) ATTR_WARN_UNUSED_RESULT
 | 
					BLI_Stack *BLI_stack_new(size_t elem_size, const char *description) ATTR_WARN_UNUSED_RESULT
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,8 +42,7 @@ extern "C" {
 | 
				
			|||||||
 * \param len: The number of bytes to duplicate
 | 
					 * \param len: The number of bytes to duplicate
 | 
				
			||||||
 * \retval Returns the duplicated string
 | 
					 * \retval Returns the duplicated string
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
char *BLI_strdupn(const char *str, const size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
 | 
					char *BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Duplicates the cstring \a str into a newly mallocN'd
 | 
					 * Duplicates the cstring \a str into a newly mallocN'd
 | 
				
			||||||
@@ -74,8 +73,7 @@ char *BLI_strdupcat(const char *__restrict str1,
 | 
				
			|||||||
 * the size of dst)
 | 
					 * the size of dst)
 | 
				
			||||||
 * \retval Returns dst
 | 
					 * \retval Returns dst
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
 | 
					char *BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL();
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Like BLI_strncpy but ensures dst is always padded by given char,
 | 
					 * Like BLI_strncpy but ensures dst is always padded by given char,
 | 
				
			||||||
@@ -107,7 +105,7 @@ char *BLI_strncpy_ensure_pad(char *__restrict dst,
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_strncpy_rlen(char *__restrict dst,
 | 
					size_t BLI_strncpy_rlen(char *__restrict dst,
 | 
				
			||||||
                        const char *__restrict src,
 | 
					                        const char *__restrict src,
 | 
				
			||||||
                        const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
					                        size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT
 | 
					size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
@@ -186,7 +184,7 @@ void BLI_str_replace_char(char *str, char src, char dst) ATTR_NONNULL();
 | 
				
			|||||||
 * \note Larger tables should use a hash table.
 | 
					 * \note Larger tables should use a hash table.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool BLI_str_replace_table_exact(char *string,
 | 
					bool BLI_str_replace_table_exact(char *string,
 | 
				
			||||||
                                 const size_t string_len,
 | 
					                                 size_t string_len,
 | 
				
			||||||
                                 const char *replace_table[][2],
 | 
					                                 const char *replace_table[][2],
 | 
				
			||||||
                                 int replace_table_len);
 | 
					                                 int replace_table_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -235,7 +233,7 @@ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \note This is used for creating animation paths in blend files.
 | 
					 * \note This is used for creating animation paths in blend files.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy)
 | 
					size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy)
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This roughly matches C and Python's string escaping with double quotes - `"`.
 | 
					 * This roughly matches C and Python's string escaping with double quotes - `"`.
 | 
				
			||||||
@@ -251,9 +249,9 @@ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const si
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_str_unescape_ex(char *__restrict dst,
 | 
					size_t BLI_str_unescape_ex(char *__restrict dst,
 | 
				
			||||||
                           const char *__restrict src,
 | 
					                           const char *__restrict src,
 | 
				
			||||||
                           const size_t src_maxncpy,
 | 
					                           size_t src_maxncpy,
 | 
				
			||||||
                           /* Additional arguments. */
 | 
					                           /* Additional arguments. */
 | 
				
			||||||
                           const size_t dst_maxncpy,
 | 
					                           size_t dst_maxncpy,
 | 
				
			||||||
                           bool *r_is_complete) ATTR_NONNULL();
 | 
					                           bool *r_is_complete) ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * See #BLI_str_unescape_ex doc-string.
 | 
					 * See #BLI_str_unescape_ex doc-string.
 | 
				
			||||||
@@ -265,7 +263,7 @@ size_t BLI_str_unescape_ex(char *__restrict dst,
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \note This is used for parsing animation paths in blend files (runs often).
 | 
					 * \note This is used for parsing animation paths in blend files (runs often).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy)
 | 
					size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy)
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -359,10 +357,10 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, char pad) ATTR_WAR
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Determine the length of a fixed-size string.
 | 
					 * Determine the length of a fixed-size string.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
					size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BLI_str_tolower_ascii(char *str, const size_t len) ATTR_NONNULL();
 | 
					void BLI_str_tolower_ascii(char *str, size_t len) ATTR_NONNULL();
 | 
				
			||||||
void BLI_str_toupper_ascii(char *str, const size_t len) ATTR_NONNULL();
 | 
					void BLI_str_toupper_ascii(char *str, size_t len) ATTR_NONNULL();
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Strip white-space from end of the string.
 | 
					 * Strip white-space from end of the string.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -479,7 +477,7 @@ bool BLI_string_all_words_matched(const char *name,
 | 
				
			|||||||
 * \return The number of words found in \a str
 | 
					 * \return The number of words found in \a str
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int BLI_string_find_split_words(const char *str,
 | 
					int BLI_string_find_split_words(const char *str,
 | 
				
			||||||
                                const size_t len,
 | 
					                                size_t len,
 | 
				
			||||||
                                char delim,
 | 
					                                char delim,
 | 
				
			||||||
                                int r_words[][2],
 | 
					                                int r_words[][2],
 | 
				
			||||||
                                int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
					                                int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,14 +110,12 @@ size_t BLI_str_utf8_from_unicode_len(unsigned int c) ATTR_WARN_UNUSED_RESULT;
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \return number of bytes written.
 | 
					 * \return number of bytes written.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf, const size_t outbuf_len)
 | 
					size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf, size_t outbuf_len) ATTR_NONNULL(2);
 | 
				
			||||||
    ATTR_NONNULL(2);
 | 
					 | 
				
			||||||
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w,
 | 
					size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w,
 | 
				
			||||||
                             const char *__restrict src_c,
 | 
					                             const char *__restrict src_c,
 | 
				
			||||||
                             const size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
					                             size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
				
			||||||
size_t BLI_str_utf32_as_utf8(char *__restrict dst,
 | 
					size_t BLI_str_utf32_as_utf8(char *__restrict dst, const char32_t *__restrict src, size_t maxncpy)
 | 
				
			||||||
                             const char32_t *__restrict src,
 | 
					    ATTR_NONNULL(1, 2);
 | 
				
			||||||
                             const size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \return The UTF-32 len in UTF-8.
 | 
					 * \return The UTF-32 len in UTF-8.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -162,21 +160,20 @@ size_t BLI_wstrlen_utf8(const wchar_t *src) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RES
 | 
				
			|||||||
size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes)
 | 
					size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes)
 | 
				
			||||||
    ATTR_NONNULL(1, 2) ATTR_WARN_UNUSED_RESULT;
 | 
					    ATTR_NONNULL(1, 2) ATTR_WARN_UNUSED_RESULT;
 | 
				
			||||||
size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
 | 
					size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
 | 
				
			||||||
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes)
 | 
					size_t BLI_strnlen_utf8_ex(const char *strc, size_t maxlen, size_t *r_len_bytes)
 | 
				
			||||||
    ATTR_NONNULL(1, 3);
 | 
					    ATTR_NONNULL(1, 3);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \param strc: the string to measure the length.
 | 
					 * \param strc: the string to measure the length.
 | 
				
			||||||
 * \param maxlen: the string length (in bytes)
 | 
					 * \param maxlen: the string length (in bytes)
 | 
				
			||||||
 * \return the unicode length (not in bytes!)
 | 
					 * \return the unicode length (not in bytes!)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
 | 
					size_t BLI_strnlen_utf8(const char *strc, size_t maxlen) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
 | 
				
			||||||
    ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
 | 
					 | 
				
			||||||
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst,
 | 
					size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst,
 | 
				
			||||||
                                 const wchar_t *__restrict src,
 | 
					                                 const wchar_t *__restrict src,
 | 
				
			||||||
                                 const size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
					                                 size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
				
			||||||
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst,
 | 
					size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst,
 | 
				
			||||||
                                   const char *__restrict src,
 | 
					                                   const char *__restrict src,
 | 
				
			||||||
                                   const size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
					                                   size_t maxncpy) ATTR_NONNULL(1, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Count columns that character/string occupies (based on `wcwidth.co`).
 | 
					 * Count columns that character/string occupies (based on `wcwidth.co`).
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,11 +57,11 @@ bool BLI_string_is_decimal(const char *string) ATTR_NONNULL();
 | 
				
			|||||||
 * Based on `BLI_split_dirfile()` / `os.path.splitext()`,
 | 
					 * Based on `BLI_split_dirfile()` / `os.path.splitext()`,
 | 
				
			||||||
 * `"a.b.c"` -> (`"a.b"`, `".c"`).
 | 
					 * `"a.b.c"` -> (`"a.b"`, `".c"`).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len);
 | 
					void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, size_t str_len);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * `"a.b.c"` -> (`"a."`, `"b.c"`).
 | 
					 * `"a.b.c"` -> (`"a."`, `"b.c"`).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len);
 | 
					void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, size_t str_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Join strings, return newly allocated string.
 | 
					 * Join strings, return newly allocated string.
 | 
				
			||||||
@@ -127,7 +127,7 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep,
 | 
				
			|||||||
size_t BLI_string_flip_side_name(char *r_name,
 | 
					size_t BLI_string_flip_side_name(char *r_name,
 | 
				
			||||||
                                 const char *from_name,
 | 
					                                 const char *from_name,
 | 
				
			||||||
                                 bool strip_number,
 | 
					                                 bool strip_number,
 | 
				
			||||||
                                 const size_t name_len);
 | 
					                                 size_t name_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Ensures name is unique (according to criteria specified by caller in unique_check callback),
 | 
					 * Ensures name is unique (according to criteria specified by caller in unique_check callback),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,7 @@ extern "C" {
 | 
				
			|||||||
 * \return length of \a str
 | 
					 * \return length of \a str
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_timecode_string_from_time(char *str,
 | 
					size_t BLI_timecode_string_from_time(char *str,
 | 
				
			||||||
                                     const size_t maxncpy,
 | 
					                                     size_t maxncpy,
 | 
				
			||||||
                                     int brevity_level,
 | 
					                                     int brevity_level,
 | 
				
			||||||
                                     float time_seconds,
 | 
					                                     float time_seconds,
 | 
				
			||||||
                                     double fps,
 | 
					                                     double fps,
 | 
				
			||||||
@@ -56,7 +56,7 @@ size_t BLI_timecode_string_from_time(char *str,
 | 
				
			|||||||
 * \param time_seconds: time total time in seconds
 | 
					 * \param time_seconds: time total time in seconds
 | 
				
			||||||
 * \return length of \a str
 | 
					 * \return length of \a str
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_timecode_string_from_time_simple(char *str, const size_t maxncpy, double time_seconds)
 | 
					size_t BLI_timecode_string_from_time_simple(char *str, size_t maxncpy, double time_seconds)
 | 
				
			||||||
    ATTR_NONNULL();
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -72,7 +72,7 @@ size_t BLI_timecode_string_from_time_simple(char *str, const size_t maxncpy, dou
 | 
				
			|||||||
 * \note in some cases this is used to print non-seconds values.
 | 
					 * \note in some cases this is used to print non-seconds values.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t BLI_timecode_string_from_time_seconds(char *str,
 | 
					size_t BLI_timecode_string_from_time_seconds(char *str,
 | 
				
			||||||
                                             const size_t maxncpy,
 | 
					                                             size_t maxncpy,
 | 
				
			||||||
                                             int brevity_level,
 | 
					                                             int brevity_level,
 | 
				
			||||||
                                             float time_seconds) ATTR_NONNULL();
 | 
					                                             float time_seconds) ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -638,7 +638,7 @@ extern "C" {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Check if memory is zeroed, as with `memset(arr, 0, arr_size)`.
 | 
					 * Check if memory is zeroed, as with `memset(arr, 0, arr_size)`.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
 | 
					extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member) \
 | 
					#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member) \
 | 
				
			||||||
@@ -840,15 +840,6 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
 | 
				
			|||||||
/** No-op for expressions we don't want to instantiate, but must remain valid. */
 | 
					/** No-op for expressions we don't want to instantiate, but must remain valid. */
 | 
				
			||||||
#define EXPR_NOP(expr) (void)(0 ? ((void)(expr), 1) : 0)
 | 
					#define EXPR_NOP(expr) (void)(0 ? ((void)(expr), 1) : 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Utility macro that wraps `std::enable_if` to make it a bit easier to use and less verbose for
 | 
					 | 
				
			||||||
 * SFINAE in common cases.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * \note Often one has to invoke this macro with double parenthesis. That's because the condition
 | 
					 | 
				
			||||||
 * often contains a comma and angle brackets are not recognized as parenthesis by the preprocessor.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define BLI_ENABLE_IF(condition) typename std::enable_if_t<(condition)> * = nullptr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** \} */
 | 
					/** \} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -192,6 +192,8 @@ set(SRC
 | 
				
			|||||||
  BLI_dlrbTree.h
 | 
					  BLI_dlrbTree.h
 | 
				
			||||||
  BLI_dot_export.hh
 | 
					  BLI_dot_export.hh
 | 
				
			||||||
  BLI_dot_export_attribute_enums.hh
 | 
					  BLI_dot_export_attribute_enums.hh
 | 
				
			||||||
 | 
					  BLI_double2.hh
 | 
				
			||||||
 | 
					  BLI_double3.hh
 | 
				
			||||||
  BLI_dynlib.h
 | 
					  BLI_dynlib.h
 | 
				
			||||||
  BLI_dynstr.h
 | 
					  BLI_dynstr.h
 | 
				
			||||||
  BLI_easing.h
 | 
					  BLI_easing.h
 | 
				
			||||||
@@ -205,6 +207,9 @@ set(SRC
 | 
				
			|||||||
  BLI_fileops.hh
 | 
					  BLI_fileops.hh
 | 
				
			||||||
  BLI_fileops_types.h
 | 
					  BLI_fileops_types.h
 | 
				
			||||||
  BLI_filereader.h
 | 
					  BLI_filereader.h
 | 
				
			||||||
 | 
					  BLI_float2.hh
 | 
				
			||||||
 | 
					  BLI_float3.hh
 | 
				
			||||||
 | 
					  BLI_float4.hh
 | 
				
			||||||
  BLI_float4x4.hh
 | 
					  BLI_float4x4.hh
 | 
				
			||||||
  BLI_fnmatch.h
 | 
					  BLI_fnmatch.h
 | 
				
			||||||
  BLI_function_ref.hh
 | 
					  BLI_function_ref.hh
 | 
				
			||||||
@@ -253,8 +258,6 @@ set(SRC
 | 
				
			|||||||
  BLI_math_statistics.h
 | 
					  BLI_math_statistics.h
 | 
				
			||||||
  BLI_math_time.h
 | 
					  BLI_math_time.h
 | 
				
			||||||
  BLI_math_vector.h
 | 
					  BLI_math_vector.h
 | 
				
			||||||
  BLI_math_vec_types.hh
 | 
					 | 
				
			||||||
  BLI_math_vec_mpq_types.hh
 | 
					 | 
				
			||||||
  BLI_memarena.h
 | 
					  BLI_memarena.h
 | 
				
			||||||
  BLI_memblock.h
 | 
					  BLI_memblock.h
 | 
				
			||||||
  BLI_memiter.h
 | 
					  BLI_memiter.h
 | 
				
			||||||
@@ -264,6 +267,8 @@ set(SRC
 | 
				
			|||||||
  BLI_mesh_boolean.hh
 | 
					  BLI_mesh_boolean.hh
 | 
				
			||||||
  BLI_mesh_intersect.hh
 | 
					  BLI_mesh_intersect.hh
 | 
				
			||||||
  BLI_mmap.h
 | 
					  BLI_mmap.h
 | 
				
			||||||
 | 
					  BLI_mpq2.hh
 | 
				
			||||||
 | 
					  BLI_mpq3.hh
 | 
				
			||||||
  BLI_multi_value_map.hh
 | 
					  BLI_multi_value_map.hh
 | 
				
			||||||
  BLI_noise.h
 | 
					  BLI_noise.h
 | 
				
			||||||
  BLI_noise.hh
 | 
					  BLI_noise.hh
 | 
				
			||||||
@@ -439,7 +444,6 @@ if(WITH_GTESTS)
 | 
				
			|||||||
    tests/BLI_math_rotation_test.cc
 | 
					    tests/BLI_math_rotation_test.cc
 | 
				
			||||||
    tests/BLI_math_solvers_test.cc
 | 
					    tests/BLI_math_solvers_test.cc
 | 
				
			||||||
    tests/BLI_math_time_test.cc
 | 
					    tests/BLI_math_time_test.cc
 | 
				
			||||||
    tests/BLI_math_vec_types_test.cc
 | 
					 | 
				
			||||||
    tests/BLI_math_vector_test.cc
 | 
					    tests/BLI_math_vector_test.cc
 | 
				
			||||||
    tests/BLI_memiter_test.cc
 | 
					    tests/BLI_memiter_test.cc
 | 
				
			||||||
    tests/BLI_memory_utils_test.cc
 | 
					    tests/BLI_memory_utils_test.cc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,8 +54,9 @@ typedef struct ParallelMempoolTaskData {
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * See #BLI_task_parallel_mempool implementation for detailed usage example.
 | 
					 * See #BLI_task_parallel_mempool implementation for detailed usage example.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
ParallelMempoolTaskData *mempool_iter_threadsafe_create(BLI_mempool *pool, const size_t num_iter)
 | 
					ParallelMempoolTaskData *mempool_iter_threadsafe_create(BLI_mempool *pool,
 | 
				
			||||||
    ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 | 
					                                                        size_t num_iter) ATTR_WARN_UNUSED_RESULT
 | 
				
			||||||
 | 
					    ATTR_NONNULL();
 | 
				
			||||||
void mempool_iter_threadsafe_destroy(ParallelMempoolTaskData *iter_arr) ATTR_NONNULL();
 | 
					void mempool_iter_threadsafe_destroy(ParallelMempoolTaskData *iter_arr) ATTR_NONNULL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,10 +25,11 @@
 | 
				
			|||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_double2.hh"
 | 
				
			||||||
#include "BLI_linklist.h"
 | 
					#include "BLI_linklist.h"
 | 
				
			||||||
#include "BLI_math_boolean.hh"
 | 
					#include "BLI_math_boolean.hh"
 | 
				
			||||||
#include "BLI_math_mpq.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vec_mpq_types.hh"
 | 
					#include "BLI_mpq2.hh"
 | 
				
			||||||
#include "BLI_set.hh"
 | 
					#include "BLI_set.hh"
 | 
				
			||||||
#include "BLI_task.hh"
 | 
					#include "BLI_task.hh"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
@@ -37,8 +38,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace blender::meshintersect {
 | 
					namespace blender::meshintersect {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Throughout this file, template argument T will be an
 | 
					/* Throughout this file, template argument T will be an
 | 
				
			||||||
 * arithmetic-like type, like float, double, or mpq_class. */
 | 
					 * arithmetic-like type, like float, double, or mpq_class. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -789,11 +788,11 @@ bool in_line<mpq_class>(const FatCo<mpq_class> &a,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  vec2<mpq_class> exact_ab = b.exact - a.exact;
 | 
					  vec2<mpq_class> exact_ab = b.exact - a.exact;
 | 
				
			||||||
  vec2<mpq_class> exact_ac = c.exact - a.exact;
 | 
					  vec2<mpq_class> exact_ac = c.exact - a.exact;
 | 
				
			||||||
  if (dot(exact_ab, exact_ac) < 0) {
 | 
					  if (vec2<mpq_class>::dot(exact_ab, exact_ac) < 0) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vec2<mpq_class> exact_bc = c.exact - b.exact;
 | 
					  vec2<mpq_class> exact_bc = c.exact - b.exact;
 | 
				
			||||||
  return dot(exact_bc, exact_ac) >= 0;
 | 
					  return vec2<mpq_class>::dot(exact_bc, exact_ac) >= 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -802,11 +801,11 @@ bool in_line<double>(const FatCo<double> &a, const FatCo<double> &b, const FatCo
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  vec2<double> ab = b.approx - a.approx;
 | 
					  vec2<double> ab = b.approx - a.approx;
 | 
				
			||||||
  vec2<double> ac = c.approx - a.approx;
 | 
					  vec2<double> ac = c.approx - a.approx;
 | 
				
			||||||
  if (dot(ab, ac) < 0) {
 | 
					  if (vec2<double>::dot(ab, ac) < 0) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vec2<double> bc = c.approx - b.approx;
 | 
					  vec2<double> bc = c.approx - b.approx;
 | 
				
			||||||
  return dot(bc, ac) >= 0;
 | 
					  return vec2<double>::dot(bc, ac) >= 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
 | 
					template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
 | 
				
			||||||
@@ -1082,7 +1081,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::split_edge(SymEdge<T> *se, T
 | 
				
			|||||||
  SymEdge<T> *sesymprev = prev(sesym);
 | 
					  SymEdge<T> *sesymprev = prev(sesym);
 | 
				
			||||||
  SymEdge<T> *sesymprevsym = sym(sesymprev);
 | 
					  SymEdge<T> *sesymprevsym = sym(sesymprev);
 | 
				
			||||||
  SymEdge<T> *senext = se->next;
 | 
					  SymEdge<T> *senext = se->next;
 | 
				
			||||||
  CDTVert<T> *v = this->add_vert(interpolate(*a, *b, lambda));
 | 
					  CDTVert<T> *v = this->add_vert(vec2<T>::interpolate(*a, *b, lambda));
 | 
				
			||||||
  CDTEdge<T> *e = this->add_edge(v, se->next->vert, se->face, sesym->face);
 | 
					  CDTEdge<T> *e = this->add_edge(v, se->next->vert, se->face, sesym->face);
 | 
				
			||||||
  sesym->vert = v;
 | 
					  sesym->vert = v;
 | 
				
			||||||
  SymEdge<T> *newse = &e->symedges[0];
 | 
					  SymEdge<T> *newse = &e->symedges[0];
 | 
				
			||||||
@@ -1705,16 +1704,16 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
 | 
				
			|||||||
  BLI_assert(se_vcva->vert == vc && se_vcva->next->vert == va);
 | 
					  BLI_assert(se_vcva->vert == vc && se_vcva->next->vert == va);
 | 
				
			||||||
  BLI_assert(se_vcvb->vert == vc && se_vcvb->next->vert == vb);
 | 
					  BLI_assert(se_vcvb->vert == vc && se_vcvb->next->vert == vb);
 | 
				
			||||||
  UNUSED_VARS_NDEBUG(vc);
 | 
					  UNUSED_VARS_NDEBUG(vc);
 | 
				
			||||||
  auto isect = isect_seg_seg<vec2<T>>(va->co.exact, vb->co.exact, curco.exact, v2->co.exact);
 | 
					  auto isect = vec2<T>::isect_seg_seg(va->co.exact, vb->co.exact, curco.exact, v2->co.exact);
 | 
				
			||||||
  T &lambda = isect.lambda;
 | 
					  T &lambda = isect.lambda;
 | 
				
			||||||
  switch (isect.kind) {
 | 
					  switch (isect.kind) {
 | 
				
			||||||
    case isect_result<vec2<T>>::LINE_LINE_CROSS: {
 | 
					    case vec2<T>::isect_result::LINE_LINE_CROSS: {
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
      if (!std::is_same<T, mpq_class>::value) {
 | 
					      if (!std::is_same<T, mpq_class>::value) {
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
      if (true) {
 | 
					      if (true) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        double len_ab = distance(va->co.approx, vb->co.approx);
 | 
					        double len_ab = vec2<double>::distance(va->co.approx, vb->co.approx);
 | 
				
			||||||
        if (lambda * len_ab <= epsilon) {
 | 
					        if (lambda * len_ab <= epsilon) {
 | 
				
			||||||
          fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
					          fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -1736,7 +1735,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case isect_result<vec2<T>>::LINE_LINE_EXACT: {
 | 
					    case vec2<T>::isect_result::LINE_LINE_EXACT: {
 | 
				
			||||||
      if (lambda == 0) {
 | 
					      if (lambda == 0) {
 | 
				
			||||||
        fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
					        fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -1751,7 +1750,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case isect_result<vec2<T>>::LINE_LINE_NONE: {
 | 
					    case vec2<T>::isect_result::LINE_LINE_NONE: {
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
      if (std::is_same<T, mpq_class>::value) {
 | 
					      if (std::is_same<T, mpq_class>::value) {
 | 
				
			||||||
        BLI_assert(false);
 | 
					        BLI_assert(false);
 | 
				
			||||||
@@ -1767,9 +1766,9 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case isect_result<vec2<T>>::LINE_LINE_COLINEAR: {
 | 
					    case vec2<T>::isect_result::LINE_LINE_COLINEAR: {
 | 
				
			||||||
      if (distance_squared(va->co.approx, v2->co.approx) <=
 | 
					      if (vec2<double>::distance_squared(va->co.approx, v2->co.approx) <=
 | 
				
			||||||
          distance_squared(vb->co.approx, v2->co.approx)) {
 | 
					          vec2<double>::distance_squared(vb->co.approx, v2->co.approx)) {
 | 
				
			||||||
        fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
					        fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
@@ -1846,7 +1845,7 @@ void get_next_crossing_from_edge(CrossData<T> *cd,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  CDTVert<T> *va = cd->in->vert;
 | 
					  CDTVert<T> *va = cd->in->vert;
 | 
				
			||||||
  CDTVert<T> *vb = cd->in->next->vert;
 | 
					  CDTVert<T> *vb = cd->in->next->vert;
 | 
				
			||||||
  vec2<T> curco = interpolate(va->co.exact, vb->co.exact, cd->lambda);
 | 
					  vec2<T> curco = vec2<T>::interpolate(va->co.exact, vb->co.exact, cd->lambda);
 | 
				
			||||||
  FatCo<T> fat_curco(curco);
 | 
					  FatCo<T> fat_curco(curco);
 | 
				
			||||||
  SymEdge<T> *se_ac = sym(cd->in)->next;
 | 
					  SymEdge<T> *se_ac = sym(cd->in)->next;
 | 
				
			||||||
  CDTVert<T> *vc = se_ac->next->vert;
 | 
					  CDTVert<T> *vc = se_ac->next->vert;
 | 
				
			||||||
@@ -2387,7 +2386,7 @@ template<typename T> void remove_non_constraint_edges_leave_valid_bmesh(CDT_stat
 | 
				
			|||||||
      dissolvable_edges[i].e = e;
 | 
					      dissolvable_edges[i].e = e;
 | 
				
			||||||
      const vec2<double> &co1 = e->symedges[0].vert->co.approx;
 | 
					      const vec2<double> &co1 = e->symedges[0].vert->co.approx;
 | 
				
			||||||
      const vec2<double> &co2 = e->symedges[1].vert->co.approx;
 | 
					      const vec2<double> &co2 = e->symedges[1].vert->co.approx;
 | 
				
			||||||
      dissolvable_edges[i].len_squared = distance_squared(co1, co2);
 | 
					      dissolvable_edges[i].len_squared = vec2<double>::distance_squared(co1, co2);
 | 
				
			||||||
      i++;
 | 
					      i++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -2570,18 +2569,18 @@ template<typename T> void detect_holes(CDT_state<T> *cdt_state)
 | 
				
			|||||||
          if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
 | 
					          if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
 | 
				
			||||||
            continue; /* Don't count hits on edges between faces in same region. */
 | 
					            continue; /* Don't count hits on edges between faces in same region. */
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          auto isect = isect_seg_seg<vec2<T>>(ray_end.exact,
 | 
					          auto isect = vec2<T>::isect_seg_seg(ray_end.exact,
 | 
				
			||||||
                                              mid.exact,
 | 
					                                              mid.exact,
 | 
				
			||||||
                                              e->symedges[0].vert->co.exact,
 | 
					                                              e->symedges[0].vert->co.exact,
 | 
				
			||||||
                                              e->symedges[1].vert->co.exact);
 | 
					                                              e->symedges[1].vert->co.exact);
 | 
				
			||||||
          switch (isect.kind) {
 | 
					          switch (isect.kind) {
 | 
				
			||||||
            case isect_result<vec2<T>>::LINE_LINE_CROSS: {
 | 
					            case vec2<T>::isect_result::LINE_LINE_CROSS: {
 | 
				
			||||||
              hits++;
 | 
					              hits++;
 | 
				
			||||||
              break;
 | 
					              break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case isect_result<vec2<T>>::LINE_LINE_EXACT:
 | 
					            case vec2<T>::isect_result::LINE_LINE_EXACT:
 | 
				
			||||||
            case isect_result<vec2<T>>::LINE_LINE_NONE:
 | 
					            case vec2<T>::isect_result::LINE_LINE_NONE:
 | 
				
			||||||
            case isect_result<vec2<T>>::LINE_LINE_COLINEAR:
 | 
					            case vec2<T>::isect_result::LINE_LINE_COLINEAR:
 | 
				
			||||||
              break;
 | 
					              break;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,10 +18,15 @@
 | 
				
			|||||||
 * \ingroup bli
 | 
					 * \ingroup bli
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_double2.hh"
 | 
				
			||||||
 | 
					#include "BLI_double3.hh"
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_hash.hh"
 | 
					#include "BLI_hash.hh"
 | 
				
			||||||
#include "BLI_math_boolean.hh"
 | 
					#include "BLI_math_boolean.hh"
 | 
				
			||||||
#include "BLI_math_mpq.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_mpq2.hh"
 | 
				
			||||||
 | 
					#include "BLI_mpq3.hh"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,83 +18,89 @@
 | 
				
			|||||||
 * \ingroup bli
 | 
					 * \ingroup bli
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BLI_double2.hh"
 | 
				
			||||||
 | 
					#include "BLI_double3.hh"
 | 
				
			||||||
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_hash.hh"
 | 
					#include "BLI_hash.hh"
 | 
				
			||||||
#include "BLI_math_vec_mpq_types.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vector.hh"
 | 
					#include "BLI_mpq2.hh"
 | 
				
			||||||
 | 
					#include "BLI_mpq3.hh"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace blender::math {
 | 
					namespace blender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<>
 | 
					float2::isect_result float2::isect_seg_seg(const float2 &v1,
 | 
				
			||||||
isect_result<float2> isect_seg_seg(const float2 &v1,
 | 
					 | 
				
			||||||
                                           const float2 &v2,
 | 
					                                           const float2 &v2,
 | 
				
			||||||
                                           const float2 &v3,
 | 
					                                           const float2 &v3,
 | 
				
			||||||
                                           const float2 &v4)
 | 
					                                           const float2 &v4)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  isect_result<float2> ans;
 | 
					  float2::isect_result ans;
 | 
				
			||||||
  float div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
					  float div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
				
			||||||
  if (div == 0.0f) {
 | 
					  if (div == 0.0f) {
 | 
				
			||||||
    ans.lambda = 0.0f;
 | 
					    ans.lambda = 0.0f;
 | 
				
			||||||
    ans.kind = isect_result<float2>::LINE_LINE_COLINEAR;
 | 
					    ans.mu = 0.0f;
 | 
				
			||||||
 | 
					    ans.kind = float2::isect_result::LINE_LINE_COLINEAR;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
					    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
				
			||||||
    float mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 | 
					    ans.mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 | 
				
			||||||
    if (ans.lambda >= 0.0f && ans.lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
 | 
					    if (ans.lambda >= 0.0f && ans.lambda <= 1.0f && ans.mu >= 0.0f && ans.mu <= 1.0f) {
 | 
				
			||||||
      if (ans.lambda == 0.0f || ans.lambda == 1.0f || mu == 0.0f || mu == 1.0f) {
 | 
					      if (ans.lambda == 0.0f || ans.lambda == 1.0f || ans.mu == 0.0f || ans.mu == 1.0f) {
 | 
				
			||||||
        ans.kind = isect_result<float2>::LINE_LINE_EXACT;
 | 
					        ans.kind = float2::isect_result::LINE_LINE_EXACT;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
        ans.kind = isect_result<float2>::LINE_LINE_CROSS;
 | 
					        ans.kind = float2::isect_result::LINE_LINE_CROSS;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      ans.kind = isect_result<float2>::LINE_LINE_NONE;
 | 
					      ans.kind = float2::isect_result::LINE_LINE_NONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return ans;
 | 
					  return ans;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<>
 | 
					double2::isect_result double2::isect_seg_seg(const double2 &v1,
 | 
				
			||||||
isect_result<double2> isect_seg_seg(const double2 &v1,
 | 
					 | 
				
			||||||
                                             const double2 &v2,
 | 
					                                             const double2 &v2,
 | 
				
			||||||
                                             const double2 &v3,
 | 
					                                             const double2 &v3,
 | 
				
			||||||
                                             const double2 &v4)
 | 
					                                             const double2 &v4)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  isect_result<double2> ans;
 | 
					  double2::isect_result ans;
 | 
				
			||||||
  double div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
					  double div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
				
			||||||
  if (div == 0.0) {
 | 
					  if (div == 0.0) {
 | 
				
			||||||
    ans.lambda = 0.0;
 | 
					    ans.lambda = 0.0;
 | 
				
			||||||
    ans.kind = isect_result<double2>::LINE_LINE_COLINEAR;
 | 
					    ans.kind = double2::isect_result::LINE_LINE_COLINEAR;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
					    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
				
			||||||
    double mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 | 
					    double mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 | 
				
			||||||
    if (ans.lambda >= 0.0 && ans.lambda <= 1.0 && mu >= 0.0 && mu <= 1.0) {
 | 
					    if (ans.lambda >= 0.0 && ans.lambda <= 1.0 && mu >= 0.0 && mu <= 1.0) {
 | 
				
			||||||
      if (ans.lambda == 0.0 || ans.lambda == 1.0 || mu == 0.0 || mu == 1.0) {
 | 
					      if (ans.lambda == 0.0 || ans.lambda == 1.0 || mu == 0.0 || mu == 1.0) {
 | 
				
			||||||
        ans.kind = isect_result<double2>::LINE_LINE_EXACT;
 | 
					        ans.kind = double2::isect_result::LINE_LINE_EXACT;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
        ans.kind = isect_result<double2>::LINE_LINE_CROSS;
 | 
					        ans.kind = double2::isect_result::LINE_LINE_CROSS;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      ans.kind = isect_result<double2>::LINE_LINE_NONE;
 | 
					      ans.kind = double2::isect_result::LINE_LINE_NONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return ans;
 | 
					  return ans;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
template<>
 | 
					mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
 | 
				
			||||||
isect_result<mpq2> isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3, const mpq2 &v4)
 | 
					                                       const mpq2 &v2,
 | 
				
			||||||
 | 
					                                       const mpq2 &v3,
 | 
				
			||||||
 | 
					                                       const mpq2 &v4)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  isect_result<mpq2> ans;
 | 
					  mpq2::isect_result ans;
 | 
				
			||||||
  mpq_class div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
					  mpq_class div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 | 
				
			||||||
  if (div == 0.0) {
 | 
					  if (div == 0.0) {
 | 
				
			||||||
    ans.lambda = 0.0;
 | 
					    ans.lambda = 0.0;
 | 
				
			||||||
    ans.kind = isect_result<mpq2>::LINE_LINE_COLINEAR;
 | 
					    ans.kind = mpq2::isect_result::LINE_LINE_COLINEAR;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
					    ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 | 
				
			||||||
@@ -103,21 +109,66 @@ isect_result<mpq2> isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3,
 | 
				
			|||||||
    if (ans.lambda >= 0 && ans.lambda <= 1 &&
 | 
					    if (ans.lambda >= 0 && ans.lambda <= 1 &&
 | 
				
			||||||
        ((div > 0 && mudiv >= 0 && mudiv <= div) || (div < 0 && mudiv <= 0 && mudiv >= div))) {
 | 
					        ((div > 0 && mudiv >= 0 && mudiv <= div) || (div < 0 && mudiv <= 0 && mudiv >= div))) {
 | 
				
			||||||
      if (ans.lambda == 0 || ans.lambda == 1 || mudiv == 0 || mudiv == div) {
 | 
					      if (ans.lambda == 0 || ans.lambda == 1 || mudiv == 0 || mudiv == div) {
 | 
				
			||||||
        ans.kind = isect_result<mpq2>::LINE_LINE_EXACT;
 | 
					        ans.kind = mpq2::isect_result::LINE_LINE_EXACT;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
        ans.kind = isect_result<mpq2>::LINE_LINE_CROSS;
 | 
					        ans.kind = mpq2::isect_result::LINE_LINE_CROSS;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      ans.kind = isect_result<mpq2>::LINE_LINE_NONE;
 | 
					      ans.kind = mpq2::isect_result::LINE_LINE_NONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return ans;
 | 
					  return ans;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double3 double3::cross_poly(Span<double3> poly)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* Newell's Method. */
 | 
				
			||||||
 | 
					  int nv = static_cast<int>(poly.size());
 | 
				
			||||||
 | 
					  if (nv < 3) {
 | 
				
			||||||
 | 
					    return double3(0, 0, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const double3 *v_prev = &poly[nv - 1];
 | 
				
			||||||
 | 
					  const double3 *v_curr = &poly[0];
 | 
				
			||||||
 | 
					  double3 n(0, 0, 0);
 | 
				
			||||||
 | 
					  for (int i = 0; i < nv;) {
 | 
				
			||||||
 | 
					    n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]);
 | 
				
			||||||
 | 
					    n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]);
 | 
				
			||||||
 | 
					    n[2] = n[2] + ((*v_prev)[0] - (*v_curr)[0]) * ((*v_prev)[1] + (*v_curr)[1]);
 | 
				
			||||||
 | 
					    v_prev = v_curr;
 | 
				
			||||||
 | 
					    ++i;
 | 
				
			||||||
 | 
					    if (i < nv) {
 | 
				
			||||||
 | 
					      v_curr = &poly[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return n;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
 | 
					mpq3 mpq3::cross_poly(Span<mpq3> poly)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* Newell's Method. */
 | 
				
			||||||
 | 
					  int nv = static_cast<int>(poly.size());
 | 
				
			||||||
 | 
					  if (nv < 3) {
 | 
				
			||||||
 | 
					    return mpq3(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const mpq3 *v_prev = &poly[nv - 1];
 | 
				
			||||||
 | 
					  const mpq3 *v_curr = &poly[0];
 | 
				
			||||||
 | 
					  mpq3 n(0);
 | 
				
			||||||
 | 
					  for (int i = 0; i < nv;) {
 | 
				
			||||||
 | 
					    n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]);
 | 
				
			||||||
 | 
					    n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]);
 | 
				
			||||||
 | 
					    n[2] = n[2] + ((*v_prev)[0] - (*v_curr)[0]) * ((*v_prev)[1] + (*v_curr)[1]);
 | 
				
			||||||
 | 
					    v_prev = v_curr;
 | 
				
			||||||
 | 
					    ++i;
 | 
				
			||||||
 | 
					    if (i < nv) {
 | 
				
			||||||
 | 
					      v_curr = &poly[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return n;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint64_t hash_mpq_class(const mpq_class &value)
 | 
					uint64_t hash_mpq_class(const mpq_class &value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -125,6 +176,20 @@ uint64_t hash_mpq_class(const mpq_class &value)
 | 
				
			|||||||
  return get_default_hash(static_cast<float>(value.get_d()));
 | 
					  return get_default_hash(static_cast<float>(value.get_d()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t mpq2::hash() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint64_t hashx = hash_mpq_class(this->x);
 | 
				
			||||||
 | 
					  uint64_t hashy = hash_mpq_class(this->y);
 | 
				
			||||||
 | 
					  return hashx ^ (hashy * 33);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint64_t mpq3::hash() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint64_t hashx = hash_mpq_class(this->x);
 | 
				
			||||||
 | 
					  uint64_t hashy = hash_mpq_class(this->y);
 | 
				
			||||||
 | 
					  uint64_t hashz = hash_mpq_class(this->z);
 | 
				
			||||||
 | 
					  return hashx ^ (hashy * 33) ^ (hashz * 33 * 37);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace blender::math
 | 
					}  // namespace blender
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,8 @@
 | 
				
			|||||||
#  include "BLI_array.hh"
 | 
					#  include "BLI_array.hh"
 | 
				
			||||||
#  include "BLI_assert.h"
 | 
					#  include "BLI_assert.h"
 | 
				
			||||||
#  include "BLI_delaunay_2d.h"
 | 
					#  include "BLI_delaunay_2d.h"
 | 
				
			||||||
 | 
					#  include "BLI_double3.hh"
 | 
				
			||||||
 | 
					#  include "BLI_float3.hh"
 | 
				
			||||||
#  include "BLI_hash.hh"
 | 
					#  include "BLI_hash.hh"
 | 
				
			||||||
#  include "BLI_kdopbvh.h"
 | 
					#  include "BLI_kdopbvh.h"
 | 
				
			||||||
#  include "BLI_map.hh"
 | 
					#  include "BLI_map.hh"
 | 
				
			||||||
@@ -35,9 +37,8 @@
 | 
				
			|||||||
#  include "BLI_math_boolean.hh"
 | 
					#  include "BLI_math_boolean.hh"
 | 
				
			||||||
#  include "BLI_math_geom.h"
 | 
					#  include "BLI_math_geom.h"
 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
#  include "BLI_math_vec_mpq_types.hh"
 | 
					 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#  include "BLI_mesh_intersect.hh"
 | 
					#  include "BLI_mesh_intersect.hh"
 | 
				
			||||||
 | 
					#  include "BLI_mpq3.hh"
 | 
				
			||||||
#  include "BLI_set.hh"
 | 
					#  include "BLI_set.hh"
 | 
				
			||||||
#  include "BLI_span.hh"
 | 
					#  include "BLI_span.hh"
 | 
				
			||||||
#  include "BLI_stack.hh"
 | 
					#  include "BLI_stack.hh"
 | 
				
			||||||
@@ -1632,13 +1633,13 @@ static Edge find_good_sorting_edge(const Vert *testp,
 | 
				
			|||||||
  ordinate[axis_next] = -abscissa[axis];
 | 
					  ordinate[axis_next] = -abscissa[axis];
 | 
				
			||||||
  ordinate[axis_next_next] = 0;
 | 
					  ordinate[axis_next_next] = 0;
 | 
				
			||||||
  /* By construction, dot(abscissa, ordinate) == 0, so they are perpendicular. */
 | 
					  /* By construction, dot(abscissa, ordinate) == 0, so they are perpendicular. */
 | 
				
			||||||
  mpq3 normal = math::cross(abscissa, ordinate);
 | 
					  mpq3 normal = mpq3::cross(abscissa, ordinate);
 | 
				
			||||||
  if (dbg_level > 0) {
 | 
					  if (dbg_level > 0) {
 | 
				
			||||||
    std::cout << "abscissa = " << abscissa << "\n";
 | 
					    std::cout << "abscissa = " << abscissa << "\n";
 | 
				
			||||||
    std::cout << "ordinate = " << ordinate << "\n";
 | 
					    std::cout << "ordinate = " << ordinate << "\n";
 | 
				
			||||||
    std::cout << "normal = " << normal << "\n";
 | 
					    std::cout << "normal = " << normal << "\n";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  mpq_class nlen2 = math::length_squared(normal);
 | 
					  mpq_class nlen2 = normal.length_squared();
 | 
				
			||||||
  mpq_class max_abs_slope = -1;
 | 
					  mpq_class max_abs_slope = -1;
 | 
				
			||||||
  Edge esort;
 | 
					  Edge esort;
 | 
				
			||||||
  const Vector<Edge> &edges = tmtopo.vert_edges(closestp);
 | 
					  const Vector<Edge> &edges = tmtopo.vert_edges(closestp);
 | 
				
			||||||
@@ -1647,12 +1648,12 @@ static Edge find_good_sorting_edge(const Vert *testp,
 | 
				
			|||||||
    const mpq3 &co_other = v_other->co_exact;
 | 
					    const mpq3 &co_other = v_other->co_exact;
 | 
				
			||||||
    mpq3 evec = co_other - co_closest;
 | 
					    mpq3 evec = co_other - co_closest;
 | 
				
			||||||
    /* Get projection of evec onto plane of abscissa and ordinate. */
 | 
					    /* Get projection of evec onto plane of abscissa and ordinate. */
 | 
				
			||||||
    mpq3 proj_evec = evec - (math::dot(evec, normal) / nlen2) * normal;
 | 
					    mpq3 proj_evec = evec - (mpq3::dot(evec, normal) / nlen2) * normal;
 | 
				
			||||||
    /* The projection calculations along the abscissa and ordinate should
 | 
					    /* The projection calculations along the abscissa and ordinate should
 | 
				
			||||||
     * be scaled by 1/abscissa and 1/ordinate respectively,
 | 
					     * be scaled by 1/abscissa and 1/ordinate respectively,
 | 
				
			||||||
     * but we can skip: it won't affect which `evec` has the maximum slope. */
 | 
					     * but we can skip: it won't affect which `evec` has the maximum slope. */
 | 
				
			||||||
    mpq_class evec_a = math::dot(proj_evec, abscissa);
 | 
					    mpq_class evec_a = mpq3::dot(proj_evec, abscissa);
 | 
				
			||||||
    mpq_class evec_o = math::dot(proj_evec, ordinate);
 | 
					    mpq_class evec_o = mpq3::dot(proj_evec, ordinate);
 | 
				
			||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "e = " << e << "\n";
 | 
					      std::cout << "e = " << e << "\n";
 | 
				
			||||||
      std::cout << "v_other = " << v_other << "\n";
 | 
					      std::cout << "v_other = " << v_other << "\n";
 | 
				
			||||||
@@ -1790,8 +1791,8 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
  ap = p;
 | 
					  ap = p;
 | 
				
			||||||
  ap -= a;
 | 
					  ap -= a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mpq_class d1 = math::dot_with_buffer(ab, ap, m);
 | 
					  mpq_class d1 = mpq3::dot_with_buffer(ab, ap, m);
 | 
				
			||||||
  mpq_class d2 = math::dot_with_buffer(ac, ap, m);
 | 
					  mpq_class d2 = mpq3::dot_with_buffer(ac, ap, m);
 | 
				
			||||||
  if (d1 <= 0 && d2 <= 0) {
 | 
					  if (d1 <= 0 && d2 <= 0) {
 | 
				
			||||||
    /* Barycentric coordinates (1,0,0). */
 | 
					    /* Barycentric coordinates (1,0,0). */
 | 
				
			||||||
    *r_edge = -1;
 | 
					    *r_edge = -1;
 | 
				
			||||||
@@ -1799,13 +1800,13 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = a\n";
 | 
					      std::cout << "  answer = a\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, a, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, a, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* Check if p in vertex region outside b. */
 | 
					  /* Check if p in vertex region outside b. */
 | 
				
			||||||
  bp = p;
 | 
					  bp = p;
 | 
				
			||||||
  bp -= b;
 | 
					  bp -= b;
 | 
				
			||||||
  mpq_class d3 = math::dot_with_buffer(ab, bp, m);
 | 
					  mpq_class d3 = mpq3::dot_with_buffer(ab, bp, m);
 | 
				
			||||||
  mpq_class d4 = math::dot_with_buffer(ac, bp, m);
 | 
					  mpq_class d4 = mpq3::dot_with_buffer(ac, bp, m);
 | 
				
			||||||
  if (d3 >= 0 && d4 <= d3) {
 | 
					  if (d3 >= 0 && d4 <= d3) {
 | 
				
			||||||
    /* Barycentric coordinates (0,1,0). */
 | 
					    /* Barycentric coordinates (0,1,0). */
 | 
				
			||||||
    *r_edge = -1;
 | 
					    *r_edge = -1;
 | 
				
			||||||
@@ -1813,7 +1814,7 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = b\n";
 | 
					      std::cout << "  answer = b\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, b, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, b, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* Check if p in region of ab. */
 | 
					  /* Check if p in region of ab. */
 | 
				
			||||||
  mpq_class vc = d1 * d4 - d3 * d2;
 | 
					  mpq_class vc = d1 * d4 - d3 * d2;
 | 
				
			||||||
@@ -1828,13 +1829,13 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = on ab at " << r << "\n";
 | 
					      std::cout << "  answer = on ab at " << r << "\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, r, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, r, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* Check if p in vertex region outside c. */
 | 
					  /* Check if p in vertex region outside c. */
 | 
				
			||||||
  cp = p;
 | 
					  cp = p;
 | 
				
			||||||
  cp -= c;
 | 
					  cp -= c;
 | 
				
			||||||
  mpq_class d5 = math::dot_with_buffer(ab, cp, m);
 | 
					  mpq_class d5 = mpq3::dot_with_buffer(ab, cp, m);
 | 
				
			||||||
  mpq_class d6 = math::dot_with_buffer(ac, cp, m);
 | 
					  mpq_class d6 = mpq3::dot_with_buffer(ac, cp, m);
 | 
				
			||||||
  if (d6 >= 0 && d5 <= d6) {
 | 
					  if (d6 >= 0 && d5 <= d6) {
 | 
				
			||||||
    /* Barycentric coordinates (0,0,1). */
 | 
					    /* Barycentric coordinates (0,0,1). */
 | 
				
			||||||
    *r_edge = -1;
 | 
					    *r_edge = -1;
 | 
				
			||||||
@@ -1842,7 +1843,7 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = c\n";
 | 
					      std::cout << "  answer = c\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, c, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, c, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* Check if p in edge region of ac. */
 | 
					  /* Check if p in edge region of ac. */
 | 
				
			||||||
  mpq_class vb = d5 * d2 - d1 * d6;
 | 
					  mpq_class vb = d5 * d2 - d1 * d6;
 | 
				
			||||||
@@ -1857,7 +1858,7 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = on ac at " << r << "\n";
 | 
					      std::cout << "  answer = on ac at " << r << "\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, r, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, r, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* Check if p in edge region of bc. */
 | 
					  /* Check if p in edge region of bc. */
 | 
				
			||||||
  mpq_class va = d3 * d6 - d5 * d4;
 | 
					  mpq_class va = d3 * d6 - d5 * d4;
 | 
				
			||||||
@@ -1873,7 +1874,7 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
    if (dbg_level > 0) {
 | 
					    if (dbg_level > 0) {
 | 
				
			||||||
      std::cout << "  answer = on bc at " << r << "\n";
 | 
					      std::cout << "  answer = on bc at " << r << "\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return math::distance_squared_with_buffer(p, r, m);
 | 
					    return mpq3::distance_squared_with_buffer(p, r, m);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  /* p inside face region. Compute barycentric coordinates (u,v,w). */
 | 
					  /* p inside face region. Compute barycentric coordinates (u,v,w). */
 | 
				
			||||||
  mpq_class denom = 1 / (va + vb + vc);
 | 
					  mpq_class denom = 1 / (va + vb + vc);
 | 
				
			||||||
@@ -1889,7 +1890,7 @@ static mpq_class closest_on_tri_to_point(const mpq3 &p,
 | 
				
			|||||||
  if (dbg_level > 0) {
 | 
					  if (dbg_level > 0) {
 | 
				
			||||||
    std::cout << "  answer = inside at " << r << "\n";
 | 
					    std::cout << "  answer = inside at " << r << "\n";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return math::distance_squared_with_buffer(p, r, m);
 | 
					  return mpq3::distance_squared_with_buffer(p, r, m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static float closest_on_tri_to_point_float_dist_squared(const float3 &p,
 | 
					static float closest_on_tri_to_point_float_dist_squared(const float3 &p,
 | 
				
			||||||
@@ -2609,7 +2610,7 @@ static void test_tri_inside_shapes(const IMesh &tm,
 | 
				
			|||||||
  double3 test_point = calc_point_inside_tri_db(tri_test);
 | 
					  double3 test_point = calc_point_inside_tri_db(tri_test);
 | 
				
			||||||
  /* Offset the test point a tiny bit in the tri_test normal direction. */
 | 
					  /* Offset the test point a tiny bit in the tri_test normal direction. */
 | 
				
			||||||
  tri_test.populate_plane(false);
 | 
					  tri_test.populate_plane(false);
 | 
				
			||||||
  double3 norm = math::normalize(tri_test.plane->norm);
 | 
					  double3 norm = tri_test.plane->norm.normalized();
 | 
				
			||||||
  const double offset_amount = 1e-5;
 | 
					  const double offset_amount = 1e-5;
 | 
				
			||||||
  double3 offset_test_point = test_point + offset_amount * norm;
 | 
					  double3 offset_test_point = test_point + offset_amount * norm;
 | 
				
			||||||
  if (dbg_level > 0) {
 | 
					  if (dbg_level > 0) {
 | 
				
			||||||
@@ -3001,7 +3002,7 @@ static void init_face_merge_state(FaceMergeState *fms,
 | 
				
			|||||||
      std::cout << "process tri = " << &tri << "\n";
 | 
					      std::cout << "process tri = " << &tri << "\n";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    BLI_assert(tri.plane_populated());
 | 
					    BLI_assert(tri.plane_populated());
 | 
				
			||||||
    if (math::dot(norm, tri.plane->norm) <= 0.0) {
 | 
					    if (double3::dot(norm, tri.plane->norm) <= 0.0) {
 | 
				
			||||||
      if (dbg_level > 0) {
 | 
					      if (dbg_level > 0) {
 | 
				
			||||||
        std::cout << "triangle has wrong orientation, skipping\n";
 | 
					        std::cout << "triangle has wrong orientation, skipping\n";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -3026,7 +3027,7 @@ static void init_face_merge_state(FaceMergeState *fms,
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      if (me_index == -1) {
 | 
					      if (me_index == -1) {
 | 
				
			||||||
        double3 vec = new_me.v2->co - new_me.v1->co;
 | 
					        double3 vec = new_me.v2->co - new_me.v1->co;
 | 
				
			||||||
        new_me.len_squared = math::length_squared(vec);
 | 
					        new_me.len_squared = vec.length_squared();
 | 
				
			||||||
        new_me.orig = tri.edge_orig[i];
 | 
					        new_me.orig = tri.edge_orig[i];
 | 
				
			||||||
        new_me.is_intersect = tri.is_intersect[i];
 | 
					        new_me.is_intersect = tri.is_intersect[i];
 | 
				
			||||||
        new_me.dissolvable = (new_me.orig == NO_INDEX && !new_me.is_intersect);
 | 
					        new_me.dissolvable = (new_me.orig == NO_INDEX && !new_me.is_intersect);
 | 
				
			||||||
@@ -3266,7 +3267,7 @@ static Vector<Face *> merge_tris_for_face(Vector<int> tris,
 | 
				
			|||||||
  bool done = false;
 | 
					  bool done = false;
 | 
				
			||||||
  double3 first_tri_normal = tm.face(tris[0])->plane->norm;
 | 
					  double3 first_tri_normal = tm.face(tris[0])->plane->norm;
 | 
				
			||||||
  double3 second_tri_normal = tm.face(tris[1])->plane->norm;
 | 
					  double3 second_tri_normal = tm.face(tris[1])->plane->norm;
 | 
				
			||||||
  if (tris.size() == 2 && math::dot(first_tri_normal, second_tri_normal) > 0.0) {
 | 
					  if (tris.size() == 2 && double3::dot(first_tri_normal, second_tri_normal) > 0.0) {
 | 
				
			||||||
    /* Is this a case where quad with one diagonal remained unchanged?
 | 
					    /* Is this a case where quad with one diagonal remained unchanged?
 | 
				
			||||||
     * Worth special handling because this case will be very common. */
 | 
					     * Worth special handling because this case will be very common. */
 | 
				
			||||||
    Face &tri1 = *tm.face(tris[0]);
 | 
					    Face &tri1 = *tm.face(tris[0]);
 | 
				
			||||||
@@ -3331,7 +3332,7 @@ static bool approx_in_line(const double3 &a, const double3 &b, const double3 &c)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  double3 vec1 = b - a;
 | 
					  double3 vec1 = b - a;
 | 
				
			||||||
  double3 vec2 = c - b;
 | 
					  double3 vec2 = c - b;
 | 
				
			||||||
  double cos_ang = math::dot(math::normalize(vec1), math::normalize(vec2));
 | 
					  double cos_ang = double3::dot(vec1.normalized(), vec2.normalized());
 | 
				
			||||||
  return fabs(cos_ang - 1.0) < 1e-4;
 | 
					  return fabs(cos_ang - 1.0) < 1e-4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,15 @@
 | 
				
			|||||||
#  include "BLI_array.hh"
 | 
					#  include "BLI_array.hh"
 | 
				
			||||||
#  include "BLI_assert.h"
 | 
					#  include "BLI_assert.h"
 | 
				
			||||||
#  include "BLI_delaunay_2d.h"
 | 
					#  include "BLI_delaunay_2d.h"
 | 
				
			||||||
 | 
					#  include "BLI_double3.hh"
 | 
				
			||||||
 | 
					#  include "BLI_float3.hh"
 | 
				
			||||||
#  include "BLI_hash.hh"
 | 
					#  include "BLI_hash.hh"
 | 
				
			||||||
#  include "BLI_kdopbvh.h"
 | 
					#  include "BLI_kdopbvh.h"
 | 
				
			||||||
#  include "BLI_map.hh"
 | 
					#  include "BLI_map.hh"
 | 
				
			||||||
#  include "BLI_math_boolean.hh"
 | 
					#  include "BLI_math_boolean.hh"
 | 
				
			||||||
#  include "BLI_math_mpq.hh"
 | 
					#  include "BLI_math_mpq.hh"
 | 
				
			||||||
#  include "BLI_math_vec_mpq_types.hh"
 | 
					#  include "BLI_mpq2.hh"
 | 
				
			||||||
#  include "BLI_math_vec_types.hh"
 | 
					#  include "BLI_mpq3.hh"
 | 
				
			||||||
#  include "BLI_polyfill_2d.h"
 | 
					#  include "BLI_polyfill_2d.h"
 | 
				
			||||||
#  include "BLI_set.hh"
 | 
					#  include "BLI_set.hh"
 | 
				
			||||||
#  include "BLI_span.hh"
 | 
					#  include "BLI_span.hh"
 | 
				
			||||||
@@ -196,14 +198,14 @@ void Face::populate_plane(bool need_exact)
 | 
				
			|||||||
      for (int i : index_range()) {
 | 
					      for (int i : index_range()) {
 | 
				
			||||||
        co[i] = vert[i]->co_exact;
 | 
					        co[i] = vert[i]->co_exact;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      normal_exact = math::cross_poly(co.as_span());
 | 
					      normal_exact = mpq3::cross_poly(co);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      mpq3 tr02 = vert[0]->co_exact - vert[2]->co_exact;
 | 
					      mpq3 tr02 = vert[0]->co_exact - vert[2]->co_exact;
 | 
				
			||||||
      mpq3 tr12 = vert[1]->co_exact - vert[2]->co_exact;
 | 
					      mpq3 tr12 = vert[1]->co_exact - vert[2]->co_exact;
 | 
				
			||||||
      normal_exact = math::cross(tr02, tr12);
 | 
					      normal_exact = mpq3::cross(tr02, tr12);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mpq_class d_exact = -math::dot(normal_exact, vert[0]->co_exact);
 | 
					    mpq_class d_exact = -mpq3::dot(normal_exact, vert[0]->co_exact);
 | 
				
			||||||
    plane = new Plane(normal_exact, d_exact);
 | 
					    plane = new Plane(normal_exact, d_exact);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
@@ -213,14 +215,14 @@ void Face::populate_plane(bool need_exact)
 | 
				
			|||||||
      for (int i : index_range()) {
 | 
					      for (int i : index_range()) {
 | 
				
			||||||
        co[i] = vert[i]->co;
 | 
					        co[i] = vert[i]->co;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      normal = math::cross_poly(co.as_span());
 | 
					      normal = double3::cross_poly(co);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
      double3 tr02 = vert[0]->co - vert[2]->co;
 | 
					      double3 tr02 = vert[0]->co - vert[2]->co;
 | 
				
			||||||
      double3 tr12 = vert[1]->co - vert[2]->co;
 | 
					      double3 tr12 = vert[1]->co - vert[2]->co;
 | 
				
			||||||
      normal = math::cross(tr02, tr12);
 | 
					      normal = double3::cross_high_precision(tr02, tr12);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    double d = -math::dot(normal, vert[0]->co);
 | 
					    double d = -double3::dot(normal, vert[0]->co);
 | 
				
			||||||
    plane = new Plane(normal, d);
 | 
					    plane = new Plane(normal, d);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1096,15 +1098,15 @@ static mpq2 project_3d_to_2d(const mpq3 &p3d, int proj_axis)
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
static double supremum_dot_cross(const double3 &a, const double3 &b)
 | 
					static double supremum_dot_cross(const double3 &a, const double3 &b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  double3 abs_a = math::abs(a);
 | 
					  double3 abs_a = double3::abs(a);
 | 
				
			||||||
  double3 abs_b = math::abs(b);
 | 
					  double3 abs_b = double3::abs(b);
 | 
				
			||||||
  double3 c;
 | 
					  double3 c;
 | 
				
			||||||
  /* This is dot(cross(a, b), cross(a,b)) but using absolute values for a and b
 | 
					  /* This is dot(cross(a, b), cross(a,b)) but using absolute values for a and b
 | 
				
			||||||
   * and always using + when operation is + or -. */
 | 
					   * and always using + when operation is + or -. */
 | 
				
			||||||
  c[0] = abs_a[1] * abs_b[2] + abs_a[2] * abs_b[1];
 | 
					  c[0] = abs_a[1] * abs_b[2] + abs_a[2] * abs_b[1];
 | 
				
			||||||
  c[1] = abs_a[2] * abs_b[0] + abs_a[0] * abs_b[2];
 | 
					  c[1] = abs_a[2] * abs_b[0] + abs_a[0] * abs_b[2];
 | 
				
			||||||
  c[2] = abs_a[0] * abs_b[1] + abs_a[1] * abs_b[0];
 | 
					  c[2] = abs_a[0] * abs_b[1] + abs_a[1] * abs_b[0];
 | 
				
			||||||
  return math::dot(c, c);
 | 
					  return double3::dot(c, c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The index of dot when inputs are plane_coords with index 1 is much higher.
 | 
					/* The index of dot when inputs are plane_coords with index 1 is much higher.
 | 
				
			||||||
@@ -1141,11 +1143,11 @@ static int filter_plane_side(const double3 &p,
 | 
				
			|||||||
                             const double3 &abs_plane_p,
 | 
					                             const double3 &abs_plane_p,
 | 
				
			||||||
                             const double3 &abs_plane_no)
 | 
					                             const double3 &abs_plane_no)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  double d = math::dot(p - plane_p, plane_no);
 | 
					  double d = double3::dot(p - plane_p, plane_no);
 | 
				
			||||||
  if (d == 0.0) {
 | 
					  if (d == 0.0) {
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  double supremum = math::dot(abs_p + abs_plane_p, abs_plane_no);
 | 
					  double supremum = double3::dot(abs_p + abs_plane_p, abs_plane_no);
 | 
				
			||||||
  double err_bound = supremum * index_plane_side * DBL_EPSILON;
 | 
					  double err_bound = supremum * index_plane_side * DBL_EPSILON;
 | 
				
			||||||
  if (fabs(d) > err_bound) {
 | 
					  if (fabs(d) > err_bound) {
 | 
				
			||||||
    return d > 0 ? 1 : -1;
 | 
					    return d > 0 ? 1 : -1;
 | 
				
			||||||
@@ -1176,9 +1178,9 @@ static inline mpq3 tti_interp(
 | 
				
			|||||||
  ab -= b;
 | 
					  ab -= b;
 | 
				
			||||||
  ac = a;
 | 
					  ac = a;
 | 
				
			||||||
  ac -= c;
 | 
					  ac -= c;
 | 
				
			||||||
  mpq_class den = math::dot_with_buffer(ab, n, dotbuf);
 | 
					  mpq_class den = mpq3::dot_with_buffer(ab, n, dotbuf);
 | 
				
			||||||
  BLI_assert(den != 0);
 | 
					  BLI_assert(den != 0);
 | 
				
			||||||
  mpq_class alpha = math::dot_with_buffer(ac, n, dotbuf) / den;
 | 
					  mpq_class alpha = mpq3::dot_with_buffer(ac, n, dotbuf) / den;
 | 
				
			||||||
  return a - alpha * ab;
 | 
					  return a - alpha * ab;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1207,7 +1209,7 @@ static inline int tti_above(const mpq3 &a,
 | 
				
			|||||||
  n.y = ba.z * ca.x - ba.x * ca.z;
 | 
					  n.y = ba.z * ca.x - ba.x * ca.z;
 | 
				
			||||||
  n.z = ba.x * ca.y - ba.y * ca.x;
 | 
					  n.z = ba.x * ca.y - ba.y * ca.x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return sgn(math::dot_with_buffer(ad, n, dotbuf));
 | 
					  return sgn(mpq3::dot_with_buffer(ad, n, dotbuf));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -1426,11 +1428,11 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
 | 
				
			|||||||
  const double3 &d_r2 = vr2->co;
 | 
					  const double3 &d_r2 = vr2->co;
 | 
				
			||||||
  const double3 &d_n2 = tri2.plane->norm;
 | 
					  const double3 &d_n2 = tri2.plane->norm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const double3 &abs_d_p1 = math::abs(d_p1);
 | 
					  const double3 &abs_d_p1 = double3::abs(d_p1);
 | 
				
			||||||
  const double3 &abs_d_q1 = math::abs(d_q1);
 | 
					  const double3 &abs_d_q1 = double3::abs(d_q1);
 | 
				
			||||||
  const double3 &abs_d_r1 = math::abs(d_r1);
 | 
					  const double3 &abs_d_r1 = double3::abs(d_r1);
 | 
				
			||||||
  const double3 &abs_d_r2 = math::abs(d_r2);
 | 
					  const double3 &abs_d_r2 = double3::abs(d_r2);
 | 
				
			||||||
  const double3 &abs_d_n2 = math::abs(d_n2);
 | 
					  const double3 &abs_d_n2 = double3::abs(d_n2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int sp1 = filter_plane_side(d_p1, d_r2, d_n2, abs_d_p1, abs_d_r2, abs_d_n2);
 | 
					  int sp1 = filter_plane_side(d_p1, d_r2, d_n2, abs_d_p1, abs_d_r2, abs_d_n2);
 | 
				
			||||||
  int sq1 = filter_plane_side(d_q1, d_r2, d_n2, abs_d_q1, abs_d_r2, abs_d_n2);
 | 
					  int sq1 = filter_plane_side(d_q1, d_r2, d_n2, abs_d_q1, abs_d_r2, abs_d_n2);
 | 
				
			||||||
@@ -1446,9 +1448,9 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const double3 &d_n1 = tri1.plane->norm;
 | 
					  const double3 &d_n1 = tri1.plane->norm;
 | 
				
			||||||
  const double3 &abs_d_p2 = math::abs(d_p2);
 | 
					  const double3 &abs_d_p2 = double3::abs(d_p2);
 | 
				
			||||||
  const double3 &abs_d_q2 = math::abs(d_q2);
 | 
					  const double3 &abs_d_q2 = double3::abs(d_q2);
 | 
				
			||||||
  const double3 &abs_d_n1 = math::abs(d_n1);
 | 
					  const double3 &abs_d_n1 = double3::abs(d_n1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int sp2 = filter_plane_side(d_p2, d_r1, d_n1, abs_d_p2, abs_d_r1, abs_d_n1);
 | 
					  int sp2 = filter_plane_side(d_p2, d_r1, d_n1, abs_d_p2, abs_d_r1, abs_d_n1);
 | 
				
			||||||
  int sq2 = filter_plane_side(d_q2, d_r1, d_n1, abs_d_q2, abs_d_r1, abs_d_n1);
 | 
					  int sq2 = filter_plane_side(d_q2, d_r1, d_n1, abs_d_q2, abs_d_r1, abs_d_n1);
 | 
				
			||||||
@@ -1475,17 +1477,17 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
 | 
				
			|||||||
  if (sp1 == 0) {
 | 
					  if (sp1 == 0) {
 | 
				
			||||||
    buf[0] = p1;
 | 
					    buf[0] = p1;
 | 
				
			||||||
    buf[0] -= r2;
 | 
					    buf[0] -= r2;
 | 
				
			||||||
    sp1 = sgn(math::dot_with_buffer(buf[0], n2, buf[1]));
 | 
					    sp1 = sgn(mpq3::dot_with_buffer(buf[0], n2, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (sq1 == 0) {
 | 
					  if (sq1 == 0) {
 | 
				
			||||||
    buf[0] = q1;
 | 
					    buf[0] = q1;
 | 
				
			||||||
    buf[0] -= r2;
 | 
					    buf[0] -= r2;
 | 
				
			||||||
    sq1 = sgn(math::dot_with_buffer(buf[0], n2, buf[1]));
 | 
					    sq1 = sgn(mpq3::dot_with_buffer(buf[0], n2, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (sr1 == 0) {
 | 
					  if (sr1 == 0) {
 | 
				
			||||||
    buf[0] = r1;
 | 
					    buf[0] = r1;
 | 
				
			||||||
    buf[0] -= r2;
 | 
					    buf[0] -= r2;
 | 
				
			||||||
    sr1 = sgn(math::dot_with_buffer(buf[0], n2, buf[1]));
 | 
					    sr1 = sgn(mpq3::dot_with_buffer(buf[0], n2, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (dbg_level > 1) {
 | 
					  if (dbg_level > 1) {
 | 
				
			||||||
@@ -1507,17 +1509,17 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
 | 
				
			|||||||
  if (sp2 == 0) {
 | 
					  if (sp2 == 0) {
 | 
				
			||||||
    buf[0] = p2;
 | 
					    buf[0] = p2;
 | 
				
			||||||
    buf[0] -= r1;
 | 
					    buf[0] -= r1;
 | 
				
			||||||
    sp2 = sgn(math::dot_with_buffer(buf[0], n1, buf[1]));
 | 
					    sp2 = sgn(mpq3::dot_with_buffer(buf[0], n1, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (sq2 == 0) {
 | 
					  if (sq2 == 0) {
 | 
				
			||||||
    buf[0] = q2;
 | 
					    buf[0] = q2;
 | 
				
			||||||
    buf[0] -= r1;
 | 
					    buf[0] -= r1;
 | 
				
			||||||
    sq2 = sgn(math::dot_with_buffer(buf[0], n1, buf[1]));
 | 
					    sq2 = sgn(mpq3::dot_with_buffer(buf[0], n1, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (sr2 == 0) {
 | 
					  if (sr2 == 0) {
 | 
				
			||||||
    buf[0] = r2;
 | 
					    buf[0] = r2;
 | 
				
			||||||
    buf[0] -= r1;
 | 
					    buf[0] -= r1;
 | 
				
			||||||
    sr2 = sgn(math::dot_with_buffer(buf[0], n1, buf[1]));
 | 
					    sr2 = sgn(mpq3::dot_with_buffer(buf[0], n1, buf[1]));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (dbg_level > 1) {
 | 
					  if (dbg_level > 1) {
 | 
				
			||||||
@@ -1719,7 +1721,7 @@ static CDT_data prepare_cdt_input(const IMesh &tm, int t, const Vector<ITT_value
 | 
				
			|||||||
  BLI_assert(tm.face(t)->plane_populated());
 | 
					  BLI_assert(tm.face(t)->plane_populated());
 | 
				
			||||||
  ans.t_plane = tm.face(t)->plane;
 | 
					  ans.t_plane = tm.face(t)->plane;
 | 
				
			||||||
  BLI_assert(ans.t_plane->exact_populated());
 | 
					  BLI_assert(ans.t_plane->exact_populated());
 | 
				
			||||||
  ans.proj_axis = math::dominant_axis(ans.t_plane->norm_exact);
 | 
					  ans.proj_axis = mpq3::dominant_axis(ans.t_plane->norm_exact);
 | 
				
			||||||
  prepare_need_tri(ans, tm, t);
 | 
					  prepare_need_tri(ans, tm, t);
 | 
				
			||||||
  for (const ITT_value &itt : itts) {
 | 
					  for (const ITT_value &itt : itts) {
 | 
				
			||||||
    switch (itt.kind) {
 | 
					    switch (itt.kind) {
 | 
				
			||||||
@@ -1755,7 +1757,7 @@ static CDT_data prepare_cdt_input_for_cluster(const IMesh &tm,
 | 
				
			|||||||
  BLI_assert(tm.face(t0)->plane_populated());
 | 
					  BLI_assert(tm.face(t0)->plane_populated());
 | 
				
			||||||
  ans.t_plane = tm.face(t0)->plane;
 | 
					  ans.t_plane = tm.face(t0)->plane;
 | 
				
			||||||
  BLI_assert(ans.t_plane->exact_populated());
 | 
					  BLI_assert(ans.t_plane->exact_populated());
 | 
				
			||||||
  ans.proj_axis = math::dominant_axis(ans.t_plane->norm_exact);
 | 
					  ans.proj_axis = mpq3::dominant_axis(ans.t_plane->norm_exact);
 | 
				
			||||||
  for (const int t : cl) {
 | 
					  for (const int t : cl) {
 | 
				
			||||||
    prepare_need_tri(ans, tm, t);
 | 
					    prepare_need_tri(ans, tm, t);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -2002,9 +2004,9 @@ static bool is_quad_flip_first_third(const double3 &v1,
 | 
				
			|||||||
                                     const double3 &normal)
 | 
					                                     const double3 &normal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  double3 dir_v3v1 = v3 - v1;
 | 
					  double3 dir_v3v1 = v3 - v1;
 | 
				
			||||||
  double3 tangent = math::cross(dir_v3v1, normal);
 | 
					  double3 tangent = double3::cross_high_precision(dir_v3v1, normal);
 | 
				
			||||||
  double dot = math::dot(v1, tangent);
 | 
					  double dot = double3::dot(v1, tangent);
 | 
				
			||||||
  return (math::dot(v4, tangent) >= dot) || (math::dot(v2, tangent) <= dot);
 | 
					  return (double3::dot(v4, tangent) >= dot) || (double3::dot(v2, tangent) <= dot);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -2122,7 +2124,7 @@ static Array<Face *> exact_triangulate_poly(Face *f, IMeshArena *arena)
 | 
				
			|||||||
    f->populate_plane(false);
 | 
					    f->populate_plane(false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  const double3 &poly_normal = f->plane->norm;
 | 
					  const double3 &poly_normal = f->plane->norm;
 | 
				
			||||||
  int axis = math::dominant_axis(poly_normal);
 | 
					  int axis = double3::dominant_axis(poly_normal);
 | 
				
			||||||
  /* If project down y axis as opposed to x or z, the orientation
 | 
					  /* If project down y axis as opposed to x or z, the orientation
 | 
				
			||||||
   * of the polygon will be reversed.
 | 
					   * of the polygon will be reversed.
 | 
				
			||||||
   * Yet another reversal happens if the poly normal in the dominant
 | 
					   * Yet another reversal happens if the poly normal in the dominant
 | 
				
			||||||
@@ -2201,15 +2203,15 @@ static bool face_is_degenerate(const Face *f)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  double3 da = v2->co - v0->co;
 | 
					  double3 da = v2->co - v0->co;
 | 
				
			||||||
  double3 db = v2->co - v1->co;
 | 
					  double3 db = v2->co - v1->co;
 | 
				
			||||||
  double3 dab = math::cross(da, db);
 | 
					  double3 dab = double3::cross_high_precision(da, db);
 | 
				
			||||||
  double dab_length_squared = math::length_squared(dab);
 | 
					  double dab_length_squared = dab.length_squared();
 | 
				
			||||||
  double err_bound = supremum_dot_cross(dab, dab) * index_dot_cross * DBL_EPSILON;
 | 
					  double err_bound = supremum_dot_cross(dab, dab) * index_dot_cross * DBL_EPSILON;
 | 
				
			||||||
  if (dab_length_squared > err_bound) {
 | 
					  if (dab_length_squared > err_bound) {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  mpq3 a = v2->co_exact - v0->co_exact;
 | 
					  mpq3 a = v2->co_exact - v0->co_exact;
 | 
				
			||||||
  mpq3 b = v2->co_exact - v1->co_exact;
 | 
					  mpq3 b = v2->co_exact - v1->co_exact;
 | 
				
			||||||
  mpq3 ab = math::cross(a, b);
 | 
					  mpq3 ab = mpq3::cross(a, b);
 | 
				
			||||||
  if (ab.x == 0 && ab.y == 0 && ab.z == 0) {
 | 
					  if (ab.x == 0 && ab.y == 0 && ab.z == 0) {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -2229,8 +2231,8 @@ static bool any_degenerate_tris_fast(const Array<Face *> triangulation)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    double3 da = v2->co - v0->co;
 | 
					    double3 da = v2->co - v0->co;
 | 
				
			||||||
    double3 db = v2->co - v1->co;
 | 
					    double3 db = v2->co - v1->co;
 | 
				
			||||||
    double da_length_squared = math::length_squared(da);
 | 
					    double da_length_squared = da.length_squared();
 | 
				
			||||||
    double db_length_squared = math::length_squared(db);
 | 
					    double db_length_squared = db.length_squared();
 | 
				
			||||||
    if (da_length_squared == 0.0 || db_length_squared == 0.0) {
 | 
					    if (da_length_squared == 0.0 || db_length_squared == 0.0) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -2238,8 +2240,8 @@ static bool any_degenerate_tris_fast(const Array<Face *> triangulation)
 | 
				
			|||||||
     * The triangle is almost degenerate if sin t is almost 0.
 | 
					     * The triangle is almost degenerate if sin t is almost 0.
 | 
				
			||||||
     * sin^2 t = |da x db|^2 / (|da|^2 |db|^2)
 | 
					     * sin^2 t = |da x db|^2 / (|da|^2 |db|^2)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    double3 dab = math::cross(da, db);
 | 
					    double3 dab = double3::cross_high_precision(da, db);
 | 
				
			||||||
    double dab_length_squared = math::length_squared(dab);
 | 
					    double dab_length_squared = dab.length_squared();
 | 
				
			||||||
    double sin_squared_t = dab_length_squared / (da_length_squared * db_length_squared);
 | 
					    double sin_squared_t = dab_length_squared / (da_length_squared * db_length_squared);
 | 
				
			||||||
    if (sin_squared_t < 1e-8) {
 | 
					    if (sin_squared_t < 1e-8) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,9 @@
 | 
				
			|||||||
#include <cmath>
 | 
					#include <cmath>
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					#include "BLI_float4.hh"
 | 
				
			||||||
#include "BLI_math_base_safe.h"
 | 
					#include "BLI_math_base_safe.h"
 | 
				
			||||||
#include "BLI_noise.hh"
 | 
					#include "BLI_noise.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
@@ -1467,7 +1469,7 @@ void voronoi_smooth_f1(const float w,
 | 
				
			|||||||
      correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
					      correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
				
			||||||
      if (r_color != nullptr) {
 | 
					      if (r_color != nullptr) {
 | 
				
			||||||
        const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
					        const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
				
			||||||
        smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
					        smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (r_w != nullptr) {
 | 
					      if (r_w != nullptr) {
 | 
				
			||||||
        smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
 | 
					        smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
 | 
				
			||||||
@@ -1590,7 +1592,7 @@ static float voronoi_distance(const float2 a,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  switch (metric) {
 | 
					  switch (metric) {
 | 
				
			||||||
    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
					    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
				
			||||||
      return math::distance(a, b);
 | 
					      return float2::distance(a, b);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
					    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
				
			||||||
      return fabsf(a.x - b.x) + fabsf(a.y - b.y);
 | 
					      return fabsf(a.x - b.x) + fabsf(a.y - b.y);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
					    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
				
			||||||
@@ -1613,7 +1615,7 @@ void voronoi_f1(const float2 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float2 *r_position)
 | 
					                float2 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float2 cellPosition = math::floor(coord);
 | 
					  const float2 cellPosition = float2::floor(coord);
 | 
				
			||||||
  const float2 localPosition = coord - cellPosition;
 | 
					  const float2 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float minDistance = 8.0f;
 | 
					  float minDistance = 8.0f;
 | 
				
			||||||
@@ -1652,7 +1654,7 @@ void voronoi_smooth_f1(const float2 coord,
 | 
				
			|||||||
                       float3 *r_color,
 | 
					                       float3 *r_color,
 | 
				
			||||||
                       float2 *r_position)
 | 
					                       float2 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float2 cellPosition = math::floor(coord);
 | 
					  const float2 cellPosition = float2::floor(coord);
 | 
				
			||||||
  const float2 localPosition = coord - cellPosition;
 | 
					  const float2 localPosition = coord - cellPosition;
 | 
				
			||||||
  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
					  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1674,10 +1676,11 @@ void voronoi_smooth_f1(const float2 coord,
 | 
				
			|||||||
        correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
					        correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
				
			||||||
        if (r_color != nullptr) {
 | 
					        if (r_color != nullptr) {
 | 
				
			||||||
          const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
					          const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
				
			||||||
          smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
					          smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (r_position != nullptr) {
 | 
					        if (r_position != nullptr) {
 | 
				
			||||||
          smoothPosition = math::interpolate(smoothPosition, pointPosition, h) - correctionFactor;
 | 
					          smoothPosition = float2::interpolate(smoothPosition, pointPosition, h) -
 | 
				
			||||||
 | 
					                           correctionFactor;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -1701,7 +1704,7 @@ void voronoi_f2(const float2 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float2 *r_position)
 | 
					                float2 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float2 cellPosition = math::floor(coord);
 | 
					  const float2 cellPosition = float2::floor(coord);
 | 
				
			||||||
  const float2 localPosition = coord - cellPosition;
 | 
					  const float2 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float distanceF1 = 8.0f;
 | 
					  float distanceF1 = 8.0f;
 | 
				
			||||||
@@ -1745,7 +1748,7 @@ void voronoi_f2(const float2 coord,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_distance_to_edge(const float2 coord, const float randomness, float *r_distance)
 | 
					void voronoi_distance_to_edge(const float2 coord, const float randomness, float *r_distance)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float2 cellPosition = math::floor(coord);
 | 
					  const float2 cellPosition = float2::floor(coord);
 | 
				
			||||||
  const float2 localPosition = coord - cellPosition;
 | 
					  const float2 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float2 vectorToClosest = float2(0.0f, 0.0f);
 | 
					  float2 vectorToClosest = float2(0.0f, 0.0f);
 | 
				
			||||||
@@ -1774,7 +1777,7 @@ void voronoi_distance_to_edge(const float2 coord, const float randomness, float
 | 
				
			|||||||
      const float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
					      const float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
				
			||||||
      if (dot_v2v2(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
					      if (dot_v2v2(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
				
			||||||
        const float distanceToEdge = dot_v2v2((vectorToClosest + vectorToPoint) / 2.0f,
 | 
					        const float distanceToEdge = dot_v2v2((vectorToClosest + vectorToPoint) / 2.0f,
 | 
				
			||||||
                                              math::normalize(perpendicularToEdge));
 | 
					                                              perpendicularToEdge.normalized());
 | 
				
			||||||
        minDistance = std::min(minDistance, distanceToEdge);
 | 
					        minDistance = std::min(minDistance, distanceToEdge);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -1784,7 +1787,7 @@ void voronoi_distance_to_edge(const float2 coord, const float randomness, float
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_n_sphere_radius(const float2 coord, const float randomness, float *r_radius)
 | 
					void voronoi_n_sphere_radius(const float2 coord, const float randomness, float *r_radius)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float2 cellPosition = math::floor(coord);
 | 
					  const float2 cellPosition = float2::floor(coord);
 | 
				
			||||||
  const float2 localPosition = coord - cellPosition;
 | 
					  const float2 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float2 closestPoint = float2(0.0f, 0.0f);
 | 
					  float2 closestPoint = float2(0.0f, 0.0f);
 | 
				
			||||||
@@ -1795,7 +1798,7 @@ void voronoi_n_sphere_radius(const float2 coord, const float randomness, float *
 | 
				
			|||||||
      const float2 cellOffset = float2(i, j);
 | 
					      const float2 cellOffset = float2(i, j);
 | 
				
			||||||
      const float2 pointPosition = cellOffset +
 | 
					      const float2 pointPosition = cellOffset +
 | 
				
			||||||
                                   hash_float_to_float2(cellPosition + cellOffset) * randomness;
 | 
					                                   hash_float_to_float2(cellPosition + cellOffset) * randomness;
 | 
				
			||||||
      const float distanceToPoint = math::distance(pointPosition, localPosition);
 | 
					      const float distanceToPoint = float2::distance(pointPosition, localPosition);
 | 
				
			||||||
      if (distanceToPoint < minDistance) {
 | 
					      if (distanceToPoint < minDistance) {
 | 
				
			||||||
        minDistance = distanceToPoint;
 | 
					        minDistance = distanceToPoint;
 | 
				
			||||||
        closestPoint = pointPosition;
 | 
					        closestPoint = pointPosition;
 | 
				
			||||||
@@ -1814,14 +1817,14 @@ void voronoi_n_sphere_radius(const float2 coord, const float randomness, float *
 | 
				
			|||||||
      const float2 cellOffset = float2(i, j) + closestPointOffset;
 | 
					      const float2 cellOffset = float2(i, j) + closestPointOffset;
 | 
				
			||||||
      const float2 pointPosition = cellOffset +
 | 
					      const float2 pointPosition = cellOffset +
 | 
				
			||||||
                                   hash_float_to_float2(cellPosition + cellOffset) * randomness;
 | 
					                                   hash_float_to_float2(cellPosition + cellOffset) * randomness;
 | 
				
			||||||
      const float distanceToPoint = math::distance(closestPoint, pointPosition);
 | 
					      const float distanceToPoint = float2::distance(closestPoint, pointPosition);
 | 
				
			||||||
      if (distanceToPoint < minDistance) {
 | 
					      if (distanceToPoint < minDistance) {
 | 
				
			||||||
        minDistance = distanceToPoint;
 | 
					        minDistance = distanceToPoint;
 | 
				
			||||||
        closestPointToClosestPoint = pointPosition;
 | 
					        closestPointToClosestPoint = pointPosition;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
					  *r_radius = float2::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* **** 3D Voronoi **** */
 | 
					/* **** 3D Voronoi **** */
 | 
				
			||||||
@@ -1833,7 +1836,7 @@ static float voronoi_distance(const float3 a,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  switch (metric) {
 | 
					  switch (metric) {
 | 
				
			||||||
    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
					    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
				
			||||||
      return math::distance(a, b);
 | 
					      return float3::distance(a, b);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
					    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
				
			||||||
      return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z);
 | 
					      return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
					    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
				
			||||||
@@ -1857,7 +1860,7 @@ void voronoi_f1(const float3 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float3 *r_position)
 | 
					                float3 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float3 cellPosition = math::floor(coord);
 | 
					  const float3 cellPosition = float3::floor(coord);
 | 
				
			||||||
  const float3 localPosition = coord - cellPosition;
 | 
					  const float3 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float minDistance = 8.0f;
 | 
					  float minDistance = 8.0f;
 | 
				
			||||||
@@ -1899,7 +1902,7 @@ void voronoi_smooth_f1(const float3 coord,
 | 
				
			|||||||
                       float3 *r_color,
 | 
					                       float3 *r_color,
 | 
				
			||||||
                       float3 *r_position)
 | 
					                       float3 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float3 cellPosition = math::floor(coord);
 | 
					  const float3 cellPosition = float3::floor(coord);
 | 
				
			||||||
  const float3 localPosition = coord - cellPosition;
 | 
					  const float3 localPosition = coord - cellPosition;
 | 
				
			||||||
  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
					  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1922,10 +1925,10 @@ void voronoi_smooth_f1(const float3 coord,
 | 
				
			|||||||
          correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
					          correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
				
			||||||
          if (r_color != nullptr) {
 | 
					          if (r_color != nullptr) {
 | 
				
			||||||
            const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
					            const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
				
			||||||
            smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
					            smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (r_position != nullptr) {
 | 
					          if (r_position != nullptr) {
 | 
				
			||||||
            smoothPosition = math::interpolate(smoothPosition, pointPosition, h) -
 | 
					            smoothPosition = float3::interpolate(smoothPosition, pointPosition, h) -
 | 
				
			||||||
                             correctionFactor;
 | 
					                             correctionFactor;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -1951,7 +1954,7 @@ void voronoi_f2(const float3 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float3 *r_position)
 | 
					                float3 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float3 cellPosition = math::floor(coord);
 | 
					  const float3 cellPosition = float3::floor(coord);
 | 
				
			||||||
  const float3 localPosition = coord - cellPosition;
 | 
					  const float3 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float distanceF1 = 8.0f;
 | 
					  float distanceF1 = 8.0f;
 | 
				
			||||||
@@ -1997,7 +2000,7 @@ void voronoi_f2(const float3 coord,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_distance_to_edge(const float3 coord, const float randomness, float *r_distance)
 | 
					void voronoi_distance_to_edge(const float3 coord, const float randomness, float *r_distance)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float3 cellPosition = math::floor(coord);
 | 
					  const float3 cellPosition = float3::floor(coord);
 | 
				
			||||||
  const float3 localPosition = coord - cellPosition;
 | 
					  const float3 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float3 vectorToClosest = float3(0.0f, 0.0f, 0.0f);
 | 
					  float3 vectorToClosest = float3(0.0f, 0.0f, 0.0f);
 | 
				
			||||||
@@ -2029,7 +2032,7 @@ void voronoi_distance_to_edge(const float3 coord, const float randomness, float
 | 
				
			|||||||
        const float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
					        const float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
				
			||||||
        if (dot_v3v3(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
					        if (dot_v3v3(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
				
			||||||
          const float distanceToEdge = dot_v3v3((vectorToClosest + vectorToPoint) / 2.0f,
 | 
					          const float distanceToEdge = dot_v3v3((vectorToClosest + vectorToPoint) / 2.0f,
 | 
				
			||||||
                                                math::normalize(perpendicularToEdge));
 | 
					                                                perpendicularToEdge.normalized());
 | 
				
			||||||
          minDistance = std::min(minDistance, distanceToEdge);
 | 
					          minDistance = std::min(minDistance, distanceToEdge);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -2040,7 +2043,7 @@ void voronoi_distance_to_edge(const float3 coord, const float randomness, float
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *r_radius)
 | 
					void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *r_radius)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float3 cellPosition = math::floor(coord);
 | 
					  const float3 cellPosition = float3::floor(coord);
 | 
				
			||||||
  const float3 localPosition = coord - cellPosition;
 | 
					  const float3 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float3 closestPoint = float3(0.0f, 0.0f, 0.0f);
 | 
					  float3 closestPoint = float3(0.0f, 0.0f, 0.0f);
 | 
				
			||||||
@@ -2052,7 +2055,7 @@ void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *
 | 
				
			|||||||
        const float3 cellOffset = float3(i, j, k);
 | 
					        const float3 cellOffset = float3(i, j, k);
 | 
				
			||||||
        const float3 pointPosition = cellOffset +
 | 
					        const float3 pointPosition = cellOffset +
 | 
				
			||||||
                                     hash_float_to_float3(cellPosition + cellOffset) * randomness;
 | 
					                                     hash_float_to_float3(cellPosition + cellOffset) * randomness;
 | 
				
			||||||
        const float distanceToPoint = math::distance(pointPosition, localPosition);
 | 
					        const float distanceToPoint = float3::distance(pointPosition, localPosition);
 | 
				
			||||||
        if (distanceToPoint < minDistance) {
 | 
					        if (distanceToPoint < minDistance) {
 | 
				
			||||||
          minDistance = distanceToPoint;
 | 
					          minDistance = distanceToPoint;
 | 
				
			||||||
          closestPoint = pointPosition;
 | 
					          closestPoint = pointPosition;
 | 
				
			||||||
@@ -2073,7 +2076,7 @@ void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *
 | 
				
			|||||||
        const float3 cellOffset = float3(i, j, k) + closestPointOffset;
 | 
					        const float3 cellOffset = float3(i, j, k) + closestPointOffset;
 | 
				
			||||||
        const float3 pointPosition = cellOffset +
 | 
					        const float3 pointPosition = cellOffset +
 | 
				
			||||||
                                     hash_float_to_float3(cellPosition + cellOffset) * randomness;
 | 
					                                     hash_float_to_float3(cellPosition + cellOffset) * randomness;
 | 
				
			||||||
        const float distanceToPoint = math::distance(closestPoint, pointPosition);
 | 
					        const float distanceToPoint = float3::distance(closestPoint, pointPosition);
 | 
				
			||||||
        if (distanceToPoint < minDistance) {
 | 
					        if (distanceToPoint < minDistance) {
 | 
				
			||||||
          minDistance = distanceToPoint;
 | 
					          minDistance = distanceToPoint;
 | 
				
			||||||
          closestPointToClosestPoint = pointPosition;
 | 
					          closestPointToClosestPoint = pointPosition;
 | 
				
			||||||
@@ -2081,7 +2084,7 @@ void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
					  *r_radius = float3::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* **** 4D Voronoi **** */
 | 
					/* **** 4D Voronoi **** */
 | 
				
			||||||
@@ -2093,7 +2096,7 @@ static float voronoi_distance(const float4 a,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  switch (metric) {
 | 
					  switch (metric) {
 | 
				
			||||||
    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
					    case NOISE_SHD_VORONOI_EUCLIDEAN:
 | 
				
			||||||
      return math::distance(a, b);
 | 
					      return float4::distance(a, b);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
					    case NOISE_SHD_VORONOI_MANHATTAN:
 | 
				
			||||||
      return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z) + fabsf(a.w - b.w);
 | 
					      return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z) + fabsf(a.w - b.w);
 | 
				
			||||||
    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
					    case NOISE_SHD_VORONOI_CHEBYCHEV:
 | 
				
			||||||
@@ -2118,7 +2121,7 @@ void voronoi_f1(const float4 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float4 *r_position)
 | 
					                float4 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float4 cellPosition = math::floor(coord);
 | 
					  const float4 cellPosition = float4::floor(coord);
 | 
				
			||||||
  const float4 localPosition = coord - cellPosition;
 | 
					  const float4 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float minDistance = 8.0f;
 | 
					  float minDistance = 8.0f;
 | 
				
			||||||
@@ -2163,7 +2166,7 @@ void voronoi_smooth_f1(const float4 coord,
 | 
				
			|||||||
                       float3 *r_color,
 | 
					                       float3 *r_color,
 | 
				
			||||||
                       float4 *r_position)
 | 
					                       float4 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float4 cellPosition = math::floor(coord);
 | 
					  const float4 cellPosition = float4::floor(coord);
 | 
				
			||||||
  const float4 localPosition = coord - cellPosition;
 | 
					  const float4 localPosition = coord - cellPosition;
 | 
				
			||||||
  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
					  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2188,10 +2191,10 @@ void voronoi_smooth_f1(const float4 coord,
 | 
				
			|||||||
            correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
					            correctionFactor /= 1.0f + 3.0f * smoothness;
 | 
				
			||||||
            if (r_color != nullptr) {
 | 
					            if (r_color != nullptr) {
 | 
				
			||||||
              const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
					              const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
 | 
				
			||||||
              smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
					              smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (r_position != nullptr) {
 | 
					            if (r_position != nullptr) {
 | 
				
			||||||
              smoothPosition = math::interpolate(smoothPosition, pointPosition, h) -
 | 
					              smoothPosition = float4::interpolate(smoothPosition, pointPosition, h) -
 | 
				
			||||||
                               correctionFactor;
 | 
					                               correctionFactor;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@@ -2218,7 +2221,7 @@ void voronoi_f2(const float4 coord,
 | 
				
			|||||||
                float3 *r_color,
 | 
					                float3 *r_color,
 | 
				
			||||||
                float4 *r_position)
 | 
					                float4 *r_position)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float4 cellPosition = math::floor(coord);
 | 
					  const float4 cellPosition = float4::floor(coord);
 | 
				
			||||||
  const float4 localPosition = coord - cellPosition;
 | 
					  const float4 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float distanceF1 = 8.0f;
 | 
					  float distanceF1 = 8.0f;
 | 
				
			||||||
@@ -2267,7 +2270,7 @@ void voronoi_f2(const float4 coord,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_distance_to_edge(const float4 coord, const float randomness, float *r_distance)
 | 
					void voronoi_distance_to_edge(const float4 coord, const float randomness, float *r_distance)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float4 cellPosition = math::floor(coord);
 | 
					  const float4 cellPosition = float4::floor(coord);
 | 
				
			||||||
  const float4 localPosition = coord - cellPosition;
 | 
					  const float4 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float4 vectorToClosest = float4(0.0f, 0.0f, 0.0f, 0.0f);
 | 
					  float4 vectorToClosest = float4(0.0f, 0.0f, 0.0f, 0.0f);
 | 
				
			||||||
@@ -2304,7 +2307,7 @@ void voronoi_distance_to_edge(const float4 coord, const float randomness, float
 | 
				
			|||||||
          const float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
					          const float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
 | 
				
			||||||
          if (dot_v4v4(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
					          if (dot_v4v4(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
 | 
				
			||||||
            const float distanceToEdge = dot_v4v4((vectorToClosest + vectorToPoint) / 2.0f,
 | 
					            const float distanceToEdge = dot_v4v4((vectorToClosest + vectorToPoint) / 2.0f,
 | 
				
			||||||
                                                  math::normalize(perpendicularToEdge));
 | 
					                                                  float4::normalize(perpendicularToEdge));
 | 
				
			||||||
            minDistance = std::min(minDistance, distanceToEdge);
 | 
					            minDistance = std::min(minDistance, distanceToEdge);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -2316,7 +2319,7 @@ void voronoi_distance_to_edge(const float4 coord, const float randomness, float
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *r_radius)
 | 
					void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *r_radius)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const float4 cellPosition = math::floor(coord);
 | 
					  const float4 cellPosition = float4::floor(coord);
 | 
				
			||||||
  const float4 localPosition = coord - cellPosition;
 | 
					  const float4 localPosition = coord - cellPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  float4 closestPoint = float4(0.0f, 0.0f, 0.0f, 0.0f);
 | 
					  float4 closestPoint = float4(0.0f, 0.0f, 0.0f, 0.0f);
 | 
				
			||||||
@@ -2330,7 +2333,7 @@ void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *
 | 
				
			|||||||
          const float4 pointPosition = cellOffset +
 | 
					          const float4 pointPosition = cellOffset +
 | 
				
			||||||
                                       hash_float_to_float4(cellPosition + cellOffset) *
 | 
					                                       hash_float_to_float4(cellPosition + cellOffset) *
 | 
				
			||||||
                                           randomness;
 | 
					                                           randomness;
 | 
				
			||||||
          const float distanceToPoint = math::distance(pointPosition, localPosition);
 | 
					          const float distanceToPoint = float4::distance(pointPosition, localPosition);
 | 
				
			||||||
          if (distanceToPoint < minDistance) {
 | 
					          if (distanceToPoint < minDistance) {
 | 
				
			||||||
            minDistance = distanceToPoint;
 | 
					            minDistance = distanceToPoint;
 | 
				
			||||||
            closestPoint = pointPosition;
 | 
					            closestPoint = pointPosition;
 | 
				
			||||||
@@ -2354,7 +2357,7 @@ void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *
 | 
				
			|||||||
          const float4 pointPosition = cellOffset +
 | 
					          const float4 pointPosition = cellOffset +
 | 
				
			||||||
                                       hash_float_to_float4(cellPosition + cellOffset) *
 | 
					                                       hash_float_to_float4(cellPosition + cellOffset) *
 | 
				
			||||||
                                           randomness;
 | 
					                                           randomness;
 | 
				
			||||||
          const float distanceToPoint = math::distance(closestPoint, pointPosition);
 | 
					          const float distanceToPoint = float4::distance(closestPoint, pointPosition);
 | 
				
			||||||
          if (distanceToPoint < minDistance) {
 | 
					          if (distanceToPoint < minDistance) {
 | 
				
			||||||
            minDistance = distanceToPoint;
 | 
					            minDistance = distanceToPoint;
 | 
				
			||||||
            closestPointToClosestPoint = pointPosition;
 | 
					            closestPointToClosestPoint = pointPosition;
 | 
				
			||||||
@@ -2363,7 +2366,7 @@ void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
					  *r_radius = float4::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** \} */
 | 
					/** \} */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,10 @@ extern "C" {
 | 
				
			|||||||
#define DO_RANDOM_TESTS 0
 | 
					#define DO_RANDOM_TESTS 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_double2.hh"
 | 
				
			||||||
#include "BLI_math_boolean.hh"
 | 
					#include "BLI_math_boolean.hh"
 | 
				
			||||||
#include "BLI_math_mpq.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vec_mpq_types.hh"
 | 
					#include "BLI_mpq2.hh"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_delaunay_2d.h"
 | 
					#include "BLI_delaunay_2d.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,149 +0,0 @@
 | 
				
			|||||||
/* Apache License, Version 2.0 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "testing/testing.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace blender::tests {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace blender::math;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, ScalarConstructorUnsigned)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float2 u(5u);
 | 
					 | 
				
			||||||
  EXPECT_EQ(u[0], 5.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(u[1], 5.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, ScalarConstructorInt)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float2 i(-5);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[0], -5.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[1], -5.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, ScalarConstructorFloat)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float2 f(5.2f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(f[0], 5.2f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(f[1], 5.2f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, ScalarConstructorDouble)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float2 d(5.2);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(d[0], 5.2f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(d[1], 5.2f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, MultiScalarConstructorVec2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int2 i(5.5f, -1.8);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[0], 5);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[1], -1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, MultiScalarConstructorVec3)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int3 i(5.5f, -1.8, 6u);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[0], 5);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[1], -1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[2], 6);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, MultiScalarConstructorVec4)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int4 i(5.5f, -1.8, 6u, 0.888f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[0], 5);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[1], -1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[2], 6);
 | 
					 | 
				
			||||||
  EXPECT_EQ(i[3], 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, MixedScalarVectorConstructorVec3)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float3 fl_v2(float2(5.5f), 1.8f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(fl_v2[0], 5.5f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(fl_v2[1], 5.5f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(fl_v2[2], 1.8f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  float3 v2_fl(1.8f, float2(5.5f));
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(v2_fl[0], 1.8f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(v2_fl[1], 5.5f);
 | 
					 | 
				
			||||||
  EXPECT_FLOAT_EQ(v2_fl[2], 5.5f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, MixedScalarVectorConstructorVec4)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int4 v2_fl_fl(float2(1), 2, 3);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_fl_fl[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_fl_fl[1], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_fl_fl[2], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_fl_fl[3], 3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  float4 fl_v2_fl(1, int2(2), 3);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v2_fl[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v2_fl[1], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v2_fl[2], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v2_fl[3], 3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  double4 fl_fl_v2(1, 2, double2(3));
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_fl_v2[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_fl_v2[1], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_fl_v2[2], 3);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_fl_v2[3], 3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int4 v2_v2(float2(1), uint2(2));
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_v2[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_v2[1], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_v2[2], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v2_v2[3], 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  float4 v3_fl(uint3(1), 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v3_fl[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v3_fl[1], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v3_fl[2], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(v3_fl[3], 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  uint4 fl_v3(1, float3(2));
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v3[0], 1);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v3[1], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v3[2], 2);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fl_v3[3], 2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, ComponentMasking)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int4 i(0, 1, 2, 3);
 | 
					 | 
				
			||||||
  float2 f2 = float2(i);
 | 
					 | 
				
			||||||
  EXPECT_EQ(f2[0], 0.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(f2[1], 1.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, PointerConversion)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float array[3] = {1.0f, 2.0f, 3.0f};
 | 
					 | 
				
			||||||
  float3 farray(array);
 | 
					 | 
				
			||||||
  EXPECT_EQ(farray[0], 1.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(farray[1], 2.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(farray[2], 3.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, PointerArrayConversion)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  float array[1][3] = {{1.0f, 2.0f, 3.0f}};
 | 
					 | 
				
			||||||
  float(*ptr)[3] = array;
 | 
					 | 
				
			||||||
  float3 fptr(ptr);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fptr[0], 1.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fptr[1], 2.0f);
 | 
					 | 
				
			||||||
  EXPECT_EQ(fptr[2], 3.0f);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(math_vec_types, VectorTypeConversion)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  double2 d(int2(float2(5.75f, -1.57f)));
 | 
					 | 
				
			||||||
  EXPECT_EQ(d[0], 5.0);
 | 
					 | 
				
			||||||
  EXPECT_EQ(d[1], -1.0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace blender::tests
 | 
					 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
/* Apache License, Version 2.0 */
 | 
					/* Apache License, Version 2.0 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_memory_utils.hh"
 | 
					#include "BLI_memory_utils.hh"
 | 
				
			||||||
#include "BLI_strict_flags.h"
 | 
					#include "BLI_strict_flags.h"
 | 
				
			||||||
#include "testing/testing.h"
 | 
					#include "testing/testing.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,8 +11,8 @@
 | 
				
			|||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
#include "BLI_map.hh"
 | 
					#include "BLI_map.hh"
 | 
				
			||||||
#include "BLI_math_mpq.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vec_mpq_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_mesh_boolean.hh"
 | 
					#include "BLI_mesh_boolean.hh"
 | 
				
			||||||
 | 
					#include "BLI_mpq3.hh"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WITH_GMP
 | 
					#ifdef WITH_GMP
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,8 +10,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
#include "BLI_math_mpq.hh"
 | 
					#include "BLI_math_mpq.hh"
 | 
				
			||||||
#include "BLI_math_vec_mpq_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_mesh_intersect.hh"
 | 
					#include "BLI_mesh_intersect.hh"
 | 
				
			||||||
 | 
					#include "BLI_mpq3.hh"
 | 
				
			||||||
#include "BLI_task.h"
 | 
					#include "BLI_task.h"
 | 
				
			||||||
#include "BLI_vector.hh"
 | 
					#include "BLI_vector.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1186,6 +1186,7 @@ static BMO_FlagSet bmo_enum_triangulate_quad_method[] = {
 | 
				
			|||||||
  {MOD_TRIANGULATE_QUAD_FIXED, "FIXED"},
 | 
					  {MOD_TRIANGULATE_QUAD_FIXED, "FIXED"},
 | 
				
			||||||
  {MOD_TRIANGULATE_QUAD_ALTERNATE, "ALTERNATE"},
 | 
					  {MOD_TRIANGULATE_QUAD_ALTERNATE, "ALTERNATE"},
 | 
				
			||||||
  {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORT_EDGE"},
 | 
					  {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORT_EDGE"},
 | 
				
			||||||
 | 
					  {MOD_TRIANGULATE_QUAD_LONGEDGE, "LONG_EDGE"},
 | 
				
			||||||
  {0, NULL},
 | 
					  {0, NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1007,6 +1007,7 @@ void BM_face_triangulate(BMesh *bm,
 | 
				
			|||||||
          break;
 | 
					          break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case MOD_TRIANGULATE_QUAD_SHORTEDGE:
 | 
					        case MOD_TRIANGULATE_QUAD_SHORTEDGE:
 | 
				
			||||||
 | 
					        case MOD_TRIANGULATE_QUAD_LONGEDGE:
 | 
				
			||||||
        case MOD_TRIANGULATE_QUAD_BEAUTY:
 | 
					        case MOD_TRIANGULATE_QUAD_BEAUTY:
 | 
				
			||||||
        default: {
 | 
					        default: {
 | 
				
			||||||
          BMLoop *l_v3, *l_v4;
 | 
					          BMLoop *l_v3, *l_v4;
 | 
				
			||||||
@@ -1023,6 +1024,12 @@ void BM_face_triangulate(BMesh *bm,
 | 
				
			|||||||
            d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
 | 
					            d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
 | 
				
			||||||
            split_24 = ((d2 - d1) > 0.0f);
 | 
					            split_24 = ((d2 - d1) > 0.0f);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          else if (quad_method == MOD_TRIANGULATE_QUAD_LONGEDGE) {
 | 
				
			||||||
 | 
					            float d1, d2;
 | 
				
			||||||
 | 
					            d1 = len_squared_v3v3(l_v4->v->co, l_v2->v->co);
 | 
				
			||||||
 | 
					            d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
 | 
				
			||||||
 | 
					            split_24 = ((d2 - d1) < 0.0f);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          else {
 | 
					          else {
 | 
				
			||||||
            /* first check if the quad is concave on either diagonal */
 | 
					            /* first check if the quad is concave on either diagonal */
 | 
				
			||||||
            const int flip_flag = is_quad_flip_v3(
 | 
					            const int flip_flag = is_quad_flip_v3(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -647,6 +647,15 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
 | 
					blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(WITH_UNITY_BUILD)
 | 
				
			||||||
 | 
					  set_target_properties(bf_compositor PROPERTIES UNITY_BUILD ON)
 | 
				
			||||||
 | 
					  set_target_properties(bf_compositor PROPERTIES UNITY_BUILD_BATCH_SIZE 10)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(COMMAND target_precompile_headers)
 | 
				
			||||||
 | 
					  target_precompile_headers(bf_compositor PRIVATE COM_precomp.h)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(CXX_WARN_NO_SUGGEST_OVERRIDE)
 | 
					if(CXX_WARN_NO_SUGGEST_OVERRIDE)
 | 
				
			||||||
  target_compile_options(bf_compositor PRIVATE "-Wsuggest-override")
 | 
					  target_compile_options(bf_compositor PRIVATE "-Wsuggest-override")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "DNA_vec_types.h"
 | 
					#include "DNA_vec_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								source/blender/compositor/COM_precomp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								source/blender/compositor/COM_precomp.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/* Pre-compiled headers, see: D13797. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cfloat>
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					#include <cstdio>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <iterator>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <ostream>
 | 
				
			||||||
 | 
					#include <set>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "COM_ConstantOperation.h"
 | 
				
			||||||
 | 
					#include "COM_ConvertOperation.h"
 | 
				
			||||||
 | 
					#include "COM_Debug.h"
 | 
				
			||||||
 | 
					#include "COM_Enums.h"
 | 
				
			||||||
 | 
					#include "COM_ExecutionGroup.h"
 | 
				
			||||||
 | 
					#include "COM_ExecutionSystem.h"
 | 
				
			||||||
 | 
					#include "COM_MultiThreadedOperation.h"
 | 
				
			||||||
 | 
					#include "COM_Node.h"
 | 
				
			||||||
 | 
					#include "COM_NodeOperation.h"
 | 
				
			||||||
 | 
					#include "COM_OpenCLDevice.h"
 | 
				
			||||||
 | 
					#include "COM_SetAlphaMultiplyOperation.h"
 | 
				
			||||||
 | 
					#include "COM_SetColorOperation.h"
 | 
				
			||||||
 | 
					#include "COM_SetSamplerOperation.h"
 | 
				
			||||||
 | 
					#include "COM_SetValueOperation.h"
 | 
				
			||||||
 | 
					#include "COM_SetVectorOperation.h"
 | 
				
			||||||
 | 
					#include "COM_defines.h"
 | 
				
			||||||
@@ -136,7 +136,7 @@ void add_exr_channels(void *exrhandle,
 | 
				
			|||||||
                      const char *layer_name,
 | 
					                      const char *layer_name,
 | 
				
			||||||
                      const DataType datatype,
 | 
					                      const DataType datatype,
 | 
				
			||||||
                      const char *view_name,
 | 
					                      const char *view_name,
 | 
				
			||||||
                      const size_t width,
 | 
					                      size_t width,
 | 
				
			||||||
                      bool use_half_float,
 | 
					                      bool use_half_float,
 | 
				
			||||||
                      float *buf);
 | 
					                      float *buf);
 | 
				
			||||||
void free_exr_channels(void *exrhandle,
 | 
					void free_exr_channels(void *exrhandle,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1475,6 +1475,17 @@ void DepsgraphRelationBuilder::build_animation_images(ID *id)
 | 
				
			|||||||
        id, NodeType::IMAGE_ANIMATION, OperationCode::IMAGE_ANIMATION);
 | 
					        id, NodeType::IMAGE_ANIMATION, OperationCode::IMAGE_ANIMATION);
 | 
				
			||||||
    TimeSourceKey time_src_key;
 | 
					    TimeSourceKey time_src_key;
 | 
				
			||||||
    add_relation(time_src_key, image_animation_key, "TimeSrc -> Image Animation");
 | 
					    add_relation(time_src_key, image_animation_key, "TimeSrc -> Image Animation");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* The image users of these ids may change during evaluation. Make sure that the image
 | 
				
			||||||
 | 
					     * animation update happens after evaluation. */
 | 
				
			||||||
 | 
					    if (GS(id->name) == ID_MA) {
 | 
				
			||||||
 | 
					      OperationKey material_update_key(id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
 | 
				
			||||||
 | 
					      add_relation(material_update_key, image_animation_key, "Material Update -> Image Animation");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (GS(id->name) == ID_WO) {
 | 
				
			||||||
 | 
					      OperationKey world_update_key(id, NodeType::SHADING, OperationCode::WORLD_UPDATE);
 | 
				
			||||||
 | 
					      add_relation(world_update_key, image_animation_key, "World Update -> Image Animation");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,7 +55,7 @@ template<class ModeObjectType> struct DepsNodeFactoryImpl : public DepsNodeFacto
 | 
				
			|||||||
void register_node_typeinfo(DepsNodeFactory *factory);
 | 
					void register_node_typeinfo(DepsNodeFactory *factory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get typeinfo for specified type */
 | 
					/* Get typeinfo for specified type */
 | 
				
			||||||
DepsNodeFactory *type_get_factory(const NodeType type);
 | 
					DepsNodeFactory *type_get_factory(NodeType type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace deg
 | 
					}  // namespace deg
 | 
				
			||||||
}  // namespace blender
 | 
					}  // namespace blender
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,8 @@
 | 
				
			|||||||
#include "MEM_guardedalloc.h"
 | 
					#include "MEM_guardedalloc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_array.hh"
 | 
					#include "BLI_array.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
#include "BLI_listbase.h"
 | 
					#include "BLI_listbase.h"
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					 | 
				
			||||||
#include "BLI_math_vector.h"
 | 
					#include "BLI_math_vector.h"
 | 
				
			||||||
#include "BLI_span.hh"
 | 
					#include "BLI_span.hh"
 | 
				
			||||||
#include "BLI_utildefines.h"
 | 
					#include "BLI_utildefines.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BLI_math_vec_types.hh"
 | 
					#include "BLI_float2.hh"
 | 
				
			||||||
 | 
					#include "BLI_float3.hh"
 | 
				
			||||||
 | 
					#include "BLI_float4.hh"
 | 
				
			||||||
#include "BLI_string.h"
 | 
					#include "BLI_string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "BKE_attribute.h"
 | 
					#include "BKE_attribute.h"
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user